GitHub Actions Tutorial — Org Shared Workflows

2 minute read

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:

  1. Identify common patterns — find workflows duplicated across repos
  2. Extract to shared repo — parameterize differences as inputs
  3. Version and tag — create v1 tag
  4. Update callers — replace inline jobs with uses: references
  5. 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 →

Updated: