Skip to content

Latest commit

 

History

History
363 lines (278 loc) · 17.6 KB

RELEASE.md

File metadata and controls

363 lines (278 loc) · 17.6 KB

This guide documents how we do releases, A to Z. The goal is that any team member can do a release, and knows what steps and which roles are involved.

[[TOC]]

Assumptions

  • The main git branch is stable and always in a runnable state
  • The definitions of done of any merged feature always includes relevant documentation we can refer to (config file changes, schema changes, etc)
  • The definitions of done of any merged feature always includes any relevant unit-, integration and/or end-to-end tests (i.e., features are tested)
  • You have cargo-edit and git-filter-repo installed

What constitutes a release?

A release is a commit in our Git repository that we tag with a semver version tag, and for which we make source code and binaries available.

To do a release, we have a whole bunch of steps we execute. Some of these steps are manual, some are automated in our CI/CD environment. This guide documents all those steps, enabling the reader to go through them sequentially, when doing a release themselves.

Doing a release

This section of the guide documents all the steps we do when we do a release.

Step 1: Make sure the release on Jira is green

We use Jira Releases (also sort-of interchangably called "versions") to keep track of things we want to have in a release. When you go to our PVW project page on Jira, and click on the "boat" icon on the left, you'll see our releases page.

For the version you want to release, have a look at the progress bar. When you click on the release, you'll see all issues in it - essentially, you want all issues to be in the Done state (except possibly for the ones which are related to doing the release work itself).

If there are still issues In Progress or otherwise, have a chit-chat with the relevant folks with regards to status and discuss with the product owner. When an issue is still far from done but important for this release, it effectively blocks the release - you need to wait until the issue is done. Alternatively, you and/or the product owner might decide that the issue can be moved to the next release.

When the release is "green" (i.e., all relevant issues are in the Done state) you know that the relevant features and fixes have been merged in the main branch, and you can create a release tag (which we do later on in this guide).

Step 2: Make sure Figma links are up-to-date in README.md

We have links to Figma in our README.md file. We always update these before we tag the release. Obtain the up-to-date links from the UX team, create an MR and update the README.

Step 3: Confirm appropiate tests and reports have been done for this release

