Skip to content

Releasing

This page is RELEASING.md from the repository, included as it stands. Only a maintainer cuts a release.

A release is a v* tag on a commit that is on main. The release workflow (.github/workflows/release.yml) does the rest: it checks the tag against every version file, builds the packages, image, chart, Python package and Galaxy collection, and publishes each from a job that only downloads. The GitHub release stays a draft until every publisher has finished.

Nothing publishes until a tag is pushed. Do the one-time setup below first; it is what makes a tag without approval harmless.

Versioning

port49 uses SemVer. v0.1.0 is the beta. In 0.x, configuration may break between releases, and every such change gets a loud release note. 1.0.0 is the compatibility promise. There is one version across every artifact (packages, image, chart, Python package, Galaxy collection), and bumps come from Conventional Commits. Tags are pushed by hand and carry no pre-release suffix unless it maps to a valid PEP 440 version. The docs site states the same on its Versions page.

One-time setup, before the first tag

  1. PyPI trusted publisher. Project port49, repository blanketfish/port49, workflow release.yml, environment pypi.
  2. Environments (Settings, Environments):
  3. release (the goreleaser, image and chart jobs): the maintainer as the required reviewer, so no tag publishes without approval.
  4. pypi and galaxy: created beside it.
  5. Each of release, pypi and galaxy: deployment branches and tags restricted to the v* tag pattern.
  6. GALAXY_API_KEY is an environment secret on galaxy only: never a repository or organization secret, so no other job can read it.
  7. Tag ruleset. A repository ruleset protecting v* tags (restrict creation, updates and deletion to the maintainers).
  8. Fork pull-request workflows. Settings, Actions, General, "Fork pull request workflows from outside collaborators": Require approval for all outside collaborators.
  9. Public packages. When the repository goes public, make the GHCR package port49 and the chart package public.
  10. Docs site. Settings, Pages, source GitHub Actions. The github-pages environment's deployment branches and tags are restricted to main and the v* tag pattern. docs.yml's deploy job is the only one that names it, and it deploys only from a public repository.
  11. Required check. Add docs (the build job in docs.yml, named docs) to the required status checks of the main ruleset. The site deploys only for the highest final vX.Y.Z tag.
  12. Link check. At go-public, run one external link check over the built site (for example lychee on site/) and fix what it finds.

Each release

  1. Set the same version in clients/python/pyproject.toml, the collection's galaxy.yml, and the chart and app versions; go run ./tests/ci/cmd/versioncheck -tag vX.Y.Z must pass.
  2. Merge to main. The tag must be on main; the workflow refuses it otherwise.
  3. The maintainer pushes the tag; nobody else, and no automation, does. The maintainer approves the release environment when the run asks.
  4. Check the draft release's assets and provenance attestations, then let the last job publish it.