GitHub Agentic Workflows
GitHub Agentic Workflows (gh-aw) lets you write repository automation in markdown and run it as GitHub Actions using AI agents. APM and gh-aw have a native integration: gh-aw recognizes APM packages as first-class dependencies.
How They Work Together
Section titled “How They Work Together”| Tool | Role |
|---|---|
| APM | Manages the context your AI agents use – skills, instructions, prompts, agents |
| gh-aw | Manages the automation that triggers AI agents – event-driven workflows |
APM defines what agents know. gh-aw defines when and how they act.
Integration Approaches
Section titled “Integration Approaches”Shared apm.md Import (Recommended)
Section titled “Shared apm.md Import (Recommended)”gh-aw ships a shared apm.md workflow component that turns APM packages into gh-aw dependencies. Import it in your workflow’s frontmatter and pass the packages you want.
---on: pull_request: types: [opened]engine: copilot
imports: - uses: shared/apm.md with: target: copilot packages: - microsoft/apm-sample-package - github/awesome-copilot/skills/review-and-refactor - your-org/security-compliance#v1.4.0---
# Code Review
Review the pull request using the installed coding standards and skills.Package reference formats:
| Format | Description |
|---|---|
owner/repo |
Full APM package (skills/agents/instructions under .apm/) |
owner/repo/path/to/primitive |
Individual primitive (skill, instruction, plugin, etc.) from any repository, regardless of layout |
owner/repo#ref or owner/repo/path/to/primitive#ref |
Pinned to a tag, branch, or commit SHA, for either a full package or a specific primitive |
The per-primitive path form is what makes github/awesome-copilot/skills/review-and-refactor work – the awesome-copilot repo lays skills out at /skills/<name>/, not under .apm/. Use this form to consume skills from existing repositories without restructuring them. See Package anatomy for the full source-vs-output model.
How it works:
- The gh-aw compiler detects the
shared/apm.mdimport and adds a dedicatedapmjob to the compiled workflow. - The
apmjob runsmicrosoft/apm-actionto install packages and uploads a bundle archive as a GitHub Actions artifact. - The agent job downloads and unpacks the bundle as pre-steps, making all primitives available at runtime.
Set the required target: input to the APM target that matches engine:. This is the only target signal: the shared workflow runs apm-action in isolated mode and intentionally ignores any apm.yml in the consumer repository. For example, use target: copilot with engine: copilot. Do not pass all: apm-action writes the value into the isolated apm.yml, where it is deprecated and degrades to auto-detection.
For no-App rows, token-source selects the package credential:
| Value | Behavior |
|---|---|
cascade (default) |
Selects the first configured value in GH_AW_PLUGINS_TOKEN -> GH_AW_GITHUB_TOKEN -> GITHUB_TOKEN. With no override it ends on the same built-in read token as github-token. On the shared workflow’s GitHub-hosted runner, a configured override that is rejected does not fall through to another identity. |
github-token |
Deterministically selects only the ephemeral built-in token and fails if that identity is unavailable. The shared apm job grants it contents: read, so it can read private package paths in the current repository but not other private repositories. |
Use token-source: github-token when every private package in packages: is readable by the current repository token and you want to bypass configured cascade overrides. Private cross-repository packages require the default cascade with an authorized GH_AW_PLUGINS_TOKEN or GH_AW_GITHUB_TOKEN, or GitHub App credentials. App rows always use their minted installation token regardless of token-source. The contents: read permission is job-wide because GitHub Actions cannot scope token permissions per matrix row.
If you customize the Pack step to inject GITHUB_APM_PAT_{ORG}, that per-org credential still takes precedence under APM’s authentication rules. The selector pins the global token chain, not custom per-org credentials.
Pinning the apm CLI version (optional):
By default the import installs APM 0.28.0, the compatibility-tested version pinned by shared/apm.md, not the latest CLI release. That version is action-tested with microsoft/apm-action@v1.10.0 for explicit-target archive packing and multi-bundle restore. To pin the version explicitly, or install a different one, set the optional apm-version input. It is threaded into both the pack and restore steps so the version cannot skew between them, and it survives gh aw update (no need to hand-edit the vendored shared/apm.md):
imports: - uses: shared/apm.md with: apm-version: '0.28.0' target: copilot packages: - microsoft/apm-sample-packageUse a bare semver tag (e.g. '0.28.0'). Pass 'latest' to opt into floating to the newest release; omit the input entirely to keep the workflow’s pinned default.
Copies vendored before this change default to APM 0.21.0, the repository’s current CLI line when that default was selected. If a copy’s apm-action pin: line reads v1.4.2, its target input applies only to packing and does not reach the isolated install. To migrate:
- Replace
.github/workflows/shared/apm.mdwith the canonical file. This also moves the default to the compatibility-tested 0.28.0. - Set
target:under the import’swith:block to matchengine:. - Optionally set
token-source: github-tokenwhen all private packages are readable by the current repository token. - Run
gh aw compileand commit the regenerated workflow locks.
apm-action Pre-Step
Section titled “apm-action Pre-Step”For more control over the installation process, use microsoft/apm-action@v1 as an explicit workflow step. This approach runs apm install directly, giving you access to the full APM CLI. To also compile, add compile: true to the action configuration.
---on: pull_request: types: [opened]engine: copilot
steps: - name: Install agent primitives uses: microsoft/apm-action@v1 with: script: install env: GITHUB_TOKEN: ${{ github.token }}---
# Code Review
Review the PR using the installed coding standards.The repo needs an apm.yml with dependencies and apm.lock.yaml for reproducibility. The action runs as a pre-agent step, deploying primitives to .github/ where the agent discovers them.
When to use this over frontmatter dependencies:
- Custom compilation options (specific targets, flags)
- Running additional APM commands (audit, preview)
- Workflows that need
apm.yml-based configuration - Debugging dependency resolution
Using APM Bundles
Section titled “Using APM Bundles”For sandboxed environments where network access is restricted during workflow execution, use pre-built APM bundles:
- Run
apm pack --format apm --archivein your CI pipeline to produce a self-contained APM bundle (.zipby default; restorable viaunziporapm-actionrestore mode). - Distribute the bundle as a workflow artifact or commit it to the repository.
- Reference the bundled primitives directly from
.github/agents/in your workflow.
Bundles resolve full dependency trees ahead of time, so workflows need zero network access at runtime.
See the CI/CD Integration guide and Pack and distribute for details on building and distributing bundles. For routing live install traffic through an enterprise proxy instead, see Registry Proxy & Air-gapped.
Content Scanning
Section titled “Content Scanning”APM automatically scans dependencies for hidden Unicode characters during installation. Critical findings block deployment. This applies to both direct apm install and when gh-aw resolves packages via shared/apm.md.
For CI visibility into scan results (SARIF reports, step summaries), see the CI/CD Integration guide.
For details on what APM detects, see Content scanning.