-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor Bug Conductor workflow for better automation #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,71 +1,224 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Bug Conductor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Triggered when an issue is labeled "bug". | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Mentions @copilot to trigger the coding agent to investigate and fix the bug. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Bug Conductor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Bug Conductor (Autonomous) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| issues: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| types: [labeled] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| types: [opened] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| issue_comment: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| types: [created] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull_request: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| types: [opened, closed] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| issues: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| issues: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DEFAULT_BRANCH: main | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| REPO_URL: https://github.com/thevalleydev/uncommitted | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| conductor: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: github.event.label.name == 'bug' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| create-shadow-pr: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: github.event_name == 'issues' && github.event.action == 'opened' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: github.event_name == 'issues' && github.event.action == 'opened' | |
| if: github.event_name == 'issues' && github.event.action == 'opened' && contains(github.event.issue.labels.*.name, 'bug') |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR body heredoc directly interpolates ${{ github.event.issue.title }} and ${{ github.event.issue.body }} into a shell run: step. Issue content is user-controlled; this can break the script or enable shell injection if it contains quotes, $(), backticks, or EOF markers. Pass these values via env: and use a quoted heredoc (<<'EOF') / --body-file to prevent evaluation.
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assumes the PR labels copilot-shadow and agent-analyzing already exist. GitHub API/CLI calls will fail if the labels are missing (common in forks/new repos). Consider creating labels if absent or using a fallback behavior.
| PR_NUMBER=$(gh pr create \ | |
| --draft \ | |
| --title "agent/issue-${ISSUE}-analysis" \ | |
| --body "$BODY" \ | |
| --base "${DEFAULT_BRANCH}" \ | |
| --head "$BRANCH" \ | |
| --label "copilot-shadow" \ | |
| --label "agent-analyzing" \ | |
| LABEL_ARGS="" | |
| # Ensure labels exist, then build LABEL_ARGS safely. | |
| if gh label list --limit 1000 | grep -q "^copilot-shadow\b"; then | |
| LABEL_ARGS="$LABEL_ARGS --label copilot-shadow" | |
| else | |
| if gh label create "copilot-shadow" --color "5319e7" --description "Shadow PR for Copilot analysis"; then | |
| LABEL_ARGS="$LABEL_ARGS --label copilot-shadow" | |
| fi | |
| fi | |
| if gh label list --limit 1000 | grep -q "^agent-analyzing\b"; then | |
| LABEL_ARGS="$LABEL_ARGS --label agent-analyzing" | |
| else | |
| if gh label create "agent-analyzing" --color "0e8a16" --description "PR currently under Copilot analysis"; then | |
| LABEL_ARGS="$LABEL_ARGS --label agent-analyzing" | |
| fi | |
| fi | |
| PR_NUMBER=$(gh pr create \ | |
| --draft \ | |
| --title "agent/issue-${ISSUE}-analysis" \ | |
| --body "$BODY" \ | |
| --base "${DEFAULT_BRANCH}" \ | |
| --head "$BRANCH" \ | |
| $LABEL_ARGS \ |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gh pr create is invoked with --json/--jq flags here. Those flags are not consistently supported for gh pr create across GH CLI versions and will likely fail at runtime. Prefer capturing the PR URL output and resolving the number via gh pr view, or use gh api to create the PR and parse the response JSON.
| PR_NUMBER=$(gh pr create \ | |
| --draft \ | |
| --title "agent/issue-${ISSUE}-analysis" \ | |
| --body "$BODY" \ | |
| --base "${DEFAULT_BRANCH}" \ | |
| --head "$BRANCH" \ | |
| --label "copilot-shadow" \ | |
| --label "agent-analyzing" \ | |
| --json number --jq '.number') | |
| gh pr create \ | |
| --draft \ | |
| --title "agent/issue-${ISSUE}-analysis" \ | |
| --body "$BODY" \ | |
| --base "${DEFAULT_BRANCH}" \ | |
| --head "$BRANCH" \ | |
| --label "copilot-shadow" \ | |
| --label "agent-analyzing" | |
| PR_NUMBER=$(gh pr view "$BRANCH" --json number --jq '.number') |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This step adds triage and agent-analyzing labels via gh issue edit. If those labels don’t already exist, the command will fail and stop the workflow (and they aren’t defined in-repo like bug/article). Consider ensuring labels exist (create if missing) or making labeling best-effort.
| gh issue edit "$ISSUE" --add-label "triage" --add-label "agent-analyzing" | |
| gh issue edit "$ISSUE" --add-label "triage" --add-label "agent-analyzing" || echo "Labeling failed, continuing without labels." |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue number extraction likely won’t work: the PR body uses **Source Issue:** #<n> but the sed pattern looks for Source Issue: #<n> (no **). This will produce an empty issue number and break mirroring; adjust the regex to tolerate the markdown or store the source issue in a more machine-readable way (e.g., PR label, branch name, or PR metadata).
| ISSUE=$(gh pr view "$PR" --json body --jq '.body' | sed -n 's/.*Source Issue: #\([0-9]\+\).*/\1/p') | |
| ISSUE=$(gh pr view "$PR" --json body --jq '.body' | sed -n 's/.*\*\*Source Issue:\*\* #\([0-9]\+\).*/\1/p') |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AUTHOR and especially BODY are populated by directly interpolating ${{ github.event.comment.* }} into a shell script. PR comments are user-controlled input and can inject shell syntax (quotes, $(), backticks), leading to command execution on the runner. Pass these values through env: (or read from $GITHUB_EVENT_PATH) and avoid direct expression interpolation inside run:.
| run: | | |
| ISSUE=${{ steps.issue.outputs.issue }} | |
| AUTHOR="${{ github.event.comment.user.login }}" | |
| BODY="${{ github.event.comment.body }}" | |
| AUTHOR: ${{ github.event.comment.user.login }} | |
| BODY: ${{ github.event.comment.body }} | |
| run: | | |
| ISSUE=${{ steps.issue.outputs.issue }} |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This job runs on every PR opened event and will label all PRs as agent-fix, including unrelated PRs and the shadow PR created by this workflow. Add additional gating (e.g., head branch starts with agent/, exclude copilot-shadow, or require a specific author/label) before applying the label.
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This attempts to close issues referenced by Closes #... on every merged PR. GitHub often auto-closes these already, so gh issue close can become non-idempotent and fail when the issue is already closed. Consider checking issue state first (or tolerating "already closed"), and/or scoping this behavior to PRs managed by the bug conductor only.
| gh issue close "$I" --comment "Closed automatically because PR #${PR} was merged." | |
| STATE=$(gh issue view "$I" --json state -q '.state' || echo "") | |
| if [ "$STATE" = "OPEN" ]; then | |
| gh issue close "$I" --comment "Closed automatically because PR #${PR} was merged." | |
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This workflow hard-codes
DEFAULT_BRANCHandREPO_URL. That will break links/PR bases when running in forks or if the default branch changes; prefer${{ github.event.repository.default_branch }}and${{ github.server_url }}/${{ github.repository }}.