Environment customization for headless mode (Copilot coding agent)
- Dominant language
- JavaScript
- Stars
- 269
- Forks
- 45
- Avg merge
- 18h 41m
- Merged PRs (30d)
- 11
Description
## Context
Git-Ape runs in two modes: **Interactive** (VS Code / Copilot Chat, backed by `.devcontainer/devcontainer.json`) and **Headless** (Copilot coding agent / GitHub Actions). Today the `.devcontainer/` tree has a full toolchain (Azure CLI, PowerShell, Checkov, PSRule, ARM-TTK, Azure MCP VS Code extension, etc.), but the **headless coding-agent environment has no equivalent customization file**. When the coding agent picks up an issue, it boots a vanilla Ubuntu runner with no Azure tooling, no MCP server, and default egress firewall rules.
Per [`.github/agents/git-ape.agent.md`](https://github.com/Azure/git-ape/blob/main/.github/agents/git-ape.agent.md) the agent is expected to:
- detect headless mode via `GITHUB_ACTIONS` / `CI`
- authenticate via OIDC (`azure/login`)
- run `az` commands (MCP tools are noted as "NOT available" — we should change that)
- generate & commit ARM templates / what-if
None of that works without a customized environment.
## Goal
Add a `.github/workflows/copilot-setup-steps.yml` (Copilot coding agent pre-run hook) plus a firewall allow-list so the coding agent has parity with the devcontainer.
## Proposed changes
### 1. `copilot-setup-steps.yml` — install the toolchain
Mirror what `.devcontainer/post-create.sh` installs today, so headless runs have the same validators.
```yaml name=.github/workflows/copilot-setup-steps.yml
name: "Copilot Setup Steps"
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
copilot-setup-steps:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # required for OIDC later in the agent's session
steps:
- uses: actions/checkout@v4
- name: Install Azure CLI + Bicep
run: |
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az bicep install
az bicep version
- name: Setup PowerShell + Azure PSRule + ARM-TTK
shell: bash
run: |
sudo apt-get update && sudo apt-get install -y powershell
pwsh -Command "Install-Module -Name PSRule.Rules.Azure -Scope CurrentUser -Force"
git clone --depth 1 https://github.com/Azure/arm-ttk.git "$HOME/.arm-ttk"
mkdir -p "$HOME/.config/powershell"
echo 'Import-Module $HOME/.arm-ttk/arm-ttk/arm-ttk.psd1' \
>> "$HOME/.config/powershell/Microsoft.PowerShell_profile.ps1"
- name: Setup Python 3.12 + Checkov
uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install --user checkov
- name: Setup Node.js 20
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install Azure MCP server (headless)
run: |
npm install -g @azure/mcp@latest
azmcp --version
- name: Verify tools
run: |
az version
checkov --version
pwsh -Command "Get-Module PSRule.Rules.Azure -ListAvailable"
```
### 2. Firewall / egress allow-list
GitHub-hosted runners used by the Copilot coding agent support an [allow-list of outbound domains](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/customize-the-agent-environment#customizing-or-disabling-the-firewall). Add the following (either via the repo's Copilot coding agent settings UI or a committed config) so Azure docs, ARM schemas, and MCP resource lookups succeed:
```text name=.github/copilot/firewall-allowlist.txt
# Microsoft / Azure docs & learn
*.microsoft.com
*.learn.microsoft.com
learn.microsoft.com
docs.microsoft.com
# Azure management & identity planes
management.azure.com
login.microsoftonline.com
graph.microsoft.com
*.azure.com
# ARM template schemas & samples
schema.management.azure.com
raw.githubusercontent.com
github.com
# Azure CLI / Bicep / PSRule installers & telemetry
aka.ms
azcliextensionsync.blob.core.windows.net
azclijlts.blob.core.windows.net
biceptypes.blob.core.windows.net
*.blob.core.windows.net
# Azure MCP server
*.mcp.azure.com
mcp.azure.com
# Package registries (already in GitHub default allow-list, listed for clarity)
registry.npmjs.org
pypi.org
files.pythonhosted.org
ghcr.io
```
> Note: evaluate trimming `*.blob.core.windows.net` to the specific subdomains actually used, since it's broad.
### 3. Azure MCP server — make it available in headless mode
Today `azure-resource-deployer.agent.md` says *"MCP tools are NOT available — use Azure CLI commands exclusively"* in headless mode. With `@azure/mcp` installed in step 1 + OIDC login, MCP can be started as a sidecar. Proposed config:
```json name=.github/copilot/mcp-config.json
{
"servers": {
"azure": {
"command": "azmcp",
"args": ["server", "start", "--mode", "namespace", "--read-only", "false"],
"env": {
"AZURE_MCP_COLLECT_TELEMETRY": "false"
}
}
}
}
```
Then update the agent docs (`.github/agents/git-ape.agent.md`, `azure-resource-deployer.agent.md`, `azure-requirements-gatherer.agent.md`) to remove the "MCP tools are NOT available in headless mode" caveat.
### 4. Anything else worth adding?
- [ ] **`jq`, `yq`** — used across scripts like [`.github/skills/azure-drift-detector/`](https://github.com/Azure/git-ape/blob/main/.github/skills/azure-drift-detector/SKILL.md) (parses JSON state files).
- [ ] **`sqlcmd`** — used by [`.github/skills/azure-integration-tester/scripts/test-database.sh`](https://github.com/Azure/git-ape/blob/main/.github/skills/azure-integration-tester/scripts/test-database.sh).
- [ ] **`mermaid-cli` (`@mermaid-js/mermaid-cli`)** — for architecture diagram rendering in the template generator.
- [ ] **`gh` CLI** — for PR comments & workflow dispatch from the agent.
- [ ] **Env vars the agent expects**: `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_SUBSCRIPTION_ID` (consumed by `azure/login@v2` in the example workflows).
- [ ] **Default region / environment defaults** for headless runs when the issue body is missing them (currently hardcoded to `East US` / `dev` in the requirements gatherer — surface as repo variables: `GIT_APE_DEFAULT_REGION`, `GIT_APE_DEFAULT_ENV`).
- [ ] **Caching**: cache `~/.azure`, PowerShell modules, and pip to speed up each agent session.
## Acceptance criteria
- [ ] `.github/workflows/copilot-setup-steps.yml` exists and is invoked by the Copilot coding agent before it starts work.
- [ ] Firewall allow-list applied (via repo Copilot settings) covering Microsoft/Azure domains.
- [ ] Azure MCP server runs successfully in a headless coding-agent session (verified by a test issue that asks the agent to run `az account show` + an MCP resource lookup).
- [ ] Agent docs updated to reflect MCP availability in headless mode.
- [ ] `docs/CODESPACES.md` gains a sibling doc `docs/HEADLESS-ENV.md` describing the coding-agent environment and how to customize it.
## References
- [`.devcontainer/devcontainer.json`](https://github.com/Azure/git-ape/blob/main/.devcontainer/devcontainer.json)
- [`.devcontainer/post-create.sh`](https://github.com/Azure/git-ape/blob/main/.devcontainer/post-create.sh)
- [`.github/agents/git-ape.agent.md`](https://github.com/Azure/git-ape/blob/main/.github/agents/git-ape.agent.md)
- [`.github/agents/azure-resource-deployer.agent.md`](https://github.com/Azure/git-ape/blob/main/.github/agents/azure-resource-deployer.agent.md)
- GitHub docs: [Customize the Copilot coding agent environment](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/customize-the-agent-environment)
Contributor guide
Assessment
This issue has not been assessed yet.