← knowledge.oriz.in

Reusable workflows layered with Dagger — 2026-07-02

decision cigithub-actionsdaggerdryreusable-workflows

Reusable workflows layered with Dagger

The 3-layer DRY stack

Downstream repo (chirag127/oriz-blog)
  └── .github/workflows/ci.yml           # 5-line pin
      └── chirag127/oriz-workflows       # reusable workflow (@v1)
          └── dagger call ci             # actual logic lives in Dagger TS
              └── @oriz/dagger-astro     # composable module for Astro sites

Repo classes → reusable workflow files

chirag127/oriz-workflows/.github/workflows/:

File For repo class Downstream slug
ci-astro-site.yml Astro sites sites/*
ci-astro-api.yml Astro static APIs api/*
ci-astro-pwa.yml Astro mobile PWAs apps-mobile/*
ci-mdbook.yml mdBook books books/*
ci-vsc-ext.yml VS Code extensions apps-vsc-ext/*
ci-bs-ext.yml Browser extensions apps-bs-ext/*
ci-userscript.yml Userscripts userscripts/*
ci-npm-package.yml Publishable npm packages infra/* npm-scoped

Downstream repo shape (thin)

Every chirag127/<repo>/.github/workflows/ci.yml:

name: ci
on: [push, pull_request]
jobs:
  ci:
    uses: chirag127/oriz-workflows/.github/workflows/ci-astro-site.yml@v1
    secrets: inherit

Nothing else. Actual CI logic lives in oriz-workflows.

Reusable workflow shape

chirag127/oriz-workflows/.github/workflows/ci-astro-site.yml:

name: ci-astro-site
on:
  workflow_call:
    secrets:
      WORKSPACE_DISPATCH_PAT: { required: true }
jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dagger/dagger-for-github@8
        with:
          version: latest
          call: ci --source=.
      - name: Trigger deploy
        if: github.ref == 'refs/heads/main' && github.event_name == 'push'
        run: gh api repos/chirag127/workspace/dispatches -f event_type=deploy -f "client_payload[repo]=$GITHUB_REPOSITORY" -f "client_payload[sha]=$GITHUB_SHA"
        env:
          GH_TOKEN: ${{ secrets.WORKSPACE_DISPATCH_PAT }}

Version pinning + Renovate

Renovate preset lives at chirag127/oriz-workflows/renovate-preset.json. Every downstream renovate.json:

{ "extends": ["github>chirag127/oriz-workflows"] }

Anti-drift — structural

There's nothing to drift because:

  1. Actual logic lives in oriz-workflows (one place).
  2. Downstream is 5 lines that only reference the version tag.
  3. Renovate auto-bumps the tag.
  4. If a repo's 5-line pin is missing (e.g. deleted by hand), CI is red on next push. Visible.

Cross-refs