feat: add stale bot and release notification workflows#42
feat: add stale bot and release notification workflows#42abhizipstack wants to merge 2 commits intomainfrom
Conversation
Stale bot: - Runs daily, marks issues/PRs as stale after 60 days of inactivity - Auto-closes after 7 more days if no activity - Exempts pinned, security, and bug labels - Uses existing 'stale' label (created in PR #15) Release notification: - Posts to Slack when a GitHub release is published - Requires SLACK_WEBHOOK_URL secret (skips if not configured) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
| Filename | Overview |
|---|---|
| .github/workflows/release-notification.yml | New release-to-Slack notification workflow; has a P1 script injection issue on lines 15-17 and a missing permissions block |
| .github/workflows/stale.yml | New stale-bot workflow; well-structured with correct permissions, all four message fields, and consistent exempt labels |
Sequence Diagram
sequenceDiagram
participant GH as GitHub
participant WF as release-notification.yml
participant Shell as run: step (bash)
participant Action as slackapi/slack-github-action
participant Slack as Slack Channel
GH->>WF: release published event
WF->>WF: check SLACK_WEBHOOK_URL secret != ''
alt secret not configured
WF-->>GH: job skipped
else secret configured
WF->>Shell: Build Slack message step
Note over Shell: TAG/URL injected via ${{ }}<br/>NAME via toJSON+jq
Shell-->>WF: steps.message.outputs.text
WF->>Action: Post to Slack (webhook + payload)
Action->>Slack: HTTP POST incoming webhook
Slack-->>Action: 200 OK
end
Prompt To Fix All With AI
This is a comment left during a code review.
Path: .github/workflows/release-notification.yml
Line: 15-17
Comment:
**Script injection via direct `${{ }}` interpolation in `run:` block**
`github.event.release.tag_name` (line 15) and `github.event.release.html_url` (line 17) are interpolated directly via `${{ }}` expressions inside a `run:` shell script. This is a known script-injection vector: if a tag name contains shell metacharacters (e.g. a backtick, `$(...)`, or a newline followed by fabricated `GITHUB_OUTPUT` content), the injected content will be executed as shell commands.
The safe pattern recommended by GitHub's security hardening guide is to pass event data through `env:` variables, which the shell treats as data rather than code:
```yaml
- name: Build Slack message
id: message
env:
TAG: ${{ github.event.release.tag_name }}
RELEASE_NAME: ${{ github.event.release.name }}
URL: ${{ github.event.release.html_url }}
run: |
NAME=$(echo "$RELEASE_NAME" | jq -Rs '.')
echo "text=🚀 *Visitran ${TAG}* released! ${RELEASE_NAME} <${URL}|View Release Notes>" >> "$GITHUB_OUTPUT"
```
This ensures no user-controlled string is ever interpolated directly into the shell command.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: .github/workflows/release-notification.yml
Line: 7-10
Comment:
**Missing `permissions` block — GITHUB_TOKEN has unnecessary default scope**
The workflow has no `permissions` key. Without it, the job inherits the repository's default token permissions, which may include write access to `contents`, `pull-requests`, etc. Since this workflow only posts to Slack via a webhook secret and never touches `GITHUB_TOKEN`, adding an explicit `permissions: {}` block follows the principle of least privilege.
Note that `stale.yml` correctly declares only the two permissions it needs — this workflow should follow the same discipline:
```suggestion
jobs:
notify:
runs-on: ubuntu-latest
permissions: {}
if: ${{ secrets.SLACK_WEBHOOK_URL != '' }}
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: .github/workflows/stale.yml
Line: 16
Comment:
**Mutable action version tags — pin to commit SHAs for supply-chain safety**
Both workflows reference actions by mutable version tags (`actions/stale@v9` here, `slackapi/slack-github-action@v2.1.0` in `release-notification.yml`). A tag can be silently moved to a different commit by the action maintainer (or a compromised account), causing malicious code to run in your workflows without any change to this repository.
The recommended practice is to pin to a full-length immutable commit SHA, with the version tag as a comment:
```suggestion
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9
```
The same applies to `slackapi/slack-github-action@v2.1.0` in `release-notification.yml` — verify the current SHA from the upstream release page before pinning.
How can I resolve this? If you propose a fix, please make it concise.Reviews (2): Last reviewed commit: "fix: address Greptile review — JSON inje..." | Re-trigger Greptile
…pt labels - Fix JSON injection in Slack payload — build message in run step to avoid malformed JSON from release names with quotes - Add close-pr-message for stale PRs — contributors get context - Add bug to exempt-pr-labels — match issue exemptions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| TAG="${{ github.event.release.tag_name }}" | ||
| NAME=$(echo '${{ toJSON(github.event.release.name) }}' | jq -r '.') | ||
| URL="${{ github.event.release.html_url }}" |
There was a problem hiding this comment.
Script injection via direct
${{ }} interpolation in run: block
github.event.release.tag_name (line 15) and github.event.release.html_url (line 17) are interpolated directly via ${{ }} expressions inside a run: shell script. This is a known script-injection vector: if a tag name contains shell metacharacters (e.g. a backtick, $(...), or a newline followed by fabricated GITHUB_OUTPUT content), the injected content will be executed as shell commands.
The safe pattern recommended by GitHub's security hardening guide is to pass event data through env: variables, which the shell treats as data rather than code:
- name: Build Slack message
id: message
env:
TAG: ${{ github.event.release.tag_name }}
RELEASE_NAME: ${{ github.event.release.name }}
URL: ${{ github.event.release.html_url }}
run: |
NAME=$(echo "$RELEASE_NAME" | jq -Rs '.')
echo "text=🚀 *Visitran ${TAG}* released! ${RELEASE_NAME} <${URL}|View Release Notes>" >> "$GITHUB_OUTPUT"This ensures no user-controlled string is ever interpolated directly into the shell command.
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/release-notification.yml
Line: 15-17
Comment:
**Script injection via direct `${{ }}` interpolation in `run:` block**
`github.event.release.tag_name` (line 15) and `github.event.release.html_url` (line 17) are interpolated directly via `${{ }}` expressions inside a `run:` shell script. This is a known script-injection vector: if a tag name contains shell metacharacters (e.g. a backtick, `$(...)`, or a newline followed by fabricated `GITHUB_OUTPUT` content), the injected content will be executed as shell commands.
The safe pattern recommended by GitHub's security hardening guide is to pass event data through `env:` variables, which the shell treats as data rather than code:
```yaml
- name: Build Slack message
id: message
env:
TAG: ${{ github.event.release.tag_name }}
RELEASE_NAME: ${{ github.event.release.name }}
URL: ${{ github.event.release.html_url }}
run: |
NAME=$(echo "$RELEASE_NAME" | jq -Rs '.')
echo "text=🚀 *Visitran ${TAG}* released! ${RELEASE_NAME} <${URL}|View Release Notes>" >> "$GITHUB_OUTPUT"
```
This ensures no user-controlled string is ever interpolated directly into the shell command.
How can I resolve this? If you propose a fix, please make it concise.
What
Why
How
Stale bot (
.github/workflows/stale.yml):stalelabelRelease notification (
.github/workflows/release-notification.yml):SLACK_WEBHOOK_URLsecret (skips gracefully if not configured)Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)
Database Migrations
Env Config
SLACK_WEBHOOK_URL— needs to be added as repo secret for release notifications (optional, workflow skips if not set)Notes on Testing
Checklist
I have read and understood the Contribution Guidelines.