Skip to content

feat: add Linear repository_dispatch workflows for issue implementation and follow-up - #5

Merged
isuttell merged 7 commits into
mainfrom
feat/linear-repository-dispatch
Dec 15, 2025
Merged

isuttell merged 7 commits into
mainfrom
feat/linear-repository-dispatch

Conversation

@isuttell

Copy link
Copy Markdown
Contributor

Summary

Add two new reusable workflows that extend Linear integration capabilities via repository_dispatch triggers, enabling automated issue implementation and follow-up handling from Linear webhooks.

Changes

  • issue-implement.yml: New workflow triggered by linear-implement dispatch event to automatically implement Linear issues, create branches/PRs, and update ticket status
  • issue-followup.yml: New workflow triggered by linear-followup dispatch event to handle follow-up messages on existing Linear issues

Risk Assessment

LOW

Changed Areas

  • GitHub Actions workflows only (no application code)
  • Additive changes - no modifications to existing workflows

Security Considerations

  • Uses existing secret patterns (claude_code_oauth_token, linear_api_token)
  • No new secret types introduced
  • Follows same permission model as existing issue-triage.yml

Performance Impact

  • None - workflows only run on explicit repository_dispatch events

Breaking Changes

  • NO - purely additive, existing workflows unaffected

🤖 Generated with Claude Code

isuttell and others added 7 commits December 11, 2025 10:02
- Add repository_dispatch trigger with type `linear-triage`
- Fix format() function to properly inject client_payload fields
- Remove unused linear_team_prefix input
- Update prompt to focus on Linear issue triage workflow
- Update README with repository dispatch documentation
- Update CLAUDE.md with accurate workflow description

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add code-review job that runs after pre-commit checks pass on non-draft PRs.
Uses the code-review.yml reusable workflow with trigger_type: auto.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move format() arguments to separate lines for better YAML parsing reliability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The workflow runs in each repo that includes it, so it should always
checkout the current repository.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…mment

