Releasing¶
The maintainer-facing runbook for cutting an Aegis-KMS release. This is the step-by-step you follow to ship a new version end-to-end.
This page renders the project-root RELEASING.md. The canonical source is at
github.com/sharma-bhaskar/aegis-kms/blob/main/RELEASING.md.
Releasing Aegis-KMS¶
This is the operator runbook for cutting a tagged release. The release.yml
GitHub Actions workflow does the heavy lifting on every v* tag push:
- CI gate (compile, scalafmt, scalafix, test) — same checks as the main branch CI.
- Publish library jars to Maven Central (
dev.aegiskms %% aegis-coreand friends) viasbt-ci-release. Skipped automatically if the signing secrets aren't configured. - Publish the
aegis-serverDocker image toghcr.io/<owner>/aegis-server:<version>using the built-inGITHUB_TOKEN. - Build the
aegis-cliuniversal tarball and attach it to a GitHub Release.
The version number is derived by sbt-dynver from the tag — v0.1.1 →
0.1.1 for the artifacts. Don't add a version := line to build.sbt;
that would override the derived value and ship every tag as
0.1.0-SNAPSHOT.
One-time setup (you, the maintainer, must do this once)¶
The Docker + GitHub Release path runs out of the box on a fresh repository. The Maven Central path requires four secrets that only you can set up.
1. Sonatype OSSRH account on s01.oss.sonatype.org¶
If dev.aegiskms is already provisioned, skip to step 2. If not:
- Sign up at https://central.sonatype.com (or https://issues.sonatype.org for the legacy OSSRH JIRA flow if your namespace is on the older host).
- Open a "New Project" ticket claiming the
dev.aegiskmsgroup ID. The reviewer will check that you controlaegiskms.dev(DNS TXT verification) or the GitHubsharma-bhaskarnamespace. - Once approved, generate a user token (NOT your account password) at https://central.sonatype.com/account → Tokens. The token's username and password are the values you'll set as GitHub Action secrets below.
2. GPG signing key¶
Maven Central rejects unsigned artifacts. sbt-ci-release expects the
private key as a base64-encoded blob in an env var.
```bash
Generate a 4096-bit RSA key. Pick a passphrase you'll remember.¶
gpg --full-generate-key
Find the key id (the long hex string) and publish the public half to a¶
keyserver so verifiers can fetch it.¶
gpg --list-secret-keys --keyid-format LONG
gpg --keyserver keyserver.ubuntu.com --send-keys
Export the private key and base64-encode it (no line wrapping).¶
gpg --armor --export-secret-keys
Save the base64 blob; it goes into PGP_SECRET below.
3. GitHub Action secrets¶
In the GitHub repo, go to Settings → Secrets and variables → Actions → New repository secret and add:
| Secret name | Value |
|---|---|
PGP_SECRET |
The base64 blob from step 2. |
PGP_PASSPHRASE |
The passphrase you chose for the GPG key. |
SONATYPE_USERNAME |
The user-token name from step 1. |
SONATYPE_PASSWORD |
The user-token value from step 1. |
The release workflow gates the Maven publish step on PGP_SECRET != ''; if
any of these are missing the workflow ships the Docker image + CLI tarball
only and adds a ::notice to the run output instead of failing.
Cutting a release¶
Once setup is done, releasing is one command per tag:
```bash
1. Update CHANGELOG: rename the ## Unreleased section to ## 0.1.1 — YYYY-MM-DD,¶
open a fresh ## Unreleased block above it. Commit the change to main.¶
2. Tag and push. sbt-dynver reads the tag verbatim, minus the v prefix.¶
git tag v0.1.1 git push origin v0.1.1 ```
That's it. Watch the workflow at https://github.com/sharma-bhaskar/aegis-kms/actions/workflows/release.yml. On success:
aegis-core_3etc. appear at https://central.sonatype.com/artifact/dev.aegiskms/aegis-core_3 (allow ~10 min for staging → release sync).- The Docker image is at
ghcr.io/sharma-bhaskar/aegis-server:0.1.1. - A
0.1.1release page on GitHub carries the CLI tarball and auto-generated changelog notes.
Troubleshooting¶
| Symptom | Likely cause | What to do |
|---|---|---|
Workflow's "Publish to Maven Central" step is skipped with a ::notice |
One of the four secrets above is unset | Set them in repo settings; subsequent tags will publish |
| Sonatype rejects with "Missing: gpg signature for ..." | GPG key not propagated to the keyserver yet | Re-run gpg --keyserver ... --send-keys against multiple servers; wait 10 min and retry the workflow |
| Sonatype rejects with "Invalid POM: missing description" | One of the modules lost its description := line |
Restore in build.sbt; the ThisBuild / description fallback should also catch this |
| Tag pushed but workflow didn't fire | Branch protection or workflow on: filter |
Verify the tag matches v*; check the Actions tab for queued runs |
Docker tag missing the v prefix |
Intentional — the workflow strips v so v0.1.1 → ghcr.io/...:0.1.1 |
This is the documented format |
For deeper diagnostics, the workflow run page captures the full sbt output including the staged Sonatype URL.
Pre-release / SNAPSHOT versions¶
Pushes to main (without a tag) automatically produce
0.1.1+<n>-<sha>-SNAPSHOT artifacts via sbt-dynver. These are useful for
internal smoke tests but are not published anywhere by default. To publish a
SNAPSHOT manually from your laptop:
```bash
Set the same env vars the workflow sets (PGP_SECRET, etc.).¶
sbt ci-release ```
The Sonatype snapshot repo accepts these without manual staging.