ci: align workflow structure with hriv reference implementation - #15
Conversation
Rewrite all CI/CD workflows to match the authoritative hriv monorepo pattern, adapted for a single-component repo. Key changes: ci.yaml: - Remove tag and workflow_dispatch triggers; fire on push/PR to main only - Remove monolithic 'versions' job; compute version inline from git tags + conventional commit analysis (same algorithm as hriv) - Replace docker/metadata-action with explicit sha-<fullsha> + <ver>-rc.<ts>.<short> tag format matching hriv's image tag contract - Split Trivy scanning: table-to-log on PRs, SARIF-to-Security on main - Load (don't push) PR builds for local Trivy scanning - Disable provenance/SBOM attestations to keep exactly 2 image artifacts - Add per-component change detection (Dockerfile, Go source) - Adopt least-privilege permissions (workflow-level contents:read, job-level elevations) - Remove inline helm-publish job (moved to dedicated workflow) release-please.yaml: - Switch from prerelease mode to standard manifest mode - Add stale release-as guard (prevents stuck version overrides) - Dispatch helm-publish.yaml + release-retag.yaml on release (same GITHUB_TOKEN dispatch pattern as hriv) - Adopt least-privilege permissions with job-level elevations - Remove graduated-release promotion (not needed in standard mode) New workflows: - helm-publish.yaml: release-only Helm chart OCI publishing - release-retag.yaml: sha→semver+latest image retagging with Cosign - pr-title-lint.yaml: conventional-commit PR title enforcement with sticky failure comments release-please-config.json: - Remove versioning/prerelease/prerelease-type fields Co-Authored-By: kyle_hunter@bcit.ca <kyle_hunter@bcit.ca>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
⚙️ Control Options:
|
Address Devin Review findings: 1. Always build on main pushes so release-please merge commits (which only touch CHANGELOG/manifest/Chart.yaml, not Go source) still produce a sha-<commit> image that release-retag.yaml can find. Change detection is now only used to skip unnecessary PR builds. 2. Add actions:read permission to the build job, required by codeql-action/upload-sarif on private repos. Co-Authored-By: kyle_hunter@bcit.ca <kyle_hunter@bcit.ca>
1. Version computation now mirrors release-please's bump-minor-pre-major setting: while MAJOR==0, breaking changes bump minor instead of major, keeping CI rc tags in sync with actual releases. 2. OCI image.version label now includes the timestamp component (<ver>-rc.<ts>.<short>) matching the published tag exactly. Co-Authored-By: kyle_hunter@bcit.ca <kyle_hunter@bcit.ca>
| SUBJECTS=$(git log "${RANGE}" --pretty=format:"%s" -- Dockerfile go.mod go.sum main.go internal/) | ||
| BODIES=$(git log "${RANGE}" --pretty=format:"%b" -- Dockerfile go.mod go.sum main.go internal/) | ||
|
|
||
| if echo "$SUBJECTS" | grep -qE "^[a-zA-Z]+(\([^)]+\))?!:" \ | ||
| || echo "$BODIES" | grep -qE "^BREAKING[ -]CHANGE:"; then | ||
| # Mirror release-please's bump-minor-pre-major: while the | ||
| # project is still on major 0, breaking changes bump minor | ||
| # instead of major so CI tags stay in sync with releases. | ||
| if ((MAJOR == 0)); then | ||
| ((MINOR+=1)); PATCH=0 | ||
| else | ||
| ((MAJOR+=1)); MINOR=0; PATCH=0 | ||
| fi | ||
| elif echo "$SUBJECTS" | grep -qE "^feat(\(.+\))?:"; then | ||
| ((MINOR+=1)); PATCH=0 | ||
| else | ||
| ((PATCH+=1)) | ||
| fi |
There was a problem hiding this comment.
📝 Info: CI version computation path-filters git log, diverging from release-please's full-history analysis
The Compute next version step (.github/workflows/ci.yaml:187-188) filters git log to only commits touching Dockerfile go.mod go.sum main.go internal/. This means a feat!: commit that only changes charts/ or docs/ would be missed by the CI version bump but picked up by release-please, causing CI pre-release tags (e.g., 0.3.1-rc.*) to diverge from the actual release version (e.g., 0.4.0). This is functionally harmless — CI tags are ephemeral artifacts and release-retag produces the authoritative stable tag — but could confuse operators inspecting image tags between a merge and a release.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Acknowledged. This matches hriv's pattern — CI version computation is path-filtered to the component's build context while release-please analyzes full history. As noted, CI rc tags are ephemeral; release-retag.yaml produces the authoritative semver tags from release-please's version.
Summary
Rewrites all CI/CD workflows to match the authoritative hriv monorepo pattern, adapted for a single-component repo. This brings haproxy-operator's release pipeline, image tag contract, and permission model into alignment with the org's reference implementation.
What changed
ci.yaml— complete rewritemainonly (removedtags: ["v*"]andworkflow_dispatch)bump-minor-pre-majorsupport for MAJOR==0)sha-<fullsha>+<ver>-rc.<ts>.<short>(hriv format) instead of<ver>-head.<sha>+ moving:headpointerignore-unfixed), SARIF-to-Security on mainload: true(local scan) instead of skipping entirelyprovenance: false,sbom: falseto keep exactly 2 image artifacts per pushcontents: read) with job-level elevations; includesactions: readfor SARIF upload on private reposDockerfile go.mod go.sum main.go internal/image→build(imageis a required check)release-please.yaml— rewriteversioning,prerelease,prerelease-typefrom config)release-asguard from hriv (fails loudly if one-shot overrides linger)helm-publish.yaml+release-retag.yamlviaworkflow_dispatch(same GITHUB_TOKEN dispatch pattern as hriv)New workflows (matching hriv)
helm-publish.yamlvX.Y.Zfrom tag)release-retag.yamlsha-<commit>→ semver +latestimage retagging with Cosign signingpr-title-lint.yamlrelease-please-config.json"versioning": "prerelease","prerelease": true,"prerelease-type": "rc"Image tag contract (after merge)
ghcr.io/<repo>/haproxy-operatorsha-<fullsha>(immutable) +<ver>-rc.<ts>.<short>vX.Y.Z)<version>+latest(via release-retag, iff highest stable)Review & Testing Checklist for Human
imagetobuild; update required status checks ifimageis listedsha-<sha>+<ver>-rc.<ts>.<short>) replace the old<ver>-head.<sha>+ moving:headformat. Confirm flux-fleetImagePolicyfor haproxy-operator is updated (or will be updated) to match the new-rc.<ts>pattern0.3.0; next release-please run will compute from conventional commits sincev0.3.0. Verify no in-flight rc release PRs will be disruptedNotes
:headchart OCI tag for haproxy-operator, that routing will need to be updated.helm-publish.yaml(only images are signed, viarelease-retag.yaml). If chart signature verification is required downstream, it can be added back.sha-<commit>image forrelease-retag.yamlto find.bump-minor-pre-major: true(improvement over hriv's reference implementation).Link to Devin session: https://app.devin.ai/sessions/616a3e66529e458fbcfc0b6cca2703a7
Requested by: @kphunter