Skip to content

ci: add release workflow (aligned with api7 lua-resty-healthcheck)#2

Open
AlinsRan wants to merge 3 commits into
masterfrom
ci/release-luarocks
Open

ci: add release workflow (aligned with api7 lua-resty-healthcheck)#2
AlinsRan wants to merge 3 commits into
masterfrom
ci/release-luarocks

Conversation

@AlinsRan

@AlinsRan AlinsRan commented Jul 8, 2026

Copy link
Copy Markdown

Adds a release workflow mirroring the release CI of other api7 lua-resty repositories (healthcheck / etcd / radixtree / expr).

Behavior

Triggered by pushing a rockspec commit to master (paths: rockspecs/**). It:

  1. Parses the version from a feat: release vX.Y.Z commit message.
  2. Creates the GitHub release and tag.
  3. Runs luarocks install dkjson then luarocks 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 message feat: 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

  • Package is published as lua-resty-session-api7 (api7-owned luarocks package), matching the -api7 convention used by the other api7 forks and sidestepping upstream package ownership.
  • Requires the LUAROCKS_TOKEN repository secret.

Summary by CodeRabbit

  • Chores
    • Updated automated release publishing to run on changes to release artifacts on the main branch.
    • Release version is now derived from commit messages using a defined release pattern, and publishing fails if the pattern isn’t found.
    • GitHub releases are created using the extracted version and the matching package artifact is uploaded to Luarocks with the appropriate API key.

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

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Updates the release workflow to run on master pushes affecting rockspecs/**, derive the release version from the commit message, create a GitHub Release, and upload the matching rockspec to Luarocks.

Changes

Release Workflow

Layer / File(s) Summary
Workflow trigger and publish flow
.github/workflows/release.yml
Switches the workflow to a master push trigger for rockspecs/** changes, parses the version from the commit message, creates a GitHub Release, and uploads the computed rockspec to Luarocks after installing dkjson.

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
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Security Check ❌ Error release.yml interpolates untrusted commit-message and step output directly into bash (lines 28, 54), enabling shell injection and token exfiltration. Move both values into env vars, quote them in the script, and resolve the rockspec path safely instead of inlining ${{ ... }} inside run:.
E2e Test Quality Review ⚠️ Warning The PR adds no end-to-end coverage for the release flow, and the workflow itself doesn’t match the intended tag-based release path. Add an end-to-end release workflow test/simulation for tag push → GitHub release → Luarocks upload, and align the trigger/path/rockspec lookup with the intended flow.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a release workflow, with a note that it is adapted from another api7 repository.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-luarocks

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

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

🧹 Nitpick comments (2)
.github/workflows/release.yml (2)

16-17: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Disable credential persistence on checkout.

zizmor flags actions/checkout@v4 here for not setting persist-credentials: false. The job doesn't need to push using the checked-out credentials (release/upload use explicit GH_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 win

Avoid 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 .rockspec are 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

📥 Commits

Reviewing files that changed from the base of the PR and between 505ff72 and ef3f423.

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

AlinsRan added 2 commits July 8, 2026 14:51
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.
@AlinsRan AlinsRan changed the title ci: add release workflow to publish to luarocks on tag ci: add release workflow (aligned with api7 lua-resty-healthcheck) Jul 8, 2026

@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: 2

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

15-16: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Consider persist-credentials: false on checkout.

Reduces the risk of the ephemeral GITHUB_TOKEN leaking 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 win

Bump actions/checkout version.

actions/checkout@v2 is 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@v1 is 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-release or gh release create via 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

📥 Commits

Reviewing files that changed from the base of the PR and between ef3f423 and c104ade.

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

Comment on lines +24 to +37
- 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

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

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.

Suggested change
- 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

Comment on lines +49 to +54
- 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}

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

Suggested change
- 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

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