Skip to content

feat: split CI pipeline, cache volumes, commit lint, checksum restore - #79

Merged
alexhraber merged 8 commits into
mainfrom
feat/pipeline-split-release-gating
Jul 11, 2026
Merged

feat: split CI pipeline, cache volumes, commit lint, checksum restore#79
alexhraber merged 8 commits into
mainfrom
feat/pipeline-split-release-gating

Conversation

@alexhraber

Copy link
Copy Markdown
Owner

Summary

Split the monolithic single-pipeline into a validation pipeline + tag-push-triggered release pipeline, with cache volumes, commit linting, and restored checksum artifact.

Changes

pipeline.yml (main CI)

  • Cache volumecache: .buildkite/cache-volume with hooks/pre-command setting GOCACHE / GOMODCACHE / GOLANGCI_LINT_CACHE (shaves ~60s off CI)
  • Snapshot Build — compiles binary on every PR without creating a release
  • Checksum restoredsha256sum builddeck after snapshot build so builddeck TUI can show it inline
  • Automatic tagging preserved — conventional commits → version.shtag.sh → push tag
  • Commit Lint — validates feature branch commits follow conventional-commits format against origin/main
  • Scoped gosec/govulncheck to ./cmd/... ./internal/... (cache volume puts GOMODCACHE inside checkout, filesystem-walking tools were picking up the entire module cache)

pipeline.release.yml (new)

Triggered by git tag push. Three steps: build release binary with version ldflags → SHA256 checksum → GitHub Release with changelog + assets.

tag.sh (rewritten)

Reads conventional commits via version.sh, computes next semver from git describe --tags, checks for duplicate tags at origin before pushing.

commitlint.sh (new)

Validates commits in origin/main..HEAD follow conventional commits format. Only runs on feature branches (main is already vetted by PR checks). Skipped if origin/main unavailable (shallow clones).

version.sh (restored)

Conventional-commits semver computation — unchanged from original.

Removed

  • Build & Release / Checksum steps from main pipeline (moved to release pipeline)
  • Manual release unblock (rejected in review — kept auto-tagging)
  • version.sh was briefly removed, restored

… release pipeline

Inspired by buildkite/cli's pipeline architecture:

pipeline.yml (main CI):
- Add cache volume (hooks/pre-command for GOCACHE/GOMODCACHE/GOLANGCI_LINT_CACHE)
- Add Snapshot Build step — compiles binary on every PR without releasing
- Replace automatic conventional-commits tagging with a manual input block
  step where a team member selects 'patch', 'minor', or 'skip'
- Tag step reads release-type from metadata, computes next semver from
  existing tags (no more version.sh)
- Removal: Build & Release, Checksum steps (moved to release pipeline)

pipeline.release.yml (triggered by tag push):
- Build binary with version ldflags
- SHA256 checksum generation
- GitHub Release creation with changelog and asset upload

tag.sh rewritten:
- Accepts 'patch' or 'minor' as argument
- Reads latest tag via git describe, bumps accordingly
- Checks for duplicate tag at origin before pushing
- Uploads builddeck.tag artifact for downstream use

release.sh simplified:
- No longer handles tag detection or conditional release
- Pure GitHub Release creation from tag-push context

Removed version.sh — replaced by metadata-based tag.sh
…nt step

- Remove manual release unblock (human intervention rejected)
- Restore version.sh for conventional-commits semver computation
- Restore tag.sh with auto-detection logic (calls version.sh, pushes tag)
- Add commitlint.sh — validates all commits since last tag follow
  conventional commits format (feat/fix/refactor/perf/etc.)
- Add commitlint as a pipeline step, run in parallel with fmt
- tag step now depends on commitlint too — ensures only properly
  formatted commits can trigger a release
GOMODCACHE now points to .buildkite/cache-volume/go/pkg/mod/ (inside the
checkout). gosec and govulncheck walk the filesystem tree rather than
using go list, so ./... picks up the entire module cache and fails.

Scoped to ./cmd/... ./internal/... — the only packages we own.
On feature branches, check origin/main..HEAD instead of latest-tag..HEAD.
This avoids flagging non-conventional commits that landed on main before
commitlint was introduced. Falls back to skipping if origin/main isn't
available (shallow clones).
Every pipeline run now produces builddeck.sha256 alongside the snapshot
binary, so builddeck's TUI can display the checksum inline on artifacts.

Tag step now depends on checksum instead of snapshot directly — the
checksum artifact is uploaded before tagging proceeds.
@alexhraber
alexhraber merged commit 9aa4cdd into main Jul 11, 2026
1 of 2 checks passed
@alexhraber
alexhraber deleted the feat/pipeline-split-release-gating branch July 11, 2026 06:25
alexhraber added a commit that referenced this pull request Jul 11, 2026
…line (#80)

PR #79 split the pipeline into validation-only (pipeline.yml) and a
separate release pipeline (pipeline.release.yml), but the release
pipeline was never wired in Buildkite. Merging to main created a
tag but no binary or GitHub release.

Fix: restore release_build (binary + sha256) and GitHub release steps
after the tag step in pipeline.yml, so a single run produces both the
tag and the release. The release pipeline remains available as a
standalone option for manually pushed tags.

Also merges build+checksum into one step in pipeline.release.yml
to match the same-agent optimization done in pipeline.yml.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant