Skip to content

Add GitHub workflow to automate release tag creation - #2753

Merged
Pierre-Gilles merged 4 commits into
masterfrom
claude/github-action-release-tag-ht845u
Aug 2, 2026
Merged

Add GitHub workflow to automate release tag creation#2753
Pierre-Gilles merged 4 commits into
masterfrom
claude/github-action-release-tag-ht845u

Conversation

@Pierre-Gilles

@Pierre-Gilles Pierre-Gilles commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new GitHub Actions workflow that automates the creation of release tags with semantic versioning. The workflow allows maintainers to manually trigger a patch or minor version bump, which automatically:

  • Bumps the version in package.json using npm version
  • Creates and pushes a git tag
  • Ensures the workflow only runs on the master branch
  • Uses a Personal Access Token (PAT) to ensure pushed tags trigger downstream release workflows

The workflow includes proper git configuration, Node.js setup, and provides a summary of the created release in the GitHub Actions job summary.

Checklist

  • No tests required (CI/CD workflow configuration)
  • No breaking changes

https://claude.ai/code/session_01NpWWjywQsozhFp7pgsz1Cy

Summary by CodeRabbit

  • New Features
    • Added a manually triggered release workflow with patch or minor version selection.
    • Automatically creates and publishes release tags and displays release details in the workflow summary.
    • Added manual execution options for demo website and Docker release builds.
    • Docker publishing remains limited to version-tagged releases, preventing unintended production image publishing.

@github-actions github-actions Bot added area:infra CI, Docker, release, deployment type:chore Deps, CI, refactoring, docs. Hidden from user changelog labels Aug 2, 2026
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Added a manual release workflow for patch and minor versions. It validates master, bumps the package version, pushes the commit and tag atomically, dispatches release workflows, and limits production Docker builds to version tags.

Changes

Manual release and workflow dispatch

Layer / File(s) Summary
Release trigger and permissions
.github/workflows/create-release-tag.yml, .github/workflows/build-demo-website.yml, .github/workflows/docker-release-build.yml
The release workflow defines patch and minor inputs, permissions, and concurrency control. The Docker and demo website workflows support manual dispatch.
Release preparation and version bump
.github/workflows/create-release-tag.yml
The release job validates master, checks out full history, configures Node.js and Git, and runs the selected version bump.
Tag publishing and release dispatch
.github/workflows/create-release-tag.yml, .github/workflows/docker-release-build.yml
The workflow pushes the commit and tag atomically, dispatches three release workflows, and writes release details to the job summary. The Docker production job runs only for version tags.

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

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions as GitHub Actions
  participant GitHubRepository as GitHub repository
  participant ReleaseWorkflows as Release workflows
  participant DockerJob as Docker production job
  GitHubActions->>GitHubRepository: Push master commit and generated tag atomically
  GitHubActions->>ReleaseWorkflows: Dispatch release workflows on the tag
  ReleaseWorkflows->>DockerJob: Run production build only for refs/tags/v
  GitHubActions->>GitHubActions: Write release details to job summary
Loading

Poem

A rabbit starts the release run,
Patch or minor, neatly done.
The tag hops out on master’s trail,
Release workflows lift their sail.
Docker builds when version tags prevail.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding a GitHub workflow that automates release tag creation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/github-action-release-tag-ht845u

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cursor cursor 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.

Stale comment

Review: Create release tag workflow

Useful automation that matches the existing manual release pattern (npm version bump of root package.json + package-lock.json, commit message like 4.84.1, tag v*.*.*docker-release-build.yml). Master-only guard, patch/minor-only choices, and bot commit identity look good.

Not approving yet — please address the silent GITHUB_TOKEN fallback (and ideally concurrency) before merge. Without RELEASE_PAT, a green run creates a tag that does not trigger the production release workflows this PR exists to drive.

No Gladys runtime / device-constants impact → no risk:high / needs:human-review.

Open in Web View Automation 

Sent by Cursor Automation: Automatic PR review

Comment thread .github/workflows/create-release-tag.yml Outdated
Comment thread .github/workflows/create-release-tag.yml
Comment thread .github/workflows/create-release-tag.yml Outdated
Comment thread .github/workflows/create-release-tag.yml
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

