Skip to content

Add release-publish: the GitHub release for a version at a commit, with a title, notes and assets - #16

Open
glaubersilva wants to merge 7 commits into
soft-5188-release-merge-actionfrom
soft-5188-release-publish-action
Open

glaubersilva wants to merge 7 commits into
soft-5188-release-merge-actionfrom
soft-5188-release-publish-action

Conversation

@glaubersilva

@glaubersilva glaubersilva commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Related

Part of SOFT-5188. Answers three review comments on #10: publish inputs, make_latest, the token and on: release.

Summary

release-publish creates the GitHub release for a version at a commit: the tag and the release in one step, with a title, notes from a file and assets. A repository's deploy workflow runs it after release-merge (#10) and its build, at the commit release-merge leaves on the base branch (base-sha), so the release is published only once the build exists and carries it. A repository that merges by hand runs it alone, with a branch as target.

Changes

  • Inputs: version, target (a commit hash; a branch name is resolved to its tip when the action runs, so a workflow that builds from a checkout passes that checkout's commit), title (the version by default), notes-file (a file in the checkout; GitHub's generated notes by default), files (assets, one path per line), token (default github.token). Outputs: published (true or skipped), release-url, sha.
  • With files, the release is created as a draft, the files are uploaded, and the draft is published last. A draft makes no tag, so a failed upload is undone by deleting the draft; every path is checked before anything is created. A repository with immutable releases needs this order, since a published release cannot be changed.
  • make_latest follows version order against the repository's current latest release, so a hotfix on an older line does not take "Latest" from a newer release.
  • A release that already exists is skipped; a tag that exists without a release is refused.
  • One template, templates/workflows/release.yml: the deploy workflow the dashboard dispatches, under the name it looks for by default. It runs release-merge, leaves room for the build, then release-publish with target: ${{ steps.merge.outputs.base-sha }}, as GiveWP's deploy workflow does. Its first step fails when the run was not started on the branch it is asked to merge, so the live environment's branch policy covers what is merged and published; the dashboard starts the run on the release branch, a hand dispatch passes --ref. The merge-only template is gone (Add release-merge: the release branch into the base branch, then the base branch into develop #10), and the publish-only shape (a release a person merged by hand) is a snippet in release-publish's README, with the checked-out commit as target.
  • READMEs: what each action needs from the token (the merge: a direct push to the base branch and develop; the publish: creating the tag, so a tag ruleset should block deletion and updates, not creation), that a personal access token or a GitHub App token does trigger on: release while github.token does not, that the caller template's environment with required reviewers is the human gate, and the one release github.token cannot create: one at a commit that changes a workflow file relative to the default branch, which after release-merge never happens (the published commit is the base branch's tip) and is the hand-merged publish's case. The release-merge README and manifest point at release-publish; its code does not change here.
  • develop-branch: '' has to be written in the caller: a workflow_dispatch input left empty takes its default, so the empty value cannot be passed through one. Said in the release-merge README.
  • Tests in tests/actions/release-publish/release-publish.test.js, against the recorded Octokit and real files in a temporary directory. The recording fetch keeps a non-JSON body (an asset upload) as it was sent.

How to test

  1. In a plugin repository with main and develop, copy templates/workflows/release.yml to .github/workflows/, with both uses: pointing at this branch's commit, add a build step between the two actions and uncomment files: with the path it writes.
  2. Cut release/x.y.z from main, bump the version files .puprc lists on it (release-prep does this) and push.
  3. Run gh workflow run release.yml --ref release/x.y.z -f branch=release/x.y.z -f version=x.y.z (without --ref the first step fails and nothing is merged): main and develop get the merges, the release x.y.z exists with the file attached, and its tag points at the merge commit on main.
  4. Run it again: the job succeeds, both merges report "Already up to date" and the release is reported as already published.
  5. For the publish alone: a workflow with the README's snippet, run for a version lower than the current latest release, creates it at the checked-out commit and "Latest" stays on the newer one.
  6. node --test (270 tests). docker run --rm -v "$PWD:/repo" -w /repo rhysd/actionlint:latest templates/workflows/release.yml.

The steps were run on the two private test plugins, pinned to e6cee72, this stack's head (the action code is unchanged since eab1115); the first two rows ran at that commit, the others at eab1115 and 9603173, whose action code is identical (only READMEs and the template changed since). The deploy callers of both and GiveWP's release-dashboard-deploy.yml have the shape of release.yml: release-merge, the build, then release-publish.

