Title | Pinning Proposal System for Automatic Rebuilds |
Status | Accepted |
Author(s) | Christopher J. "CJ" Wright <[email protected]>; Matthew R. Becker <[email protected]>; Marius van Niekerk <[email protected]> |
Created | Feb 20, 2019 |
Updated | Aug 30, 2019 |
Discussion | NA |
Implementation | NA |
This CFEP proposes a change to how our internal pinning system works.
To propose a migration in one or more pins a PR will be issued into
the pinning feedstock
with a yaml expressing the changes to the global
pinning file into the migrations
folder.
Once the PR is squashed and merged the bot will take the yaml
to calculate which packages need to be rebuilt and start issuing
PRs with the new pinning as a local pinning file to the feedstocks
in topo order.
This CFEP is taken from @beckermr's work on conda-forge.github.io and @mariusvniekerk's work in conda-smithy.
Currently when we move pinnings we move the pin in the conda-forge-pinning-feedstock
.
Then we start a migration using the regro-cf-autotick-bot
.
This order of operations causes some issues, when new feedstocks
are created, or existing feedstocks rerendered they receive the new pinnings
even if their dependencies are not rebuilt with the new pinnings themselves.
- We make a PR into the
migrations
folder in theconda-forge-pinning-feedstock
with a new yaml file representing the migration. - Once the change is merged, the bot picks it up, builds a migrator object and begins the migration process
- A migration PR is issued for a node only if
- The node depends on the changed pinnings.
- It has no dependencies that depend on the new pinnings and have not been migrated.
- Process 3 continues until we determine that the migration is sufficiently complete and the change is applied to the global pinning file via a PR.
Given a feedstock with the following pinnings
# Existing pins
a:
- 1.5
b:
- 1.2
someflag:
- disabled
There are four classes of pinning we can do in general.
# Existing pins
a:
- 1.5
b:
- 1.2
someflag:
- disabled |
with |
# migrator
__migrator: kind: version
a:
- 1.6
b:
- 1.1 |
-> |
# resulting pins
a:
- 1.6
b:
- 1.2
someflag:
- disabled |
These are the most common version migrations and encompass things like moving the pinnings for openssl etc.
Note that the version of b
was NOT decreased.
This is intentional as we don't wish to downgrade accidentally.
In practice many migrators could be in flight and may affect the same version.
In this case the higher version should always win.
If we want to downgrade there is a mechanism but it is purposefully clunky and bad.
# Existing pins
a:
- 1.5
python:
- 3.6
someflag:
- disabled |
with |
# migrator
__migrator: kind: version
python:
- 3.6
- 3.8a1 |
-> |
# resulting pins
a:
- 1.5
python:
- 3.6
- 3.8a1
someflag:
- disabled |
These are things like the compiler migration and can be thought of as additions to a version.
These need substantial care when dealing with things like zip_keys.
But in general it should be feasible to perform for many common cases.
This can also be used to do something like add a new python version to the matrix or remove an existing one.
For each sublist we perform the version comparison of all the elements within that list and come to a final result.
Names don't sort well and as such are a bit problematic.
However we can impose a new name by
stating what the ordering of names are.
This allows us to effectively treat a name migration exactly the the same as
a version migration because we have an ordering that we can impose on the system.
# Existing pins
c_compiler:
- toolchain_c |
with |
# migrator
__migrator:
kind: version
ordering:
c_compiler:
- toolchain_c
- gcc
c_compiler:
- gcc |
-> |
# resulting pins
c_compiler:
- gcc |
Some times we want to perform a migrator where we delete a given value and don't wish to substitute it with a new one. A deletion migration is designed purely to remove values
# Existing pins
ruamel_yaml:
- 1.40
numpy:
- 1.14 |
with |
# migrator
__migrator:
kind: deletion
ruamel_yaml:
- 1.40 |
-> |
# resulting pins
numpy:
1.14 |
To downgrade a pin one can use the order parameter
# Existing pins
jpeg:
- 3.0 |
with |
# migrator
__migrator:
ordering:
jpeg:
- 3.0
- 2.0
jpeg:
- 2.0 |
-> |
# resulting pins
jpeg:
2.0 |
Key removals followed by additions are a viable way to perform a migration to a lower version.
We have never done this really.
A feedstock can get multiple migration PRs at once, it is up to the feedstock maintainers to choose which PRs to merge in what order.
This is fully backwards compatible with the current ecosystem.
All CFEPs are explicitly CC0 1.0 Universal.