ci: add release workflow (aligned with api7 lua-resty-healthcheck)#2
ci: add release workflow (aligned with api7 lua-resty-healthcheck)#2AlinsRan wants to merge 3 commits into
Conversation
Pushing a `v*` tag creates a GitHub release and uploads the matching root rockspec to luarocks. Follows the release CI convention used by other api7 lua-resty repositories, adapted to this repo's tag-based release flow and root rockspec layout. Requires the `LUAROCKS_TOKEN` repository secret.
📝 WalkthroughWalkthroughUpdates the release workflow to run on ChangesRelease Workflow
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant GitHub as GitHub push
participant Workflow as release.yml
participant GitHubRelease as GitHub Release API
participant Luarocks as Luarocks
GitHub->>Workflow: push to master with rockspecs/** changes
Workflow->>Workflow: parse version from commit message
Workflow->>GitHubRelease: create release with tag_name and release_name
GitHubRelease-->>Workflow: release created
Workflow->>Luarocks: upload rockspec with LUAROCKS_TOKEN
Luarocks-->>Workflow: upload result
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
.github/workflows/release.yml (2)
16-17: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winDisable credential persistence on checkout.
zizmor flags
actions/checkout@v4here for not settingpersist-credentials: false. The job doesn't need to push using the checked-out credentials (release/upload use explicitGH_TOKEN/LUAROCKS_TOKEN), so persisting the token in the local git config is unnecessary exposure.🔒 Proposed fix
- name: Checkout code uses: actions/checkout@v4 + with: + persist-credentials: false🤖 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/release.yml around lines 16 - 17, The release workflow’s Checkout code step uses actions/checkout@v4 without disabling credential persistence. Update that checkout step to set persist-credentials to false so the job does not leave the GitHub token in the local git config, since later release/upload steps use explicit GH_TOKEN and LUAROCKS_TOKEN instead.Source: Linters/SAST tools
39-51: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winAvoid direct template expansion of step outputs in
run:scripts.zizmor flags lines 43, 44, and 51 for template-injection risk:
${{ steps.release_env.outputs.tag }}and.rockspecare expanded inline into the shell script before execution rather than passed as quoted environment variables. Practical risk is low here since values derive from a maintainer-pushed tag and a filename match on the repo's own naming convention, but hardening is trivial and matches the pattern already used for secrets (GH_TOKEN,LUAROCKS_TOKEN) in this same file.🔒 Proposed fix
- name: Create GitHub release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_TAG: ${{ steps.release_env.outputs.tag }} run: | - gh release create "${{ steps.release_env.outputs.tag }}" \ - --title "${{ steps.release_env.outputs.tag }}" \ + gh release create "${RELEASE_TAG}" \ + --title "${RELEASE_TAG}" \ --generate-notes - name: Upload to luarocks env: LUAROCKS_TOKEN: ${{ secrets.LUAROCKS_TOKEN }} + ROCKSPEC_PATH: ${{ steps.release_env.outputs.rockspec }} run: | - luarocks upload "${{ steps.release_env.outputs.rockspec }}" --api-key="${LUAROCKS_TOKEN}" + luarocks upload "${ROCKSPEC_PATH}" --api-key="${LUAROCKS_TOKEN}"🤖 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/release.yml around lines 39 - 51, Inline GitHub Actions template outputs in the release jobs are being expanded directly inside the shell scripts, which zizmor flags as template-injection risk. Update the Create GitHub release and Upload to luarocks steps to pass steps.release_env.outputs.tag and steps.release_env.outputs.rockspec through env variables first, then reference those shell variables in the gh and luarocks commands, matching the existing GH_TOKEN and LUAROCKS_TOKEN pattern.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.
Nitpick comments:
In @.github/workflows/release.yml:
- Around line 16-17: The release workflow’s Checkout code step uses
actions/checkout@v4 without disabling credential persistence. Update that
checkout step to set persist-credentials to false so the job does not leave the
GitHub token in the local git config, since later release/upload steps use
explicit GH_TOKEN and LUAROCKS_TOKEN instead.
- Around line 39-51: Inline GitHub Actions template outputs in the release jobs
are being expanded directly inside the shell scripts, which zizmor flags as
template-injection risk. Update the Create GitHub release and Upload to luarocks
steps to pass steps.release_env.outputs.tag and
steps.release_env.outputs.rockspec through env variables first, then reference
those shell variables in the gh and luarocks commands, matching the existing
GH_TOKEN and LUAROCKS_TOKEN pattern.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 66869e6d-d003-4dd4-99b1-ef37b09abf27
📒 Files selected for processing (1)
.github/workflows/release.yml
luarocks upload needs dkjson to communicate with the luarocks.org API, matching the release workflow of other api7 lua-resty repositories.
Trigger on rockspec commits to master (paths: rockspecs/**), parse the version from a 'feat: release vX.Y.Z' commit message, create the GitHub release/tag, and upload rockspecs/lua-resty-session-api7-<version>-0.rockspec to luarocks. Mirrors the release CI of other api7 lua-resty repositories.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
.github/workflows/release.yml (3)
15-16: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueConsider
persist-credentials: falseon checkout.Reduces the risk of the ephemeral
GITHUB_TOKENleaking via the persisted git credential helper for the rest of the job.🤖 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/release.yml around lines 15 - 16, The checkout step currently uses the default git credential persistence, which can leave the job token available for later steps. Update the existing actions/checkout usage in the release workflow to disable credential persistence by setting persist-credentials to false on the checkout step, keeping the fix localized to the Checkout code action.Source: Linters/SAST tools
15-16: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winBump
actions/checkoutversion.
actions/checkout@v2is too old to run on the current GitHub Actions runner image; bump to a supported major version (e.g.@v4).🤖 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/release.yml around lines 15 - 16, The Checkout step in the release workflow is using an outdated actions version, so update the actions/checkout reference in the workflow to a supported major version. Locate the Checkout code step in the release job and bump the existing actions/checkout usage to a current release such as v4, keeping the step name and behavior unchanged.Source: Linters/SAST tools
39-47: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win
actions/create-release@v1is archived/unmaintained.The upstream repository for this action is archived, so it receives no fixes or security patches. Migrate to a maintained alternative such as
softprops/action-gh-releaseorgh release createvia the GitHub CLI.🤖 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/release.yml around lines 39 - 47, The Create Release step still uses the archived actions/create-release@v1 action, so update the release job to use a maintained release mechanism instead. Replace the existing Create Release step in the workflow with either softprops/action-gh-release or a GitHub CLI gh release create invocation, and keep the current release metadata from release_env.outputs.version so the release tag/name behavior stays the same.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/release.yml:
- Around line 24-37: The release name extraction step is vulnerable because
`github.event.head_commit.message` is interpolated directly into the bash script
in `release_env`. Move the commit message into an environment variable for that
step, then read it from the shell instead of inline template expansion, and keep
the parsing/validation logic in `Extract release name` using the existing
`re`/`BASH_REMATCH` flow. This prevents untrusted commit text from being treated
as shell syntax while preserving the version parsing behavior.
- Around line 49-54: In the Upload to luarocks step, stop interpolating
steps.release_env.outputs.version_withou_v directly inside the run script and
pass the version through an env var instead to avoid template/script injection.
Also replace the hardcoded rockspec filename in the luarocks upload command with
a version-based glob that matches lua-resty-session-<version>-*.rockspec so the
upload works regardless of revision suffix or the api7 infix.
---
Nitpick comments:
In @.github/workflows/release.yml:
- Around line 15-16: The checkout step currently uses the default git credential
persistence, which can leave the job token available for later steps. Update the
existing actions/checkout usage in the release workflow to disable credential
persistence by setting persist-credentials to false on the checkout step,
keeping the fix localized to the Checkout code action.
- Around line 15-16: The Checkout step in the release workflow is using an
outdated actions version, so update the actions/checkout reference in the
workflow to a supported major version. Locate the Checkout code step in the
release job and bump the existing actions/checkout usage to a current release
such as v4, keeping the step name and behavior unchanged.
- Around line 39-47: The Create Release step still uses the archived
actions/create-release@v1 action, so update the release job to use a maintained
release mechanism instead. Replace the existing Create Release step in the
workflow with either softprops/action-gh-release or a GitHub CLI gh release
create invocation, and keep the current release metadata from
release_env.outputs.version so the release tag/name behavior stays the same.
🪄 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
Run ID: e33d26c7-7c7a-46a8-8626-4e4f899dca37
📒 Files selected for processing (1)
.github/workflows/release.yml
| - name: Extract release name | ||
| id: release_env | ||
| shell: bash | ||
| run: | | ||
| title="${{ github.event.head_commit.message }}" | ||
| re="^feat: release v*(\S+)" | ||
| if [[ $title =~ $re ]]; then | ||
| v=v${BASH_REMATCH[1]} | ||
| echo "##[set-output name=version;]${v}" | ||
| echo "##[set-output name=version_withou_v;]${BASH_REMATCH[1]}" | ||
| else | ||
| echo "commit format is not correct" | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win
Script injection via untrusted commit message.
github.event.head_commit.message is interpolated directly into the run: script body (Line 28). Commit messages are attacker-controlled by anyone with push access (or via a crafted merge/rebase), and the pattern \S+ will happily capture shell metacharacters (backticks, $(), ;), allowing arbitrary command execution on the runner — including exfiltration of LUAROCKS_TOKEN/GITHUB_TOKEN used later in this job.
Pass the value through an environment variable instead of inline template expansion.
🔒 Proposed fix
- name: Extract release name
id: release_env
shell: bash
+ env:
+ COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
run: |
- title="${{ github.event.head_commit.message }}"
+ title="$COMMIT_MESSAGE"
re="^feat: release v*(\S+)"
if [[ $title =~ $re ]]; then📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Extract release name | |
| id: release_env | |
| shell: bash | |
| run: | | |
| title="${{ github.event.head_commit.message }}" | |
| re="^feat: release v*(\S+)" | |
| if [[ $title =~ $re ]]; then | |
| v=v${BASH_REMATCH[1]} | |
| echo "##[set-output name=version;]${v}" | |
| echo "##[set-output name=version_withou_v;]${BASH_REMATCH[1]}" | |
| else | |
| echo "commit format is not correct" | |
| exit 1 | |
| fi | |
| - name: Extract release name | |
| id: release_env | |
| shell: bash | |
| env: | |
| COMMIT_MESSAGE: ${{ github.event.head_commit.message }} | |
| run: | | |
| title="$COMMIT_MESSAGE" | |
| re="^feat: release v*(\S+)" | |
| if [[ $title =~ $re ]]; then | |
| v=v${BASH_REMATCH[1]} | |
| echo "##[set-output name=version;]${v}" | |
| echo "##[set-output name=version_withou_v;]${BASH_REMATCH[1]}" | |
| else | |
| echo "commit format is not correct" | |
| exit 1 | |
| fi |
🧰 Tools
🪛 actionlint (1.7.12)
[error] 27-27: "github.event.head_commit.message" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details
(expression)
🪛 zizmor (1.26.1)
[error] 28-28: 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/release.yml around lines 24 - 37, The release name
extraction step is vulnerable because `github.event.head_commit.message` is
interpolated directly into the bash script in `release_env`. Move the commit
message into an environment variable for that step, then read it from the shell
instead of inline template expansion, and keep the parsing/validation logic in
`Extract release name` using the existing `re`/`BASH_REMATCH` flow. This
prevents untrusted commit text from being treated as shell syntax while
preserving the version parsing behavior.
Source: Linters/SAST tools
| - name: Upload to luarocks | ||
| env: | ||
| LUAROCKS_TOKEN: ${{ secrets.LUAROCKS_TOKEN }} | ||
| run: | | ||
| luarocks install dkjson | ||
| luarocks upload rockspecs/lua-resty-session-api7-${{ steps.release_env.outputs.version_withou_v }}-0.rockspec --api-key=${LUAROCKS_TOKEN} |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Template injection + brittle hardcoded rockspec path.
steps.release_env.outputs.version_withou_v is derived from the untrusted commit message and interpolated directly into the run: command on Line 54 (same script-injection class flagged on Line 28) rather than via an env var. Separately, the rockspec path hardcodes revision -0 and an api7- infix; per the PR objectives the rockspec should be resolved by globbing lua-resty-session-<version>-*.rockspec, since the revision suffix is not guaranteed to always be 0.
🔒 Proposed fix
- name: Upload to luarocks
env:
LUAROCKS_TOKEN: ${{ secrets.LUAROCKS_TOKEN }}
+ ROCKSPEC_VERSION: ${{ steps.release_env.outputs.version_withou_v }}
run: |
luarocks install dkjson
- luarocks upload rockspecs/lua-resty-session-api7-${{ steps.release_env.outputs.version_withou_v }}-0.rockspec --api-key=${LUAROCKS_TOKEN}
+ rockspec=$(fd . rockspecs -g "lua-resty-session-${ROCKSPEC_VERSION}-*.rockspec")
+ luarocks upload "$rockspec" --api-key="${LUAROCKS_TOKEN}"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Upload to luarocks | |
| env: | |
| LUAROCKS_TOKEN: ${{ secrets.LUAROCKS_TOKEN }} | |
| run: | | |
| luarocks install dkjson | |
| luarocks upload rockspecs/lua-resty-session-api7-${{ steps.release_env.outputs.version_withou_v }}-0.rockspec --api-key=${LUAROCKS_TOKEN} | |
| - name: Upload to luarocks | |
| env: | |
| LUAROCKS_TOKEN: ${{ secrets.LUAROCKS_TOKEN }} | |
| ROCKSPEC_VERSION: ${{ steps.release_env.outputs.version_withou_v }} | |
| run: | | |
| luarocks install dkjson | |
| rockspec=$(fd . rockspecs -g "lua-resty-session-${ROCKSPEC_VERSION}-*.rockspec") | |
| luarocks upload "$rockspec" --api-key="${LUAROCKS_TOKEN}" |
🧰 Tools
🪛 zizmor (1.26.1)
[info] 54-54: 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/release.yml around lines 49 - 54, In the Upload to
luarocks step, stop interpolating steps.release_env.outputs.version_withou_v
directly inside the run script and pass the version through an env var instead
to avoid template/script injection. Also replace the hardcoded rockspec filename
in the luarocks upload command with a version-based glob that matches
lua-resty-session-<version>-*.rockspec so the upload works regardless of
revision suffix or the api7 infix.
Source: Linters/SAST tools
Adds a release workflow mirroring the release CI of other api7
lua-restyrepositories (healthcheck / etcd / radixtree / expr).Behavior
Triggered by pushing a rockspec commit to
master(paths: rockspecs/**). It:feat: release vX.Y.Zcommit message.luarocks install dkjsonthenluarocks upload rockspecs/lua-resty-session-api7-<version>-0.rockspec.Release flow
To cut a release, commit
rockspecs/lua-resty-session-api7-X.Y.Z-0.rockspec(source pointing at this fork) with messagefeat: release vX.Y.Z. CI creates the tag/release and publishes — no separate manual tag step, which avoids a tag being pushed without a matching rockspec.Notes
lua-resty-session-api7(api7-owned luarocks package), matching the-api7convention used by the other api7 forks and sidestepping upstream package ownership.LUAROCKS_TOKENrepository secret.Summary by CodeRabbit