Case Run
With an asset: 2.1.44 created as a draft, the zip uploaded, published at the merge commit, "Latest" plugin-a #41532028207
Without assets: 1.1.14 created directly at the merge commit with generated notes plugin-b #41532147821
Same release again: reported as already published and skipped plugin-b #41530221853
Publish only, a hotfix on an older line (2.1.38.1 from a branch cut at 2.1.38): tagged at the branch's tip, titled "Hotfix Release 2.1.38.1", notes from a file, "Latest" stays on 2.1.40 plugin-a #41514346329
Merge conflict on develop: release-merge fails, release-publish never runs, no tag and no release plugin-b #41514461252
Run started on main for release/M26.split6: refused by the first step, nothing merged; the same dispatch with --ref goes through plugin-b #41532901830, #41532958048
A release whose branch changed a workflow file: 1.1.15 published with github.token at the merge commit plugin-b #41532958048

Stack created with GitHub Stacks CLI • Give Feedback 💬

Summary by CodeRabbit

  • New Features

    • Added a manually triggered release workflow for a selected branch and version.
    • Releases can include a title, notes, and uploaded assets; releases with assets are published after uploads complete.
    • Existing releases are skipped, while a tag without an associated release prevents publication.
    • Releases can be published after a build at the commit produced by the merge.
    • Older version releases do not replace the current latest version.
    • Runs are serialized without cancelling an in-progress run.
  • Documentation

    • Added guidance and examples for configuring release publication, choosing a target commit, handling retries, and setting up tokens.

@linear

linear Bot commented Nov 2, 2026

Copy link
Copy Markdown

SOFT-5188

@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • Resume reviews
  • Trigger review
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: cd77b438-299e-461d-bf7d-4f9688cf39a6
Commits

Reviewing files that changed from the base of the PR and between e6c9816 and ef353a6.

Files selected for processing: 2
  • templates/workflows/release-merge.yml
  • templates/workflows/release-publish.yml
Files skipped from review as they are similar to previous changes: 1
  • templates/workflows/release-merge.yml

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 8 remain after this review.

Walkthrough

The PR adds a composite action that publishes GitHub releases, a manually triggered workflow that invokes it, and tests for release creation and asset uploads. It also updates release-merge guidance to build before publishing at the merge action’s base-sha.

Changes: Release Publishing

