Skip to content

Instantly share code, notes, and snippets.

@koistya
Last active July 10, 2023 11:16
Show Gist options
  • Save koistya/1b620a220239097ba49951d26a7593aa to your computer and use it in GitHub Desktop.
Save koistya/1b620a220239097ba49951d26a7593aa to your computer and use it in GitHub Desktop.
Reusable workflows in GitHub Actions

Reusable Workflows in GitHub Actions

Assuming you have the root-level main.yml and a couple of reusable workflows main-a.yml and main-b.yml.

Your goal is to run the the workflows A and B automatically as part of the main (root) workflow as well as being able to fire up them manually one by one for different environments.

The top-level (root) workflow would looks something like this:

.github/workflows/main.yml

name: CI/CD

on:
  # Fires up automatically on push to the main branch or push of a tag such as v1.3.0
  push:
    branches: [main]
    tags:
      - "v*"
  # Fires up automatically when a pull requeest (PR) is created or updates against the main branch
  pull_request:
    branches: [main]
  # Fires up automatically nightly at 7am
  schedule:
    - cron: "0 7 * * *"
  # Fires up manually by repository/organization admin against the target environment
  workflow_dispatch:
    inputs:
      environment:
        description: "Environment to deploy to"
        type: environment
        default: "test"
        required: true

env:
  NODE_VERSION: 20

jobs:
  setup:
    name: "Setup"
    runs-on: ubuntu-latest
    steps:
      - use: actions/checkout@v3
      - uses: actions/setup-node@v3
      - run: 'echo "..."'
  main-a:
    name: "Main A"
    uses: ./.github/workflows/main-a.yml
    needs: [setup]
    secrets: inherit
    with:
      environment: ${{ inputs.environment || 'test' }}
  main-b:
    name: "Main B"
    uses: ./.github/workflows/main-b.yml
    needs: [setup]
    secrets: inherit
    with:
      environment: ${{ inputs.environment || 'test' }}

While, a child workflow looks somewhat like this:

.github/workflows/main-a.yml

name: Main A

on:
  # Fires up by a call from the parent (root) workflow (main.yml)
  workflow_call:
    inputs:
      environment:
        type: string
        default: "test"
  # Fires up manually by repisotory/organization admin
  workflow_dispatch:
    inputs:
      environment:
        type: environment
        default: "test"
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: ${{ inputs.environment }}
    steps:
      - uses: actions/checkout@v3
      - run: 'echo "xxx"'
        env:
          SOME_SECRET: "${{ secrets.SOME_SECRET }}"

NOTE:

  • In the example above the child (reusable) workflow (main-a.yml) has access to all secrets also available in the root-level workflow, because at the root level there is secrets: inherit argument is used.
  • The default environment inside of the deploy job of the reusable workflow is set to test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment