This document describes the release workflow for DRAForge.
All three binaries embed version and commit information at build time via GoReleaser ldflags:
| Binary | LDFLAGS |
|---|---|
draforge |
-X main.versionVal= -X main.commitSHA= |
draforge-controller |
-X main.versionVal= -X main.commitSHA= |
draforge-sim-driver |
-X main.versionVal= -X main.commitSHA= |
These values are set by GoReleaser during goreleaser release and are visible via go version -m on the compiled binary. The CLI also exposes them via draforge version.
Snapshot builds (local dry-runs) use a synthetic version like v0.0.0-SNAPSHOT-<commit> and do not publish anything. The CI pipeline validates the release configuration with goreleaser release --snapshot --skip=docker,sbom,sign in the goreleaser job (see .github/workflows/ci.yml).
$PATH.ghcr.io container registry.repo and write:packages scopes.export GITHUB_TOKEN=ghp_... # GitHub PAT with repo + write:packages
export COSIGN_PASSWORD=... # If signing with a cosign key
A snapshot build validates the pipeline without publishing anything:
goreleaser release --snapshot --clean --skip=publish
dist/.-SNAPSHOT-.To verify the output:
task release:verify
Ensure CHANGELOG.md is up to date:
# Review unreleased changes
grep -A 999 "## \\[Unreleased\\]" CHANGELOG.md | head -50
# Move Unreleased entries to a new version section
# and update the [Unreleased] compare link at the bottom of CHANGELOG.md
Commit the changelog update:
git add CHANGELOG.md
git commit -m "docs: prepare v0.1.0 changelog"
git tag v0.1.0
git push origin v0.1.0
goreleaser release --clean
This will:
draforge, draforge-controller, draforge-sim-driver)
for linux/amd64, linux/arm64, darwin/amd64, darwin/arm64.tar.gz / zip).checksums.txt.ghcr.io/oaslananka/:
v0.1.0-amd64, v0.1.0-arm64.v0.1.0, v0.1, latest).# Check GitHub release
gh release view v0.1.0
# Check container images
docker pull ghcr.io/oaslananka/draforge-server:v0.1.0
# Verify binary version
docker run --rm ghcr.io/oaslananka/draforge-server:v0.1.0 version
# Check SBOM
gh release download v0.1.0 -p "*.sbom"
SBOMs are generated by GoReleaser via Syft during the release pipeline. Each archive
gets a CycloneDX JSON SBOM (.sbom).
To generate an SBOM manually outside the release pipeline:
# Full project SBOM
task sbom
# Equivalent to: syft dir:. -o cyclonedx-json > draforge.sbom.json
# Per-binary SBOM
syft dist/draforge_linux_amd64_v1/draforge -o cyclonedx-json > draforge.sbom.json
| Artifact | Location | Description |
|---|---|---|
| Binaries | dist/ |
GoReleaser staging directory (not committed) |
| Archives | dist/*.tar.gz, dist/*.zip |
Compressed release archives |
| Checksums | dist/checksums.txt |
SHA-256 checksums of all archives |
| SBOMs | dist/*.sbom |
CycloneDX JSON software bills of materials |
| Docker images | ghcr.io/oaslananka/ |
Multi-arch container images |
| GitHub release | https://github.com/oaslananka/draforge/releases/tag/v0.1.0 |
Release with assets |
Simple — delete the tag locally and revert the changelog commit:
git tag -d v0.1.0
git reset --hard HEAD~1
git push --delete origin v0.1.0
git tag -d v0.1.0
v0.1.1).The following are generated by GoReleaser and must not be committed
(already covered by .gitignore):
dist/ — GoReleaser output directorybin/ — local task build output*.sbom.json — SBOM filescoverage.out — test coverage outputAdditionally, never commit:
dist/ or bin/| Problem | Likely cause | Fix |
|---|---|---|
goreleaser not found |
Not installed or not on $PATH |
Install via go install github.com/goreleaser/goreleaser/v2@latest |
| Docker build fails | Docker daemon not running | Start Docker Desktop / dockerd |
syft command not found |
Syft not installed | Install from https://github.com/anchore/syft |
gh auth failure |
No GitHub token or expired token | Run gh auth login or set GITHUB_TOKEN |
| Cosign signing fails | Cosign key not set up | See Cosign documentation |
| Release created but no assets | Missing GITHUB_TOKEN |
Ensure token has repo scope |