Layer / File(s) Summary
Action inputs and release data
.github/actions/release-publish/action.yml, .github/actions/release-publish/release-publish.js, .github/actions/release-publish/README.md
The action defines version, target, title, notes, asset, and token inputs, plus publishing outputs. It validates inputs, resolves a commit or branch, reads optional files, and determines whether the release is marked latest. The README documents the action and its execution.
Release checks and publishing
.github/actions/release-publish/release-publish.js, tests/actions/release-publish/*, tests/support/actions.js
The action skips an existing release and refuses a tag without a release. It creates a release directly or uploads assets to a draft before publishing it. Tests cover API behavior, outputs, upload failures, input validation, and recorded request bodies.
Workflow integration
templates/workflows/release-publish.yml, templates/workflows/release-merge.yml, .github/actions/release-merge/action.yml, .github/actions/release-merge/README.md, README.md
The new manual workflow invokes the publishing action with the checked-out commit SHA. Release-merge guidance directs callers to build before publishing at base-sha. The project checklist marks the action complete.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant PublishWorkflow
  participant ReleasePublishAction
  participant GitHubAPI
  participant CheckoutFiles
  PublishWorkflow->>ReleasePublishAction: Pass version, target, title, and token
  ReleasePublishAction->>GitHubAPI: Resolve target and check release and tag
  ReleasePublishAction->>CheckoutFiles: Read optional notes and assets
  ReleasePublishAction->>GitHubAPI: Create release or draft
  ReleasePublishAction->>GitHubAPI: Upload assets and publish draft when assets exist
Loading

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: d4mation, larodiel

Merge Risk: Moderate · previous review ef353

The new release-publish template can race with the release-merge template when a repository uses both, can publish a branch other than the one the live environment's branch policy approved, and fails when the target commit changes workflow files. Fix these in the templates before merge. None of them affects repositories that use the action with the template's default scope.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main change: adding the release-publish action to create a GitHub release for a version at a commit with title, notes, and assets.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 12 functions across 3 files. (2 skipped: 2 unsupported.)

Finishing Touches
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@glaubersilva
glaubersilva added this pull request to stack #17 November 2, 2026 19:35
glaubersilva added a commit to impress-org/givewp that referenced this pull request Nov 2, 2026
…p attached, through release-publish

release-merge no longer publishes: the toolbox split the release into its
own action, release-publish, run after the build at the commit the merge
left on master. The release is created with give.zip already on it and
only once the wp.org deploy succeeded, so a failed build or deploy leaves
no release behind. Pinned to plugin-toolbox 657eb50 (stellarwp/plugin-toolbox#16).
@glaubersilva glaubersilva self-assigned this Nov 2, 2026
@glaubersilva
glaubersilva force-pushed the soft-5188-release-publish-action branch 2 times, most recently from b529772 to eab1115 Compare November 2, 2026 20:10
@glaubersilva
glaubersilva marked this pull request as ready for review November 2, 2026 20:27

@coderabbitai coderabbitai Bot 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.

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread templates/workflows/release-publish.yml Resolved
@glaubersilva glaubersilva changed the title Add release-publish: the GitHub release as its own action, with a title, notes and assets Add release-publish: the GitHub release for a version at a commit, with a title, notes and assets Nov 2, 2026
@glaubersilva
glaubersilva force-pushed the soft-5188-release-publish-action branch from 05d78d2 to 9603173 Compare November 2, 2026 20:46

@coderabbitai coderabbitai Bot 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.

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread templates/workflows/release-publish.yml Resolved
@glaubersilva
glaubersilva force-pushed the soft-5188-release-publish-action branch 3 times, most recently from e6c9816 to ef353a6 Compare November 2, 2026 21:37
…le, notes and assets

release-merge published the release as its second step, right after the
merges and before the caller built anything, so a release went public
without its build and a failed build left a published release behind;
with immutable releases that could not be corrected. Publishing is now
the release-publish action, which the caller runs after its build at the
commit release-merge leaves on the base (its base-sha output).

release-publish takes a title (the version by default), a notes file
(GitHub's generated notes by default) and assets, one path per line.
With assets the release is created as a draft, the files are uploaded,
and the draft is published last: a draft makes no tag, so an upload that
fails is undone by deleting it. A hotfix on an older line no longer
takes Latest from a newer release (make_latest by version order). A
release that already exists is skipped, as before. validateVersion
moved to the shared lib for both actions.

release-merge loses the publish input and the published / release-url
outputs; the template runs the two actions with the build between them.

SOFT-5188
…l publishes

The merge template had grown a publish step. Each template now shows one
action; a repository that merges with release-merge adds release-publish
to that workflow after its build, as GiveWP's deploy workflow does, and
the READMEs say so.

SOFT-5188
The release-publish template checked out the branch, invited a build
from that checkout, and passed the branch name as target, which the
action resolves to the branch's tip when it runs: a push between the
checkout and the publish would tag a commit other than the one the
assets came from. The template now records the checked-out commit and
passes it.

SOFT-5188

@coderabbitai coderabbitai Bot 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.

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread templates/workflows/release-publish.yml Resolved
Comment thread templates/workflows/release-publish.yml Resolved
Comment thread templates/workflows/release-publish.yml Resolved
…ispatches

The per-action templates matched no repository: nobody merges without
publishing, and a repository that only publishes does not go through
the dashboard. release.yml, the name the dashboard looks for by
default, runs release-merge, leaves room for the build, then
release-publish at the merged commit. The publish-only shape stays as
a snippet in release-publish's README.

SOFT-5188
@glaubersilva
glaubersilva force-pushed the soft-5188-release-publish-action branch from ef353a6 to 879516b Compare November 2, 2026 21:49
…s github.token cannot create

The environment's branch policy protects the branch a run is started
on, not the branch input, so a run started on an allowed branch could
merge and publish any other. The template's first step fails when the
two differ; the dashboard starts the run on the release branch, and a
hand dispatch passes --ref. A failing step rather than an if on the job,
since a skipped job reads as a success to the dispatcher.

The release-publish README also says that a release at a commit that
changes a workflow file relative to the default branch needs a token
allowed to modify workflows, which github.token cannot be; after
release-merge the published commit is the base branch's tip, so the
case is the hand-merged publish only.

SOFT-5188
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