Turris OS release workflow ========================== Turris OS is released as a set of packages, updater rules and medkit of distinct version. Such set is marked as some exact Turris OS version. To facilitate automatic updates with versioned distribution updater (tool on router to facilitate updates) follows so-called branches. This makes Turris OS effectively rollings distribution as well, although you have to understand that branch is in reality some floating link to full build of Turris OS (so not a real rolling distribution with incremental packages updates). User can choose to follow various binary feeds. There are some pure branches, such as HBS and HBT and also branches with corresponding source branch in this git repository. In reality, binaries in HBS and HBT are built in HBK and from there only copied. Binary branches are signed with two different signing keys. There is release key and test key. The reason is that the release key is stored more securely and requires more than one developer to receive it while the test key is available for all build jobs on build server. Users can switch between these branches with `switch-branch` script on the router. List of all primary binary branches continues. Branches are sorted in order of stability. Changes are flowing from bottom branch to top ones. Here Be Snails (HBS) -------------------- -------------------------------------------------------------------------------- .----. @ @ / .-"-.`. \v/ | | '\ \ \_/ ) ,-\ `-.' /.' / '---`----'----' -------------------------------------------------------------------------------- This is stable release branch. It contains the most tested and stable version. It is end-users branch. This is default branch routers follow. Binary packages in this branch are signed with release key. Releases in this branch are tagged in this repository with appropriate version tag (such as `v5.1.2`). Binaries in this branch are built in HBK branch and copied to this branch from HBT. Here Be Turtles (HBT) --------------------- -------------------------------------------------------------------------------- __ .,-;-;-,. /'_\ _/_/_/_|_\_\) / '-<_><_><_><_>=/\ jgs `/_/====/_/-'\_\ "" "" "" -------------------------------------------------------------------------------- This is branch used for end-users testing of next release. This branch contains basically release candidate versions. Binary packages in this branch are signed with release key. Releases in this branch are tagged in this repository with appropriate version tag with `-rcX` suffix where `X` is sequence number. Content of this branch can be potentially same as HBS if there is no other release candidate. Binaries in this branch are built and copied from HBK branch. Here Be Kittens (HBK) --------------------- -------------------------------------------------------------------------------- ("`-''-/").___..--''"`-._ `6_ 6 ) `-. ( ).`-.__.`) (_Y_.)' ._ ) `._ `. ``-..-' _..`--'_..-_/ /--'_.' ((((.-'' ((((.' (((.-' -------------------------------------------------------------------------------- This branch contains accumulated changes for next release. It is used to build and continuously test binaries that are later moved to HBT and subsequently to HBS. Binary packages in this branch are signed with test key. This branch corresponds to git branch *hbk*. Feeds in this branch are configured to OpenWrt stable and Turris OS packages master branch. This means that this branch in general continually receives only hotfixes. The only case when it jumps and receives new features is when git branch *hbl* is merged in to it. Here Be Lions (HBL) ------------------- -------------------------------------------------------------------------------- ,%%%%%%%%, ,%%/\%%%%/\%% ,%%%\c "" J/%%% %. %%%%/ o o \%%% `%%. %%%% _ |%%% `%% `%%%%(__Y__)%%' // ;%%%%`\-/%%%' (( / `%%%%%%%' \\ .' | \\ / \ | | \\/ ) | | jgs \ /_ | |__ (___________))))))) -------------------------------------------------------------------------------- This branch contains the latest development of Turris OS features that are based on stable OpenWrt. It is used to build and test the latest Turris features before they are merged to git branch *hbk*. Binary packages in this branch are signed with test key. Feeds in this branch are configured to OpenWrt stable branch and Turris OS packages development branch. This means that branch in general continually receives hotfixes from OpenWrt and the latest features and bugfixes from Turris OS. New features from OpenWrt are delivered to this branch by merging git branch *hbd* in to it. Here Be Dragons (HBD) --------------------- -------------------------------------------------------------------------------- \||/ | @___oo /\ /\ / (__,,,,| ) /^\) ^\/ _) ) /^\/ _) ) _ / / _) /\ )/\/ || | )_) < > |(,,) )__) || / \)___)\ | \____( )___) )___ \______(_______;;; __;;; -------------------------------------------------------------------------------- This is the most unstable branch with all the latest development. It is used to test the latest OpenWrt development changes together with the latest Turris OS improvements before they are merged to git branch *hbl*. Binary packages in this branch are signed with test key. Feeds in this branch are configured to Turris OS packages development branch and OpenWrt development branch. OpenWrt branch in this case is either *master* or next not yet released stable branch. This branch is merged to *hbl* when OpenWrt releases new stable version. Turris-build repository workflow ================================ This section describes the development flow for this repository. It is closely related to the previous section, but unless you are developer looking to contribute or maintainer of this repository then it is probably not of interest to you. Primary (protected) branches of this repository ----------------------------------------------- *hbk*:: is default branch with version of Turris OS that is considered stable. This branch contains stable version with only bugfixes on top of it. It is based on OpenWrt stable branch (`openwrt-XX.XX`). *hbl*:: is branch used for development and contains possibly new features and larger changes. It is still based on OpenWrt stable branch, same as *hbk*. *hbd*:: is branch used for development of next major version. It contains not only large changes from Turris but also automatically pulls changes from OpenWrt development branch. The exact OpenWrt branch changes between _master_ and future OpenWrt stable. Overview of flow in this repository ----------------------------------- Following flow describes how branches are merged and how repository works in general. It also describes feeds configured in that specific branch. We specify branch in OpenWrt repository (abbreviated as _owrt_) and branch in Turris OS packages (abbreviated as _tos_). There are other repositories (feeds) but they should be configured to be consistent with OpenWrt feeds configuration. The master branch of this repository is called *hbk* and all branches are forked from it. Let's follow development of Turris OS 5.0 that is based on Turris OS 4.0 and OpenWrt 19.07. Turris OS is based on OpenWrt 18.06. Initially this version is being developer in *hbd* branch and meanwhile *hbl* contains next minor release and *hbk* next fixup release for Turris OS 4.0 .................................................................................. hbd hbl hbk _______________________________________________/| |--------------------- |--------------------- |--------------------- | owrt: openwrt-19.07| | owrt: openwrt-18.06| | owrt: openwrt-18.06| | tos: develop | | tos: develop | | tos: stable | |--------------------- |--------------------- |--------------------- | | | .................................................................................. When problem is discovered in *hbd*, such as that patches are broken, then fix is prepared in branch forked off of it. .................................................................................. fix/foo | | | ____/| | | | | | | | | | | .................................................................................. Later such branch is merged back to *hbd* when fix is finished and tested. .................................................................................. | | | | |___ | | | \| | | | | | .................................................................................. Once OpenWrt releases new stable (marks in example case OpenWrt 19.07 as stable and 18.06 as old stable) then content of *hbd* can be merged to *hbl*. _Note that after that we can't release next minor release for previous major release of Turris OS._ .................................................................................. |______________________ | | |--------------- \|--------------------- | | owrt: master | | owrt: openwrt-19.07| | | tos: develop | | tos: develop | | |--------------- |--------------------- | | | | .................................................................................. When problem is discovered then new branch is forked off of *hbl* to fix it. .................................................................................. | bugfix/foo | | | _______/| | | | | | | | | | .................................................................................. That is later merged to both *hbl* and *hbd* when bugfix is finished and tested. .................................................................................. | | | | | ______________|______ | | |/ \| | | | | .................................................................................. To do final release of Turris OS 5.0.0 we have to first merge it to *hbk* and build it there. _Note that this is last step before releasing first release candidate as that removes possibility to release fixup for previous major version._ .................................................................................. | |______________________ | | |--------------------- \|--------------------- | | owrt: openwrt-19.07| | owrt: openwrt-19.07| | | tos: develop | | tos: stable | | |--------------------- |--------------------- | | |\<-v5.0.0 | | | .................................................................................. Any problem discovered in *hbk*, *hbt* or *hbs* is fixed in branch forked off of latest commit in *hbk*. .................................................................................. | | hotfix/foo | | | _______/| | | | | | | | | .................................................................................. Such fix has to be merged to *hbk* as well as to *hbl* and *hbd*. .................................................................................. | | | | | ______________________|_______________|______ | |/ |/ \| | | |\<- v5.0.1 .................................................................................. Now when new feature should be added then new branch is forked off of *hbl*. .................................................................................. | feature/foo | | | ______/| | | | | | | | | | .................................................................................. This feature is going to be part of Turris OS 5.1.0 and when it is finished and tested its branch is merged to both *hbl* as well as *hbd*. .................................................................................. | | | | | _______________|_____ | | |/ \| | | | | .................................................................................. To release Turris OS 5.1.0 we merge again *hbl* to *hbk*. .................................................................................. | |______________________ | | | \| | | |\<-v5.1.0 | | | .................................................................................. Now we continue with flow to release fixups as well as subsequent minor and major versions. All changes this way sooner or later end up in *hbk* branch and that way in binary branches and at users. Branch naming convention ------------------------ For quick orientation of maintainers in repository stable naming convention is required. Depending on what you are planning to do you can create new branch with name prefixed with one of following: *hotfix/*:: This is fix for problem affecting *hbk* or binary branches *hbt* and *hbs*. It has to be based on the latest commit in *hbk* branch and merged to all branches (*hbk*, *hbl*, *hbd*). *bugfix/*:: This is fix for problem affecting *hbl* that is not present neither in *hbk* branch or in any subsequent binary branches. It has to be based on the latest commit in *hbl* branch. It is merged to *hbl* as well as to *hbd*. *fix/*:: This is fix for problem affecting *hbd* that is not present in neither *hbl* nor *hbk* or subsequent binary branches. It has to be based on the latest commit in *hbd* branch and is merged only to *hbd*. *feature/*:: New featured that is supposed to be part of next minor release so that means that it has to be based on *hbl* branch. This can be any change that modifies packages/lists/medkit or build process itself. It is merged to both *hbl* as well as to *hbd*. *majorfeature/*:: New feature that is supposed to be part of only next major release. This is discouraged as you probably want to release it rather in some subsequent minor update but there can be reason why that can't be done and in that case this can be used. It has to be based on the latest commit in *hbd* branch and merged back to *hbd*. *refactor/*:: This is same as *feature/* but it should not change packages/lists/medkit or build process. This can be code cleanup, patches cleanup or any other refactor. *majorrefactor/*:: This is combination of *refactor/* and *majorfeature/*. Use when what you are refactoring is available only in *hbd* branch. *hack/*:: This is feature that is to be reverted in the future. *majorhack/*:: This is combination of *hack/* and *majorfeature/*. Use this if hack should be merged only to *hbd*. After prefix you should add short name for what you are about to do. Acceptable is for example name of package or feature you are about to implement. Please do not use issue numbers of nothing saying generic words (such as: hotfix/problem). Release tags ------------ Operations performed by developers ---------------------------------- Developer is anyone who wants to contribute to this repository. Developers are not allowed to merge to primary branches (*hbk*, *hbl* and *hbd*) and have to ask maintainers to do so (submit pull or merge request or patch). === Implementing fix for problem in *hbk* (hotfix) You have to base your work on latest commit in *hbk*. For example: [,sh] ---------------------------------------------------------------------------------- git fetch git checkout -b hotfix/foo origin/hbk ---------------------------------------------------------------------------------- Also note that you might and will be asked by maintainer to possibly rebase your changes on latest *hbk* commit. [,sh] ---------------------------------------------------------------------------------- git fetch git checkout hotfix/foo git rebase origin/hbk ---------------------------------------------------------------------------------- === Implementing new feature or fixing something affecting *hbl* (bugfix/feature/refactor/hack) You have to base you work on latest commit in *hbl* branch. For example: [,sh] ---------------------------------------------------------------------------------- git fetch git checkout -b bugfix/foo origin/hbl ---------------------------------------------------------------------------------- Same as in case of hotfixes you might be asked by maintainer to rebase your work on latest commit in *develop* branch. [,sh] ---------------------------------------------------------------------------------- git fetch git checkout bugfix/foo git rebase origin/develop ---------------------------------------------------------------------------------- === Implementing feature or fix that requires OpenWrt unstable (fix/majorfeature/majorrefactor/majorhack) You have to base you work on latest commit in *hbk* branch. For example: [,sh] ---------------------------------------------------------------------------------- git fetch git checkout -b bugfix/foo origin/hbk ---------------------------------------------------------------------------------- Operations performed by maintainers ----------------------------------- There are well informed maintainers who are well educated with git-craft and with the flow of this repository that they are allowed to manage *hbk*, *hbl* and *hbd* branches. For those not so lucky and new in this craft there is following list of operations commonly performed by maintainer. === Merging hotfix Hotfixes should always be merged to branches *hbk*, *hbl* and *hbd*. [,sh] ---------------------------------------------------------------------------------- git checkout hbk git merge --ff-only --gpg-sign hotfix/foo git checkout hbl git merge --no-ff --gpg-sign -m "Merge branch 'hotfix/foo' into hbl" hbk git checkout hbd git merge --no-ff --gpg-sign -m "Merge branch 'hotfix/foo' into hbd" hbl git push origin hbk hbl hbd git branch -d hotfix/foo && git push origin :hotfix/foo ---------------------------------------------------------------------------------- IMPORTANT: Push target first before you remove source branch. Otherwise GitLab merge request would be _closed_ and not _merged_. Hotfix merge to *hbk* should always be clean. That means that there should be no merge conflicts (ensured by requiring fast forward only). This is to ensure that stable release won't be broken by merge. When that can't be done rebase to latest changes has to be performed. The maintainer can either ask author or do it by himself. There is possibility that hotfix is not required in *hbl* or *hbd* branch because it can be fixed by some other means or was already fixed by some previous feature. In such case it should be merged anyway to ease future merge of *hbl* and *hbd* back to *hbk*. For doing merge without merging changes you can use git merge strategy `ours`. [,sh] ---------------------------------------------------------------------------------- git checkout hbd git merge --no-ff --strategy=ours --gpg-sign hbk ---------------------------------------------------------------------------------- === Merging feature, bugfix and others for git branch *hbl* Branches with new features, bugfixes, refactoring or hacks are merged to *hbl* branch. This merge should be without conflict as well to prevent bugs created by merge skipping testing. On merge conflict it should be evaluated, rebased on latest commit in *hbl* (to resolve conflict) and test again before merge. [,sh] ---------------------------------------------------------------------------------- git checkout hbl git merge --ff-only --gpg-sign feature/foo git checkout hbd git merge --no-ff --gpg-sign -m "Merge branch 'feature/foo' into hbd" hbl git push origin hbl hbd git branch -d feature/foo && git push origin :feature/foo ---------------------------------------------------------------------------------- IMPORTANT: Push target first before you remove source branch. Otherwise Gitlab merge request would be _closed_ and not _merged_. === Merging features, fixes and other to git branch *hbd* Branches with new major features, fixes, major refactoring or major hacks are merged to *hbd* branch. This merge should be without conflict as well to prevent bugs created by merge skipping testing. On merge conflict it should be evaluated, rebased on latest commit in *hbd* (to resolve conflict) and test again before merge. [,sh] ---------------------------------------------------------------------------------- git checkout hbd git merge --ff-only --gpg-sign majorfeature/foo git push origin hbd git branch -d majorfeature/foo && git push origin :majorfeature/foo ---------------------------------------------------------------------------------- IMPORTANT: Push target first before you remove source branch. Otherwise Gitlab merge request would be _closed_ and not _merged_. === Merging and reverting hack or majorhack Hacks are intended to be present only temporally and so it is expected that in the future we want them reverted and that way removed. This means that hacks are merged as an exception with merge commit instead of doing fast-forward merge. [,sh] ---------------------------------------------------------------------------------- git checkout hbl git merge --no-ff --gpg-sign feature/foo ... ---------------------------------------------------------------------------------- Later hack, thanks to merge commit, can be just reverted by locating appropriate merge commit hash and reverting it. Note that this is considered as refactor and new appropriate merge request should be created and review should be performed. [,sh] ---------------------------------------------------------------------------------- git checkout -b refactor/foo origin/hbl git revert -m 1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ---------------------------------------------------------------------------------- All stated here also apply on major hack with exception that target branch is *hbd* instead of *hbl*. === Moving minor release to *hbk* for release build Turris OS minor releases are prepared in *hbl* branch but all changes introduced have to land to *hbk* before they are propagated for testing to HBT and later for final release to HBS. Thanks to previous steps this should be merge without conflicts. [,sh] ---------------------------------------------------------------------------------- git checkout hbk git merge --no-ff --no-commit hbl ---------------------------------------------------------------------------------- Do not create commit immediately as it is required to modify few files: - Change `PUBLISH_BRANCH` variable value to `hbs` in file `defaults.sh`. - Change branch from `develop` to `master` for `turrispackages` feed in `feeds.conf` file. - Change branch from `develop` to `master` for `updater-lists` comment in `feeds.conf` file. Now add changes to the git staging area and create a commit. [,sh] ---------------------------------------------------------------------------------- git add defaults.sh feeds.conf git commit --no-edit --gpg-sign ---------------------------------------------------------------------------------- The last step before the push to the server has to be propagation of changes to *hbl* and *hbd* branches. Failing to do so would reset defaults for those branches with next merge. [,sh] ---------------------------------------------------------------------------------- git checkout hbl git merge --no-ff -m "Merge Turris OS 4.2.0 into hbl" hbk git checkout hbd git merge --no-ff -m "Merge Turris OS 4.2.0 into hbd" hbl git push origin hbk hbl hbd ---------------------------------------------------------------------------------- Lastly all changes are pushed to server. [IMPORTANT] At the same time it is required to merge branch *develop* to *master* in the _turris-os-packages_ and _updater-lists_ repositories! === Moving major release to *hbl* and later to *hbk* for release build Turris OS major releases are based on major versions of OpenWrt. HBD branch collects fixes and changes based on latest OpenWrt development and thus when these changes became stable thanks to OpenWrt release they have to be moved/merged to *hbl* and *hbk*. At some point it is decided that there is going to be no new minor version of Turris OS based on at that time old stable version of OpenWrt and major release is going to be performed. This can take considerable amount of time during which it is desirable to still be able to develop and release fixes. This means that first step has to be move of all changes from *hbd* just to *hbl*. This is analogous to move of *hbl* to *hbk*: [,sh] ---------------------------------------------------------------------------------- git checkout hbl git merge --no-ff --no-commit hbd ---------------------------------------------------------------------------------- Commit is not created immediately as changes to defaults have to be reverted: - Change `PUBLISH_BRANCH` variable value to `hbl` in file `defaults.sh`. [,sh] ---------------------------------------------------------------------------------- git add defaults.sh git commit --no-edit --gpg-sign ---------------------------------------------------------------------------------- The last step before the push to the server has to be propagation of changes back to *hbd*. Failing to do so would reset defaults for those branches with next merge. [,sh] ---------------------------------------------------------------------------------- git checkout hbd git merge --no-ff -m "Merge Turris OS 4.0 into hbd" hbl git push origin hbl hbd ---------------------------------------------------------------------------------- Lastly all changes are pushed to server. Subsequent merge to *hbk* is performed the same way as if minor release of Turris OS is being released. === Releasing release candidate The release itself is performed outside of this repository. In effect files in HBK branch are taken, all signatures are updated and all is deployed to HBT. Before release the verification should be performed using dedicated script: [,sh] ---------------------------------------------------------------------------------- ./helpers/new_release.sh verify ---------------------------------------------------------------------------------- This checks if all boards are in sync. It is acceptable to do release of release candidate even when not all boards are in sync but such build should not be pushed to HBS. === Releasing release The final release itself is just move of files from HBT to HBS. The final releases have to be tagged in this repository as well as in _turris-os-packages_ repository. There is helper script implemented to correctly create tag in this repository. Tag is not automatically pushed. It should be reviewed and pushed manually. [,sh] ---------------------------------------------------------------------------------- ./helpers/new_release.sh release git push origin vX.Y.Z ---------------------------------------------------------------------------------- Tips for developers and maintainers ----------------------------------- This is collection of various tips and primarily configuration options you can use to simplify commands described in this flow. Use project specific git configuration:: It is highly advised to use project specific git config. You can apply it by running following command: [,sh] ---------------------------------------------------------------------------------- git config --local include.path ../.gitconfig ---------------------------------------------------------------------------------- Sign commits and tags with GPG without using `--gpg-sign` and `-s`:: You can configure global or local git option `commit.gpgSign` and `tag.gpgSign`. [,sh] ---------------------------------------------------------------------------------- git config --local commit.gpgSign true git config --local tag.gpgSign true ---------------------------------------------------------------------------------- Sign commits and tags with specific PGP key:: If you have more than one PGP key (for example different for personal and work identity), you can specify exactly which should be always used in git configuration option `user.signingKey`. Value of that option is fingerprint of your PGP key. [,sh] ---------------------------------------------------------------------------------- git config --local user.signingKey "XXXXXXXXXXXXXXXX" ----------------------------------------------------------------------------------