-
-
Notifications
You must be signed in to change notification settings - Fork 318
Add GitHub workflow to automate release tag creation #2753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0a483cf
7e13fcf
f35e27a
a25fc84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| name: Create release tag | ||
| run-name: Create ${{ inputs.release_type }} release tag | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| release_type: | ||
| description: 'Type of version bump' | ||
| required: true | ||
| default: 'patch' | ||
| type: choice | ||
| options: | ||
| - patch | ||
| - minor | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
cursor[bot] marked this conversation as resolved.
|
||
| # Needed to dispatch the release workflows on the new tag. | ||
| actions: write | ||
|
|
||
| # Two overlapping runs would bump from the same tip and race on the same tag. | ||
| concurrency: | ||
| group: create-release-tag | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| create-release-tag: | ||
|
cursor[bot] marked this conversation as resolved.
|
||
| name: Bump version and push tag | ||
| runs-on: ubuntu-latest | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| steps: | ||
| - name: 🛑 Ensure workflow runs on master | ||
| if: github.ref != 'refs/heads/master' | ||
| env: | ||
| REF_NAME: ${{ github.ref_name }} | ||
| run: | | ||
| echo "::error::This workflow can only be run on master, got ${REF_NAME}." | ||
| exit 1 | ||
|
Comment on lines
+31
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
fiRepository: GladysAssistant/Gladys Length of output: 4472 🌐 Web query:
💡 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 Citations:
🌐 Web query:
💡 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:
💡 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.
🧰 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 AgentsSource: Linters/SAST tools |
||
| - name: ⬇️ Checkout Gladys code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| # Always release from the current tip of master, not from the commit | ||
| # master pointed at when the workflow was dispatched. | ||
| ref: master | ||
| fetch-depth: 0 | ||
| - name: 💽 Setup nodejs | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version-file: './package.json' | ||
| - name: 🔧 Configure git | ||
| run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| - name: 🔖 Bump version and create tag | ||
| id: bump | ||
| env: | ||
| RELEASE_TYPE: ${{ inputs.release_type }} | ||
| run: | | ||
| NEW_VERSION=$(npm version "${RELEASE_TYPE}") | ||
| echo "version=${NEW_VERSION}" >> "$GITHUB_OUTPUT" | ||
| echo "Created tag ${NEW_VERSION}" | ||
| - name: 🚀 Push commit and tag | ||
| env: | ||
| NEW_VERSION: ${{ steps.bump.outputs.version }} | ||
| run: | | ||
| git push --atomic origin master "refs/tags/${NEW_VERSION}" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ops reminder (not a merge blocker): this push now uses the default 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. |
||
| - name: 🎬 Trigger the release workflows | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| GH_REPO: ${{ github.repository }} | ||
| NEW_VERSION: ${{ steps.bump.outputs.version }} | ||
| run: | | ||
| # A tag pushed with the default GITHUB_TOKEN does not trigger the | ||
| # workflows listening on `push: tags`, so they are dispatched explicitly | ||
| # on the new tag. workflow_dispatch is one of the two events GitHub does | ||
| # start from a GITHUB_TOKEN, which is why no PAT is needed here. | ||
| for workflow in docker-release-build.yml build-demo-website.yml build-apidoc-documentation.yml; do | ||
| echo "Triggering ${workflow} on ${NEW_VERSION}" | ||
| gh workflow run "${workflow}" --ref "${NEW_VERSION}" | ||
| done | ||
| - name: 📝 Job summary | ||
| env: | ||
| NEW_VERSION: ${{ steps.bump.outputs.version }} | ||
| RELEASE_TYPE: ${{ inputs.release_type }} | ||
| run: | | ||
| { | ||
| echo "### 🚀 Release ${NEW_VERSION} created" | ||
| echo "" | ||
| echo "- Bump type: \`${RELEASE_TYPE}\`" | ||
| echo "- Tag: [\`${NEW_VERSION}\`](${{ github.server_url }}/${{ github.repository }}/releases/tag/${NEW_VERSION})" | ||
| echo "- Release workflows dispatched on the tag: production images, demo website, apidoc" | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,9 @@ name: Release Gladys Production Images | |
| run-name: Release Gladys ${{ github.ref_name }} Production Image | ||
|
|
||
| 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: | ||
| push: | ||
| tags: | ||
| - 'v*.*.*' | ||
|
|
@@ -121,6 +124,9 @@ jobs: | |
| docker: | ||
| needs: build-front | ||
| name: Docker magic ! | ||
| # 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') | ||
|
Comment on lines
+127
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 || trueRepository: 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}")
PYRepository: GladysAssistant/Gladys Length of output: 1652 🌐 Web query:
💡 Result: In GitHub Actions, the Citations:
Require an exact release-tag format before publishing images. The Docker job runs when 🤖 Prompt for AI Agents |
||
| runs-on: ubuntu-22.04 | ||
| env: | ||
| DOCKERHUB_USER: ${{secrets.DOCKERHUB_USER}} | ||
|
|
||
There was a problem hiding this comment.
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_dispatchhere 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.ymlcorrectly skips publishing unlessgithub.refis arefs/tags/v*ref. Apidoc already had the same ungated dispatch before this PR, so this is not a merge blocker — consider mirroring the Docker-styleif:on the deploy job if you want demo publishes limited to release tags.