Skip to content

Release flow

PR merge (main) ──→ release-please opens / updates a release PR
│ (release PR merged)
semver git tag pushed (v0.7.2)
docker-publish.yml workflow runs
Multi-arch images pushed to Docker Hub:
scani/api:0.7.2, :0.7, :0, :latest
scani/worker:...
scani/data-provider:...
scani/frontend-app:...

release-please is a GitHub Action that watches main for conventional-commit messages. It maintains a “release PR” that accumulates the next version’s changelog and bumps the manifest.

Commit prefixTriggers release?Bump
feat:yesminor
fix:yespatch
feat!: or BREAKING CHANGE:yesminor pre-1.0, major post-1.0
docs:, refactor:, chore:, test:, ci:no

Configuration: release-please-config.json. Pre-1.0, the bump-minor-pre-major: true setting promotes breaking changes to minor bumps so the version number stays in the 0.x series.

When the release PR merges, release-please pushes a git tag (v0.7.2) which triggers the docker-publish workflow.

.github/workflows/docker-publish.yml builds four images on:

  • Pushes to main — tags :latest and :sha-<short>.
  • Semver tag pushes — tags :1.2.3, :1.2, :1, and :latest.
  • PRs — builds amd64-only (no push) to catch image-build regressions early.
  • workflow_dispatch — manual trigger.

Architectures: linux/amd64 + linux/arm64 on main/tag pushes. PRs are amd64-only for speed.

Images published to Docker Hub under the scani/ namespace:

  • scani/api
  • scani/worker
  • scani/data-provider
  • scani/frontend-app

The frontend image bakes VITE_API_URL=/api (a relative path) so nginx can do the backend routing at runtime — no rebuild per deployment.

Conventional commit prefixes — the honest list

Section titled “Conventional commit prefixes — the honest list”

Use the prefix that actually describes the change. release-please trusts it.

PrefixUse forExamples
feat:New user-visible feature.Adding a Kraken adapter; adding the vaults dashboard.
fix:Bug fix.Wrong cost basis after a re-import; broken splash hero on mobile.
refactor:Code change with no behaviour change.Renaming a service; moving a helper.
chore:Tooling, deps, CI, build.Bumping Bun version; adding a CI step.
docs:Docs-only change.This entire docs site.
test:Tests-only change.Adding a regression test for a fixed bug.
ci:CI / workflow changes.New GitHub Actions job.
perf:Performance improvement.Two-query transfer matcher replacing N queries.

feat!: / fix!: / refactor!: + BREAKING CHANGE: footer signal a breaking change.

Every commit needs a Signed-off-by: trailer — generated by git commit -s. This is the Developer Certificate of Origin: you certify you have the right to contribute the code under the project’s MIT license.

CI rejects PRs with unsigned commits.

What to do when release-please opens a release PR

Section titled “What to do when release-please opens a release PR”
  • Don’t merge it immediately. Wait until CI is green and you’ve read the auto-generated changelog. The changelog is what users read when they upgrade — fix awkward wording before merging.
  • Don’t add commits to the release PR. release-please owns it and will rebase. If the changelog needs a fix, change the commit messages it draws from, not the release PR.
  • Don’t merge the release PR while another release PR is open upstream. release-please tracks state via labels; manually closing/reopening can desync.

If you accidentally land a feat: commit that shouldn’t trigger a release (e.g. an internal-only change), follow up with an empty commit:

Terminal window
git commit --allow-empty -m "chore: re-classify previous as internal"

…and edit the release PR’s changelog entry to remove the spurious feature. Awkward but rare.