This document covers the one-time infrastructure setup required to run the release workflow, and how to cut a release once everything is configured.
Pushing a v0.x.y tag triggers the release workflow (.github/workflows/release.yml), which:
- Linux job — cross-compiles all platform binaries inside
goreleaser-cross(Docker), builds archives, and creates a GitHub draft release with the Linux and Windows assets. - macOS job — signs and notarizes the Darwin binaries using an Apple Developer certificate, re-archives them, replaces the macOS assets on the draft release, publishes the release, then updates the Homebrew tap formula.
All binaries are distributed as GitHub release assets — Homebrew and WinGet download directly from https://github.com/APImetrics/APImetrics-cli/releases/download/<tag>/.
Snapshot builds (no publish) can be triggered via workflow_dispatch with snapshot: true.
Binaries are distributed as GitHub release assets, so the repository must be public (or the download URLs used by Homebrew/WinGet must otherwise be reachable by end users). No cloud storage or service-account setup is required.
The workflow uses a GitHub App to push formula updates to APImetrics/homebrew-tap. This avoids a long-lived personal access token.
- Go to GitHub → APImetrics org settings → Developer settings → GitHub Apps → New GitHub App.
- Name it something like
apimetrics-release-bot. - Under Permissions → Repository permissions, set Contents to
Read & write. No other permissions needed. - Uncheck Webhooks (not needed).
- Set Where can this GitHub App be installed? to
Only on this account. - Create the app and note the App ID.
- Under Private keys, generate and download a private key (
.pemfile). - Go to Install App and install it on
APImetrics/homebrew-taponly.
Secrets to add to APImetrics/APImetrics-cli:
| Secret | Value |
|---|---|
GH_APP_ID |
Numeric App ID shown on the app settings page |
GH_APP_PRIVATE_KEY |
Full contents of the downloaded .pem file, including the -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- header/footer lines |
macOS binaries must be signed and notarized with an Apple Developer ID certificate so they run without Gatekeeper warnings.
Prerequisites:
- An Apple Developer Program membership.
- A Developer ID Application certificate. Export it as a
.p12file from Keychain Access (include the private key, set a strong export password). - An app-specific password for the Apple ID used to notarize.
Encode the certificate:
base64 -i certificate.p12 | pbcopy # copies base64 to clipboardSecrets to add to APImetrics/APImetrics-cli:
| Secret | Value |
|---|---|
APPLE_CERT_P12 |
Base64-encoded .p12 certificate (see above) |
APPLE_CERT_PASSWORD |
Password set when exporting the .p12 |
KEYCHAIN_PASSWORD |
Any strong random string (used for the temporary CI keychain) |
APPLE_SIGNING_IDENTITY |
Certificate common name, e.g. Developer ID Application: APImetrics Inc (XXXXXXXXXX) |
APPLE_ID |
Apple ID email used for notarization |
APPLE_ID_PASSWORD |
App-specific password for that Apple ID |
APPLE_TEAM_ID |
10-character Apple Developer Team ID |
The Homebrew formula is pushed to APImetrics/homebrew-tap. Ensure:
- The repository exists.
- A
Formula/directory exists in the repository root (create it with a.gitkeepif needed — the release workflow will createFormula/apimetrics.rbon first release). - The GitHub App from step 1 is installed on this repository.
The workflow uses wingetcreate to submit a PR to microsoft/winget-pkgs after each release, keeping the Windows Package Manager entry up to date.
The package must exist in microsoft/winget-pkgs before automated updates can run. Create the initial manifest with wingetcreate:
# Download wingetcreate.exe (Windows only — run this on a Windows machine)
Invoke-WebRequest -Uri "https://github.com/microsoft/winget-create/releases/download/v1.12.8.0/wingetcreate.exe" -OutFile wingetcreate.exe
$version = "0.1.0" # set to the first published version
$installerUrl = "https://github.com/APImetrics/APImetrics-cli/releases/download/v$version/apimetrics-$version-windows-amd64.zip"
.\wingetcreate.exe new $installerUrl `
--id APIContext.APImetricsCLI `
--version $version `
--name "APImetrics CLI" `
--publisher "APIContext" `
--token <YOUR_GITHUB_PAT>Review the generated manifest files, then submit the PR manually. Once merged, subsequent releases are automated.
The wingetcreate update --submit command creates a PR on microsoft/winget-pkgs using a GitHub account you control.
- Classic PAT (recommended):
public_reposcope is sufficient. - Fine-grained PAT: grant access to your fork of
winget-pkgsand enable Contents: read/write and Pull requests: read/write. Note thatwingetcreatecreates the fork on first run — the fork must exist before you can pre-select it when generating the token.
Secret to add to APImetrics/APImetrics-cli:
| Secret | Value |
|---|---|
WINGET_GITHUB_TOKEN |
Token used by wingetcreate to push to your fork and open PRs on microsoft/winget-pkgs |
All secrets required on APImetrics/APImetrics-cli:
| Secret | Purpose |
|---|---|
GH_APP_ID |
GitHub App ID for Homebrew tap access |
GH_APP_PRIVATE_KEY |
GitHub App private key for Homebrew tap access |
APPLE_CERT_P12 |
Base64 Apple Developer ID certificate |
APPLE_CERT_PASSWORD |
Password for the p12 certificate |
KEYCHAIN_PASSWORD |
Temporary CI keychain password |
APPLE_SIGNING_IDENTITY |
Apple signing identity string |
APPLE_ID |
Apple ID for notarization |
APPLE_ID_PASSWORD |
App-specific password for notarization |
APPLE_TEAM_ID |
Apple Developer Team ID |
WINGET_GITHUB_TOKEN |
PAT for submitting WinGet PRs to microsoft/winget-pkgs |
Once all secrets are configured:
git tag v0.x.y
git push origin v0.x.yMonitor progress in the Actions tab. The full pipeline (Linux build + macOS sign/notarize) takes approximately 20–30 minutes.
To build all artifacts without publishing anywhere:
- Go to Actions → Release → Run workflow.
- Check Run goreleaser in --snapshot mode.
- Run from any branch.
The workflow only triggers on v0.* tags. This is intentional during initial development to prevent accidental production releases. Update the tag pattern in .github/workflows/release.yml to v* when ready to ship v1.0.