This document has two parts:
- Release policy, for users: versions, cadence, where to get a release, and the backport policy.
- Release process, for maintainers: how to make a release, and the playbooks to follow.
A release has a name of the form release-<yyyymmdd>.<N>, for example
release-20261005.0.
<yyyymmdd>is the date of the release branch. It is the Monday (UTC) of the week in which the release was cut. The release is usually published a few days later.<N>is the point release number. The first release for a date is.0. A point release (.1,.2, ...) adds backported security fixes to the release of that date.
Versions are ordered by date, then by point number: 20261005.0 is newer than
20260928.1, even if 20260928.1 was published later.
gVisor publishes a new release weekly. Each release is cut from the master
branch.
gVisor does not offer long-term support (LTS) releases. Users are expected to
track the newest release. Bug fixes land on master and roll out with the next
weekly release.
The Google Cloud Storage release bucket (gs://gvisor/releases/) and the apt
repository are the canonical channels. The
GitHub releases page mirrors these
artifacts. See Installation for the channels (latest,
specific release, point release, nightly, and HEAD) and the install commands.
latest, the apt release suite, and the "Latest" label on GitHub always point
to the highest version. A backport to an older release branch does not affect
them.
Each artifact is accompanied by a .sha512 file. The GitHub release also
provides SHA256SUMS and SHA512SUMS. Verify the digest before installing.
A backport applies a security fix to a published release branch, producing a
point release (for example 20261005.1). gVisor backports only security fixes:
- To the newest release: any security fix. Most users install the latest release, so the newest release is always fixed.
- To an older release: only a fix for an issue that crosses the sandbox boundary (see SECURITY.md), and only for a release date that users pin.
gVisor does not backport other bug fixes or new features; these roll out with the next weekly release.
If you pin a release date, use the specific release channel for that date to
receive its backports. A pinned point release (for example 20260928.0) never
receives backports.
Report a vulnerability as described in SECURITY.md.
If a fix is under embargo, it stays private until the disclosure date agreed
upon with the reporter. On that date, the fix merges to master, and point
releases are published shortly thereafter, once the builds complete. The
security advisory is published concurrently with the release.
This part is for gVisor maintainers.
The release branch holds the code for one release. The release tag comes from that branch.
The commit is the input of a release, not a result. The maintainer who starts a release chooses the commit when they cut the branch. The branch moves only when a gVisor maintainer explicitly moves it.
Release branches have a short lifecycle: they are cut from master, may receive
cherry-picked fixes through pull requests, and are published. Once published,
the branch remains inert unless a security backport is required (see
Backports).
| Step | Who | Result |
|---|---|---|
| 1. Cut | A maintainer | release/<yyyymmdd> at one commit on master |
| 2. Cherry-pick (optional) | A maintainer | Cherry-picks from master, merged to the branch by pull request |
| 3. Stage | A maintainer, with a GitHub workflow | Tag release-<yyyymmdd>.<N>-staging on the branch head |
| 4. Publish | Buildkite | Artifacts in gs://gvisor/releases/, then tag release-<yyyymmdd>.<N> |
| 5. Mirror | GitHub workflow | GitHub release with the artifacts and release notes |
All cherry-picks go to the branch before step 3. After step 3, the branch does not change, except for a backport.
A backport applies a fix to a published release branch to produce a point
release, for example 20260928.1. Create one only if the
backport policy allows it; otherwise, merge the fix to
master and let it roll out in the next weekly release.
- Always merge the fix to master first. The workflows refuse a commit that is not on master.
- Backport to the newest release if it does not have the fix.
- Backport to an older release only for an issue that crosses the sandbox boundary, and only if users pin that date.
- For a vulnerability, obey the embargo rules.
An embargo is an agreement with the reporter: the fix stays private until an agreed date. GitHub supplies the private workspace (a draft security advisory and its temporary private fork), and gVisor uses it.
Before the embargo date:
- Do the work only in the private fork of the advisory.
- Do not push a branch, open a pull request, or run a release workflow in
google/gvisor. All of these are public.
On the embargo date:
- Merge the fix from the advisory to master.
- Backport the fix and stage the releases (Playbook C).
- Publish the advisory when the release is published.
The fix becomes public immediately upon merging to master. The release follows
several hours later because artifact builds take time. Be sure to notify the
reporter about this gap when coordinating disclosure timing.
Only repository admins and security managers can create advisories. Ensure release maintainers are granted the security manager role.
Start each workflow from Actions → workflow name → Run workflow. The Use workflow from branch is the target branch.
- Open Cut Release Branch.
- Set Use workflow from to
master. - Leave
commitempty to use the head of master, or enter a commit on master. - Click Run workflow.
- Make sure that the run summary shows
Cut release/<yyyymmdd> at <commit>.
- Merge each fix to master first.
- Open Cherry-pick to Release Branch.
- Set Use workflow from to
release/<yyyymmdd>. - In
commits, enter the master commits, oldest first, separated by spaces. - Click Run workflow. Open the pull request link in the run summary.
- Review the pull request and merge it. Use "Create a merge commit" or "Rebase and merge", not "Squash and merge".
- If a commit has conflicts, the run stops and lists the files. Do that cherry-pick by hand (B2).
- Make sure that all cherry-pick pull requests are merged.
- Open Stage Release.
- Set Use workflow from to
release/<yyyymmdd>. - In
version, enter<yyyymmdd>.0. - Click Run workflow.
- Open
https://buildkite.com/gvisor/release/builds?branch=release-<version>-staging. Make sure that the build started. If it did not, see Troubleshooting. - When the build passes, make sure that:
- The tag
release-<version>exists, and the staging tag does not. https://storage.googleapis.com/gvisor/releases/release/<version>/x86_64/gvisor.tar.zstdexists. Do the same check foraarch64.- The Release Mirror run passed, and the GitHub release exists.
- If this is the highest version, the GitHub release has the "Latest" label.
- The tag
Use this playbook only if GitHub Actions is not available. You must have push
access to google/gvisor, and origin must point to it. These steps do not run
the workflow checks, so do each check yourself.
git fetch origin --tags
date=20261005 # The Monday of this week.commit="$(git rev-parse origin/master)" # Or a chosen commit on master.
# Checks. Each one prints STOP if it fails.
git merge-base --is-ancestor "${commit}" origin/master ||
echo "STOP: ${commit} is not on master."
git ls-remote --exit-code origin "refs/heads/release/${date}" >/dev/null &&
echo "STOP: release/${date} already exists."
[[ -z "$(git tag -l "release-${date}.*")" ]] ||
echo "STOP: a release-${date}.* tag already exists."Run the next command only if no check printed STOP:
git push origin "${commit}:refs/heads/release/${date}"You can push the cherry-pick branch to your fork.
git switch -c "cherry-pick/${date}-<topic>" "origin/release/${date}"
git cherry-pick -x <sha> # Add "-m 1" for a merge commit.
git push <your-remote> HEAD
gh pr create --repo google/gvisor --base "release/${date}" \
--head "<you>:cherry-pick/${date}-<topic>"Get a review, then merge the pull request.
git fetch origin --tags
commit="$(git rev-parse "origin/release/${date}")"
# Check. It prints STOP if it fails.
released="$(git tag --points-at "${commit}" -l 'release-*' |
grep -v -- '-staging$')"
[[ -z "${released}" ]] ||
echo "STOP: ${commit} is already released."Run the next commands only if the check did not print STOP:
echo "Release ${date}.0" >/tmp/msg
tools/tag_release.sh "${commit}" "${date}.0" /tmp/msgThis is the same as make tag RELEASE_COMMIT="${commit}" RELEASE_NAME="${date}.0" RELEASE_NOTES=/tmp/msg.
Do the steps in A4.
Follow this playbook only when the backport policy allows it. For an embargoed fix, start on the embargo date.
- Merge the fix to master.
- Find the releases that need the fix:
- The newest release. Run cherry-pick on its branch. If the branch already has the fix, the run stops with "already on release/...".
- Older releases, only for an issue that crosses the sandbox boundary, and only if users pin them.
- For each branch, do A2 and merge the pull request.
- For each branch, do A3 with the next point version, for example
20261005.1. You can stage the branches in any order. - For each release, do A4. Only the highest version
gets
latestand the "Latest" label. - Publish the security advisory.
Releases made before this process (for example release-20260928.0) do not have
a branch. Create the branch one time from the tag. Then add the release workflow
files to the branch, or use Playbook B:
git push origin 'release-20260928.0^{commit}:refs/heads/release/20260928'| Symptom | Cause | Action |
|---|---|---|
Cut: release-X is not older than <date> |
This date has a release, or a newer release exists | Wait for the next week. To fix the existing release, use Playbook C. |
"Workflow does not exist or does not have a workflow_dispatch trigger in this branch" |
The selected branch does not contain the workflow | Use a branch that was cut from master after the workflows were added. |
Stage: already released as ... |
There is no new commit since the last release | Merge the cherry-pick pull request first. |
| No Buildkite build after stage | The webhook did not start a build for the tag | Examine the Buildkite webhook. As a fallback, do B3. |
| The Buildkite build failed | A build or upload error | Fix the problem. Then stage again with the same version. This replaces the staging tag. |
| Release Mirror failed | The artifacts were late, or a network error occurred | Run Release Mirror again with the tag. |
- Do not delete or move a published
release-*tag. - Do not use
gh release delete --cleanup-tag. - Do not run a release workflow or open a public pull request for an embargoed fix before the embargo date.
- Do not backport a fix that is not a security fix.
- Do not use another release process at the same time as this one.