2.2.5. YAML Anchors, Aliases, and Merge Keys
💡 First Principle: Anchors and aliases are a YAML parser feature, not a GitHub feature — the file is expanded before Actions ever sees it — which explains both their power (reuse any repeated mapping) and their two hard limits: they cannot reach across files, and Actions only implements the part of the YAML spec it chose to.
The syntax has three pieces, and GitHub Actions supports only the first two. &name defines an anchor and *name references it — both shipped in September 2025. <<:, the merge key, folds an anchored mapping's keys into the surrounding one; the Actions parser does not implement it, and a workflow that uses it fails to parse.
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 15
env: &common_env # anchor defined on first real use
NODE_ENV: test
CI: "true"
steps:
- uses: actions/checkout@v4
- run: npm test
lint:
runs-on: ubuntu-latest
timeout-minutes: 5
env: *common_env # alias substitutes the whole mapping
steps:
- uses: actions/checkout@v4
- run: npm run lint
Two constraints shape that example, and both are commonly got wrong. First, the anchor is declared on first use inside a real key rather than in a shared block at the top: a workflow's top level accepts only name, run-name, on, permissions, env, defaults, concurrency, and jobs, so a holder key like x-defaults: is rejected as an unexpected value. Second, because an alias substitutes the anchored node wholesale, there is no way to inherit a block and override one key inside it — that is precisely what the merge key would have done. When you need base-plus-overrides, the answer is a reusable workflow or a composite action, not YAML.
Because expansion happens at parse time, the effective workflow is what you'd get by copy-pasting the anchored content everywhere the alias appears. That has consequences the January 2026 objectives call out explicitly in both the authoring domain and the troubleshooting domain (4.1.3): when you read a run's behavior, you must mentally expand aliases first, because the UI and the logs reflect the expanded document, not your compact source.
Anchors shine for repeated env: maps, shared step blocks, and consistent job scaffolding inside one large workflow. They are the wrong tool the moment you want the reuse to span repositories or even files — that's reusable workflows and composite actions, and choosing between the three is exactly the 4.3.2 comparison.
⚠️ Exam Trap: The January 2026 objectives list "&, * and merge <<", but GitHub's Actions team confirmed merge keys are not supported by the parser and there is no plan to add them. Hold both layers: in YAML, a merged key yields to a locally-written one, which is the semantics an exam item asking "which value applies?" is testing; in a real workflow, <<: is a syntax error. Answer the item on YAML semantics, and never write a merge key into a workflow you intend to run.
⚠️ Exam Trap: Anchors and aliases are scoped to a single YAML document. There is no way to anchor in one workflow file and alias from another, and no include directive in YAML. Any answer proposing cross-file anchor reuse is wrong.
Reflection Question: Anchors reduce duplication but make a workflow harder to read at a glance. Given that troubleshooting is a whole exam domain, when would you accept the duplication instead?