-
Notifications
You must be signed in to change notification settings - Fork 0
chore: sync workflow templates #317
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
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,238 @@ | ||||||||||||||||||||||||||||||||||||||
| name: Claude Code Review (Opt-in) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| 'on': | ||||||||||||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||||||||||||
| pr_number: | ||||||||||||||||||||||||||||||||||||||
| description: 'Pull request number to review' | ||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||
| pull_request: | ||||||||||||||||||||||||||||||||||||||
| types: [labeled, synchronize, reopened, ready_for_review] | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||
| resolve-target: | ||||||||||||||||||||||||||||||||||||||
| name: Resolve review target | ||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||
| pull-requests: read | ||||||||||||||||||||||||||||||||||||||
| outputs: | ||||||||||||||||||||||||||||||||||||||
| should_run: ${{ steps.resolve.outputs.should_run }} | ||||||||||||||||||||||||||||||||||||||
| pr_number: ${{ steps.resolve.outputs.pr_number }} | ||||||||||||||||||||||||||||||||||||||
| reason: ${{ steps.resolve.outputs.reason }} | ||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||
| - id: resolve | ||||||||||||||||||||||||||||||||||||||
| uses: actions/github-script@v8 | ||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||
| script: | | ||||||||||||||||||||||||||||||||||||||
| const eventName = context.eventName; | ||||||||||||||||||||||||||||||||||||||
| let shouldRun = "false"; | ||||||||||||||||||||||||||||||||||||||
| let prNumber = ""; | ||||||||||||||||||||||||||||||||||||||
| let reason = "not_opted_in"; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (eventName === "workflow_dispatch") { | ||||||||||||||||||||||||||||||||||||||
| const raw = `${core.getInput("pr_number") || ""}`.trim(); | ||||||||||||||||||||||||||||||||||||||
| if (!/^\d+$/.test(raw)) { | ||||||||||||||||||||||||||||||||||||||
| reason = "invalid_pr_number"; | ||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||
| const pull_number = Number(raw); | ||||||||||||||||||||||||||||||||||||||
| const { owner, repo } = context.repo; | ||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||
| const { data: pr } = await github.rest.pulls.get({ | ||||||||||||||||||||||||||||||||||||||
| owner, | ||||||||||||||||||||||||||||||||||||||
| repo, | ||||||||||||||||||||||||||||||||||||||
| pull_number, | ||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||
| prNumber = String(pull_number); | ||||||||||||||||||||||||||||||||||||||
| if (pr.state !== "open") { | ||||||||||||||||||||||||||||||||||||||
| reason = "pr_not_open"; | ||||||||||||||||||||||||||||||||||||||
| } else if (pr.draft) { | ||||||||||||||||||||||||||||||||||||||
| reason = "pr_is_draft"; | ||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||
| shouldRun = "true"; | ||||||||||||||||||||||||||||||||||||||
| reason = "manual_dispatch"; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||
| reason = "pr_not_found"; | ||||||||||||||||||||||||||||||||||||||
| core.warning(`Unable to load PR #${pull_number}: ${error.message}`); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| } else if (eventName === "pull_request") { | ||||||||||||||||||||||||||||||||||||||
| const pr = context.payload.pull_request; | ||||||||||||||||||||||||||||||||||||||
| prNumber = String(pr.number); | ||||||||||||||||||||||||||||||||||||||
| const labels = (pr.labels || []).map((label) => label.name); | ||||||||||||||||||||||||||||||||||||||
| if (labels.includes("claude-review")) { | ||||||||||||||||||||||||||||||||||||||
| shouldRun = "true"; | ||||||||||||||||||||||||||||||||||||||
| reason = "label_opt_in"; | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+67
to
+70
|
||||||||||||||||||||||||||||||||||||||
| const labels = (pr.labels || []).map((label) => label.name); | |
| if (labels.includes("claude-review")) { | |
| shouldRun = "true"; | |
| reason = "label_opt_in"; | |
| if (pr.draft) { | |
| reason = "pr_is_draft"; | |
| } else { | |
| const labels = (pr.labels || []).map((label) => label.name); | |
| if (labels.includes("claude-review")) { | |
| shouldRun = "true"; | |
| reason = "label_opt_in"; | |
| } |
Copilot
AI
Mar 3, 2026
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.
In the workflow-integrity guard, github.base_ref is empty for workflow_dispatch, so the step unconditionally sets workflow_unchanged=true and allows the secrets-gated jobs to run even when this workflow file was modified on the dispatched ref. This defeats the “workflow must match default branch to safely access secrets” intent for manual dispatch; consider comparing the file against the repository default branch for workflow_dispatch too (or failing closed unless github.ref_name is the default branch).
| echo "workflow_unchanged=true" >>"$GITHUB_OUTPUT" | |
| exit 0 | |
| echo "github.base_ref is empty; resolving repository default branch from origin/HEAD" | |
| # Ensure we have the remote HEAD reference so we can determine the default branch. | |
| git fetch --no-tags origin '+HEAD:refs/remotes/origin/HEAD' | |
| # Resolve default branch name (strip the leading "origin/"). | |
| default_remote_head="$(git symbolic-ref --short refs/remotes/origin/HEAD || true)" | |
| default_branch="${default_remote_head#origin/}" | |
| if [ -z "$default_branch" ]; then | |
| echo "Could not determine default branch; failing closed." | |
| echo "workflow_unchanged=false" >>"$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| base_ref="$default_branch" | |
| echo "Using default branch '${base_ref}' for workflow integrity check." |
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.
max_prsis declared as anumberinput, but the expression${{ inputs.max_prs || '10' }}returns a number when provided and a string when defaulting. If the called reusable workflow expects a consistent type (common when passing inputs across workflows), castinputs.max_prsto string as well (or keep the value numeric by using a numeric default).