GitHub Actions Tutorial — Org Shared Workflows
Org Shared Workflows
Organizations benefit most from reusable workflows — standardize CI/CD across dozens of repositories from a single source of truth.
Central Workflow Repository
Create a dedicated repository for shared workflows:
my-org/shared-workflows/
└── .github/
└── workflows/
├── ci-node.yml # Node.js CI template
├── ci-python.yml # Python CI template
├── deploy.yml # Deployment template
├── security-scan.yml # Security scanning
└── release.yml # Release automation
Calling Org Workflows
From any repository in the organization:
# my-org/my-service/.github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
ci:
uses: my-org/shared-workflows/.github/workflows/ci-node.yml@v3
with:
node-version: '20'
secrets: inherit
security:
uses: my-org/shared-workflows/.github/workflows/security-scan.yml@v3
secrets: inherit
Repository Visibility
| Workflow Repo | Caller Repo | Works? |
|---|---|---|
| Public | Public | ✅ |
| Public | Private | ✅ |
| Internal | Internal | ✅ |
| Internal | Private (same org) | ✅ |
| Private | Private (same org) | ✅ (with setting) |
| Private | Public | ❌ |
For private workflow repos, enable “Accessible from repositories in the organization” in: Settings → Actions → General → Access.
Versioning Strategy
Semantic Version Tags
v1.0.0 ← initial release
v1.1.0 ← new feature (backward compatible)
v2.0.0 ← breaking change
v1 ← major version tag (points to latest v1.x.x)
How to create major version tags:
# Tag a release
git tag v1.2.0
git push origin v1.2.0
# Update the major version tag
git tag -fa v1 v1.2.0
git push origin v1 --force
Callers use @v1 for automatic patch updates. Use @v1.2.0 for exact pinning.
Standardized Templates
Create workflows that enforce organizational standards:
# shared-workflows/.github/workflows/ci-node.yml
name: Node.js CI (Org Standard)
on:
workflow_call:
inputs:
node-version:
type: string
default: '20'
run-lint:
type: boolean
default: true
run-security:
type: boolean
default: true
jobs:
lint:
if: inputs.run-lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci
- run: npm test
security:
if: inputs.run-security
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm audit --audit-level=high
Every Node.js repo in the org uses this template, guaranteeing consistent lint, test, and security checks.
Migration Guide
Moving from duplicated workflows to shared ones:
- Identify common patterns — find workflows duplicated across repos
- Extract to shared repo — parameterize differences as inputs
- Version and tag — create
v1tag - Update callers — replace inline jobs with
uses:references - Deprecate old workflows — remove duplicated files
Common Mistakes
| Mistake | Fix |
|---|---|
| Private repo not accessible | Enable “Accessible from repositories in the organization” |
| Tag not found | Ensure the tag exists and is pushed to the remote |
| Breaking change hits all repos | Use semantic versioning; breaking changes go in v2 |
| Secrets not available | Use secrets: inherit or declare explicitly |
Quick Reference
| Concept | Detail |
|---|---|
| Shared repo | my-org/shared-workflows |
| Call syntax | uses: my-org/shared-workflows/.github/workflows/ci.yml@v1 |
| Versioning | Major version tags (@v1) with semantic releases |
| Visibility | Set in repo Settings → Actions → General |
| Secrets | secrets: inherit for convenience |
← Previous: Composition Patterns
Next: Practice Exercises →