A Reusable GitHub Actions Workflow for Build-Test-Deploy

Once the third repo copies the same workflow YAML, it's time for a reusable workflow instead of copy-paste drift.

The reusable workflow

.github/workflows/build-test-deploy.yml in a shared repo:

on:
  workflow_call:
    inputs:
      image_name:
        required: true
        type: string
      environment:
        required: true
        type: string
    secrets:
      REGISTRY_TOKEN:
        required: true

jobs:
  build-test-deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment }}
    steps:
      - uses: actions/checkout@v4

      - name: Run tests
        run: make test

      - name: Build image
        run: docker build -t ${{ inputs.image_name }}:${{ github.sha }} .

      - name: Push image
        run: |
          echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
          docker push ${{ inputs.image_name }}:${{ github.sha }}          

Calling it from a service repo

jobs:
  deploy:
    uses: acme/ci-workflows/.github/workflows/build-test-deploy.yml@main
    with:
      image_name: ghcr.io/acme/checkout
      environment: production
    secrets:
      REGISTRY_TOKEN: ${{ secrets.GHCR_TOKEN }}

Useful gh CLI checks

Watch the current run:

gh run watch

Re-run only the failed jobs:

gh run rerun --failed

Every service repo now imports the same pipeline logic — one file to fix when the build process changes, not fifteen.