Skip to content

refactor: consolidate release pipeline with draft-first pattern#124

Merged
jmeridth merged 2 commits into
mainfrom
jm_consolidate
May 10, 2026
Merged

refactor: consolidate release pipeline with draft-first pattern#124
jmeridth merged 2 commits into
mainfrom
jm_consolidate

Conversation

@jmeridth
Copy link
Copy Markdown
Collaborator

@jmeridth jmeridth commented Apr 6, 2026

Pull Request

Proposed Changes

What

Consolidated the three separate release workflows (release.yaml, release-image.yaml, release-discussion.yaml) into a single release.yaml reusable workflow with a draft-first release pattern. Added optional GoReleaser support for building and uploading Go binaries. Added a publish_release job that publishes the draft only after all artifact, attestation, and discussion jobs succeed.

The deprecated release-image.yaml and release-discussion.yaml workflows are preserved as stubs that fail with clear migration instructions.

Why

The three release workflows were always chained together and shared data flow. Consolidating reduces caller complexity from three workflow calls to one. The draft-first pattern (draft → tags → artifacts → attestation → publish) supports repositories with immutable releases enabled, ensuring all artifacts and attestations are in place before the release becomes visible.

Notes

  • Breaking change: callers of release-image.yaml or release-discussion.yaml will get a deprecation error with migration instructions
  • Breaking change: update-major-tag input removed — major tag is now always pushed in create_release
  • publish input defaults to true (backwards compatible) but release-drafter always creates a draft first; publish_release job handles the final publish
  • publish_release uses always() with per-job result checks so it runs even when optional jobs are skipped, but blocks on any failure
  • GoReleaser config is validated via yq to ensure release.disable: true is set, preventing conflicts with the release-drafter draft
  • Both GoReleaser and image attestation steps check repo visibility via the GitHub API — private repos get a warning instead of a cryptic failure
  • release_discussion job always spins up a runner when a tag is created, then skips at step level if secrets aren't set (can't use secrets in job-level if: conditions)
  • -F draft=false (capital F) is used in publish_release to send a boolean, not a string

Testing

  • actionlint passes on all modified workflow files
  • Workflow logic validated against the tasktrakkr release workflow which uses the same draft-first pattern in production
  • Full end-to-end testing requires a release trigger (PR merge with release label or workflow_dispatch)

Readiness Checklist

Author/Contributor

  • If documentation is needed for this change, has that been included in this pull request

Comment thread .github/workflows/release.yaml
Comment thread .github/workflows/release.yaml Outdated
@jmeridth jmeridth requested a review from zkoppert April 6, 2026 21:57
zkoppert
zkoppert previously approved these changes Apr 7, 2026
Copy link
Copy Markdown
Contributor

@zkoppert zkoppert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 3, 2026

This PR is stale because it has been open 20 days with no activity. Replace the no-pr-activity label with a work-in-progress label or comment or this will be closed in 5 days.

@jmeridth jmeridth added the keep label May 4, 2026
@jmeridth jmeridth requested a review from zkoppert May 5, 2026 09:49
zkoppert
zkoppert previously approved these changes May 7, 2026
## What

Collapse the three separate release workflows (release.yaml, release-image.yaml, release-discussion.yaml) into a single release.yaml reusable workflow using a draft-first pattern: create draft, push tags, build artifacts (optional GoReleaser, optional Docker image), create discussion, then publish. Preserve the legacy release-image.yaml and release-discussion.yaml as stubs that fail with migration instructions.

## Why

The three workflows were always chained and shared data flow, so callers had to wire up three workflow calls and reason about ordering themselves. The draft-first sequence supports repositories with immutable releases enabled by ensuring every artifact and attestation lands before the release becomes visible.

## Notes

- Breaking: callers of release-image.yaml / release-discussion.yaml hit a deprecation error with migration instructions.
- Breaking: update-major-tag input removed; the major tag is always pushed in create_release.
- publish defaults to true and is backwards compatible, but release-drafter always creates a draft first and publish_release handles the final flip.
- publish_release uses always() with per-job result checks so it runs when optional jobs are skipped but blocks on any failure.
- GoReleaser config is validated via yq to require release.disable: true, avoiding conflict with the draft.
- Attestation steps probe repo visibility via the GitHub API and warn on private repos instead of failing cryptically.
- release_discussion always spins up a runner when a tag is created and skips at the step level if secrets are missing (job-level if: cannot read secrets).
- publish_release uses -F draft=false (capital F) to send a boolean rather than a string.

Signed-off-by: jmeridth <jmeridth@gmail.com>
zkoppert
zkoppert previously approved these changes May 7, 2026
@ Conflicts:
@	.github/workflows/release.yaml
@jmeridth jmeridth merged commit 592067a into main May 10, 2026
9 checks passed
@jmeridth jmeridth deleted the jm_consolidate branch May 10, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants