Skip to content

Modify start-pull-request.yml to pass label values through env instead of inline interpolation - #97

Merged
VibratingKoala merged 4 commits into
mainfrom
i95-20260824-1740
Aug 28, 2026
Merged

VibratingKoala merged 4 commits into
mainfrom
i95-20260824-1740

Conversation

@github-actions

Copy link
Copy Markdown

1. Target

2. Specification / Test Plan

(Text here)

3. Additional Instructions / Notes for Shipping (optional)

N/A

4. Check before Review Request

  • Self Review : I reviewed changes by myself and approved them.
    • Ensure there is no sensitive information, typos, unrelated changes, or debugging code.
  • Evidence : I attached evidences to prove the changes.
    • Record and attach a demo video. For minor changes, attaching an image is also acceptable.
    • Evidences should be updated to the latest version when further changes are made.

5. Evidence

(Attach here before request review)

@github-actions github-actions Bot added modification A mirror label for the "Modification" issue type. 🔄 CI/CD Configuring GitHub Actions. 🔒 Security Fixing vulnerabilities or improving security. labels Aug 24, 2026
…ation

start-pull-request.yml interpolated ${{ env.LABELS }}, ${{ env.ASSIGNEES }},
${{ env.NEW_BRANCH_NAME }} and ${{ github.event.issue.number }} directly into
run: script text. GitHub Actions substitutes these as text before the shell
runs, so a value containing $() or backticks would execute on the runner in a
job holding contents/issues/pull-requests write + id-token write. Not
currently exploitable (every label/branch-name producer today is a hardcoded
literal or numeric), but the safety was external to this file rather than
built into it.

Switched every run: step to reference the already-exported $GITHUB_ENV shell
variables directly instead, matching the pattern the file already used at
:47-49/:66-68.

Fixes #95
/code-review on #97 caught that --base "${{ github.event.repository.default_branch }}"
was still spliced directly into run: script text — the same class the rest of
this file was just fixed for. Git ref-name rules don't forbid $, backticks or
parens in a branch name, so a renamed default branch could inject the same
way. Added DEFAULT_BRANCH to the job-level env block alongside ISSUE_NUM/
ISSUE_TITLE and switched --base to reference it as a shell variable.
@VibratingKoala VibratingKoala added the ci-testing Enable a GitHub Action for unit testing on a pull request. label Aug 24, 2026
@VibratingKoala

Copy link
Copy Markdown
Contributor

Code review (high effort) on 8841740 — no findings against this change.

Verified each substitution is shell-equivalent to what it replaced: LABELS, ASSIGNEES and NEW_BRANCH_NAME are all written to $GITHUB_ENV in earlier steps so they're real process env vars where they're used, and DEFAULT_BRANCH is valid at job level (the issues webhook payload carries repository). The sink is genuinely closed — values expanded from a shell variable aren't re-scanned for $()/backticks. No ${{ }} remains inside any run: block. The other workflows (prepare-release.yml, release.yml, run-tests.yml) were checked for the same anti-pattern; none present.

Two pre-existing defects sit on lines this PR touches. Neither is introduced by it and both are out of scope for #95 — recording them here so they're not lost, to be filed separately rather than expanding this PR:

  1. --label "$LABELS" aborts PR creation for an unlabeled issue (:114). There's no config.yml in .github/ISSUE_TEMPLATE/, so blank issues are enabled and a zero-label issue is possible; gh then fails with could not add label: '' not found. Because git push (:109) already ran, this leaves an orphan timestamped branch with an empty commit and no PR — and re-assigning the issue creates a second orphan rather than recovering. ${LABELS:+--label "$LABELS"} would guard it.

  2. The idea/epic guard can fail open (:55). The step shell is the default bash -e {0} with no pipefail, and labels=$(gh api … | tr … | sed …) takes its exit status from sed — so if gh api errors (rate limit, transient 5xx) LABELS is silently empty, the guard takes the else branch, and a PR is created for an epic/idea issue: exactly what the step exists to block. Separately, grep -q "idea\|epic" is an unanchored substring match over the comma-joined list, so a future label like epic-candidate would falsely terminate a valid issue.

@sn0wm1ku sn0wm1ku left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Code review on 8841740 — approve, no blocking findings.

Independently re-verified the diff against the file at head:

  • Correctness of the substitution. Every ${{ }} removed from run: script text now reaches the shell as a real environment variable at its point of use: LABELS / ASSIGNEES / NEW_BRANCH_NAME / OPEN_LINKED_PR_LENGTH are written to $GITHUB_ENV by earlier steps, and REPO / ISSUE_NUM / ISSUE_TITLE / DEFAULT_BRANCH sit in the job-level env: block (with DEFAULT_BRANCH newly added there — github.event.repository.default_branch is available on the issues trigger). No ${{ }} remains inside any run: block in this workflow.
  • The sink is closed. A value expanded from a shell variable is not re-scanned for $()/backticks, so a metacharacter-bearing label name can no longer execute in a job holding contents/issues/pull-requests/id-token: write. This is the handbook's required shape — data must cross into an interpreter as data, not be concatenated into script text (application-security.md §3-9 "encode/parameterize at the sink", §3-10 command/template injection defences).
  • Scope is minimal and matches #95 exactly — the fix the issue proposed, nothing else (code-review.md §3-1: correct and minimal, KISS/YAGNI). CI (run-tests) is green on head.

The two pre-existing defects on touched lines (unlabeled issue aborts gh pr create after the push, leaving an orphan branch; the idea/epic guard failing open when gh api errors under default no-pipefail shell) are already recorded in the thread and are correctly kept out of this PR — they predate it and belong in their own issue.


🤖 auto-posted by sn0wm1ku/ghDuty · co-authored by Claude (claude-opus-4-8)

@VibratingKoala
VibratingKoala merged commit fe6a391 into main Aug 28, 2026
3 checks passed
@VibratingKoala
VibratingKoala deleted the i95-20260824-1740 branch August 28, 2026 03:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔄 CI/CD Configuring GitHub Actions. ci-testing Enable a GitHub Action for unit testing on a pull request. modification A mirror label for the "Modification" issue type. 🔒 Security Fixing vulnerabilities or improving security.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Modify start-pull-request.yml to pass label values through env instead of inline interpolation

3 participants