HOW TO ROLL RELEASES IN PRIVATE =============================== This file documents how to roll a security release in private, in a way that generates tarballs that differ from the previous release's tarballs only by a security patch. For instance, subversion-1.5.7.tar.gz differs from subversion-1.5.6.tar.gz only by the patch for CVE-2009-2411, and was rolled and voted on privately (on svn-full-committers@red-bean.com, the predecessor of private@subversion.apache.org). To roll the release: -------------------- - For each CVE, there should be a CVE patch for each supported release line that is vulnerable. These are the patches that will be distributed with the advisory. They are indexed in /metadata ['patches']. - Write patches for CHANGES for each supported release line. These will be part of the tarball but will not be distributed with the advisory. The CHANGES patch for each minor line should include the CHANGES patches for each older minor line, e.g., if releasing 1.8.19 and 1.9.7, the CHANGES patch for 1.9 would add not only 1.9.7 but also 1.8.19. [TODO: And how are the patches to be committed to trunk, then?] - You'll be rolling a 1.a.b release with b>0, so for the magic revision argument pass the magic revision of 1.a.c where c=b-1. You can find the magic revision by running 'svn log -v' on the 1.a.c tag. Run 'release.py roll' and pass '--patch DIR' where DIR contains the CVE and CHANGES patches. The names of the patch files should include '1.a' and end 'patch'. Example rolls: release.py roll --patch .../security/CVE-2017-9800 1.8.19 1800620 release.py roll --patch .../security/CVE-2017-9800 1.9.7 1800392 - Compare the contents of the candidate tarballs with the previous release tarballs, and verify that the differences correspond to the patches. - Run 'release.py sign-candidates' as usual. - Upload the artifacts to /repos/private/pmc/subversion/security/staging-dist. DO NOT USE 'release.py post-candidates', that would PUBLISH them, days before the end of the embargo. - Post a "up for testing/signing" mail to private@. DO NOT SEND it to dev@... - Prepare a website update announcing the release. Remember to update /site/publish/security/ as well. Note that the advisory files therein contain patches (see tools/dist/README.advisory) and are signed with PGP detached signatures. - Prepare a log message for committing the patch to trunk. (send pre-notifications) (wait for sufficient votes) To post the release: -------------------- - Check that your machine's clock is synced. A good way to do this is to run 'ssh known-good-host env TZ=UTC date; TZ=UTC date' (in one line) in the shell and ensure the results are no more than a second apart. This ensures you will not announce before the end of the embargo. - Join IRC so the other committers can easily report any problems to you. - At the designated end of the embargo, upload and announce the release as usual. + Upload: svn import \ .../security/staging-dist/dev/subversion/ \ https://dist.apache.org/repos/dist/release/subversion \ -m "Release Apache Subversion 1.9.7 and 1.8.19 with a fix for CVE-2017-9800." + Commit the website patch which you had prepared above. With the new (2021) Apache Download Content Delivery Network, artifacts are available on the CDN within 15 minutes. (No need for the old update= argument on the download.cgi link.) + Send the email announcement. Remember to pass --security to 'release.py write-announcement', and use the ?update=YYYYMMDD... link. - Commit the patch to trunk. Use the log message prepared earlier. - Commit any additional patches, e.g., hook scripts to tools/hook-scripts/. - [TODO details] Commit the CHANGES patches to trunk. - Backport the patch to HEAD of the 1.a.x branch. Copy the shadow-status entry to the log message (or just add it directly to the "Approved changes:" section of the public STATUS file and let the bot merge it overnight). This ensures the next 1.a.x release, 1.a.(c+2), will have the patch applied. - Bump SVN_VER_PATCH on the 1.a.x branch, as explained in the public release rolling documentation. The order of the last two steps ensures that any interim revision of the 1.a.x branch that has SVN_VER_PATCH == 1.a.(c+2) has the patch applied. - Tag the release: + Checkout a working copy of the 1.a.x branch. Revert all local changes, and update (back in time) to the the magic revision of 1.a.c (the same 1.a.c from earlier). + Cherry-pick any patches from 1.a branch, these are patches from the "future" i.e. revisions later than the magic revision. Do not commit (you can't, since your wc is backdated). + When release.py rolled the tarball it left a working copy with all the tarball changes applied, this includes the patches above but also other changes, in particular svn_version.h. Either use this original working copy or reroll to create a another instance of this working copy. Be aware that the release.py working copy is sparse. + Run 'svn diff' in the release.py working copy to create a total tarball patch. Use 'svn patch' to apply this to the magic revision working copy. This will patch svn_version.h to match the tarball and should report "already applied" for all the other hunks as they should match the merges from the "future". + Tag your magic revision working copy: svn cp ./ ^/subversion/tags/1.a.b -m "..."