Releasing Studio¶
Studio follows the tag-and-artifact approach used by AtomWorks and tmol: build once, test the installed packages, then publish those artifacts in a separate job. Documentation builds separately, as in RFD4, and is included in every release.
The editor keeps atomworks[ml] pinned to the release in dependencies.toml, including Torch. Native PyMOL is an optional host application; inference is outside Studio.
One-time setup¶
The publishing repository is RosettaCommons/atomworks-studio.
Development history stays in the private baker-laboratory/atomworks-studio-dev repository.
release/rosettacommons from the development repository is mirrored there commit for commit
(see Promote development to RosettaCommons).
Repository visibility is managed separately from releases.
Create a GitHub environment named pypi. Register a
PyPI Trusted Publisher
for atomworks-studio, using owner RosettaCommons, repository
atomworks-studio, workflow release.yaml, and environment pypi.
No PyPI API token or private dependency token is needed. CI uses the bundled, hash-verified scientific definitions.
Optional destinations:
Set
VSCE_PATto publish the already-built VSIX to the VS Code Marketplace. The VSIX is always attached to the GitHub release.Enable GitHub Pages from
gh-pagesand set the repository variableSTUDIO_PUBLISH_DOCS=trueto publish docs under/v<version>/. Earlier versions are retained. The documentation archive is always attached to the GitHub release, even when Pages is disabled.
Cut a release¶
Update
VERSIONand the Python, JavaScript, and Rust package versions. Runpython scripts/verify_distribution.pyand update the lockfiles.Merge the reviewed change after CI passes.
Push the matching
v<version>tag. A manual workflow run must also select that tag; branch refs and the rollingvscode-latesttag are rejected.
The workflow runs the CI suite for the tagged commit (currently without the browser acceptance job; see the comment in release.yaml). The package job
builds the wheel and source archive, rejects missing or stale artifacts,
checks package metadata with Twine, and installs the built Studio wheel in a
fresh environment outside the checkout. It exercises CLI startup, bundled
browser/WASM assets, CIF loading, protonation, selections, export, and Undo.
CI also checks the native PyMOL plugin, browser workflows and docs.
Only after those jobs succeed does the publish job upload the Python
artifacts to PyPI through OIDC. The GitHub release then receives the same
packages, VSIX, docs archive, checksums, and build provenance.
If an upload fails partway through, rerun the failed jobs while the build artifacts remain available. PyPI uploads skip files already present. Published versions are immutable: use a new version and tag for changed code.
For local builds, start with an empty output directory so the artifact check can catch stale packages:
pnpm build
make docs
uv build --out-dir dist
uv run scripts/check_distribution_assets.py dist
uv run --no-project --with twine python -m twine check --strict dist/*
The RFD4 adapter bundles the definition files listed with SHA-256 hashes in
providers/rfd4/UPSTREAM.toml. They come from the pinned
RosettaCommons RFD4 repository,
including its BSD license. The build verifies every file; wheel and source
archive checks verify the bundled copies. Users need no checkout to annotate.
Promote development to RosettaCommons¶
Work in atomworks-studio-dev first. release/rosettacommons is the clean branch
that RosettaCommons/atomworks-studio mirrors: the same commits, never rewritten.
It equals main plus the committed browser bundle and guide, so pip install
from the public repository needs no Node, Rust or Sphinx.
Merge reviewed changes to
main(use merge commits, not squashes, so the release branch can mergemaincleanly).make build, thenscripts/make_release_branch.sh. It mergesorigin/mainintorelease/rosettacommonsand commits the fresh bundle and guide.Push the branch to
origin, wait for its CI workflow to pass, including package, Docker Space, browser, and documentation checks. Never substitute an older green run for the release commit.Push that same branch to the RosettaCommons remote as
main(git push rosettacommons release/rosettacommons:main), and wait for its CI and VS Code extension workflows before tagging a PyPI release there.
The release branch deletes the two build-output lines from .gitignore; keep edits to
that file away from them on main to avoid merge conflicts. Do not rewrite published release tags.