Skip to content

Release

Release #208

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
release-type:
description: "What kind of release is this?"
type: choice
options:
- alpha
- rc
- final
required: true
concurrency:
group: ${{ github.ref_name }}
cancel-in-progress: true
defaults:
run:
shell: bash
# wants to push commits and create a PR
permissions: write-all
jobs:
# Re-entrancy:
# - `version` is re-entrant because it doesn't commit/create PR if the version doesn't change,
# and the version doesn't change if we're already on the final version specified by the branch name.
# - `update-docs` is re-entrant because it overwrites history of the `gh-pages` branch, so any
# previous partial update will just be overwritten by the next successful run.
# - `publish-crates` is re-entrant because the `crates.py` script correctly handles publish failures
# by first checking if a crate has already been published before attempting to publish it.
# - `build-and-publish-wheels` is re-entrant because all the uploaded artifacts will be overwritten
# by any subsequent runs, and the final upload to PyPI has the `--skip-existing` flag, which ignores
# any wheels already uploaded.
# - `build-and-publish-web` is re-entrant for the same reason as `build-and-publish-wheels`,
# except that uploads are done to GCS instead of PyPI.
checks:
name: "Checks"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Check links for `?speculative-link`
# This checks that we have no links with `?speculative-link` in its query params.
# We use those markers to get our link checker to ignore links to unreleased docs.
#
# NOTE: For alpha releases, we won't fully publish all our docs,
# so we skip the check here, because we won't be able to
# remove the markers yet.
run: |
if [ ${{ inputs.release-type }} != "alpha" ]; then
python3 scripts/ci/check_speculative_links.py
fi
# NOTE: When updating this job, also remember to update `post-release-version-bump`.
version:
name: "Versioning"
runs-on: ubuntu-latest
outputs:
previous: ${{ steps.versioning.outputs.previous }}
current: ${{ steps.versioning.outputs.current }}
final: ${{ steps.versioning.outputs.final }}
# will be set to `github.sha` if the pull request already exists
# this is the last (and not merge) commit in the release branch
release-commit: ${{ steps.commit.outputs.version_bump_commit_sha || github.sha }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.RERUN_BOT_TOKEN }}
- uses: actions/setup-node@v4
with:
node-version: 18
- uses: prefix-dev/[email protected]
with:
pixi-version: v0.25.0
- name: Update crate versions
id: versioning
run: |
echo Check that the release version matches expected format…
pixi run python scripts/ci/crates.py check-git-branch-name
echo Parse the release version from the branch name…
# `release-0.8.1-meta.N` -> `0.8.1`
release_version=$(pixi run python scripts/ci/crates.py get-version --from git --finalize)
echo "release_version: $release_version"
echo Store version before the update, so we can later detect if it changed…
previous=$(pixi run python scripts/ci/crates.py get-version)
echo If the version minus prerelease/build metadata is not the same as the release version, then update it.…
if [ $(pixi run python scripts/ci/crates.py get-version --finalize) != $release_version ]; then
pixi run python scripts/ci/crates.py version --exact $release_version
fi
echo If this is an 'rc', additionally set add '-rc.N'. This will also bump the 'N' if '-rc.N' is already set…
if [ ${{ inputs.release-type }} = "rc" ]; then
pixi run python scripts/ci/crates.py version --bump prerelease --pre-id=rc
fi
echo If this is an 'alpha', set the version to whatever is in the git branch name.…
if [ ${{ inputs.release-type }} = "alpha" ]; then
pixi run python scripts/ci/crates.py version --exact $(pixi run python scripts/ci/crates.py get-version --from git)
fi
echo If this is a 'final', set the version to the final release version…
if [ ${{ inputs.release-type }} = "final" ]; then
pixi run python scripts/ci/crates.py version --exact $release_version
fi
echo Store version after the update, and the expected "final" release version…
current=$(pixi run python scripts/ci/crates.py get-version)
final=$(pixi run python scripts/ci/crates.py get-version --finalize)
echo Output everything for use in other steps…
echo "previous=$previous"
echo "current=$current"
echo "final=$final"
echo "previous=$previous" >> "$GITHUB_OUTPUT"
echo "current=$current" >> "$GITHUB_OUTPUT"
echo "final=$final" >> "$GITHUB_OUTPUT"
- name: Update rerun_py & rerun_c version
run: |
pixi run python scripts/ci/update_rerun_py_and_c_version.py "${{ steps.versioning.outputs.current }}"
- name: Update rerun_notebook package version
run: |
pixi run python scripts/ci/update_rerun_notebook_version.py "${{ steps.versioning.outputs.current }}"
- name: Update JS package versions
run: |
pixi run node rerun_js/scripts/version.mjs "${{ steps.versioning.outputs.current }}"
- run: pixi run toml-fmt
- name: Commit new version
id: commit
if: steps.versioning.outputs.previous != steps.versioning.outputs.current
run: |
git pull
git config --global user.name "rerun-bot"
git config --global user.email "[email protected]"
git commit -am "Bump versions to ${{ steps.versioning.outputs.current }}"
git push
echo "version_bump_commit_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Create pull request
env:
GH_TOKEN: ${{ secrets.RERUN_BOT_TOKEN }}
run: |
set +e
pr=$(gh pr view --json headRefName 2>/dev/null || echo "{}")
if echo "$pr" | jq '. | has("headRefName")' | grep -q 'true'; then
echo "PR already exists"
exit 0
fi
set -e
echo "PR does not exist, creating…"
cat <<EOF > pr-body.txt
### Next steps
- Test the release
- If this is an 'alpha' release, you can just merge the pull request.
- Otherwise:
- For any added commits, run the release workflow in 'rc' mode again
- After testing, _ensure that this PR is mergeable to `main`_, then run the release workflow in 'release' mode
- Once the final release workflow finishes it will create a GitHub release for you. Then:
- [ ] Sanity check the build artifacts:
- [ ] pip install: does it install and run?
- [ ] cargo install of cli tool: does it install and run?
- [ ] C++ SDK zip: does it contain rerun_c for all platforms?
- [ ] Populate the release with the changelog and a nice header video/picture, check `Set as latest release`, then click `Publish release`.
- [ ] Update the [google colab notebooks](https://drive.google.com/drive/folders/0AC0q24MFKh3fUk9PVA) to install this version and re-execute the notebook.
A few hours after the GitHub release is created, `regro-cf-autotick-bot` will create a
[conda feedstock PR](https://github.com/conda-forge/rerun-sdk-feedstock/pulls).
Make sure Jeremy is on top of it!
- [ ] Tests
- [ ] Windows
- [ ] Linux
- [ ] MacOS
EOF
gh pr create \
--base main \
--head $(git branch --show-current) \
--title "Release ${{ (inputs.release-type == 'alpha' && steps.versioning.outputs.current) || steps.versioning.outputs.final }}" \
--label "⛴ release" \
--label "exclude from changelog" \
--fill \
--body-file pr-body.txt
update-docs:
name: "Update Docs"
needs: [version, publish-web]
uses: ./.github/workflows/reusable_deploy_docs.yml
with:
CONCURRENCY: ${{ github.ref_name }}
PY_DOCS_VERSION_NAME: ${{ inputs.release-type == 'final' && needs.version.outputs.final || 'dev' }}
CPP_DOCS_VERSION_NAME: ${{ inputs.release-type == 'final' && 'stable' || 'dev' }}
RS_DOCS_VERSION_NAME: ${{ inputs.release-type == 'final' && 'stable' || 'dev' }}
RELEASE_COMMIT: ${{ needs.version.outputs.release-commit }}
RELEASE_VERSION: ${{ needs.version.outputs.final }}
UPDATE_LATEST: ${{ inputs.release-type == 'final' }}
secrets: inherit
publish-crates:
name: "Publish Crates"
needs: [version]
uses: ./.github/workflows/reusable_release_crates.yml
with:
CONCURRENCY: ${{ github.ref_name }}
RELEASE_COMMIT: ${{ needs.version.outputs.release-commit }}
secrets: inherit
publish-rerun_c:
name: "Build and Publish C/C++ SDKs"
needs: [version]
uses: ./.github/workflows/reusable_publish_rerun_c.yml
with:
release-version: ${{ needs.version.outputs.current }}
release-commit: ${{ needs.version.outputs.release-commit }}
concurrency: ${{ github.ref_name }}
secrets: inherit
publish-rerun-cli:
name: "Publish rerun-cli"
needs: [version]
uses: ./.github/workflows/reusable_publish_rerun_cli.yml
with:
release-version: ${{ needs.version.outputs.current }}
release-commit: ${{ needs.version.outputs.release-commit }}
concurrency: ${{ github.ref_name }}
secrets: inherit
publish-wheels:
name: "Build and Publish Wheels"
needs: [version, publish-rerun-cli]
uses: ./.github/workflows/reusable_publish_wheels.yml
with:
release-version: ${{ needs.version.outputs.current }}
concurrency: ${{ github.ref_name }}
release-commit: ${{ needs.version.outputs.release-commit }}
secrets: inherit
publish-web:
name: "Build and Publish Web"
needs: [version, publish-wheels]
uses: ./.github/workflows/reusable_publish_web.yml
with:
release-version: ${{ needs.version.outputs.current }}
release-commit: ${{ needs.version.outputs.release-commit }}
concurrency: ${{ github.ref_name }}
wheel-artifact-name: linux-x64-wheel
update-latest: ${{ inputs.release-type == 'final' }}
secrets: inherit
publish-js:
name: "Publish JS"
needs: [version]
uses: ./.github/workflows/reusable_publish_js.yml
with:
release-commit: ${{ needs.version.outputs.release-commit }}
concurrency: ${{ github.ref_name }}
secrets: inherit
# Force-pushes `latest` and `docs-latest` to the contents of the release branch.
# The push to `docs-latest` also triggers a re-deploy of `rerun.io`.
update-latest-branch:
name: "Update Latest Branch"
if: inputs.release-type == 'final'
needs:
[
version,
update-docs,
publish-crates,
publish-wheels,
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-js,
]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.RERUN_BOT_TOKEN }}
ref: ${{ needs.version.outputs.release-commit }}
- name: Update latest branch
run: |
git config --global user.name "rerun-bot"
git config --global user.email "[email protected]"
git fetch
git checkout ${{ github.ref_name }}
git push --force origin refs/heads/${{ github.ref_name }}:refs/heads/latest
git push --force origin refs/heads/${{ github.ref_name }}:refs/heads/docs-latest
github-release:
name: "GitHub Release"
if: inputs.release-type == 'final'
needs:
[
version,
update-docs,
publish-crates,
publish-wheels,
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-js,
]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.RERUN_BOT_TOKEN }}
- name: Release tag
env:
GH_TOKEN: ${{ secrets.RERUN_BOT_TOKEN }}
run: |
version="${{ needs.version.outputs.final }}"
commit="${{ needs.version.outputs.release-commit }}"
git tag $version $commit
git push origin $version
gh release create $version --verify-tag --draft --title $version
- name: Create comment
env:
GH_TOKEN: ${{ secrets.RERUN_BOT_TOKEN }}
run: |
pr_number=$(gh pr view --json number | jq '.number')
version="${{ needs.version.outputs.final }}"
cat <<EOF > comment-body.txt
GitHub release draft: [$version](https://github.com/rerun-io/rerun/releases/tag/$version)
Do NOT create a GitHub release yet!
The release will be automatically un-drafted by the "Sync Release Assets" job, which will run automatically.
EOF
gh pr comment $pr_number --body-file comment-body.txt
# Bump versions to next minor+alpha after the release has finished,
# so that the release PR can be merged.
post-release-version-bump:
name: "Post-Release Version Bump"
# We don't need to bump versions for `rc` releases, because we don't merge those.
if: inputs.release-type == 'alpha' || inputs.release-type == 'final'
needs:
[
version,
update-docs,
publish-crates,
publish-wheels,
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-js,
]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.RERUN_BOT_TOKEN }}
- uses: actions/setup-node@v4
with:
node-version: 18
- uses: prefix-dev/[email protected]
with:
pixi-version: v0.25.0
- name: git config
run: |
git config --global user.name "rerun-bot"
git config --global user.email "[email protected]"
git checkout ${{ github.ref_name }}
git pull --rebase
- name: Update crate versions
id: crates
run: |
pixi run python scripts/ci/crates.py version --bump auto
version="$(pixi run python scripts/ci/crates.py get-version)"
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Update rerun_notebook package version
run: |
pixi run python scripts/ci/update_rerun_notebook_version.py "${{ steps.crates.outputs.version }}"
- name: Update JS package versions
run: |
pixi run node rerun_js/scripts/version.mjs "${{ steps.crates.outputs.version }}"
- name: Update rerun_py & rerun_c version
run: |
pixi run python scripts/ci/update_rerun_py_and_c_version.py "${{ steps.crates.outputs.version }}"
- run: pixi run toml-fmt
- name: Commit new version
run: |
git commit -am "Bump versions to ${{ steps.crates.outputs.version }}"
git push
comment-artifact-links:
name: "Link to artifacts"
needs:
[
version,
update-docs,
publish-crates,
publish-wheels,
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-js,
]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.RERUN_BOT_TOKEN }}
- name: Create comment
env:
GH_TOKEN: ${{ secrets.RERUN_BOT_TOKEN }}
run: |
pr_number=$(gh pr view --json number | jq '.number')
echo "pr_number: $pr_number"
short_commit_hash=$(echo ${{ needs.version.outputs.release-commit }} | cut -c1-7)
if [ ${{ inputs.release-type }} = "final" ]; then
web_app_link="https://rerun.io/viewer/version/${{ needs.version.outputs.final }}"
rerun_io_docs_link="https://rerun.io/docs"
py_docs_link="https://ref.rerun.io/docs/python/${{ needs.version.outputs.final }}"
else
web_app_link="https://rerun.io/viewer/commit/$short_commit_hash"
rerun_io_docs_link="https://rerun.io/preview/$short_commit_hash/docs"
py_docs_link="https://ref.rerun.io/docs/python/dev"
fi
wheels_link="https://pypi.org/project/rerun-sdk/${{ needs.version.outputs.current }}"
crates_link="https://crates.io/crates/rerun/${{ needs.version.outputs.current }}"
npm_link="https://www.npmjs.com/package/@rerun-io/web-viewer/v/${{ needs.version.outputs.current }}"
rs_docs_link="https://docs.rs/rerun/${{ needs.version.outputs.current }}"
cpp_sdk_zip_link="https://build.rerun.io/commit/$short_commit_hash/rerun_cpp_sdk.zip"
pip_install="pip install rerun-sdk==${{ needs.version.outputs.current }}"
cargo_install="cargo install rerun-cli@${{ needs.version.outputs.current }}"
npm_install="npm install @rerun-io/web-viewer@${{ needs.version.outputs.current }}"
cat <<EOF > comment-body.txt
Version ${{ needs.version.outputs.current }} published successfully.
| artifact | install |
| --------------------------------- | -------------- |
| [web app]($web_app_link) | |
| [wheels]($wheels_link) | $pip_install |
| [crates]($crates_link) | $cargo_install |
| [npm]($npm_link) | $npm_install |
| [docs]($rerun_io_docs_link) | |
| [py docs]($py_docs_link) | |
| [rs docs]($rs_docs_link) | |
| [cpp_sdk zip]($cpp_sdk_zip_link) | |
EOF
gh pr comment $pr_number --body-file comment-body.txt