GitHub Issues + Projects ↔ Copilot Coding Agent: End-to-End Automation
Status: background, not as-built. The repo adopted a provider-agnostic implementation that runs the coding agent via GitHub Agentic Workflows (This document describes an automation that turns a GitHub Issue into a deployed dev build with minimal human steps, entirely inside GitHub (no external tracker, no external orchestrator). The implementer is GitHub Copilot Coding Agent; the orchestrator is GitHub Actions; the human-facing “buttons” are issue labels, GitHub Project status columns, and slash commands in issue/PR comments. The visual board is a GitHub Project (v2) attached to the repo. The design satisfies four constraints:gh-aw) on the repository’s own API key, not the GitHub Copilot Coding Agent, so any maintainer with write access can drive it without a Copilot seat (see ADR-0002). The canonical, as-built description is ai-pathway.md; where the two differ, that document wins. Notable deviations from the design below: theai:improve-writingbutton was dropped; “assign toCopilot” became “addpath:ai-automation→ agent posts a plan →/approve-plan”; the@copilotiteration loop became the/cocoslash command (gh-aw has no@mentiontrigger); and notifications are GitHub @-mentions rather than email. This document is retained for the design rationale and the broader landscape (§10).
- Every step of the lifecycle is recorded as a comment on a single GitHub issue and as a status change on the Project board; together they are the audit log.
- All AI instructions (system prompts, persistent agent rules, per-flow prompts) live in this repository, version-controlled and reviewable in PRs.
- The reviewer can talk back to Copilot by
@copilot-mentioning it on the PR. Copilot replies, pushes new commits, and CI re-runs. No custom backend is needed for the iteration loop; GitHub provides it natively. - The existing CI pipeline (semver tags →
dev-vX.Y.Z→ dev environment) is kept as-is. The automation only triggers it; it does not replace it.
1. High-level flow
Every transition writes a comment back to the originating issue and updates the issue’s row on the Project board.2. Why this shape
- Copilot Coding Agent is the implementer. When an issue is assigned to Copilot, it provisions a sandboxed VM, clones the repo, reads the agent instructions, opens a draft PR, and iterates until tests pass. The feedback loop is built in: a comment that mentions
@copiloton the PR is treated as a new instruction, and Copilot preserves PR history as context. That loop does not need to be built separately. - GitHub Actions is the orchestrator, not a separate backend service. Each “button” is either an
issues: labeledworkflow, anissue_commentworkflow, or (rarely) aprojects_v2_itemworkflow. Secrets live in GitHub Secrets; there is no extra host to operate and no cross-system token. - All prompts live in the repo (
.github/prompts/,AGENTS.md,.github/instructions/). They are reviewed in PRs and rollback isgit revert. - The Project (v2) is the visual board. It is GitHub-native, supports custom fields and saved views, and has built-in automations for the obvious transitions (issue closed → Done, PR merged → Done). For more nuanced transitions, an Action calls the GraphQL
updateProjectV2ItemFieldValuemutation. - The existing CI tag-based deploy is the deploy mechanism.
promote-dev.ymlonly creates the tag;ci.ymldoes the rest.
Native Copilot integration. This document assumes a GitHub Copilot plan that grants the Copilot Coding Agent. Assigning an issue to the Copilot user is the only trigger Copilot needs to start work (no app install, no webhook setup). The trigger is already in GitHub.
3. Repository + Project layout
Everything the automation needs is in.github/ and a single GitHub Project attached to the repo (or to the org):
What goes where, conceptually
The.prompt.mdand.agent.mdfilename conventions are reserved for IDE/CLI chat; they are not used here. This repo uses plain.mdfiles invoked by workflows, which gives full control over the body.
4. The seven manual triggers
Every trigger is a native GitHub gesture:
Triggers 1 and 3 use labels as buttons: adding the label is the user’s action, and the workflow’s first step is to remove the label so it can be re-added later. Triggers 4 and 7 use slash/mention commands in PR comments, which read naturally in the review thread. Trigger 2 uses the native assign field, which is the single trigger the Copilot Coding Agent listens for.
Trigger 7 deliberately bypasses the orchestration: Copilot’s own iteration loop is the simplest, most reliable way to apply a reviewer’s instruction with full history.
5. Step-by-step setup
Step 5.1: Decide on the Project shape
Create a GitHub Project (v2), either at the org or user level, and attach it to this repo. Add these custom fields:- Status (single-select, built-in):
Backlog,Ready for AI,In Progress,Review,On Dev,Approved,Done. - AI Status (single-select, optional):
Idle,Improving,Implementing,Reviewing,On Dev. Useful for a concurrent field separating human progress from AI progress on the same row. - Reviewer (User picker): drives email notifications.
- Dev URL (URL).
- PR URL (URL): also auto-filled when an issue is linked to a PR via “Development” sidebar.
- Sprint / Iteration (Iteration field, optional).
- Triage: filter
Status = Backlog. Where humans land new issues. - AI queue: filter
Status in (Ready for AI, In Progress). Where Copilot’s work is watched. - Review on dev: filter
Status = On Dev. Reviewer’s queue. - Released: filter
Status = Done, group by iteration.
- Item added to project → set
Status = Backlog. - Pull request merged → set
Status = Done. - Issue closed → set
Status = Done. - Code changes requested on PR → set
Status = In Progress.
project-status-sync.yml (§5.11) using the GraphQL API.
There is no need to model every status as a hard state machine; most transitions are advisory and the workflows reconcile them.
Step 5.2: Configure repository permissions for Actions
Because every trigger fires from inside GitHub, the workflows can use the defaultGITHUB_TOKEN. It just needs enough scope granted.
In Settings → Actions → General → Workflow permissions:
- Choose Read and write permissions.
- Allow GitHub Actions to create and approve pull requests.
GITHUB_TOKEN cannot write to org-owned projects. If the Project is org-owned, create a fine-grained PAT for a service account with Projects: read & write on the relevant org, store it as the repo secret PROJECTS_TOKEN, and reference it from project-status-sync.yml. If the Project is user-owned and attached to this repo only, GITHUB_TOKEN is sufficient.
Step 5.3: Add LLM + notification secrets
The only secrets required are:OPENAI_API_KEY(orANTHROPIC_API_KEY): for the LLM calls in workflows.SENDGRID_API_KEY(orSMTP_*): for notification emails.PROJECTS_TOKEN: only if the Project is org-owned (§5.2).
Step 5.4: Write the persistent agent instructions
CreateAGENTS.md at .github/AGENTS.md. This is the file Copilot reads on every implementation run. Keep it short and load-bearing.
Step 5.5: Write the one-shot prompts
Each file in.github/prompts/ is a Markdown template with placeholders the workflow substitutes at runtime. Example improve-issue.md.
review-pr.md (review prompt fed the PR diff) and any other one-shot LLM operation as needed.
Step 5.6: Workflow: improve issue writing (label-triggered)
.github/workflows/improve-issue.yml:
.github/scripts/improve_issue.py reads .github/prompts/improve-issue.md, substitutes placeholders, calls the LLM, and runs gh issue edit "$ISSUE_NUMBER" --body-file <(...). It also posts a comment with the diff against the previous body so the audit log is preserved.
Why a label and not a slash command? A label is visible in the issue sidebar, can be added from mobile, and is reflected on the Project board as a filterable property. Slash commands are great for PRs but slightly hidden on issues.
Step 5.7: Hand the issue to Copilot
There are two equally good UX choices; either can be picked, or both supported. Option A: Direct assignment (recommended). The human opens the issue and sets the Assignees field toCopilot. That is the only trigger the Copilot Coding Agent needs. No workflow required.
Option B: Status-driven. The human drags the row on the Project board to Status = Ready for AI. A workflow (assign-to-copilot.yml) listens to projects_v2_item events, sees the status change, and runs gh issue edit --add-assignee Copilot. This is the nicer board-driven UX but costs an extra workflow.
.github/workflows/assign-to-copilot.yml (Option B):
gh issue edit "$NUMBER" --add-assignee Copilot. When the issue is assigned to Copilot, Copilot spins up a sandboxed environment, reads AGENTS.md, opens a draft PR on copilot/issue-<n>, and begins committing. No workflow is needed for that step; the assignment is the trigger.
Step 5.8: Workflow: AI review after CI passes
.github/workflows/ai-review-pr.yml runs when CI completes successfully on a PR (or when the ai:review label is added for an on-demand re-review):
Step 5.9: Workflow: /promote dev comment → dev tag
.github/workflows/promote-dev.yml:
ci.yml already deploys on dev-vX.Y.Z tags, that is the entire dev-promotion step.
Permission gate. Theauthor_associationcheck restricts who can run/promote dev; otherwise anyone with read access could trigger a deploy. Tighten further with a team check viagh api /orgs/.../teams/.../membersto restrict the power to a specific team.
Step 5.10: Workflow: notify on approval
.github/workflows/notify-on-approve.yml listens for pull_request_review events of type approved and sends the email:
.github/automation/config.yml (mapped from the GitHub login of the author) or, better, from the Project’s Reviewer field via GraphQL; that way the recipient is whatever the human set on the row.
Step 5.11: Configure Project automations (the human side)
Most of the Project board’s behavior comes from its built-in workflows (set up in Step 5.1). The remaining transitions are handled by.github/workflows/project-status-sync.yml, which reacts to GitHub events and writes back to the Project via GraphQL:
Skeleton workflow:
PROJECT_ID, STATUS_FIELD_ID, and the option IDs are resolved once via the GraphQL Explorer (or gh api graphql -f query='…') and stored as repo variables. They do not rotate.
The script uses the updateProjectV2ItemFieldValue GraphQL mutation:
6. The Copilot loop in detail
Once the issue is assigned to Copilot:- Copilot creates branch
copilot/issue-<n>and opens a draft PR using.github/pull_request_template.md. - Copilot reads
AGENTS.md, then the relevant.github/instructions/*.instructions.mdfiles based on which paths it is about to touch. - Copilot iterates internally: write → run tests → diagnose → revise. Each iteration pushes a commit, which appears as a comment-like entry in the PR timeline.
ci.ymlruns on each push because of the existingpull_requesttrigger.- When the agent believes it is done, it marks the PR ready for review and posts a summary comment.
7. Optional: structured input via Issue Forms
A free-text issue body is fine, but issue forms (.github/ISSUE_TEMPLATE/*.yml) give Copilot cleaner context. Example feature_request.yml:
8. Things that are deliberately not in scope
- A FastAPI orchestrator. Adding one is justified if the project later needs cross-repo orchestration, long-running jobs >6h, or non-GitHub destinations (Slack threads, custom dashboards). Until then, Actions is enough.
- Auto-approval by AI.
ai-review-pr.ymlposts a comment, never an approval. The human gate is non-negotiable for merges todevelop. - Status as a hard state machine. The Project’s Status field is a convenience for humans, not a contract. Workflows do not block on it being in a particular state; they react to the underlying GitHub events.
- Mirroring to external systems. The whole point of this variant is that the issue + PR + Project board are the audit log. No mirror layer.
9. Open decisions to make
- Hand-off UX. Option A (assign to
Copilot) is simpler and works withoutprojects_v2_itempermissions. Option B (drag on the board) is nicer for teams that live on the board. Both can be supported; they are not exclusive. - Which LLM provider for the non-Copilot calls. OpenAI, Anthropic, or Google. Pick one and set it in
.github/automation/config.yml. - Tag-naming for dev promotions. The existing CI expects strict
dev-vX.Y.Z. Decide whether/promote devbumps PATCH automatically or whether the comment must include the version:/promote dev v1.2.3. - Permission policy for
/promote dev. Restrict toOWNER/MEMBER(default in the example), or to a specific GitHub team. - Project scope (user vs. org). Org-owned Projects support
projects_v2_itemevents but require thePROJECTS_TOKENPAT for writes. User-owned Projects skip the PAT but lose the event-driven status updates, falling back to polling or label-based triggers. - Issue forms vs. free-text. Strongly recommended to use forms; they make §5.6’s improve-issue workflow optional.
10. The broader GitHub AI automation landscape
The GitHub-only Issue → Copilot loop is one slice of what GitHub now ships. This section catalogues the rest so the doc gives a holistic picture, and notes which ones are worth turning on for this repo. Each item is tagged:- Turn on: clear ROI for this repo, low setup cost.
- Consider: useful but adds operational surface; pick when there’s a need.
- Watch: preview / early-stage; revisit later.
A. Native integrations worth enabling
A.1. GitHub Copilot code review (Turn on)
A built-in PR-review feature, distinct from this repo’s customai-review-pr.yml. Two modes:
- On-demand: request a review from
Copilotin the PR reviewers panel. - Automatic: configure Copilot to review every PR opened in selected repos (Repository → Rulesets → branch ruleset, or in user settings for personal Copilot Pro).
AGENTS.md rules. That’s what the custom ai-review-pr.yml prompt is for. Recommendation: run both. The native review is free with the Copilot plan; the custom review is where HAICO-specific constraints are encoded.
A.2. CodeQL + Copilot Autofix (Turn on)
CodeQL is GitHub’s static-analysis engine (free for public repos, included with GitHub Advanced Security on private). Copilot Autofix turns each CodeQL finding into a suggested patch that can be merged with one click. Together they cover the “security review” leg without a custom workflow. Setup: Settings → Code security → enable CodeQL analysis (default config) and Copilot Autofix for CodeQL. Findings appear in the Security tab and as PR review comments.A.3. Dependabot (already on)
This repo already has.github/dependabot.yml. The AI layer worth adding here is Dependabot’s grouped updates + Copilot Autofix for vulnerable dependencies, which can land a tested upgrade PR with no human-authored code.
A.4. Secret scanning + push protection (Turn on)
GitHub-native, free for public repos. Push protection blocks commits that contain known secret patterns before they reach the remote, an important guardrail when Copilot has write access to the branch.A.5. Project built-in workflows (Turn on)
Already used in §5.1. Worth flagging here as a reminder: the Item added, Auto-close issue, Auto-archive items, and Pull request merged automations cover ~60% of the Project transitions that would otherwise need scripting. Reach for the customproject-status-sync.yml only for the rest.
There is no issue-creation workflow in this design, because the issue is filed directly in GitHub.
B. New surface area for AI-driven workflows
B.1. Agentic Workflows (gh-aw) (Consider: technical preview)
Released as a technical preview in February 2026. A workflow is written as a Markdown file with natural-language instructions and a frontmatter declaring inputs / tools / triggers; the gh aw compile CLI emits a hardened *.lock.yml GitHub Actions workflow that runs an AI agent (Copilot, Claude, or Codex) in a sandboxed container.
Example use cases that fit this repo:
- Triage incoming issues: read the issue, apply labels (
needs-info,bug,enhancement), ask for missing reproduction info. Especially useful in the GitHub-only flow since there is no upstream layer to do triage. - Generate a changelog for each
dev-vX.Y.Ztag from the commit range. - Refresh documentation when files in
backend/app/api/change. - Project hygiene: sweep the Project board weekly, flag stale items, ask authors for status.
B.2. GitHub Copilot Spaces (Consider)
GA since 2025. A Space is a shareable container of repos + docs + free text + behavioural instructions that Copilot uses as grounding context. A Space is useful when knowledge sits outside the repo (e.g. a Notion export of architecture decisions, transcripts of design reviews, third-party API specs) and should be considered by Copilot in chat. For HAICO specifically: a “HAICO architecture” Space attached to this repo, with the project’s design/reference documents attached, would make Copilot answer architecture questions with paper-aware context, without adding those documents to the repo’s text-search index.B.3. MCP servers (Model Context Protocol) (Consider for advanced flows)
MCP lets an agent call external tools as if they were local functions. Copilot in VS Code, CLI, and the cloud agent can all consume MCP servers. Relevant catalog for a GitHub-only flow:
MCP servers are configured per-environment (e.g.
.vscode/mcp.json for the IDE; the Copilot Coding Agent has its own configuration UI). For this scope, the GitHub server covers ~90% of value because the rest of the world lives outside this stack anyway.
B.4. GitHub Spark (Watch)
GitHub’s prompt-to-app builder. Out of scope for an established repo; it’s better suited to generating new prototypes. Worth knowing about when sketching a sibling demo app.C. Things to enforce in the repo’s structure
Independent of any product, these are conventions that make every AI feature work better:AGENTS.mdat the repo root: already in the plan (§5.4). This is the single highest-leverage file that can be added..github/instructions/*.instructions.mdwithapplyTo:frontmatter for per-area rules (backend/frontend/deployment).- Issue forms (
.github/ISSUE_TEMPLATE/*.yml): see §7. The GitHub-only flow leans hard on these, because they serve as the structured input. - CODEOWNERS mapping paths to humans: Copilot uses this to choose reviewers when opening PRs, and the Project’s Reviewer field can default from this mapping.
- ADRs (Architecture Decision Records) under
docs/adr/: Copilot reads them as context for architecture-touching changes.
11. Sources
- Assigning and completing issues with coding agent in GitHub Copilot (GitHub Blog)
- About GitHub Copilot cloud agent (GitHub Docs)
- Adding repository custom instructions for GitHub Copilot (GitHub Docs)
- Copilot coding agent now supports AGENTS.md (GitHub Changelog)
- Ask @copilot to make changes to any pull request (GitHub Changelog)
- About Projects (GitHub Docs)
- Automating Projects using Actions (GitHub Docs)
- Using the API to manage Projects (GitHub Docs)
- Workflow events:
projects_v2_item(GitHub Docs) - Syntax for issue forms (GitHub Docs)
- About GitHub Copilot code review (GitHub Docs)
- Configuring automatic code review by Copilot (GitHub Docs)
- About GitHub Copilot Spaces (GitHub Docs)
- GitHub Agentic Workflows (Documentation)
- GitHub Agentic Workflows are now in technical preview (GitHub Changelog)
- github/gh-aw (repository)