🐳 A Docker image has been built for this branch and pushed to the GitHub Container Registry.

You can test this pull request (AMD64 only) by pulling the image below:

ghcr.io/gladysassistant/gladys-preview:claude-github-action-release-tag-ht845u

For example, run it with:

sudo docker run -d \
  --log-driver json-file \
  --log-opt max-size=10m \
  --cgroupns=host \
  --restart=always \
  --privileged \
  --network=host \
  --name gladys-claude-github-action-release-tag-ht845u \
  -e NODE_ENV=production \
  -e SERVER_PORT=80 \
  -e TZ=Europe/Paris \
  -e SQLITE_FILE_PATH=/var/lib/gladysassistant/gladys-production.db \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/gladysassistant:/var/lib/gladysassistant \
  -v /dev:/dev \
  -v /run/udev:/run/udev:ro \
  ghcr.io/gladysassistant/gladys-preview:claude-github-action-release-tag-ht845u

This comment and the image are automatically updated on every new commit pushed to this pull request.

Need an ARM64 image (Raspberry Pi, Apple Silicon, …)? Comment /build-arm64 on this pull request.

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

Actionable comments posted: 4

🧹 Nitpick comments (3)
.github/workflows/create-release-tag.yml (3)

53-58: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Keep dynamic values out of the shell source.

The summary expands step outputs and workflow metadata directly into Bash. Pass these values through env and use quoted printf arguments. GitHub evaluates context expressions before the runner executes the script. (docs.github.com)

📝 Proposed fix
       - name: 📝 Job summary
+        env:
+          VERSION: ${{ steps.bump.outputs.version }}
+          RELEASE_TYPE: ${{ inputs.release_type }}
+          SERVER_URL: ${{ github.server_url }}
+          REPOSITORY: ${{ github.repository }}
         run: |
-          echo "### 🚀 Release ${{ steps.bump.outputs.version }} created" >> "$GITHUB_STEP_SUMMARY"
-          echo "" >> "$GITHUB_STEP_SUMMARY"
-          echo "- Bump type: \`${{ inputs.release_type }}\`" >> "$GITHUB_STEP_SUMMARY"
-          echo "- Tag: [\`${{ steps.bump.outputs.version }}\`](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ steps.bump.outputs.version }})" >> "$GITHUB_STEP_SUMMARY"
+          printf '### 🚀 Release %s created\n' "$VERSION" >> "$GITHUB_STEP_SUMMARY"
+          printf '\n' >> "$GITHUB_STEP_SUMMARY"
+          printf -- '- Bump type: `%s`\n' "$RELEASE_TYPE" >> "$GITHUB_STEP_SUMMARY"
+          printf -- '- Tag: [`%s`](%s/%s/releases/tag/%s)\n' \
+            "$VERSION" "$SERVER_URL" "$REPOSITORY" "$VERSION" >> "$GITHUB_STEP_SUMMARY"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/create-release-tag.yml around lines 53 - 58, Update the
“📝 Job summary” step to pass the release version, release type, server URL, and
repository through an env block, then write the summary using quoted printf
arguments instead of interpolating GitHub expressions directly in the Bash
source. Preserve the existing headings, bump type, and release-tag link output.

Source: Linters/SAST tools


44-49: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Make the version bump deterministic.

The downstream workflow matches only v*.*.* tags. npm 10 defaults to the v prefix, but npm configuration can override tag-version-prefix. Pass the input through env, validate patch or minor, and set --tag-version-prefix=v explicitly. (docs.npmjs.com)

🏷️ Proposed fix
       - name: 🔖 Bump version and create tag
         id: bump
+        env:
+          RELEASE_TYPE: ${{ inputs.release_type }}
         run: |
-          NEW_VERSION=$(npm version ${{ inputs.release_type }})
+          case "$RELEASE_TYPE" in
+            patch|minor) ;;
+            *) echo "Unsupported release type" >&2; exit 1 ;;
+          esac
+          NEW_VERSION=$(npm version --tag-version-prefix=v "$RELEASE_TYPE")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/create-release-tag.yml around lines 44 - 49, Update the
“Bump version and create tag” step to pass the release type through its
environment, validate that it is only patch or minor, and invoke npm version
with an explicit v tag-version prefix so generated tags always match v*.*.*.

