Skip to content

feat(vcluster-release): add single release dispatcher action - #162

Merged
sydorovdmytro merged 5 commits into
mainfrom
devops-1050/cut-release-action
Jul 9, 2026
Merged

sydorovdmytro merged 5 commits into
mainfrom
devops-1050/cut-release-action

Conversation

@sydorovdmytro

@sydorovdmytro sydorovdmytro commented Jul 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds a vcluster-release composite action: one entry point for cutting a vCluster release on any supported line, so nobody has to remember which release procedure a version needs.
  • Named per-product (vcluster-release, not cut-release) since this shared repo releases multiple products and the action is vcluster-specific (hardcodes loft-sh/vcluster + loft-sh/vcluster-pro and the v0.36 cutover). Leaves room for e.g. platform-release later.
  • Routes by numeric (major, minor) compare against the v0.36 cutover: legacy (< v0.36) fans out to both loft-sh/vcluster and loft-sh/vcluster-pro (OSS first); monorepo (>= v0.36) dispatches loft-sh/vcluster-pro only.
  • Creates the tag(s) and dispatches each line's own release.yaml via workflow_dispatch (gh workflow run --ref <tag>, which runs the tagged commit's version). The GitHub Release is a pipeline output, not a trigger — so a monorepo-created OSS release can't re-trigger the OSS builder.
  • Guards: double-cut (existing tag/release), unprepared/missing branch (distinguishing a real 404 from a transient API error), and a dry-run default that still runs the read-only routing checks.

Test plan

  • make test-vcluster-release — 26 bats cases: pure routing (parse_major_minor/derive_line/classify_era incl. numeric v0.9 < v0.36 and v1.0 boundary), legacy dispatch order (OSS before pro), double-cut guards, monorepo main fallback, and the 404-vs-transient distinction (stub mirrors real gh exiting non-zero on 404).
  • make lint (actionlint + zizmor, whole repo) clean; make check-docs up to date.
  • Verified end-to-end in dry-run against the real repos: legacy v0.35.99 routes OSS→pro; monorepo v0.36.99 falls back to main; the double-cut guard correctly refused a real existing release.

Notes

  • The unpinned-uses zizmor finding on the sibling semver-validation reference is expected (internal action pinned by SHA + tag comment per this repo's convention).
  • Consumed by a workflow_dispatch button in loft-sh/vcluster-pro (separate PR, held until this merges and vcluster-release/v1 is tagged).

References DEVOPS-1050

@sydorovdmytro
sydorovdmytro force-pushed the devops-1050/cut-release-action branch from 5d32634 to 223d51a Compare July 3, 2026 12:26
@sydorovdmytro sydorovdmytro changed the title feat(cut-release): add single release dispatcher action feat(vcluster-release): add single release dispatcher action Jul 3, 2026
@sydorovdmytro
sydorovdmytro requested a review from Piotr1215 July 3, 2026 12:56
One entry point for cutting a vCluster release on any supported line. Routes by
numeric era compare against the v0.36 cutover: legacy (< v0.36) fans out to both
loft-sh/vcluster and loft-sh/vcluster-pro (OSS first), monorepo (>= v0.36)
dispatches loft-sh/vcluster-pro only. Creates the tag(s) and dispatches each
line's own release.yaml via workflow_dispatch; the GitHub Release is a pipeline
output, not a trigger. Named per-product (vcluster-release) since this shared
repo releases multiple products. See DEVOPS-1050.
@sydorovdmytro
sydorovdmytro force-pushed the devops-1050/cut-release-action branch from 675bf3d to 11c6416 Compare July 3, 2026 14:24
- guard the jq null-string hazard in create_tag with '.object.sha // empty'
  plus an explicit non-empty check, matching this repo's gh api convention
- emit a partial-failure recovery notice after the legacy OSS dispatch and
  document the recovery path in the README (non-atomic tag+dispatch sequence)
- assert the tag-before-dispatch invariant in the legacy dry-run test
- add live (non-dry-run) happy-path coverage for legacy and monorepo flows
- add a GH_STUB_UNEXPECTED mode covering the unexpected-HTTP-status arm of
  branch_exists

References DEVOPS-1050
…se-action

# Conflicts:
#	Makefile
#	README.md
Previously any INPUT_DRY_RUN value other than exactly 'true' ran a real
cross-repo release, so a typo ('yes', '1', 'True', stray whitespace) would
silently cut for real - fail-open on a release-cutting action. Now only an
explicit, case-insensitive 'false' fires; every other value stays in dry-run
and warns. Covered by two new bats cases.

References DEVOPS-1050

@Piotr1215 Piotr1215 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Solid action - routing, guards, dry-run fail-closed, and the 31 bats cases all look good, and I confirmed the semver-validation pin resolves to semver-validation/v1. One real bug: the double-cut tag guard uses the plural prefix-matching git/refs/tags/ endpoint, so cutting a final release while its rc tag exists (or a version like v0.35.4 vs an existing v0.35.40) falsely trips 'already exists'. One-char fix inline. Second note is optional.

… errors

Double-cut guard used the plural git/refs/tags/ endpoint, which prefix-matches:
cutting the final v0.35.4 after v0.35.4-rc.1 exists tripped a false "already
exists". Switch to the singular git/ref/tags/ (exact match, 404s otherwise).

guard_not_released also read any non-zero exit as "not released", so a transient
API error (rate-limit/auth/DNS) silently skipped the double-cut check. Extract
the HTTP-status discrimination from branch_exists into a shared api_exists helper
and route both guard probes (release + tag) through it, so a transient failure
aborts loudly instead of being misread as absent.

Model the real API in the bats stub (singular exact / plural prefix) and add a
scoped transient knob so both fixes are regression-covered.
@sydorovdmytro
sydorovdmytro requested a review from Piotr1215 July 8, 2026 14:04
@sydorovdmytro
sydorovdmytro merged commit 445c297 into main Jul 9, 2026
10 checks passed
@sydorovdmytro
sydorovdmytro deleted the devops-1050/cut-release-action branch July 9, 2026 08:02
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.

3 participants