Skip to content

Add starter centralized workflows (poutine + reusable PR review)#5

Merged
Mehdi-Bl merged 2 commits intomainfrom
feat/reusable-workflow-starters
Feb 15, 2026
Merged

Add starter centralized workflows (poutine + reusable PR review)#5
Mehdi-Bl merged 2 commits intomainfrom
feat/reusable-workflow-starters

Conversation

@Mehdi-Bl
Copy link
Copy Markdown
Contributor

@Mehdi-Bl Mehdi-Bl commented Feb 14, 2026

Summary

  • add required workflow: (ruleset-compatible)
  • add reusable Claude manual PR review workflow:
  • add reusable OpenCode manual PR review workflow:
  • document new workflows in

Why

  • start centralizing shared workflows in
  • keep one OpenCode workflow that supports both single model and multi-model matrix (via + inputs)
  • enable Terraform org ruleset path to resolve to an existing workflow

Notes

  • OpenCode matrix workflow supports single model runs by leaving empty and setting
  • no app-repo wrappers changed in this PR; this is the central foundation step

Summary by Sourcery

Introduce centralized required and reusable workflows for security scanning and manual AI-assisted PR reviews across repositories.

New Features:

  • Add a required poutine workflow that runs Boost Security poutine scans and uploads SARIF results to GitHub code scanning for pull requests and merge groups.
  • Add a reusable Claude-based manual PR review workflow that fetches credentials from Azure Key Vault and posts a structured consolidated review comment on a target PR.
  • Add a reusable OpenCode-based manual PR review workflow that supports both single-model and multi-model matrix reviews with Azure Key Vault–backed API key retrieval and size-based auto-skip thresholds.

Documentation:

  • Document the new required poutine workflow and reusable Claude/OpenCode manual review workflows in the repository README, including capabilities and model configuration options.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Feb 14, 2026

Reviewer's Guide

Adds 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 workflow

sequenceDiagram
  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)
Loading

Sequence diagram for reusable Claude manual PR review workflow

sequenceDiagram
  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)
Loading

Flow diagram for OpenCode model matrix preparation

flowchart 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)"]
Loading

File-Level Changes

Change Details Files
Introduce a required poutine security scan workflow suitable for GitHub org rulesets and code scanning ingestion.
  • Define a required workflow that can be triggered by pull_request, merge_group, or workflow_call.
  • Run boostsecurityio/poutine-action to generate SARIF output and normalize it for GitHub.
  • Upload SARIF results to GitHub code scanning (with fork-safety guard) and as a build artifact.
.github/workflows/required-poutine.yml
README.md
Add a reusable Claude-based manual PR review workflow that gates execution, fetches credentials via Azure OIDC + Key Vault, and runs anthropics/claude-code-action with a strict review prompt.
  • Expose workflow_call inputs for PR number, force_review toggle, dispatcher allowlist, Azure identity parameters, Key Vault secret name, and PR size thresholds.
  • Enforce default-branch-only dispatch and actor allowlist before doing any privileged work.
  • Authenticate to Azure via OIDC, retrieve a Claude OAuth token from Key Vault, and mask it for downstream use.
  • Resolve PR metadata via gh api, compute simple size metrics, and skip tiny PRs unless force_review is set.
  • Check out the PR head SHA and invoke anthropics/claude-code-action with a structured review prompt and non-blocking failure handling.
.github/workflows/reusable-claude-review.yml
README.md
Add a reusable OpenCode-based manual PR review workflow supporting both single-model and matrix runs with Azure-backed secret management.
  • Expose workflow_call inputs for PR number, force_review, model/models selection, max_parallel, dispatcher allowlist, Azure identity parameters, Key Vault/secret names, and PR size thresholds.
  • Implement a prepare-model-matrix job that normalizes a comma/newline-separated model list into a unique JSON matrix and emits a summary.
  • Gate the review job on default-branch dispatch and an actor allowlist, then use Azure OIDC and Key Vault to fetch the ZHIPU API key.
  • Resolve PR metadata via gh api, compute change-size metrics, and short-circuit tiny PRs unless force_review is enabled.
  • For eligible PRs, check out the head SHA, synthesize a mock issue_comment event for manual invocation, run anomalyco/opencode/github with a detailed prompt per model in the matrix, and emit a non-blocking warning if the review step fails.
.github/workflows/reusable-opencode-review.yml
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-advanced-security
Copy link
Copy Markdown

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.

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

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

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +30 to +33
- 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
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

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

@Mehdi-Bl Mehdi-Bl merged commit 55070d1 into main Feb 15, 2026
6 checks passed
@Mehdi-Bl Mehdi-Bl deleted the feat/reusable-workflow-starters branch February 15, 2026 00:52
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