29-35: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Limit the PAT to the push operation.

actions/checkout@v4 persists the supplied token for later Git commands by default. This makes the write-capable PAT available to later steps, including package lifecycle scripts. Set persist-credentials: false and configure a temporary credential only in the push step. Do not add the flag without updating the push authentication. (github.com)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/create-release-tag.yml around lines 29 - 35, Update the
checkout configuration in the “⬇️ Checkout Gladys code” step to set
persist-credentials to false, then update the later tag-push step to
authenticate explicitly with the release PAT only for that push operation,
preserving the existing fallback behavior where applicable.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/create-release-tag.yml:
- Around line 19-22: Add a workflow-level concurrency configuration for
create-release-tag, using a release-specific group and setting
cancel-in-progress to false so manually dispatched release runs queue instead of
overlapping. Keep the existing create-release-tag job configuration unchanged.
- Around line 29-35: Update the checkout step in the release workflow to require
secrets.RELEASE_PAT directly, removing the fallback to secrets.GITHUB_TOKEN.
Preserve the existing token usage so checkout and subsequent git push operations
fail when RELEASE_PAT is unavailable.
- Around line 24-28: Move the master-branch restriction from the “🛑 Ensure
workflow runs on master” step to the job-level if condition, preventing the job
from starting for other refs. Update the checkout action to explicitly target
refs/heads/master, and remove the shell-based github.ref_name interpolation and
late branch guard.
- Around line 50-52: Update the “🚀 Push commit and tag” step to use Git’s
atomic push option so the release commit and tags succeed or fail together. Also
ensure this workflow is serialized with other release or branch-update workflows
using the repository’s existing concurrency mechanism, preventing simultaneous
ref updates.

---

Nitpick comments:
In @.github/workflows/create-release-tag.yml:
- Around line 53-58: Update the “📝 Job summary” step to pass the release
version, release type, server URL, and repository through an env block, then
write the summary using quoted printf arguments instead of interpolating GitHub
expressions directly in the Bash source. Preserve the existing headings, bump
type, and release-tag link output.
- Around line 44-49: Update the “Bump version and create tag” step to pass the
release type through its environment, validate that it is only patch or minor,
and invoke npm version with an explicit v tag-version prefix so generated tags
always match v*.*.*.
- Around line 29-35: Update the checkout configuration in the “⬇️ Checkout
Gladys code” step to set persist-credentials to false, then update the later
tag-push step to authenticate explicitly with the release PAT only for that push
operation, preserving the existing fallback behavior where applicable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b17cbd1b-71dc-4a9b-ad78-9d1a38fe3db3

📥 Commits

Reviewing files that changed from the base of the PR and between bd9342a and 0a483cf.

📒 Files selected for processing (1)
  • .github/workflows/create-release-tag.yml

Comment thread .github/workflows/create-release-tag.yml
Comment on lines +24 to +28
- name: 🛑 Ensure workflow runs on master
if: github.ref != 'refs/heads/master'
run: |
echo "This workflow can only be run on master, got ${{ github.ref_name }}."
exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow files =="
git ls-files '.github/workflows/*' || true

echo "== target workflow =="
if [ -f .github/workflows/create-release-tag.yml ]; then
  cat -n .github/workflows/create-release-tag.yml
else
  echo "target file missing"
fi

echo "== package lifecycle scripts / npm version config =="
if [ -f package.json ]; then
  python3 - <<'PY'
import json
p=json.load(open('package.json'))
for k in ['scripts','version']: print(k, p.get(k))
PY
fi

Repository: GladysAssistant/Gladys

Length of output: 4472


🌐 Web query:

GitHub Actions run workflow button select branch workflow_dispatch manual runs on branch security bash injection github.ref_name

💡 Result:

