Skip to content

Latest commit

 

History

History
182 lines (141 loc) · 6.15 KB

MAINTAINERS.md

File metadata and controls

182 lines (141 loc) · 6.15 KB

Maintainers

Cutting a New Release

Caution

Cutting a release, end-to-end, takes a reasonable amount of time -- mostly waiting on the CI -- and also requires the availability of colleagues to properly review and approve.

Plan for it to take an entire working day.

Do not rush the process and avoid days on which you and colleagues have limited availability. Don't release on the last working day before a weekend or holiday, etc. If something goes awry before the point of no return, keep calm and don't carry on: Better to revert and try again the next day than having a broken release (and a stressful evening)!

1. Create a release preparation branch from main

  • If necessary, cherry-pick the commits that should be included in the release. (This should only be done in exceptional circumstances.)

  • Update the CHANGELOG, if necessary. This is used in the release announcement, so ensure it conforms to the correct format (as described in the CHANGELOG introduction).

    • By convention, this should be up-to-date as part of the PR process, but it ought to be double-checked. (See below for suggestions on how to partially automate this.)

    • Retitle the "Unreleased" section to this release and create a fresh "Unreleased" section (see comments in the CHANGELOG for details).

      Don't forget to update the "Full list of changes" links appropriately.

Tip

Do not wrap bullet points over multiple lines in the CHANGELOG. GitHub will preserve those line breaks in the Release Notes, which is probably not what you want.

Important

Point releases (i.e., not patch releases) should also be given a name, taking the form "[ADJECTIVE] [TREE]", incrementing alphabetically from the previous release (e.g., "Archetypal Aspen", "Benevolent Beech", etc.). Both parts are relatively loose, particularly when it comes to botanical correctness, and a degree of assonance has become traditional.

The name should be decided amongst the team before release.

  • Update the root level Cargo.toml.

    • Bump workspace.package.version.
    • Bump any workspace dependency versions, respectively.
  • Update lockfiles and the release workflow.

    • Run nix flake update to update flake.lock.

    • Run cargo update to update Cargo.lock.

    • The release workflow is generated by dist (formerly cargo-dist); the version that is currently in use can be found in dist-workspace.toml. If a newer version exists, then:

      • Download the new version of dist.
      • Run dist init. This should update the dist-workspace.toml configuration and the release workflow (.github/workflows/release.yml)
  • Push these changes and wait for green CI across all workflows and peer approval. Upon both, squash-and-merge the PR into main.

2. Make the release

  • Tag the merged commit in main with the release version, prefixed with a v (e.g., v0.1.0), and push it to GitHub. The version number must match the one in Cargo.toml, otherwise dist will fail during CI.

    git tag v0.1.0
    git push --tags

Caution

Pushing the tag will trigger the release workflow (described below). If that succeeds, the release is finalised. This is the point of no return. Only push the tag if you are sure everything is ready for the release.

  • Let the dist release workflow create a new release. That is:

    • Build binary artefacts for a variety of targets (currently: Apple Silicon macOS, Intel macOS, x64 Windows, ARM64 Linux and x64 Linux). This can take some time; the best part of an hour.

    • Publish a release announcement, featuring the relevant section from the CHANGELOG for this version.

Warning

If this step fails, delete the new release tag as quickly as possible from GitHub and start over:

git push --delete origin vX.Y.Z
  • Update crates.io. As of writing, the workspace cannot be published automatically, so each package in the workspace needs to be individually published in topological order. That is, currently, something like:

    cargo publish --package topiary-web-tree-sitter-sys
    cargo publish --package topiary-tree-sitter-facade
    cargo publish --package topiary-core
    cargo publish --package topiary-queries
    cargo publish --package topiary-config
    cargo publish --package topiary-cli

Important

Publication to crates.io requires appropriate access. You may need to escalate this appropriately.

Tip

cargo tree --invert is useful to determine the topology.

3. Publicise

Warning

Point releases, only. Don't publicise patch releases, unless there's a pressing need to do so (e.g., fix of a security vulnerability, etc.).

  • Announce the new version on Tweag's Twitter, Discord and other official social network accounts, via someone with access.

  • Share amongst other social networks (e.g., Reddit, Hacker News, Mastodon, etc.), under personal accounts, at your discretion.

Generating the PR List for the CHANGELOG

If the unreleased changes in the CHANGELOG have become stale, the list of merged PRs can be fetched from:

https://github.com/tweag/topiary/pulls?q=is:pr+base:main+merged:>YYYY-MM-DD

Replacing YYYY-MM-DD by the date of the last release.

If you have the GitHub CLI client, something like the following may be more convenient:

gh pr list \
    --limit 500 \
    --base main \
    --state merged \
    --json number,mergedAt,title,body \
| jq \
    --raw-output \
    --argjson release "$(gh release view --json createdAt)" \
    '
        reverse
        | .[]
        | select(.mergedAt > $release.createdAt)
        | ["# PR#\(.number): \(.title)", "*Merged: \(.mergedAt)*", "\(.body)\n"]
        | join("\n\n")
    '

Tip

The --limit 500 is an arbitrary "large number" ™️ limit of PRs to fetch, overriding the low default. As of writing, there's no way to set this to "unlimited"; adjust as necessary.