Automated Release Process #240
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # The purpose of this workflow is to orchestrate Wasmtime's release process as | |
| # much as possible. This specific workflow is responsible for a few timed parts | |
| # of the process: | |
| # | |
| # * On the 5th of every month a new release branch is automatically created, | |
| # the version number of the `main` branch is increased, and the first release | |
| # candidate of the new release branch is prepared. | |
| # * On the 20th of every month the previous release branch is published. | |
| # | |
| # This automation is all done through PRs except for the creation of the release | |
| # branch itself which is an write-action performed by this script. Otherwise | |
| # humans are ideally reviewing and rubber-stamping the output of the script all | |
| # other steps of the way. | |
| # | |
| # Note that this script also helps manage patch releases by sending a PR to the | |
| # release branch with a bumped version number for all crates with a patch-bump, | |
| # as well as publishing additional release candidates for a release branch which | |
| # hasn't been released yet. | |
| name: "Automated Release Process" | |
| on: | |
| schedule: | |
| # “At 00:00 on day-of-month 5.” | |
| # | |
| # https://crontab.guru/#0_0_5_*_* | |
| - cron: '0 0 5 * *' | |
| - cron: '0 0 20 * *' | |
| # Allow manually triggering this request via the button at | |
| # https://github.com/bytecodealliance/wasmtime/actions/workflows/release-process.yml | |
| workflow_dispatch: | |
| inputs: | |
| action: | |
| description: 'Publish script argument: "cut", "release-latest", "release-rc", or "release-patch"' | |
| required: false | |
| default: 'cut' | |
| permissions: | |
| contents: write | |
| jobs: | |
| release_process: | |
| if: "github.repository == 'bytecodealliance/wasmtime' || !github.event.schedule" | |
| name: Run the release process | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| submodules: true | |
| - name: Setup | |
| run: | | |
| git config user.name 'Wasmtime Publish' | |
| git config user.email 'wasmtime-publish@users.noreply.github.com' | |
| git remote set-url origin https://git:${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/${{ github.repository }} | |
| - uses: ./.github/actions/install-rust | |
| - uses: ./.github/actions/cargo-install | |
| with: | |
| crate: cargo-vet | |
| version: 0.10.2 | |
| - name: Bump major version number | |
| if: >- | |
| github.event.schedule == '0 0 5 * *' || | |
| github.event.inputs.action == 'cut' | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| run: | | |
| set -ex | |
| # The `main` branch always carries a `-dev` version. Strip that suffix | |
| # to get the version that's about to be released. | |
| cur_dev=$(./ci/print-current-version.sh) | |
| cur=${cur_dev%-dev} | |
| branch=release-${cur_dev%-dev} | |
| # Remember where the release branch starts so that the release | |
| # candidate below can be built from exactly this commit. | |
| base=$(git rev-parse HEAD) | |
| # Push the current contents of `main` to a new release branch | |
| git push origin HEAD:$branch | |
| # Update version numbers and make a commit indicating that. Note that | |
| # on merge this will not trigger a publish. | |
| cargo run -p wasmtime-publish bump-major | |
| num=$(./ci/print-current-version.sh | sed 's/-dev$//') | |
| # Remove all release notes for the current version now that the | |
| # release branch has been created. Additionally add an entry in the | |
| # list of all versions pointing to the release notes on the newly | |
| # created branch. | |
| sed -i '0,/-----------/d' RELEASES.md | |
| version_with_trailing_x=$(echo $cur | sed 's/.$/x/') | |
| sed -i "/ARCHIVE_START/a * [$version_with_trailing_x](https://github.com/${{ github.repository }}/blob/$branch/RELEASES.md)" RELEASES.md | |
| # Use `RELEASES-template.md` as the new release notes and then append | |
| # the archive of all historical releases to the end of it. | |
| cp RELEASES.md backup-releases | |
| sed "s/VERSION/$num/" ci/RELEASES-template.md > RELEASES.md | |
| cat backup-releases >> RELEASES.md | |
| rm backup-releases | |
| # Update `cargo vet` entries for all the new crate versions | |
| cargo vet | |
| # Commit all of the above changes. | |
| git commit -am "Bump Wasmtime to $num" | |
| # Push the result to a branch and open a PR against `main`. | |
| git push origin HEAD:ci/bump-to-$num | |
| cat > pr-body-main <<-EOF | |
| This is an [automated pull request][process] from CI which indicates that the next [\`$branch\` branch][branch] has been created and the \`main\` branch is getting its version number bumped from $cur to $num. | |
| Maintainers should take a moment to review the [release notes][RELEASES.md] for $cur and any updates should be made directly to the [release branch][branch]. | |
| A second automated PR has been opened against the [release branch][branch] to publish \`$cur-rc.1\` as a release candidate, and another automated PR will be made in roughly 2 weeks time for the actual release itself. | |
| If any issues arise on the \`main\` branch before the release is made then the issue should first be fixed on \`main\` and then backport to the \`$branch\` branch. | |
| [RELEASES.md]: https://github.com/${{ github.repository }}/blob/$branch/RELEASES.md | |
| [branch]: https://github.com/${{ github.repository }}/tree/$branch | |
| [process]: https://docs.wasmtime.dev/contributing-release-process.html | |
| EOF | |
| gh pr create --repo ${{ github.repository }} \ | |
| --head ci/bump-to-$num \ | |
| --base main \ | |
| --title "Bump Wasmtime to $num" \ | |
| --body-file pr-body-main | |
| # Now go back to where the release branch was cut and prepare the | |
| # first release candidate for it. | |
| git reset --hard $base | |
| git submodule update --init --recursive | |
| cargo run -p wasmtime-publish bump-rc | |
| rc=$(./ci/print-current-version.sh) | |
| cargo vet | |
| git commit -a -F-<<EOF | |
| Release Wasmtime $rc | |
| [automatically-tag-and-release-this-commit] | |
| EOF | |
| git push origin HEAD:ci/rc-$rc | |
| cat > pr-body-rc <<-EOF | |
| This is an [automated pull request][process] from CI which will publish \`$rc\` as a release candidate for the upcoming $cur release. When this PR is merged a \`v$rc\` tag will be created, the crates will be published to crates.io, and a GitHub pre-release will be produced. | |
| [process]: https://docs.wasmtime.dev/contributing-release-process.html | |
| EOF | |
| gh pr create --repo ${{ github.repository }} \ | |
| --head ci/rc-$rc \ | |
| --base $branch \ | |
| --title "Release Wasmtime $rc" \ | |
| --body-file pr-body-rc | |
| - name: Perform latest release | |
| if: >- | |
| github.event.schedule == '0 0 20 * *' || | |
| github.event.inputs.action == 'release-latest' | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| run: | | |
| set -ex | |
| git fetch origin | |
| # Determine the latest release branch | |
| cur=$(cargo run -q -p wasmtime-publish latest-release) | |
| # Move to the most recent release branch, drop the release-candidate | |
| # suffix from all version numbers, update the release date and commit | |
| # it, indicating that the commit is what will get tagged and released. | |
| git reset --hard origin/release-$cur | |
| git submodule update --init --recursive | |
| cargo run -p wasmtime-publish bump-drop-rc | |
| cargo vet | |
| sed -i "s/^Unreleased/Released $(date +'%Y-%m-%d')/" RELEASES.md | |
| git commit --allow-empty -a -F-<<EOF | |
| Release Wasmtime $cur | |
| [automatically-tag-and-release-this-commit] | |
| EOF | |
| # Push the result to a branch and open a PR for it | |
| git push origin HEAD:ci/release-$cur | |
| cat > pr-body <<-EOF | |
| This is an [automated pull request][process] from CI which is intended to notify maintainers that it's time to release Wasmtime $cur. The [release branch][branch] was created roughly two weeks ago and it's now time for it to be published and released. | |
| It's recommended that maintainers double-check that [RELEASES.md] is up-to-date and that there are no known issues before merging this PR. When this PR is merged a release tag will automatically created, crates will be published, CI artifacts will be produced, and the final release candidate will be yanked from crates.io. | |
| [RELEASES.md]: https://github.com/${{ github.repository }}/blob/release-$cur/RELEASES.md | |
| [process]: https://docs.wasmtime.dev/contributing-release-process.html | |
| [branch]: https://github.com/${{ github.repository }}/tree/release-$cur | |
| EOF | |
| gh pr create --repo ${{ github.repository }} \ | |
| --head ci/release-$cur \ | |
| --base release-$cur \ | |
| --title "Release Wasmtime $cur" \ | |
| --body-file pr-body | |
| - name: Release a new release candidate | |
| if: github.event.inputs.action == 'release-rc' | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| run: | | |
| set -ex | |
| # Move to the next release candidate for this branch. Note that this | |
| # commit message indicates that on-merge a release will be made. | |
| cargo run -p wasmtime-publish bump-rc | |
| # Update `cargo vet` entries for all the new crate versions | |
| cargo vet | |
| rc=$(./ci/print-current-version.sh) | |
| git commit -a -F-<<EOF | |
| Release Wasmtime $rc | |
| [automatically-tag-and-release-this-commit] | |
| EOF | |
| # Push the result to a branch and open a PR for it | |
| git push origin HEAD:ci/rc-$rc | |
| cat > pr-body <<-EOF | |
| This is an [automated pull request][process] from CI to publish \`$rc\` as a new release candidate, requested by @${{ github.actor }}. When this PR is merged a \`v$rc\` tag will be created, the crates will be published to crates.io, a GitHub pre-release will be produced, and the previous release candidate will be yanked from crates.io. | |
| [process]: https://docs.wasmtime.dev/contributing-release-process.html | |
| EOF | |
| gh pr create --repo ${{ github.repository }} \ | |
| --head ci/rc-$rc \ | |
| --base ${{ github.ref_name }} \ | |
| --title "Release Wasmtime $rc" \ | |
| --body-file pr-body | |
| - name: Bump and release patch version number | |
| if: github.event.inputs.action == 'release-patch' | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| run: | | |
| set -ex | |
| # Update version numbers on a patch basis and update RELEASES.md if a | |
| # patch release marker is already in there. Note that this commit | |
| # message indicates that on-merge a release will be made. | |
| cargo run -p wasmtime-publish bump-patch | |
| # Update `cargo vet` entries for all the new crate versions | |
| cargo vet | |
| sed -i "s/^Unreleased/Released $(date +'%Y-%m-%d')/" RELEASES.md | |
| num=$(./ci/print-current-version.sh) | |
| git commit -a -F-<<EOF | |
| Release Wasmtime $num | |
| [automatically-tag-and-release-this-commit] | |
| EOF | |
| # Push the result to a branch and open a PR for it | |
| git push origin HEAD:ci/bump-to-$num | |
| cat > pr-body <<-EOF | |
| This is an [automated pull request][process] from CI to create a patch release for Wasmtime $num, requested by @${{ github.actor }}. | |
| It's recommended that maintainers double-check that [RELEASES.md] is up-to-date and that there are no known issues before merging this PR. When this PR is merged a release tag will automatically be created, crates will be published, and CI artifacts will be produced. | |
| [RELEASES.md]: https://github.com/${{ github.repository }}/blob/release-$num/RELEASES.md | |
| [process]: https://docs.wasmtime.dev/contributing-release-process.html | |
| EOF | |
| gh pr create --repo ${{ github.repository }} \ | |
| --head ci/bump-to-$num \ | |
| --base ${{ github.ref_name }} \ | |
| --title "Release Wasmtime $num" \ | |
| --body-file pr-body |