Using ${{ github.ref_name }} or workflow inputs directly within a bash run block is a significant security risk, classified as template or shell command injection [1][2][3]. When you place these expressions directly into a run block, the GitHub Actions runner replaces the placeholders with their raw string values before the shell executes the command [4][2][5]. An attacker can craft a branch name or workflow input containing shell meta-characters (such as ;, &, |, or backticks) to break out of your intended command and execute arbitrary code on the runner [1][6][3]. To secure your workflows, you must never interpolate untrusted values directly into run scripts [1][2][5]. Instead, follow these industry-standard defensive practices: 1. Use Environment Variables: Map all untrusted inputs (including github.ref_name and workflow_dispatch inputs) to environment variables at the step level [4][6][7]. This ensures the values are treated as data, not code, by the shell [2][6][8]. Example of secure implementation: - name: Process branch name env: BRANCH_NAME: ${{ github.ref_name }} run: | # Use the variable in quotes to prevent shell interpretation echo "Processing branch: $BRANCH_NAME" 2. Input Validation: For workflow_dispatch inputs, implement strict validation using regular expressions or allowlists before the input is used in any downstream logic [4][9][6]. For example, ensure a version input matches a known pattern (e.g., ^[a-zA-Z0-9._-]+$) [4][6]. 3. Static Analysis: Enable code scanning with CodeQL in your repository [2][5]. CodeQL includes specialized queries designed to detect unsafe interpolation of untrusted inputs into GitHub Actions workflows, helping you catch these vulnerabilities before they are exploited [2][5]. By treating all inputs—including branch names, issue titles, and workflow_dispatch fields—as untrusted, you significantly reduce the risk of supply chain compromise and credential exfiltration [1][4][6].

Citations:


🌐 Web query:

npm version lifecycle scripts runs lifecycle scripts prepublish preversion version postversion

💡 Result:

In the npm lifecycle, scripts are triggered by specific commands to manage package preparation, versioning, and publishing [1][2]. Version Lifecycle Scripts When running the npm version command, the lifecycle scripts execute in the following fixed order [1][2]: 1. preversion: Runs before the package version is bumped [3][4]. 2. version: Runs after the version is bumped, but before the commit [3][4]. 3. postversion: Runs after the version is bumped and after the commit [3][4]. Prepublish and Related Scripts The prepublish script is considered deprecated because its behavior can be confusing; it runs both before the package is packed/published and during a local npm install without arguments [3][1]. To replace this, npm introduced other lifecycle events [3][1]: - prepublishOnly: Runs only before the package is prepared and packed, specifically during npm publish [3][1]. - prepare: Runs after prepublish, but before prepublishOnly. It executes during both npm publish and local npm install, serving as a reliable alternative for build steps [3][1]. General Note For any script (e.g., myscript), npm automatically looks for pre- and post- counterparts (premyscript and postmyscript) if they are defined in your package.json [1][2]. Additionally, the environment variable npm_lifecycle_event is always set to the name of the script currently being executed, allowing you to use a single script to handle multiple lifecycle stages [3][1].

Citations:


🌐 Web query:

GitHub Actions workflow_dispatch manual run select workflow branch if condition github.ref jobs job if

💡 Result:

When using workflow_dispatch to run a GitHub Actions workflow manually, the GitHub UI allows you to select any branch in the repository as the target for the workflow execution [1][2]. For the manual branch selection to function, the workflow file must exist in the default branch of the repository [1][3]. Once triggered, the workflow execution context identifies the selected branch through standard GitHub context variables [2]. You can use the github.ref or github.ref_name context variables within your workflow to dynamically handle the selected branch [2]. To restrict or control job execution based on the branch selected during the manual run, you can use the jobs.<job_id>.if condition [4][3]. Example implementation using a conditional job: jobs: deploy: runs-on: ubuntu-latest # This job will only run if the branch selected in the manual UI is 'main' if: ${{ github.ref_name == 'main' }} steps: - uses: actions/checkout@v4 - run: echo "Running on ${{ github.ref_name }}" If you need to control the branch used by the actions/checkout step itself (for example, to support scheduled runs alongside manual runs), you can use a ternary expression to dynamically set the ref [2]: jobs: checkout-job: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: # Use 'main' for scheduled runs, or the selected branch for manual runs ref: ${{ github.event_name == 'schedule' && 'main' || github.ref_name }}

