Add starter centralized workflows (poutine + reusable PR review)#5
Add starter centralized workflows (poutine + reusable PR review)#5
Conversation
Reviewer's GuideAdds a new required poutine security scanning workflow and introduces two centralized reusable manual PR review workflows (Claude-based and OpenCode-based), including Azure OIDC + Key Vault secret retrieval and matrix/single-model support, with documentation updates. Sequence diagram for reusable OpenCode manual PR review workflowsequenceDiagram
actor Dispatcher
participant CallerWorkflow
participant OpenCodeWorkflow as reusable-opencode-review.yml
participant GitHubAPI as GitHub_API
participant AzureOIDC as Azure_OIDC
participant KeyVault
participant OpenCode as OpenCode_action
participant PR as Pull_Request
Dispatcher->>CallerWorkflow: workflow_dispatch with inputs
CallerWorkflow->>OpenCodeWorkflow: workflow_call(pr_number, model, models, ...)
OpenCodeWorkflow->>OpenCodeWorkflow: prepare-model-matrix job
OpenCodeWorkflow->>OpenCodeWorkflow: normalize models\n(single or comma/newline list)
OpenCodeWorkflow-->>OpenCodeWorkflow: models_json, model_count
OpenCodeWorkflow->>GitHubAPI: gh api pulls/{pr_number}
GitHubAPI-->>OpenCodeWorkflow: PR metadata\n(head_sha, size stats)
OpenCodeWorkflow->>OpenCodeWorkflow: check force_review and thresholds
OpenCodeWorkflow-->>Dispatcher: skip message when PR tiny
OpenCodeWorkflow->>AzureOIDC: azure/login with OIDC
AzureOIDC->>KeyVault: read ZHIPU API key
KeyVault-->>OpenCodeWorkflow: ZHIPU_API_KEY
OpenCodeWorkflow->>PR: checkout head_sha
loop for each matrix.model
OpenCodeWorkflow->>OpenCodeWorkflow: build mock event payload
OpenCodeWorkflow->>OpenCode: run anomalyco/opencode/github\n(model = matrix.model)
OpenCode-->>PR: single consolidated PR comment
end
OpenCodeWorkflow-->>Dispatcher: workflow completion\n(warnings are non-blocking)
Sequence diagram for reusable Claude manual PR review workflowsequenceDiagram
actor Dispatcher
participant CallerWorkflow
participant ClaudeWorkflow as reusable-claude-review.yml
participant GitHubAPI as GitHub_API
participant AzureOIDC as Azure_OIDC
participant KeyVault
participant ClaudeAction as Claude_code_action
participant PR as Pull_Request
Dispatcher->>CallerWorkflow: workflow_dispatch with inputs
CallerWorkflow->>ClaudeWorkflow: workflow_call(pr_number, ...)
ClaudeWorkflow->>ClaudeWorkflow: enforce default branch
ClaudeWorkflow->>ClaudeWorkflow: authorize dispatcher allowlist
ClaudeWorkflow->>AzureOIDC: azure/login with OIDC
AzureOIDC->>KeyVault: read Claude token
KeyVault-->>ClaudeWorkflow: claude_code_oauth_token
ClaudeWorkflow->>GitHubAPI: gh api pulls/{pr_number}
GitHubAPI-->>ClaudeWorkflow: PR metadata\n(head_sha, size stats)
ClaudeWorkflow->>ClaudeWorkflow: check force_review and thresholds
ClaudeWorkflow-->>Dispatcher: skip message when PR tiny
ClaudeWorkflow->>PR: checkout head_sha
ClaudeWorkflow->>ClaudeAction: anthropics/claude-code-action\nwith PR context and prompt
ClaudeAction-->>PR: single consolidated PR comment
ClaudeWorkflow-->>Dispatcher: workflow completion\n(warnings are non-blocking)
Flow diagram for OpenCode model matrix preparationflowchart TD
A["Start workflow_call\nwith model and models inputs"] --> B{models input empty?}
B -- Yes --> C["Use SINGLE_MODEL = model\n(default zai-coding-plan/glm-4.7)"]
B -- No --> D["Use MULTI_MODELS = models\n(comma or newline list)"]
C --> E["source_models = SINGLE_MODEL"]
D --> E
E --> F["Normalize list:\nreplace commas/semicolons with newlines\ntrim whitespace\ndeduplicate non-empty lines"]
F --> G{Any models left?}
G -- No --> H["Fail: no valid model entries"]
G -- Yes --> I["Build models_json = JSON array"]
I --> J["Compute model_count"]
J --> K["Expose models_json and model_count\nas prepare-model-matrix outputs"]
K --> L["Matrix strategy fan-out\nmodel in fromJSON(models_json)"]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation. |
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The Claude and OpenCode reusable review workflows duplicate the same allowlist, Azure login, PR metadata resolution, and size-threshold logic; consider extracting this shared logic into a composite action or a third reusable workflow job to keep behavior consistent and reduce maintenance overhead.
- In the
reusable-opencode-reviewworkflow, the model list parsing and matrix prep rely onjq,awk, andsedbeing available; if you ever move offubuntu-latest, it may be safer to make this dependency explicit (e.g., via a setup step or an action) to avoid subtle runtime failures.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The Claude and OpenCode reusable review workflows duplicate the same allowlist, Azure login, PR metadata resolution, and size-threshold logic; consider extracting this shared logic into a composite action or a third reusable workflow job to keep behavior consistent and reduce maintenance overhead.
- In the `reusable-opencode-review` workflow, the model list parsing and matrix prep rely on `jq`, `awk`, and `sed` being available; if you ever move off `ubuntu-latest`, it may be safer to make this dependency explicit (e.g., via a setup step or an action) to avoid subtle runtime failures.
## Individual Comments
### Comment 1
<location> `.github/workflows/required-poutine.yml:30-33` </location>
<code_context>
+ format: sarif
+ output: results.sarif
+
+ - name: Normalize poutine SARIF for GitHub upload
+ run: |
+ jq 'del(.runs[]?.tool.driver.supportedTaxonomies)' results.sarif > results.cleaned.sarif
+ mv results.cleaned.sarif results.sarif
+
+ - name: Upload poutine SARIF
</code_context>
<issue_to_address>
**suggestion:** Harden the SARIF normalization step against missing or invalid SARIF output to produce clearer failure signals.
If `results.sarif` is missing or malformed (e.g., `boostsecurityio/poutine-action` fails earlier), this step will fail with a generic `jq` or `mv: cannot stat 'results.cleaned.sarif'` error, which hides the real issue. Consider adding `set -euo pipefail` and an explicit `test -f results.sarif` with a clear error message before invoking `jq` so logs clearly show that the SARIF file was never produced.
```suggestion
- name: Normalize poutine SARIF for GitHub upload
run: |
set -euo pipefail
if [ ! -f results.sarif ]; then
echo "Error: results.sarif was not produced by boostsecurityio/poutine-action. Check the poutine scan step for failures or configuration issues." >&2
exit 1
fi
jq 'del(.runs[]?.tool.driver.supportedTaxonomies)' results.sarif > results.cleaned.sarif
mv results.cleaned.sarif results.sarif
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| - name: Normalize poutine SARIF for GitHub upload | ||
| run: | | ||
| jq 'del(.runs[]?.tool.driver.supportedTaxonomies)' results.sarif > results.cleaned.sarif | ||
| mv results.cleaned.sarif results.sarif |
There was a problem hiding this comment.
suggestion: Harden the SARIF normalization step against missing or invalid SARIF output to produce clearer failure signals.
If results.sarif is missing or malformed (e.g., boostsecurityio/poutine-action fails earlier), this step will fail with a generic jq or mv: cannot stat 'results.cleaned.sarif' error, which hides the real issue. Consider adding set -euo pipefail and an explicit test -f results.sarif with a clear error message before invoking jq so logs clearly show that the SARIF file was never produced.
| - name: Normalize poutine SARIF for GitHub upload | |
| run: | | |
| jq 'del(.runs[]?.tool.driver.supportedTaxonomies)' results.sarif > results.cleaned.sarif | |
| mv results.cleaned.sarif results.sarif | |
| - name: Normalize poutine SARIF for GitHub upload | |
| run: | | |
| set -euo pipefail | |
| if [ ! -f results.sarif ]; then | |
| echo "Error: results.sarif was not produced by boostsecurityio/poutine-action. Check the poutine scan step for failures or configuration issues." >&2 | |
| exit 1 | |
| fi | |
| jq 'del(.runs[]?.tool.driver.supportedTaxonomies)' results.sarif > results.cleaned.sarif | |
| mv results.cleaned.sarif results.sarif |
Summary
Why
Notes
Summary by Sourcery
Introduce centralized required and reusable workflows for security scanning and manual AI-assisted PR reviews across repositories.
New Features:
Documentation: