The Problem

Managing AI agents in CI means writing YAML workflows by hand, wiring permissions, sandboxing, and output sanitization for every job. That work repeats per repository, is easy to get wrong, and makes agent behavior opaque to the humans who must review it. GitHub Agentic Workflows (gh-aw) treats the workflow definition itself as the problem: write intent in markdown, generate the Actions YAML, and let the platform enforce the safety boundaries.

What This Does

gh aw converts natural-language markdown files into GitHub Actions workflows that run AI agents (Copilot, Claude, Codex) in containerized environments on a schedule or manually. The core CLI entry point is cmd/gh-aw/main.go; the markdown-to-workflow pipeline and the agent runtime live under pkg/. The actions/ tree is a separate JavaScript project — a setup action with an MCP server that handles safe input/output processing and secret redaction (actions/setup/js/redact_secrets.cjs, safe_outputs_mcp_client.cjs).

This repository is not one codebase. It is six self-contained projects — pkg (Go, 1368 code files), actions (JS), cmd, scripts, internal, skills — plus 409 files of .github/ agents, runbooks, and workflow definitions. Treat each as its own unit; there is no single architecture spanning them.

How It Is Wired

Execution starts at cmd/gh-aw/main.go. The CLI reads a markdown workflow file, validates it, and emits a .github/workflows/*.yml that invokes the setup action. The action's JavaScript is the real hub: actions/setup/js/error_helpers.cjs has 73 modules depending on it — the highest blast radius in the repo, and the highest-churn file to change. The module graph is healthy: 295 internal modules, 229 import edges, zero circular dependencies.

For the Go side, the wiring is not mapped in the measured analysis — no traced call paths are available for pkg/. The actions/ project, by contrast, is well-traced: error_helpers.cjs is the failure-handling hub everything routes through, and the MCP client/server pair (safe_outputs_mcp_client.cjs, safe_inputs_mcp_server_http.cjs) owns the network boundary where agent output is sanitized before it touches GitHub's API.

How To Use It

gh extension install github/gh-aw
gh aw create my-workflow.md   # generates the Actions workflow

The README's quick start is the authoritative path: install the extension, add a sample workflow, run it. Configuration lives in the markdown frontmatter (on, permissions, safe-outputs). No .env or key management is needed — the action's validate_secrets.cjs and redact_secrets.cjs handle secret handling inside the action.

Real-World Use

A team wants a daily status issue generated from repository activity. They write a markdown file declaring on: schedule: daily, read-only permissions, and a safe-outputs block that constrains the agent to creating issues with a title prefix and labels. gh aw compiles it, CI runs the agent container, and the only write the agent can perform is through the sanitized output handler — with human approval gating if configured.

Code Health & Issues

Static analysis (468 findings: 37 high, 431 medium) flags deep nesting in pkg/workflow/ (max indentation depth 9), 449 duplicated 6-line blocks across 242 files, and two silent catch {} blocks in actions/setup/js/. The health audit adds:

  • High — ci.yml lines 100 and 330 discard step exit codes; the job can report green on stale artifacts.
  • Med — .devcontainer/Dockerfile uses a mutable base image tag; pin by digest.
  • Med — 42MB and 21.2MB videos committed to docs/public/videos/; move to LFS or object storage.
  • Med — ci.yml checkout leaves persist-credentials enabled; disable it.
  • Low — agentics-maintenance.yml lacks timeout-minutes on jobs.
  • High — committed secrets detected in the repo; audit and rotate.

The Bottom Line

Solid, security-conscious design for a genuinely useful tool — the safe-outputs model is the right instinct. The fork carries real hygiene debt (committed secrets, large binaries, discarded exit codes) that must be resolved before trusting it in production. Use it if you want agent-driven CI with guardrails; audit the fork's delta from upstream first.