Citations:


Move the branch restriction and checkout target outside untrusted output.

.github/workflows/create-release-tag.yml allows manual dispatch on any branch. Interpolating github.ref_name into the shell can allow command injection, and npm version can run lifecycle scripts from the selected repository state before the guard exits. Apply the check at job level and force checkout to refs/heads/master.

🧰 Tools
🪛 zizmor (1.28.0)

[error] 27-27: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/create-release-tag.yml around lines 24 - 28, Move the
master-branch restriction from the “🛑 Ensure workflow runs on master” step to
the job-level if condition, preventing the job from starting for other refs.
Update the checkout action to explicitly target refs/heads/master, and remove
the shell-based github.ref_name interpolation and late branch guard.

Source: Linters/SAST tools

Comment thread .github/workflows/create-release-tag.yml Outdated
Comment thread .github/workflows/create-release-tag.yml Outdated
@codecov

codecov Bot commented Aug 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.15%. Comparing base (bd9342a) to head (a25fc84).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2753      +/-   ##
==========================================
- Coverage   99.16%   99.15%   -0.01%     
==========================================
  Files        1189     1189              
  Lines       24973    24979       +6     
==========================================
+ Hits        24764    24768       +4     
- Misses        209      211       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Require the RELEASE_PAT secret instead of silently falling back to
  GITHUB_TOKEN, which would create a tag that never triggers the release build
- Add a concurrency group so two dispatches cannot bump from the same tip
- Checkout the current tip of master rather than the dispatch-time commit
- Push the commit and the tag atomically
- Pass refs and inputs through env vars instead of interpolating them in shell

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NpWWjywQsozhFp7pgsz1Cy
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 2, 2026

Copy link
Copy Markdown

Deploying gladys-plus with  Cloudflare Pages  Cloudflare Pages

Latest commit: a25fc84
Status: ✅  Deploy successful!
Preview URL: https://24f4d05f.gladys-plus.pages.dev
Branch Preview URL: https://claude-github-action-release.gladys-plus.pages.dev

View logs

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/create-release-tag.yml:
- Around line 46-55: Update the checkout step in the release workflow to use
github.token for its token and set persist-credentials to false. Remove
RELEASE_PAT from actions/checkout, then pass it only to the final atomic git
push via a one-shot http.extraheader.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 108f6938-19a5-4a20-82b1-a3de0f950ffe

📥 Commits

Reviewing files that changed from the base of the PR and between 0a483cf and 7e13fcf.

📒 Files selected for processing (1)
  • .github/workflows/create-release-tag.yml

Comment thread .github/workflows/create-release-tag.yml Outdated
Checkout now runs with the default GITHUB_TOKEN and persist-credentials
disabled. RELEASE_PAT is only passed to the final push, through a one-shot
masked authentication header.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NpWWjywQsozhFp7pgsz1Cy
@Pierre-Gilles Pierre-Gilles added needs:cursor-review Automated review by Cursor is needed and removed needs:cursor-review Automated review by Cursor is needed labels Aug 2, 2026
cursor[bot]
cursor Bot previously approved these changes Aug 2, 2026

@cursor cursor 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.

Stale comment

Re-review: ready to merge

Hard blockers from the previous pass are addressed in 7e13fcf / f35e27a:

  • RELEASE_PAT is required — early fail if the secret is empty; no GITHUB_TOKEN fallback, so tag pushes can actually trigger docker-release-build.yml
  • Concurrency (create-release-tag, cancel-in-progress: false) serializes overlapping dispatches
  • Checkout tip of master with persist-credentials: false, PAT only on the final atomic push via one-shot http.extraheader
  • Atomic push of the version commit + v*.*.* tag

This matches the existing manual release pattern (root package.json / lockfile bump, bare-semver commit, v-prefixed tag → production image pipeline). No Gladys runtime / device-taxonomy changes; not risk:high / not needs:human-review.

Ops reminder (not a merge blocker): ensure RELEASE_PAT can push to protected master and create tags. An optional GitHub Environment with required reviewers remains a nice hardening if you want a second human checkpoint before shipping production images.

