feat(ci): add Copilot full automation pipeline

- copilot-assign.yml: GraphQL agentAssignment
- ai-review.yml: Claude Opus auto-review
- auto-merge.yml: CI + APPROVE squash merge
- decompose.yml: Issue decomposition + sub-issues

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
林 駿甫 (Shunsuke Hayashi) 2026-03-29 21:48:22 +09:00
parent dfdd52ec1d
commit 2d500c3654
6 changed files with 836 additions and 0 deletions

78
.github/workflows/copilot-assign.yml vendored Normal file
View file

@ -0,0 +1,78 @@
name: Auto-assign Copilot Coding Agent
# copilot ラベルが付いた Issue に GitHub Copilot Coding Agent を GraphQL でアサインする。
# 正しい API: GraphQL replaceActorsForAssignable + agentAssignment フィールド
# (REST API の assignees や @github-copilot コメントは Coding Agent を起動しない)
on:
issues:
types: [labeled, opened]
jobs:
assign:
name: Assign Copilot Coding Agent
runs-on: ubuntu-latest
# copilot ラベルが付いている Issue のみ対象
if: contains(github.event.issue.labels.*.name, 'copilot')
permissions:
issues: write
steps:
- name: Check if Copilot already assigned
id: check
uses: actions/github-script@v7
with:
result-encoding: string
script: |
const timeline = await github.rest.issues.listEventsForTimeline({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100,
mediaType: { previews: ['mockingbird'] },
});
// "assigned" イベントで assignee.login === "Copilot" が存在すれば既に割り当て済み
const already = timeline.data.some(
e => e.event === 'assigned' && e.assignee?.login === 'Copilot'
);
return already ? 'yes' : 'no';
- name: Assign Copilot via GraphQL
if: steps.check.outputs.result == 'no'
uses: actions/github-script@v7
with:
# GITHUB_TOKEN で動作PAT 不要)
# 修正: agentAssignment.targetRepositoryId が必須。ないと silent fail する。
script: |
const issueNodeId = context.payload.issue.node_id;
// リポジトリの Node ID を取得agentAssignment に必須)
const repoData = await github.graphql(`
query GetRepoId($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) { id }
}
`, {
owner: context.repo.owner,
name: context.repo.repo,
});
const repoId = repoData.repository.id;
await github.graphql(`
mutation AssignCopilot($input: ReplaceActorsForAssignableInput!) {
replaceActorsForAssignable(input: $input) {
assignable {
... on Issue { number title }
}
}
}
`, {
input: {
assignableId: issueNodeId,
actorLogins: [],
agentAssignment: {
targetRepositoryId: repoId, // 必須: これがないと Copilot が起動しない
baseRef: 'master',
customInstructions: 'IMPORTANT: Every PR MUST contain at least one executable code file (.js .ts .py .sh .go .rs etc). Do NOT create PRs with only .md documentation files — that is not acceptable. Implement exactly what the Issue acceptance criteria require. Write tests for new functions. Keep the PR title concise and never include [WIP]. Make small focused commits. If the Issue is unclear, implement the minimal working version that satisfies the stated acceptance criteria.',
},
},
});
console.log(`✅ Copilot Coding Agent assigned to #${context.issue.number}`);