We do most testing in an automated fashion using our CI/CD pipeline. There are however still a few things we confirm. Most notably:

  • Stable main pipeline (CI/CD pipeline for main is green)
  • Automated nightly E2E testsuite succesful
  • Manual E2E testsuite executed and green (there is a metric in our quality time instance that our software quality engineer uses for this, you can ask him for the link)
  • OSV scanner ran and results accepted (see osv-scanner job in pipeline)
  • ZAP scanner ran and results accepted (manual run, pipeline job coming)
  • No blocker or critical Sonar findings (you can check our Sonar instance for these findings, ask around for the link if you don't have it)

The manual E2E tests are usually executed by a member of the Dart/Flutter team. We are working on getting automated ZAP tests as part of the pipeline that will block on serious issues, and warn on lower priority ones.

The confirmation of the acceptability of the tests and any required reports is done by our software quality engineer. He will e-mail our shared e-mail account, the software delivery manager and the product owner with their approval and/or any remarks or findings.

If there are any findings which can't be accepted or worked around, they will probably block the release and need to be addressed or otherwise accepted before further release-steps can occur.

Step 4: Release approval

The release in Jira is green, manual and automated testing is done and the other things we confirm in the previous step are all ok or accepted. The product owner and the software delivery manager now need to reply to the e-mail from the software quality engineer (see previous step) with an approval for release. The software delivery manager and the product owner CC the shared e-mail account and the technical team members who are executing the release.

When you have received this CC and it contains the approval from both the product owner and the software delivery manager, you can continue onwards with the steps to execute the release.

If for some reason the release is not approved, then we as a team need to address any issues and concerns raised by the PO and/or SDM before further release-steps can occur.

Step 5: Freeze git main branch

To avoid someone accidentally or otherwise sniping in another change, you can temporarily "freeze" the main branch. To do this in GitLab, you can follow these steps:

  1. Go to the project page, click Settings, go to Repository settings;
  2. Click Expand on Protected branches and see the main branch there;
  3. Set Allowed to merge to None;
  4. Set Allowed to push and merge to specifically your user account;

After doing the above, no one except you can merge or push to the main branch.

Don't forget to undo the above when you're done (at least after you've completed steps 6 and 7).

Step 6: Set release version and tag

We are now ready to tag the release in our git repository. Before we create the tag though, we need to make sure that a couple of project files contain the right version also.

In the scripts subdirectory you'll find the version.sh release helper. It's a straightforward tool that assists you in setting the version of our components and can show you which versions we have already.

Start a new MR and run version.sh -s RELEASE_VERSION (where RELEASE_VERSION is something like v0.2.2). Run git status to see what changed and verify the sanity of the changes (should be small and easy to comprehend).

Get the MR merged and after merge, run git tag RELEASE_VERSION (where RELEASE_VERSION is something like v0.2.2). After tagging, push the tag with git push --tags.

Step 7: Set development version

Immediately start a new MR to set the development version. To do so, run version.sh -s DEVELOPMENT_VERSION (where DEVELOPMENT_VERSION is something like v0.2.3-dev). To clarify, when you set a version like v0.2.3-dev, you are indicating that this is the development version of the upcoming v0.2.3. This development version v0.2.3-dev will remain set in the component project files, until we are ready to release, which then leads us to repeat the cycle, set v0.2.3 and tag, set the next dev version, etc.

After you've set the development version, merge the MR. It is best if this is done quickly so people don't accidentally start doing work under the older version tags.

Step 8: Do commit review

Before we publish our code, we do a commit review to make sure a couple of things are in order. To be more specific, we don't want:

  • Personally identifiable information
  • Non-open source copyrighted files or data
  • Secrets or possibly sensitive internal identifiers such as hostnames, project IDs, etc
  • Other unexpected, strange or inappropriate things (..)

To do so, we review the commits between this new release we just tagged and the previous release. Reviewing in this case means going through the commits one by one to ascertain that they do not include one of the above mentioned items.

Tip: We've found it helpful to use a GUI tool to assist with this review process. We've had good experiences with GitHub Desktop (Linux, macOS and Windows compatible) and GitUp (macOS-only).

If you don't find any commits to contain any of the unwanted items on the list, you are ready to run our publication-guard utility.

If, on the other hand, you did have findings, you need to do a few things:

  1. Discuss the finding(s) with a colleague to confirm the issue (4-eyes principle);
  2. Determine how to address the finding:
    • It's so serious it shouldn't even exist in the private repo, so git-filter-branch the private repo to fix, or
    • It's fine, but shouldn't exist in the public repo, so pick it up as a new item-to-filter in publication-guard

Step 9: Run publication guard

After you've reviewed all the commits and taken any appropriate steps, i.e.,

  • you made sure the private repository does not contain any of the items mentioned in the previous step, or
  • you have fixed any items by undoing commits (by using something like git-filter-branch for example) in the private repository, or
  • you are going to create new item filters in publication-guard for any findings you had;

You should now be ready to run publication-guard, which assists us with filtering the repository. It takes into account various things like who opted to have his/her public email address in the commit message and who did not, and filters out various things which we have considered once to be unwanted in the public repository (note: that does not mean it is considered as such in perpetuity - we should allow for reconsideration from time to time).

Clone the publication-guard repository, read the README.md. Follow the instructions, for which you will find some overlap with this howto. Create any new to-filter-items for things you might have encountered during your review.

Finally, make sure that, for any person that has done commits between the previous release and this one, you have followed the procedure documented in the README.md of publication-guard with regards to their explicit permission to have their name and e-mail address publicly available (or explicit denial and relevant anonymized e-mail address and/or name).

Step 10: Publish source code to GitHub

After executing the publication-guard filtering steps, you are ready to publish the filtered repository that publication-guard created.

To do that, you need to access the filtered repository directory, rename the filtered-repository branch to main, add GitHub as a remote and then git push --tags (i.e., to the remote main on GitHub).

Step 11: Collect build artifacts for release

We currently (2024-10-22) collect 4 artifacts from our GitLab CI/CD pipeline:

  • wallet-sbom_vX.Y.Z_generic.zip: The software-bill-of-materials for this release
  • wallet-verification-server_vX.Y.Z_x86_64-linux-glibc.zip: The wallet verification server for relying parties, for glibc-based Linux systems
  • wallet-verification-server_vX.Y.Z_x86_64-linux-musl.zip: The wallet verification server for relying parties, for musl-libc based Linux systems
  • wallet-web_vX.Y.Z_generic.zip: The javascript helper library for relying parties, to assist with integrating relying party applications with the wallet platform

You can collect these artifacts from our GitLab CI/CD pipeline - you need to go to the relevant job and click on download artifact/zip. You might need to rename the zip file and/or repackage in the case of verification_server.

Currently (2024-11-07) you need to create the sha256sums manually (in the future we would like to adjust the pipeline that creates the binary artifacts such that it will create the sha256 hashes also). To create the sha256sum texts, enter the directory which contains the above mentioned zip files and run:

for zip in *.zip; do sha256sum $zip > $(echo $zip | sed 's|.zip$|.sha256sum.txt|g'); done

When you have these zip files and sha256sum texts, and you made sure they're named correctly, you are ready to create the release notes. We will upload the zip files and sha256sum texts as artifacts of the release.

Note on other binaries like wallet_server_migrations and schema changes in general: When any of our binaries that use a database backend require schema changes in the database, we can provide either documentation that instruct how someone can effect the necessary changes, or a wallet_server_migrations utility and clear instructions with regards to how-to-use. When we as a team decide to provide a wallet_server_migrations binary, make sure that binary is included in the verification server zip files, with instructions on how to use (i.e., an end-user must be able to update the schema using the provided utility by following the additionally supplied read-me or other installation instructions).

Note about obtaining artifacts automatically: Currently the above is manual. We have an issue on Jira which is about creating an artifact uploader. This utility is called uploader.mjs and can talk to the GitHub releases API and add binary artifacts and their sha256 sums to a release. The idea is that our pipeline, when invoked with a CI_COMMIT_TAG environment variable present (i.e., a build triggered by a git push --tags that results in new version tags being pushed) can invoke this utility and create or update a release with relevant binary artifacts.

Step 12: Create release notes

Here is a template/example for the release notes. Make sure you replace DAY, MONTH, YEAR, A.B.C, X.Y.Z, CONDITIONAL_PRE_RELEASE_WARNING, OPTIONAL_RELEASE_STORY and list all CHANGE items (tip: can be issue titles from the Jira release page):

Release date: DAY of MONTH, YEAR

  * All commits in this release: https://github.com/MinBZK/nl-wallet/compare/vA.B.C...vX.Y.Z
  * Documentation for this release: https://github.com/MinBZK/nl-wallet/blob/vX.Y.Z/documentation/index.md

We have the following artifacts as a part of this release:

  * `wallet-sbom_vX.Y.Z_generic.zip`: The software-bill-of-materials for this release
  * `wallet-verification-server_vX.Y.Z_x86_64-linux-glibc.zip`: The wallet verification server for relying parties, for glibc-based Linux systems
  * `wallet-verification-server_vX.Y.Z_x86_64-linux-musl.zip`: The wallet verification server for relying parties, for musl-libc based Linux systems
  * `wallet-web_vX.Y.Z_generic.zip`: The javascript helper library for relying parties, to assist with integrating relying party applications with the wallet platform

## Notes

**CONDITIONAL_PRE_RELEASE_WARNING**

**OPTIONAL_RELEASE_STORY**

## Changes
- CHANGE
- CHANGE
- CHANGE

Note on CONDITIONAL_PRE_RELEASE_WARNING: When you mark this release as a pre-release, you need to include the following sentence here: "This is currently a pre-release; as such it may contain issues we're not aware of and might not contain full documentation for any introduced changes. A pre-release is intended for testing purposes and is not production ready, use at your discretion."

Note on OPTIONAL_RELEASE_STORY: You can include a paragraph or two here which details what is special about this release, highlight some features or good to knows, like config-file-format changes, schema changes, etc.

Note about CHANGE lines: You can either construct change lines by hand by reviewing commits in this release, or (preferably) you can use our Jira release page to find the issues in this release and use the Jira issue number and title (and optionally an additional information field which concisely describes the feature or fix). This probably would involve some scripting or creative copy and paste work.

After you've created the above release notes for this release, save it somewhere so we can use it in the next step where we're going to create the actual GitHub release. It is also a good idea (if time and logistics allow) to have a colleague have a look at the release notes (not a hard requirement, just a recommendation).

Step 13: Create GitHub release from tag

When you visit our GitHub page, you should now see all the additional commits and the version tag you've previously set to indicate the release. This version tag will point to the head of the repository and will not have an associated release yet.

  1. Go to the Releases page and click on the Draft a new release icon. You'll be presented with a release creation page;
  2. Click on Choose a tag and select the version you want to create a release for (normally the latest one for which you did all the previous steps);
  3. As title, write: Wallet X.Y.Z, where X.Y.Z is the version number you're releasing (i.e., should match tag without the v prefix);
  4. Add the previously collected/created zip files and sha256 text files;
  5. Insert the previously created release notes markdown in the body text of this release;
  6. Enable the Set as a pre-release flag;
  7. Click on Publish release;

Note on setting the pre-release flag: We always set this flag when doing an initial release. A versioned release like we've just created is also going through a larger scale testing and deployment phase through the operations team. When they have finished their testing phases and obtained their relevant approvals, a go-ahead could be given to unset the pre-release flag. This is an asynchronous process and never blocks the release itself (i.e., don't wait, just leave the release marked as pre-release until someone comes around later on to tell you/us that a specific release can have the pre-release flag removed)

Note on removing a pre-release flag: This only happens when the software is fully vetted by our operations team and deemed ready to run on our production backend. When the flag is removed (and so becomes a fully stable release), don't forget to remove the CONDITIONAL_PRE_RELEASE_WARNING paragraph from the release notes.

References