Open in Web View Automation 

Sent by Cursor Automation: Automatic PR review

A tag pushed with the default GITHUB_TOKEN does not start the workflows
listening on `push: tags`, which is why a PAT was required. workflow_dispatch
is one of the two events GitHub does start from a GITHUB_TOKEN, so the release
workflows are now dispatched explicitly on the new tag instead.

- Drop the RELEASE_PAT secret entirely
- Add workflow_dispatch to the production image and demo website workflows
- Only publish production images from a release tag, never from a branch a
  manual dispatch could have been started on

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NpWWjywQsozhFp7pgsz1Cy

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/docker-release-build.yml:
- Around line 127-129: Update the Docker publish condition around the docker job
to require the prerelease validation job and an exact supported release-tag
format, rather than only the refs/tags/v prefix. Allow production publishing
only for vMAJOR.MINOR.PATCH tags, while permitting prerelease jobs to publish
supported forms such as vMAJOR.MINOR.PATCH-next.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bb2bb359-33ce-462a-b8dc-81ab7f5fec7b

📥 Commits

Reviewing files that changed from the base of the PR and between f35e27a and a25fc84.

📒 Files selected for processing (3)
  • .github/workflows/build-demo-website.yml
  • .github/workflows/create-release-tag.yml
  • .github/workflows/docker-release-build.yml

Comment on lines +127 to +129
# Production images are only published from a release tag, never from a
# branch a manual dispatch could have been started on.
if: startsWith(github.ref, 'refs/tags/v')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate workflow =="
fd -a 'docker-release-build\.yml$' . || true

echo "== workflow relevant sections =="
if [ -f .github/workflows/docker-release-build.yml ]; then
  wc -l .github/workflows/docker-release-build.yml
  sed -n '1,220p' .github/workflows/docker-release-build.yml
fi

echo "== occurrences of docker job and ref usage =="
rg -n "name: docker|docker-run|docker release|github\.ref|prerelease|on:|workflow_dispatch|pull_request|push:" .github/workflows/docker-release-build.yml || true

Repository: GladysAssistant/Gladys

Length of output: 7939


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== inspect release workflow context =="
python3 - <<'PY'
from pathlib import Path
p=Path('.github/workflows/docker-release-build.yml')
if not p.exists():
    print('missing')
    raise SystemExit
lines=p.read_text().splitlines()
for i,l in enumerate(lines,1):
    if 'workflow_dispatch' in l or 'push:' in l or 'pull_request:' in l or any(kw in l for kw in ['if:', 'refs/tags', 'docker', 'needs:']):
        print(f"{i}: {l}")
PY

Repository: GladysAssistant/Gladys

Length of output: 1652


🌐 Web query:

GitHub Actions workflow_dispatch workflow ref input github.ref tags values examples

💡 Result:

In GitHub Actions, the workflow_dispatch event allows you to manually trigger a workflow [1][2]. While you can define custom inputs for this event, the ref (reference) is a distinct parameter used to specify which branch, tag, or commit SHA the workflow should run against [1][3]. Key Concepts regarding Ref and Inputs: 1. The Ref Parameter: The ref is not defined as an input within your YAML workflow file's inputs section [4]. Instead, it is a required parameter provided when triggering the workflow via the GitHub UI, GitHub CLI, or REST API [1][2][3]. - GitHub UI: You select the branch or tag from a dropdown menu after clicking the Run workflow button [2]. - GitHub CLI: You use the --ref flag (e.g., gh workflow run WORKFLOW --ref BRANCH_OR_TAG) [1][2]. - REST API: You include it as a mandatory field in the request body (e.g., "ref": "main") [5][3]. 2. Inputs: You can define up to 25 custom inputs in your workflow YAML file under the on.workflow_dispatch.inputs key [1][4][3]. These inputs are separate from the Git ref [4][3]. Example of triggering via REST API: You must provide the ref as a top-level key in the JSON payload, while custom inputs reside within their own inputs object [3]. curl -L -X POST https://api.github.com/repos/OWNER/REPO/actions/workflows/WORKFLOW_ID/dispatches \ -d '{ "ref": "main", "inputs": { "logLevel": "warning", "tags": "production-release" } }' If you need to pass a tag or branch dynamically as an input, you must define a string input in your YAML (e.g., named target_ref) and manually handle that value within your workflow steps, as the system-level ref parameter used by the trigger mechanism is not automatically mapped to custom input fields [4].

