DEV Community

Abhiuday
Abhiuday

Posted on

pipeline-compose 1.0: Cross-Repo GitHub Actions Orchestration Without Generated YAML

Release context: v1.0.0 GA + v1.1.0 (validate --simulate)

Discussion: https://github.com/aeswibon/pipeline-compose/discussions/2


Native GitHub Actions needs: stops at repo boundaries. Multi-stage release pipelines that span workflow files — or other repositories — turn into mega-workflows, fragile workflow_run chains, or generated YAML you have to commit and review twice.

I built pipeline-compose to declare order and wiring in one pipeline file, dispatch stage workflows (including cross-repo), and merge outputs into context — without compiling a graph into git unless you choose to.

v1.0.0 GA landed this week. v1.1.0 adds dry-run simulation before you push. This post is what changed at 1.0 and why it matters.


The problem: orchestration ≠ workflow definition

Tag release flow:

ci → version sync → release publish
Enter fullscreen mode Exit fullscreen mode

Each stage deserves its own workflow file — different triggers, permissions, reuse via workflow_call. Splitting files breaks native needs: across runs.

Teams then pick:

Approach What breaks
Mega-workflow Stages share one trigger; file grows without bound
workflow_run chains Output passing is indirect; renames fail quietly
Compile-to-YAML Generated workflow becomes a second codebase

pipeline-compose-run is a third path: one orchestrator step, pipeline YAML as source of truth, optional compile for compliance-heavy shops.


What 1.0 GA actually ships

Schema v2 only

Pipeline files use version: 2 with named pipelines:

version: 2
companion_workflows:
  - .github/workflows/release.yml
pipelines:
  release:
    stages:
      - id: ci
        workflow: .github/workflows/ci.yml
      - id: version-sync
        workflow: .github/workflows/stage-version-sync.yml
        needs: [ci]
        outputs: [version]
      - id: release-publish
        workflow: .github/workflows/stage-release-publish.yml
        needs: [version-sync]
        inputs:
          version: ${{ context.version-sync.version }}
Enter fullscreen mode Exit fullscreen mode

v1 documents are rejected at validate — no silent drift from old examples.

Cross-repo stages

Stages can target another repository:

- id: remote-echo
  repo: your-org/your-target-repo
  workflow: .github/workflows/cross-repo-echo.yml
  outputs: [message]
Enter fullscreen mode Exit fullscreen mode

That is the headline for 1.0: orchestration across repos, not just across workflow files in one repo.

pipeline-compose-export (new required companion)

When a stage declares outputs:, you add pipeline-compose-export as the last step in that stage's job — instead of hand-written jq + upload-artifact.

GitHub does not expose job outputs across workflow_dispatch runs. The export action uploads pipeline-compose-<stage-id>/outputs.json; the run action merges it into context.<stage-id>.<key>.

Five Marketplace actions now: run, export, compile, eval, context-merge.


Entry workflow (pin v1.0.0)

- uses: aeswibon/pipeline-compose-run@v1.0.0
  with:
    pipeline_file: .github/pipelines/pipeline.yml
Enter fullscreen mode Exit fullscreen mode

Stage with downstream outputs — last step in that stage:

- uses: aeswibon/pipeline-compose-export@v1.0.0
  if: success()
  with:
    stage_id: version-sync
    outputs: |
      version=${{ steps.version.outputs.value }}
Enter fullscreen mode Exit fullscreen mode

Copy-paste: examples/run-tag-release · cross-repo: examples/cross-repo-dispatch


Validate before CI burns minutes (v1.1.0)

Local / CI:

pnpm run validate .github/pipelines/pipeline.yml \
  --repo-root . --workflows --strict --mermaid
Enter fullscreen mode Exit fullscreen mode

validate --simulate — dry-run stage table using when:, upstream skips, and missing context. Mirrors run orchestrator skip logic.

validate --mermaid — topology diagram; failed stages render red; blocked upstream amber.

PR bot can attach simulation + mermaid + issue list — see docs/mermaid-demo.md.

Frozen public contracts: docs/specs/1.0-contracts.md

Migrating from pre-1.0: docs/migration/v1.0.md


Run vs compile (unchanged tradeoff)

Mode Committed artifact Best for
Run Pipeline YAML only Tag releases, cross-repo, runtime when:
Compile Pipeline YAML + generated workflow Teams requiring native needs: in review
Mega-workflow One large YAML 2–3 jobs total — do not add orchestration

TypeScript monorepo (why not Go/Java here)

pnpm workspace, shared core, Vitest, schema validation — Actions tooling on Node matches the runtime. My backend work is Go/Java; this layer optimized for shipping CLI + action bundles fast.


When to skip pipeline-compose

  • Simple repos — native Actions is fine
  • Orgs that forbid programmatic workflow_dispatch
  • You need heavy cross-run state beyond stage outputs — use a store

Sweet spot: multi-stage, multi-workflow, optionally multi-repo releases.


Try it

  1. Copy examples/run-tag-release/.github
  2. Run validate --strict --workflows --mermaid locally
  3. Push tag → watch Actions → Release

Changelog: v1.1.0 · v1.0.0 GA


Feedback

Original RFC (pre-v2 artifact contract): https://github.com/aeswibon/pipeline-compose/discussions/2

If you migrate from v0.x → v1.0, reply there or open a thread on cross-repo + simulate UX.

Top comments (0)