Make a new release » History » Revision 113

Revision 112 (osmith, 09/28/2023 11:26 AM) → Revision 113/115 (Hoernchen, 11/10/2023 09:30 AM)


 h1. Make a new release 

 The efforts to automate the release process are tracked in 

 h2. When to make a new release 

 Various Osmocom projects depend on others. 

 *Proposed policy:* 
 * master branch is expected to depend on latest master branches of depended-upon projects 
 * make release of depended-upon projects if necessary before making non-library project release 
 * make sure that we have correct version dependencies before making non-library project release 

 Alternatively/additionally we can make timely releases of non-library projects (and corresponding depended-upon libraries): 
 * once per XX months? 
 * before every OsmoDevCon? 
 * once YY items accumulated in TODO-RELEASE file(see [[Make_a_new_release#TODO-RELEASE-file-format-and-maintenance|TODO-RELEASE file format]]) 
 * when configuration/db format changes? 

 This would help to avoid batching too many changes together and to adhere to RERO better - see "2015-Why-and-HowShould-OpenSource-ProjectsAdopt-Time-Based-Releases.pdf": 

 h2. Versioning considerations for libraries 

 Every osmocom library is built using libtool's version-info system. This system format and algorithm to update the versions is documented in "here": 

 However, debian packaging system follows a different versioning convention, but conveniently the debian versioning system can be deduced from libtool's version-info. More information can be found in "here": 
 Specially interesting is the warning section: 

 > A common mistake is to assume that the three values passed to -version-info map directly into the three numbers at the end of the library name. This is not the case, and indeed, current, revision and age are applied differently depending on the operating system that one is using. 
 > For Linux, for instance, while the last two values map directly from the command-line, the first is calculated by subtracting age from current. On the other hand, on modern FreeBSD, only one component is used in the library version, which corresponds to current.  

 More related information on the version translation procedure can be found here: "[1]": "[2]": 

 Summary: For libtool's system @current:revision:age@, it gets translated into version number @major.age.revision@, where @major=current-age@, reflecting the fact that ABIs can be backwards compatible. Debian uses @major@ to generate the package name. 

 The following command, when run on a shared library, will output the name to be used for the Debian package containing that shared library: 
 objdump -p \ 
     | sed -n -e's/^[[:space:]]*SONAME[[:space:]]*//p' \ 
     | LC_ALL=C sed -r -e's/([0-9])\.so\./\1-/; s/\.so(\.|$)//; y/_/-/; s/(.*)/\L&/' 


 The helper (installed by @libosmocore-dev@) available via @make release@ takes care of 

 * version bump 
 * debian/changelog update 
 * commit 
 * sign 
 * tag 

 Feel free to send patches implementing further automation as you see fit. 

 You can alternatively run directly from your git repo in /foo/bar/libosmocore by using: 
 PATH="$PATH:/foo/bar/libosmocore" make REL=minor release --include-dir="/foo/bar/libosmocore" 

 h3. Dependencies 

 The requires several extra dependencies. Make sure you have them installed in your system: 
 * bumpversion 
 * git-buildpackage 
 * devscripts 

 h3. TODO-RELEASE file format and maintenance 

 * all the strings which contain @#@ considered comment and will be ignored 
 * actual entries consists of 3 tab-separated fields: 
 # library - name of the library affected (should correspond to @lib* file in project's root directory) 
 # what - API or ABI change (used as a guidance to properly bump @*_LIBVERSION@) 
 # description - textual description (will end up in changelog) 

 When change affecting library's API/ABI is made then new entry should be added to TODO-RELEASE according to the format above. The file will be claned-up automatically by @make release@ command. 

 h2. How to make a new release 

 First we outline specific steps for different project types, then common part. 
 * Grep for @PKG_CHECK_MODULES@ in, and build with dependencies listed there (check versions after @>=@). If cannot compile, adjust the versions there so compilation works. eg: @osmo-ci.git/scripts/ -w /tmp/depcheck -b -j 8 -u /home/$USER/where-my-local-git-repos-are/ osmo-ggsn@ 
 * Adjust dependency versions in @debian/control@ (under @Build-Depends@) to match those of 
 * Adjust dependency version in @contrib/* to match those of 
 * Make sure patches under @debian/patches@ still apply correctly. 

 h3. Extra steps for Libraries 

 Some extra previous steps are required if the project installs a public shared library. 

 * modify @*_LIBVERSION@ in @src/ as necessary according to TODO-RELEASE file. Usually the easiest is using @git diff $OLD_RELEASE -- include/foobar/@ to check API/ABI changes, and implementation changes similarly with @git diff $OLD_RELEASE -- src/foobar/@ 
 * if necessary ("@major = current - age@" component of @*LIBVERSION@ was bumped, package name changing as a result) then: 
 ** Rename @debian/lib*.install@ to match the name change. See [[Make_a_new_release#Versioning-considerations-for-libraries|Versioning considerations for libraries]]. 
 ** Adjust package names in @contrib/* accordingly. 
 ** Adjust package names in @debian/control@ accordingly. Specifically look for "Package" and "Depends" attributes. 
 ** Some projects containing both binaries and libraries (@osmo-ggsn@, @libosmo-sccp@) also state the library version in dh_strip lines in @debian/rules@. That one needs to be updated too to match the new library version. 

 Upon major libversion change ("old_major" -> "new_major"), the change pattern in general follow this structure: 
 * @"s/${libname}${old_major}/${libname}${new_major}/g"@ 
 * @"s/${libname}.so.${old_major}/${libname}.so.${new_major}/g"@ 

 The release helper is trying to be smart about it and prevent making new library release with non-empty TODO-RELEASE file if @*_LIBVERSION@ is not adjusted beforehand. 

 h3. Release steps 

 By default @make release@ prepares 'patch' release but you can manually specify any of 'major/minor/patch' as necessary - see for details. 

 * Run @git fetch --tags@ to ensure your local copy of the repository has the latest tags. 
 * Create a new branch from where you would like to create a new release (master or a previous release) and name it @YOURNAME/RELEASE@ 
 * Make sure all the manual changes you want in the release commit are staged (@git add@), (see previous sections about changes needed). 
 * Run @make REL=minor release@ 
 * an editor will be opened in case you want to reword the release commit. Useful if you want to add any remarks on the actions taken. 
 * inspect the latest commit which was just created 
 * adjust it if necessary and re-sign (see [[Make_a_new_release#How-to-retag-a-new-release|Re-tag new release]]) 
 * push commit for review to gerrit and ask somebody to review and merge it quickly (to avoid other commits being merged in between). 
 $ git push origin HEAD:refs/for/YOURNAME/RELEASE%topic=PROJECT-RELEASE 
 * Once merged, make sure the merged release commit did not change (due to in-between merges), then push the release tag with @git push gerrit --tags@ 
 * consider preparing article for and sending announcement to appropriate ML for major release once release commit passed the review 

 In case you want to undo the release commit you did locally: 
 * @git tag -d TAG_JUST_CREATED@ 
 * @git reset --soft HEAD^@ 
 * @git restore --staged debian/changelog && git restore debian/changelog@ 
 * Do your modifications 
 * Proceed again with the release steps listed above 

 In case there is no @make release@ target (e.g. osmo_dia2gsup): 
 * run @gbp dch@ 
 * adjust debian/changelog, at least change UNRELEASED to unstable 
 * commit as "Bump version: 0.1.1" (replace 0.1.1 with new version) 
 * run @git tag -s 0.1.1@, put as title "Release 0.1.1" 

 h2. Which new release to make 

 Use following guidelines when choosing release type: 
 * major - ?? TBD 
 * minor - ?? TBD 
 * patch - ?? TBD 

 If unsure - ask in corresponding ML. 

 h2. Deprecation policy 

 Functions/interfaces marked as deprecated for X releases of type Y can be removed in next Z release. 

 TBD: what's appropriate value for X? which Y and Z (from major/minor/patch) should we use? 

 h2. How to (re)tag a new release 

 This might be necessary if previous release was made manually with some mistakes which have to be corrected and amended to the release commit. 

 git tag -s 0.4.0 -f -m "Release v0.4.0 on 2017-08-25." 

 This will automatically (re)sign the latest commit. You can specify which commit to sign explicitly. 

 Say, for example, the git hash is @012342abcdefg@ and the next open version is 0.1.3: 
 git tag -s 0.1.3 012342abcdefg -m "release 0.1.3" 

 (If @gpg@ complains, see [[Make a new release#GPG-Have-a-matching-user-id|GPG: Have a matching user id]].) 

 Verify that git picks up the new version tag: 
 $ git describe 

 N. B: *For your local build, _nothing will change_ until you delete the @.version@ file and completely rebuild:* 

 rm .version 
 autoreconf -fi 
 cat .version 

 This should show the same as @git describe@. 

 When you're convinced that all is in order, push the new tag: 

 git push origin 0.1.3 

 If anything went wrong, you can delete the tag (locally) by 
 git tag -d 0.1.3 
 and, if you've already pushed it, by 
 git push --delete origin 0.1.3 

 h2. GPG: Have a matching user id 

 By default, @git tag -s@ takes your author information to lookup the secret GPG key to sign a tag with. 
 If the author+email do not exactly match one of the key's @uid@s, you will get this error: 

 gpg: signing failed: secret key not available 

 Verify: say, your author+email info in your git config says "John Doe <>", try 
 gpg --list-secret-keys "John Doe <>" 
 If this fails, GPG won't find the right key automatically. 

 Ways to resolve: 

 * Use @git tag -u <key-id>@ 
 * Edit your secret key to add a uid that matches your author information 
 gpg --edit-key 
 gpg> adduid 
 # enter details to match the git author 
 gpg> save 

 h2. GPG: failed to sign 

 If you are seeing this error: 

 $ git tag ... 
 error: gpg failed to sign the data 
 error: unable to sign the tag 

 you may need to set this in your terminal's environment: 

 export GPG_TTY=$(tty) 

 Furthermore, for headless operation (remote server) it may be necessary to direct the GPG key entry to the terminal. 
 On debian, make sure the curses key entry is installed: 
 apt-get install pinentry-curses 

 and possibly also uninstall other pinentry alternatives, or otherwise make sure it is not trying to launch a graphical pinentry. 


 h1. Creating a patch release 

 Sometimes we want to create a patch release to apply an important fix to an older major/minor release. Assuming you're in libosmocore and want to create 1.3.1 off 1.3.0, this works as follows: 

 # %{color:red}warning% : using the final tag name as the temp branch name is a bad idea because it causes annoying problems like 
 ❯ git push -d origin 1.3.1       
 error: dst refspec 1.3.1 matches more than one</pre> 
 You need to use *git show-ref* or *git ls-remote* to figure out the refspec like refs/heads/1.3.1 to distinguish tag and branch name. Or just use different names! 
 # (Locally checkout 1.3.0 as a new branch called rel-1.3.1) 
 git checkout -b rel-1.3.1 1.3.0 
 # Create a rel-1.3.1 branch in gerrit 
 git push gerrit rel-1.3.1:refs/heads/rel-1.3.1 
 # Do whatever local modifications such as cherry-picking of fixes, ... 
 # Perform the release process as outlined above, using 'REL=patch' 
 make REL=patch release 
 # Push the changes for review to the rel-1.3.1 branch 
 git push gerrit HEAD:refs/for/rel-1.3.1 
 # Perform gerrit review, merge patches in gerrit UI 
 # Do @git fetch gerrit@ and make sure your local branch with your tag points to the remote one (eg @gitk --all@ or @git show@). 
 # Push the tag to the repo, *after the patches were merged* to that branch 
 git push gerrit 1.3.1 
 # Remove the temporary branch 
 git push gerrit :rel-1.3.1 


 h1. Dependency graph 

 This section aims at providing a dependency graph of the osmocom cellular network infrastructure projects in case a cascade of releases is intended: 

 digraph G { 
     libusrp -> {osmo_trx}; 
     libas1nc -> {osmo_iuh, osmo_msc, openbsc, osmo_hnodeb, osmo_hnbgw}; 
     libsmpp34 -> {osmo_msc, openbsc}; 
     libgtpnl -> {osmo_ggsn, osmo_upf}; 
     libosmocore -> {libosmo_abis, libosmo_gprs, libosmo_netif, libosmo_sccp, libosmo_pfcp, osmo_iuh, osmo_ggsn, osmo_sgsn, osmo_mgw, osmo_msc, osmo_hlr, osmo_bsc, osmo_bts, osmo_pcu, osmo_trx, openbsc, osmo_sip_connector, osmo_pcap, osmo_gbproxy, osmo_hnodeb, osmo_hnbgw, osmo_cbc, osmo_smlc, osmo_upf, osmo_uecups}; 
     osmo_gsm_manuals -> {osmo_pcu, osmo_trx, osmo_sip_connector, osmo_hlr, libosmo_sccp, osmo_sgsn, osmo_bsc, osmo_ggsn, osmo_msc, osmo_mgw, osmo_bts}; 
     libosmo_abis -> {libosmo_netif, osmo_sgsn, osmo_msc, osmo_hlr, osmo_bsc, osmo_mgw, osmo_bts, openbsc, osmo_hnodeb}; 
     libosmo_gprs -> {osmo_pcu}; 
     libosmo_netif -> {libosmo_sccp, osmo_iuh, osmo_sgsn, osmo_mgw, osmo_msc, osmo_bsc, openbsc, osmo_hnodeb, osmo_hnbgw, osmo_cbc, osmo_uecups}; 
     libosmo_sccp -> {osmo_iuh, osmo_sgsn, osmo_msc, osmo_bsc, openbsc, osmo_hnodeb, osmo_hnbgw, osmo_smlc}; 
     libosmo_pfcp -> {osmo_hnbgw, osmo_upf}; 
     osmo_iuh -> {osmo_msc, osmo_sgsn, openbsc, osmo_hnodeb, osmo_hnbgw}; 
     osmo_ggsn -> {osmo_sgsn}; 
     osmo_mgw -> {osmo_msc, osmo_bsc}; 
     osmo_hlr -> {osmo_msc, osmo_sgsn}; 
Add picture from clipboard (Maximum size: 48.8 MB)