Cuts the weekly release across cbioportal and cbioportal-frontend, up to a
published and verified Docker image, then files an issue saying what to deploy.
Deployment itself is not automated.
uv sync
uv run pytest
uv run ruff check .
uv run release --helpRequires uv and Python 3.11+. Java 21 and Maven are only needed for the
bump-pom and bump-snapshot commands.
To run anything against the real repos you need a token that can see draft releases:
export GITHUB_TOKEN=$(gh auth token)
uv run release plan --plan /tmp/plan.json # read-only
uv run release notes --plan /tmp/plan.json # read-onlyEvery command that writes takes --dry-run, which performs all the reads and
prints the intended writes instead of making them.
| Variable | Used by | Purpose |
|---|---|---|
GITHUB_TOKEN |
all | API auth. Must be able to read draft releases. |
RELEASE_ASSIGNEE |
report, promote-scan, promote |
GitHub handle to assign issues and bump PRs to. Unset means unassigned. |
GITHUB_STEP_SUMMARY |
plan, notes, report |
Set by Actions. Appended to when present. |
GITHUB_ACTIONS |
logging | Set by Actions. Switches the log formatter to workflow commands. |
RUNNER_DEBUG |
logging | Set by Actions when a run is re-run with debug logging. Forces -v. |
Stdlib logging, configured once in cli.py. Modules just call
logging.getLogger(__name__) — nothing takes a logger or a callback as an argument.
Streams are split by purpose. Diagnostics go to stderr, the deliverable goes to
stdout, so release notes > notes.md gives you the notes and nothing else.
| Flag | Level | Shows |
|---|---|---|
-q |
WARNING | Only things that need attention |
| (default) | INFO | One line per step |
-v |
DEBUG | Adds every HTTP call with status and timing |
Both flags go before the subcommand: release -v plan.
Under Actions the formatter emits workflow commands instead of timestamps:
WARNING and ERROR become ::warning::/::error::, which annotates them on the
run summary page, and each stage is wrapped in a collapsible ::group::. Multi-line
records are escaped to %0A, since a workflow command that contains a raw newline
loses everything after it.
When adding log lines:
- Use
%splaceholders (logger.info("target is %s", target)), not f-strings — the formatting is skipped entirely when the level is disabled. logger.warningfor anything a human should notice but that does not stop the release; raise for anything that does. Errors are logged once, at the top level inmain(), so exceptions should carry the message rather than log it themselves.- Never log headers or tokens.
gh.pytraces method, URL, status and duration only.
| Workflow | Trigger | Does |
|---|---|---|
release.yml |
manual | The release. Inputs: bump, dry_run. One job per stage. |
promote.yml |
nightly 13:17 UTC, manual | Scans for overdue pre-releases. With a version input, performs the promotion. Everything it files — the scan issue and both bump PRs — is assigned and put on the board. |
rehearse.yml |
Mondays 12:23 UTC, manual | Read-only plan + notes, to catch drift before release day. |
ci.yml |
PR, push to main |
ruff and pytest. |
release.yml uses concurrency: release, so two releases cannot overlap. Stage 3
sits behind the release-approval environment.
Dispatch Release. Leave bump on patch unless the release needs a database
migration or breaks something. When it finishes, Release vX.Y.Z is filed in this
repo with the image tag and sha256 digest, assigned to RELEASE_ASSIGNEE and put
on cBioPortal Team Planning in
Todo and the current sprint; close it once deployed.
A GitHub App installed on cbioportal, cbioportal-frontend, cbioportal-helm,
cbioportal-docker-compose and this repo, with permissions: contents write,
pull requests write, issues write, actions write, metadata read, and
the organisation permission projects write so stage 9 can put the release issue
on the team planning board.
| Kind | Name | Value |
|---|---|---|
| Secret | APP_ID |
the App's ID |
| Secret | APP_PRIVATE_KEY |
the App's private key |
| Variable | RELEASE_ASSIGNEE |
GitHub handle for release issues |
| Environment | release-approval |
with required reviewers |
| Labels | release, succeeded, failed, promotion |
in this repo |
The cbioportal master ruleset must give the App an Always allow bypass.
Stages 5 and 8 commit the pom directly to master rather than opening a PR —
those two commits are release logistics, and a PR would file them in the release
notes this release then publishes. The ruleset bypass covers both its pull-request
and required-status-check rules; App repository permissions alone do not.
Everything environment-specific lives there. The parts most likely to need updating:
[required_checks] — an allowlist of checks that must be green before a
release starts (stage 1, on the pinned SHA), covering both GitHub check-runs and
CircleCI commit statuses.
Both lists are currently empty, so CI does not gate a release at all; stage 1
logs a warning saying so. That is deliberate — the combined status of
both masters is normally failure (sonarcloud, GitBook, Dependabot,
e2e_localdb), so there was no dependable gate to enforce. It is an allowlist,
never "everything green": add a name only if it should genuinely stop a release.
To see the current names on a commit:
gh api repos/cBioPortal/cbioportal/commits/master/check-runs --jq '.check_runs[].name'
gh api repos/cBioPortal/cbioportal/commits/master/status --jq '.statuses[].context'[docker] tag_suffixes and platforms — must match what
cbioportal/.github/workflows/dockerimage.yml publishes. If a new image variant
or architecture is added there, add it here or the release will not wait for it.
[maven] artifact ids — must match the artifactId in each repo's pom.xml.
[timeouts] — maven_attempts × maven_interval_seconds is the publish
wait. Maven Central routinely takes 20 minutes.
[promotion] age_days — how long a pre-release must run before promote-scan
flags it.
Tests use recorded fixtures and hand-written fakes; nothing hits the network.
tests/conftest.py holds draft bodies shaped like the real release-drafter output.
When changing behaviour that depends on an external format — the drafter template,
the pom layout, the Docker Hub manifest shape — update the corresponding fixture
in tests/ rather than loosening the assertion.
bump-pomandbump-snapshotshell out tomvn versions:set, so their jobs needsetup-java. Never edit the pom withsed: a pattern that stops matching is indistinguishable from a pattern with nothing to do.cbioportal-frontend'smaven-package-build.ymlcurrently triggers on bothrelease: publishedandpush: tags: '*', so it runs twice per release and the two runs race on Maven Central. Itsupdate-backendjob also pushes directly to backendmaster, which conflicts withbump-pom. Both need fixing in that repo before a real release is run from here.