wiki/release-process.md
This guide covers the engineering steps for publishing the streamlit package.
It combines the regular release and patch release runbooks with the automation
in this repository.
The checked-in workflows are the source of truth for what GitHub performs. If this guide and a workflow disagree, follow the workflow and update this page.
release environment.v prefix, such as 1.60.0 or 1.60.1.release/* PR.All release branches and tags use the same version:
branch: release/1.60.0
tag: 1.60.0
| Workflow | Use | Required inputs | Result |
|---|---|---|---|
| Release Branch Creation | Regular release | release_version, nightly_tag | Creates release/<version> from a nightly tag and sets the production version |
| Patch Release Branch Creation | Patch release | patch_version, base_tag | Creates release/<patch-version> from an existing release tag |
| Cherry-Pick to Release Branch | Either release type | release_version, cherry_pick_sha | Cherry-picks one commit and pushes the release branch |
| Release Tag and PR Creation | Either release type | release_version | Tags the release branch and opens its merge-back PR to develop |
| Build Release | Either release type | Run the workflow from the release tag | Tests, builds, publishes to PyPI, and creates the GitHub release |
The workflows validate version formats, branch and tag existence, and other preconditions before changing the repository. They also send the configured release notifications.
The Nightly Build workflow runs daily at 04:30 UTC. Use the nightly from the scheduled release cutoff day as the release candidate.
1.60.0 release typically has a nightly
tag like 1.59.1.dev20260725 (not 1.60.1.dev20260725), because the
nightly version increments the patch component of the latest PyPI release
by one.Run Release Branch Creation
from develop with:
release_version: the production version, such as 1.60.0nightly_tag: the exact tested nightly tagThe workflow verifies the nightly marker, removes the nightly-only package-name
and version commit, creates release/<version>, updates the Python and
JavaScript package versions, regenerates uv.lock, commits those changes, and
pushes the branch.
Most releases ship the cutoff nightly as-is. When a post-cutoff change is needed, the original author is responsible for getting it onto the release branch. Cherry-pick only changes that are necessary and low risk, such as:
For each commit, run Cherry-Pick to Release Branch
with the target release version and one commit SHA. The workflow accepts a
7-to-40-character SHA, checks out release/<version>, cherry-picks the commit,
and pushes the branch.
If the workflow reports a conflict, it aborts without pushing. Resolve the cherry-pick manually on a local checkout of the release branch, run the checks appropriate to the change, and push the resolved commit. Do not broaden the change while resolving the conflict.
If you cherry-picked anything:
<nightly-tag>^, i.e. the commit before the nightly version bump) to the
release branch.Run Release Tag and PR Creation with the release version.
The workflow:
release/<version> exists and <version> is not already a tag;[chore] Release v<version> from the release branch to develop;change:chore and impact:users labels.Before publication, the tag may be moved if the release branch changes (see Handling failures for the delete-and-recreate commands). After publication, treat the tag as immutable and use a new version for additional fixes.
Do not merge the generated PR yet. Build Release
uses an open release/* PR to verify that the selected tag corresponds to a
release branch. Until publishing completes:
release/* PR;release/<version> and its base is develop.Run the Static Assets Workflow for SiS after creating the release tag and before building the release. This ensures that Streamlit in Snowflake on Snowpark Container Services (SPCS) loads static assets from the CDN instead of serving them locally.
Follow the Snowflake-internal Static Assets Workflow for SiS instructions before continuing:
Open Build Release,
select the newly created tag in Use workflow from, and run the workflow.
Selecting develop or the release branch instead of the tag will fail the
version checks.
The workflow:
release environment;make package;lib/dist to PyPI using trusted publishing;Before approving the protected environment, the second release-team member should verify:
Confirm the new version appears in the Streamlit PyPI history.
Install from PyPI in a clean environment:
uv venv .venv-release-test
source .venv-release-test/bin/activate
uv pip install "streamlit==<version>"
streamlit version
Confirm the command prints the expected version and smoke-test that the app starts successfully.
Confirm the GitHub release exists and skim its generated notes.
Merge the release PR back into develop.
Complete the documentation release, public release notes, and any relevant issue or forum follow-ups.
Wait for the automated release PR to appear in the conda-forge Streamlit feedstock. This can take a couple of hours after the PyPI release.
Confirm the feedstock PR checks pass, fix any failures if needed, and merge the PR.
Request publication to the default Conda channel in the Snowflake-internal
#anaconda-snowflake-technical
Slack channel. This keeps Streamlit current in the main anaconda channel
(separate from conda-forge). You may need to request access to the channel
first. Use this message template:
Released Streamlit v<version>
The Anaconda team will publish the package to the default Conda channel, which may take a day or two.
Use a patch release for a focused fix that must reach users before the next
regular release. Agree on the scope and release owner before creating the
branch. Keep the patch minimal; unrelated changes remain on develop.
The patch workflow enforces that:
x.y.z versions;For example, create 1.60.2 from 1.60.1, not from 1.60.0.
Run Patch Release Branch Creation
from develop with:
patch_version: the new patch version;base_tag: the immediately preceding release in that minor line.The workflow checks out the base tag, creates release/<patch-version>, updates
the core package versions, regenerates uv.lock, commits the version update,
and pushes the branch.
Use Cherry-Pick to Release Branch
once for each approved fix commit. Prefer commits that have already landed on
develop, so the merge-back PR does not become the only place containing the
fix.
Verify:
If the incident affected custom components, also test the relevant component API and decide whether a separate npm package release is required.
Use the same steps as a regular release:
Also respond to the people who reported the issue. For a significant incident or a failed emergency release, create a postmortem and schedule a review according to the current internal incident process.
The core release automation does not update either component-library package;
their versions are independent from the streamlit version.
For @streamlit/component-v2-lib:
frontend/component-v2-lib/package.json change is in
the release branch before tagging. If it landed after cutoff, cherry-pick its
commit.release environment approval, publishes through npm trusted
publishing, and verifies registry propagation.Publishing the v1 streamlit-component-lib must currently be handled manually.
Components v1 is considered legacy, and no new releases are planned.
Cherry-pick conflict: The workflow aborts and does not push. Resolve it
manually on release/<version>, test, and push.
Test failure before publication: Determine whether the failure is a
product regression, a bad test, or a confirmed flake. Fix real defects on
develop and cherry-pick only the approved fix. If a tag already exists but
the release has not been published, move the tag to the updated release
branch head. Do not re-run Release Tag and PR Creation;
that workflow refuses to recreate an existing tag. Delete and recreate the
tag manually on the updated release-branch head instead:
git fetch origin "release/<version>"
git tag -d "<version>"
git push origin ":refs/tags/<version>"
git tag -a "<version>" -m "Streamlit <version>" "origin/release/<version>"
git push origin "<version>"
Failure during or after publication: Check PyPI and GitHub Releases before retrying. Package uploads and releases are externally visible and cannot be treated like an unstarted job.
Unexpected branch, PR, tag, or version validation failure: Stop and correct the repository state. Do not bypass the guard or publish from an arbitrary ref.