- Remove synchronize trigger (don't review on every push)
- Add issue_comment trigger for /review command
- Split into code-review-auto and code-review-manual jobs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add two new reusable workflows for Linear integration:

- issue-implement: Triggered via repository_dispatch (linear-implement)
  to implement Linear issues, create PRs, and update ticket status

- issue-followup: Triggered via repository_dispatch (linear-followup)
  to handle follow-up messages on Linear issues

Both workflows use Linear MCP for ticket management and support
custom prompts/allowed_tools via client_payload.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Dec 15, 2025

Copy link
Copy Markdown

Claude finished @isuttell's task in 1m 58s —— View job


Code Review

tldr; Solid implementation with good patterns, but found some issues: missing documentation updates, potential security concerns with unrestricted bash commands, inconsistent client_payload field naming, and the issue-followup workflow allows code changes without branch naming strategy.


🎯 Key Findings

Critical Issues:

  1. Overly permissive bash tools - Both new workflows allow Bash(npm:*) and Bash(bun:*) which could execute arbitrary package scripts. The implement workflow especially shouldn't need these for git/PR operations.

  2. Inconsistent payload field naming - issue-followup.yml uses different field names (issue_url, issue_title, user_prompt) vs the other workflows (url, title). This makes the webhook integration harder to implement consistently.

  3. Missing branch creation strategy in followup - The issue-followup workflow can make code changes but doesn't specify how to handle branch creation vs updating existing PRs. Line 90-101 suggests it should handle this, but there's no branch naming convention or conflict resolution strategy.

Documentation Gaps:

  • CLAUDE.md still only lists 3 workflows when there are now 5 total
  • README workflow table missing the two new workflows
  • No documentation on repository dispatch payloads for linear-implement and linear-followup

Code Quality Observations:

Good patterns:

  • Consistent structure across all workflows
  • Proper secret fallback patterns (secrets.linear_api_token || secrets.LINEAR_API_TOKEN)
  • Using format() for client_payload injection (though see naming issue above)
  • Sensible default prompts with clear numbered instructions

⚠️ Needs attention:

  • issue-implement.yml:67-70 - The allowed_tools fallback chain should match the input default on lines 10-12. Currently they're identical but easy to drift.
  • issue-followup.yml:118 - Field issue_url but triage uses url. Pick one naming convention.
  • issue-implement.yml:106 - Says 'Update the ticket status to "In Review"' but doesn't verify this status exists in the user's Linear workspace.

📋 Detailed Review

issue-implement.yml (.github/workflows/issue-implement.yml:1-112)

  • Lines 11-12, 69-70: Bash(npm:*) and Bash(bun:*) seem unnecessary for git operations. Implementation should only need git, gh pr, and maybe basic shell commands.
  • Line 106: Hard-codes "In Review" status which may not exist in all Linear workspaces.
  • Line 94: "Ensure the code compiles and tests pass" - but the allowed_tools don't include typical test runners. Either remove this instruction or expand allowed_tools.

issue-followup.yml (.github/workflows/issue-followup.yml:1-122)

  • Line 118-121: Inconsistent field names (issue_url vs url, issue_title vs title, adds new user_prompt field)
  • Lines 92-107: The branching logic in the prompt is complex but there's no enforcement of branch naming conventions
  • Line 100: "If there is an existing PR, update it" - but how does Claude find the existing PR? By Linear issue ID in the PR body? By branch name? This needs clarification.

issue-triage.yml (.github/workflows/issue-triage.yml:1-103)

  • Refactored well, consistent with new workflows
  • Lines 66-69: Same fallback pattern is good

ci.yml (.github/workflows/ci.yml:34-45)

  • The auto-review integration looks clean
  • Good conditional to skip draft PRs

Documentation Updates:

  • CLAUDE.md:10-15 - Still only documents 3 workflows, should be 5
  • README.md:9-13 - Workflow table needs issue-implement.yml and issue-followup.yml entries
  • README.md - Missing example repository_dispatch payloads for the two new workflows

🔒 Security Assessment

Secret Handling: ✅ Follows established patterns

  • Both workflows use the same secret fallback pattern as existing code
  • No secrets exposed in logs or outputs

Permissions: ⚠️ Could be more restrictive

  • Both workflows request contents: write which is necessary for branch creation
  • But they also get pull-requests: write and issues: write - these are broad. Consider if they're all needed.

Input Validation: ⚠️ Minimal

  • No validation that client_payload fields are present
  • If webhook sends malformed data, workflows will fail silently or with cryptic errors
  • The format() calls will fail if required fields are missing

🏃 Performance & CI

CI Status: ✅ Pre-commit checks passed

  • actionlint, prettier, and other checks clean
  • Auto code-review job currently running (this review)

Workflow Efficiency:

  • Both workflows are triggered via repository_dispatch, so no performance impact on PR operations
  • Reasonable default tool restrictions

🧪 Testing Considerations

Missing:

  • No test coverage for the new workflows (understandable for GitHub Actions)
  • No example webhook payloads in docs for users to test with
  • Would be helpful to have a testing guide for repository_dispatch events

📝 Recommendations

High Priority:

  1. Standardize client_payload field names across all three dispatch workflows:

    • Use url, issue_id, title consistently
    • Add prompt field for followup: user_promptprompt
  2. Remove unnecessary bash tools from issue-implement.yml:

    • Change lines 11-12 to: 'Read,Write,Edit,Grep,Glob,LS,Bash(git:*),Bash(gh pr:*),mcp__linear__*'
    • Remove npm/bun unless there's a specific need
  3. Document the new workflows:

    • Update CLAUDE.md to list all 5 workflows
    • Add table entries in README.md
    • Add repository_dispatch examples to README.md for both new workflows

Medium Priority:
4. Add branch naming strategy to issue-followup.yml prompt (around line 100)
5. Clarify PR discovery logic in followup workflow - how does it find existing PRs?
6. Make Linear status updates configurable instead of hard-coding "In Review"

Nice to Have:
7. Add webhook payload validation
8. Consider adding example webhook handler code
9. Document error cases (missing fields, wrong event types)


🎭 The Verdict

This is solid foundational work that extends the Linear integration in a logical way. The architecture is clean and follows existing patterns well. However, the inconsistent field naming and missing documentation will cause friction for users setting up webhooks. The bash tool permissions are overly broad, which isn't a security vulnerability per se, but violates least-privilege principles.

Ship it after addressing the field naming and documentation gaps. The other issues are nice-to-haves that can be iterated on.


@isuttell
isuttell merged commit ba7d013 into main Dec 15, 2025
3 checks passed
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