If you manage a multi-repository architecture, you already know the pain I'm about to describe.
You need to roll out a standardized CI/CD update. Maybe you’re bumping a Node version, swapping out a deprecated linter, or rotating a secret. In a perfect world, you update one template. In reality, you spend your afternoon copy-pasting the exact same 15 lines of YAML across 40 different .github/workflows/ files.
It feels fundamentally wrong. As engineers, we are taught to keep our code DRY (Don't Repeat Yourself). Yet, when it comes to the infrastructure defining our deployments, we tolerate massive duplication.
The Current State of Affairs
Let's look at a realistic, everyday scenario. You have a matrix of jobs—say, building a project across Linux, macOS, and Windows.
jobs:
build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
- run: npm ci
- run: npm run build
build-mac:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
- run: npm ci
- run: npm run build
This configuration drift happens slowly. One developer adds a security scanning step to the Linux job but forgets to add it to the macOS job. Suddenly, your pipelines are inconsistent, and debugging takes hours.
Existing Solutions (And Where They Fall Short)
To be fair, GitHub hasn't completely ignored this problem. We currently have two main workarounds:
1. Reusable Workflows
Reusable workflows are excellent for massive, standardized pipelines (e.g., "Deploy to Production"). You define a workflow in a central repository and call it from your other repos.
- The friction: They can be incredibly rigid. If Repository A needs to tweak just one step in the reusable workflow, you often end up creating a messy web of boolean inputs (
if: inputs.run_custom_step == true). Passing secrets into reusable workflows also introduces significant boilerplate.
2. Composite Actions
Composite actions allow you to group a sequence of steps into a single action.
- The friction: They are great for small utilities, but they abstract away visibility. When a composite action fails, the logs can be harder to parse, and you still have to maintain them in a separate repository or dedicated path.
Why This Problem Still Exists
If you write standard YAML outside of GitHub Actions, this problem is already solved. Standard YAML supports Anchors and Aliases. You define a block once with &anchor_name and reuse it anywhere with *anchor_name.
.setup_template: &setup
steps:
- uses: actions/checkout@v3
- run: npm ci
jobs:
build-linux:
runs-on: ubuntu-latest
<<: *setup
Unfortunately, the GitHub Actions parser aggressively strips out YAML anchors before execution. The community has been begging for this feature for years (Issue #1182 is practically legendary at this point), but it remains unsupported.
A Personal Observation
After reading countless threads on Reddit and GitHub, it seems like everyone hits this exact wall. Some teams settle for the copy-paste nightmare. Others invest weeks building internal python scripts or Makefiles to template their YAML locally before pushing to GitHub.
I'm an engineer, and I hate building internal tools for problems that shouldn't exist.
The Validation Experiment
I want to be perfectly clear: I am not launching a product.
I've been mapping out the architecture for a lightweight, drop-in preprocessor. It would allow you to write advanced, DRY YAML (with anchors and includes) and securely compile it down to native GitHub YAML right before the run. No infrastructure changes, no vendor lock-in.
But before I spend my nights and weekends writing the backend logic for this, I am trying to validate if this is a problem actually worth solving, or if it's just an inconvenience we've all learned to live with.
How does your team handle this?
I want to hear from you.
- How are you currently handling YAML duplication?
- Have you fully migrated to Reusable Workflows, or did you build a custom templating script?
- Do you see a fatal flaw in the idea of a preprocessor?
Let me know in the comments.
(If you strongly believe this preprocessor needs to exist and want to follow the validation experiment, I set up a barebones Waitlist / Landing Page here. But honestly, I'm more interested in hearing your workarounds.)
Top comments (1)
TextStow could be useful for this workflow — clipboard history + reusable favorites + prompt templates + cleanup for JSON/PDF/URLs. Local-first, free: textstow.com