Citations:


Require an exact release-tag format before publishing images.

The Docker job runs when workflow_dispatch is invoked with any refs/tags/v* ref because startsWith(github.ref, 'refs/tags/v') only checks the prefix. Gate docker on a prerelease job that validates github.ref against the release tag grammar, such as vMAJOR.MINOR.PATCH, and let prerelease jobs publish only vMAJOR.MINOR.PATCH-next or another supported prerelease form.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/docker-release-build.yml around lines 127 - 129, Update
the Docker publish condition around the docker job to require the prerelease
validation job and an exact supported release-tag format, rather than only the
refs/tags/v prefix. Allow production publishing only for vMAJOR.MINOR.PATCH
tags, while permitting prerelease jobs to publish supported forms such as
vMAJOR.MINOR.PATCH-next.

@Pierre-Gilles Pierre-Gilles added the needs:cursor-review Automated review by Cursor is needed label Aug 2, 2026

@cursor cursor 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.

Re-review @ a25fc84: approve

The design shift away from a long-lived RELEASE_PAT is a solid improvement. Pushing the version commit + tag with GITHUB_TOKEN, then explicitly gh workflow run … --ref <tag> on the three release workflows, correctly works around GitHub’s “GITHUB_TOKEN pushes do not start push workflows” rule without storing a write PAT.

What looks good:

  • Master-only gate, concurrency (cancel-in-progress: false), tip-of-master checkout, atomic push
  • workflow_dispatch added to docker-release-build.yml / build-demo-website.yml (apidoc already had it)
  • Production Docker publish gated with startsWith(github.ref, 'refs/tags/v') so a branch dispatch cannot ship images
  • Matches existing manual release shape (root package.json / lockfile via npm version, bare-semver commit, v*.*.* tag)

No Gladys runtime / device-constants impact → not risk:high / not needs:human-review. Soft residuals called out inline (demo branch dispatch; confirm GITHUB_TOKEN can push protected master).

Open in Web View Automation 

Sent by Cursor Automation: Automatic PR review

on:
# Dispatched on the new tag by the "Create release tag" workflow: a tag pushed
# with the default GITHUB_TOKEN does not trigger the `push` event below.
workflow_dispatch:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Soft (parity with Docker): workflow_dispatch here has no tag/ref guard, so anyone with Actions write can publish the demo site from an arbitrary branch via the UI. docker-release-build.yml correctly skips publishing unless github.ref is a refs/tags/v* ref. Apidoc already had the same ungated dispatch before this PR, so this is not a merge blocker — consider mirroring the Docker-style if: on the deploy job if you want demo publishes limited to release tags.

env:
NEW_VERSION: ${{ steps.bump.outputs.version }}
run: |
git push --atomic origin master "refs/tags/${NEW_VERSION}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ops reminder (not a merge blocker): this push now uses the default GITHUB_TOKEN (contents: write) instead of a PAT. Confirm branch protection / rulesets allow GitHub Actions to push commits and tags to master; if not, the job fails closed (atomic push), but the workflow will not ship until that is allowed (or an Environment with a bypass actor is configured).

Optional hardening still stands: pin this job to a GitHub Environment with required reviewers so “Create release tag” is not a one-click production ship for every collaborator with write access.

@Pierre-Gilles Pierre-Gilles removed the needs:cursor-review Automated review by Cursor is needed label Aug 2, 2026
@Pierre-Gilles
Pierre-Gilles merged commit 9d1f7f8 into master Aug 2, 2026
11 checks passed
@Pierre-Gilles
Pierre-Gilles deleted the claude/github-action-release-tag-ht845u branch August 2, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:infra CI, Docker, release, deployment type:chore Deps, CI, refactoring, docs. Hidden from user changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants