Skip to content

feat: automatically run release after preparing it - #103

Merged
carlos-granados merged 2 commits into
php-debugger:mainfrom
carlos-granados:feat/auto-release
Aug 3, 2026
Merged

carlos-granados merged 2 commits into
php-debugger:mainfrom
carlos-granados:feat/auto-release

Conversation

@carlos-granados

Copy link
Copy Markdown
Collaborator

No description provided.

@carlos-granados

Copy link
Copy Markdown
Collaborator Author

@claude review

@claude

claude Bot commented Aug 2, 2026

Copy link
Copy Markdown

Claude finished @carlos-granados's task in 1m 42s —— View job


Code review

  • Read changed workflow files
  • Analyze workflow logic and security
  • Post review feedback

Nice, clean piece of automation. The RELEASE_REF centralization and the inline comments explaining why the odd bits exist (GITHUB_TOKEN anti-recursion, workflow_dispatch checkout defaults) are exactly the kind of context that makes future‑you not curse past‑you. Nothing blocking; a few small things worth considering.


1. workflow_dispatch.inputs.tag has no validation (minor)

prepare-release.yml already regex-validates inputs.version before doing anything destructive, so the tag that gets dispatched from there is always well-formed. But when someone triggers release.yml directly via the Actions UI (which is now supported), the tag input is trusted verbatim — a typo like v0.3.0 (with a v) or 0.3 will silently sail past dispatch, fail deep inside actions/checkout on every matrix job, and burn a full fan-out worth of runner minutes before failing.

Suggest a lightweight first job that validates the input and confirms the tag actually exists on the remote, then needs: it from all the build jobs. Same regex as prepare-release.yml plus git ls-remote --exit-code --tags origin refs/tags/$TAG.

Fix this →

2. No concurrency group on release.yml

prepare-release.yml has concurrency: prepare-release-main but release.yml has nothing. Two ways this bites in practice:

  • Rerunning a failed prepare-release run for the same version — the tag push is a no-op (self-healing path already documented) but gh workflow run will happily fire a second release build in parallel with a still-running first one. Two matrices doing the same work, and softprops/action-gh-release racing to create the same release.
  • Human pushes a tag right around the same time the prep workflow runs.

Adding concurrency: { group: release-${{ github.event.inputs.tag || github.ref_name }}, cancel-in-progress: false } would serialize per-tag.

Fix this →

3. Silent failure window if gh workflow run fails

If the final Trigger release build step in prepare-release.yml fails (e.g. transient API blip), the tag is already pushed but the release workflow never starts. The step's failure surfaces the job as failed, so it's not invisible — but there's no self-healing narrative in the comment the way there is for the tag push. Suggest either a one-line retry (for i in 1 2 3; do gh workflow run ... && break; sleep 5; done) or a short comment noting "if this step fails after the tag push, rerun release.yml manually via the Actions UI with the same tag."

4. Tiny nit: --ref main on the dispatch

gh workflow run release.yml --ref main pins the workflow file version to main's copy, while the checkouts inside use the tag. This is the right split (you want the newest CI logic building an older tag) but it means a release cut from an older codebase runs through today's workflow — worth noting in the comment so nobody "helpfully" changes it to --ref "${{ inputs.version }}" and gets a subtly different build.


Verdict

Ship it after adding input validation on the manual-dispatch path (#1) and ideally the concurrency guard (#2). The other two are polish.
· feat/auto-release

@carlos-granados

Copy link
Copy Markdown
Collaborator Author

@claude updated, review again

@claude

claude Bot commented Aug 3, 2026

Copy link
Copy Markdown

Claude finished @carlos-granados's task in 1m 20s —— View job


Re-review

  • Read the updated workflow files
  • Compare with previous review feedback
  • Post updated review

All four points from the previous review are addressed, and the treatments are well thought through — the inline comments in particular do a good job of preempting future "why is this here?" churn.

What landed

  1. Input validation (Bump actions/checkout from 4 to 6 #1) — New validate-tag job (release.yml:72) applies the same regex as prepare-release.yml when the trigger is workflow_dispatch, then confirms tag existence via gh api …/git/ref/tags/${TAG} for both trigger types. Every build job now needs: validate-tag, so a bad manual dispatch fails in seconds instead of burning the full matrix. Existence-check-on-push is technically belt-and-braces (the push is what triggered the workflow), but at one API call per run it's cheap defense and I'd keep it.
  2. Concurrency (Bump actions/download-artifact from 4 to 8 #2)release.yml:27 serializes by tag with cancel-in-progress: false, which is the right call for release builds (you don't want a rerun kicking off a build only for a still-running earlier attempt to publish the release under it).
  3. Retry on gh workflow run (Bump actions/upload-artifact from 4 to 7 #3)prepare-release.yml:123 retries three times with sleep 5, and the failure message tells the operator exactly how to recover (gh workflow run release.yml --ref main -f tag=<version>) — matches the self-healing narrative already established for the tag push.
  4. Clarifying comment on --ref main (Phase 2: RINIT fast-path & deferred hooks — 630% → 10% overhead #4)prepare-release.yml:111-116 explains the split (workflow-file version pinned to main, checkouts pinned to the tag) and specifically warns off the "helpful" change to --ref "${{ inputs.version }}". Perfect.

Small things noticed on this pass — all optional

  • resolve-php-versions doesn't needs: validate-tag (release.yml:91). It'll run in parallel with the validation job. Not incorrect — it doesn't touch the tag — but a bad tag will still burn one runner minute here before the workflow gives up. Adding needs: validate-tag is a one-line consistency fix; ignoring it is defensible on the "cheap job" grounds.
  • Regex enforcement is workflow_dispatch-only. On push: tags any tag format is still accepted, which preserves the pre-existing behavior (arbitrary tags can trigger a release). If that's intentional (e.g. someone hand-pushing nightly-YYYYMMDD), fine as-is; if you'd rather lock all releases to X.Y.Z[-suffix], drop the if [ "$event_name" = "workflow_dispatch" ] guard. Not a blocker either way.
  • permissions: at the release-workflow level is still contents: write even though validate-tag only needs contents: read. Step-scoping isn't worth it here — the release step at the end genuinely needs write. Just noting for completeness; no change suggested.

Verdict

LGTM. Nice write-up of the reasoning in the comments — future readers won't have to reverse-engineer any of the odd bits.
· feat/auto-release

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the release automation so that a release build is reliably kicked off after prepare-release.yml pushes a new version tag, even when the tag push is authored by GITHUB_TOKEN (which won’t trigger push: tags workflows due to GitHub Actions’ recursion protections).

Changes:

  • Add a workflow_dispatch trigger to release.yml (with a tag input) and ensure the workflow checks out/builds/releases the specified tag.
  • Add a validate-tag job plus per-tag concurrency to prevent wasted matrix runs and duplicate releases for the same tag.
  • Extend prepare-release.yml permissions and dispatch release.yml via gh workflow run after tagging.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
.github/workflows/release.yml Supports manual/API dispatch with a tag input, validates tag existence, serializes runs per tag, and ensures all checkouts/releases use the intended tag ref.
.github/workflows/prepare-release.yml Grants actions: write and triggers release.yml via gh workflow run after pushing the version tag.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@carlos-granados
carlos-granados merged commit 6099fc2 into php-debugger:main Aug 3, 2026
32 checks passed
@carlos-granados
carlos-granados deleted the feat/auto-release branch August 3, 2026 07:09
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.

2 participants