DEV Community

kanta13jp1
kanta13jp1

Posted on

GitHub Actions Advanced Patterns: Matrix, Cache, and Reusable Workflows

GitHub Actions Advanced Patterns: Matrix, Cache, and Reusable Workflows

Beyond the basic push-to-deploy. Three patterns to speed up CI, reduce duplication, and parallelize builds.

Matrix: Parallel Tests Across Configs

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest]
        flutter: ['3.19.0', '3.22.0']
        exclude:
          - os: macos-latest
            flutter: '3.19.0'

    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ matrix.flutter }}
      - run: flutter test
Enter fullscreen mode Exit fullscreen mode

Dynamic matrix from JSON output:

jobs:
  setup:
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - id: set-matrix
        run: |
          echo 'matrix={"include":[{"env":"staging"},{"env":"prod"}]}' \
            >> $GITHUB_OUTPUT

  deploy:
    needs: setup
    strategy:
      matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
    steps:
      - run: echo "Deploying to ${{ matrix.env }}"
Enter fullscreen mode Exit fullscreen mode

Cache: Cut Dependency Install Time

steps:
  - uses: actions/checkout@v4

  # subosito/flutter-action built-in cache
  - uses: subosito/flutter-action@v2
    with:
      flutter-version: '3.22.0'
      cache: true

  # Manual control if you need it
  - uses: actions/cache@v4
    with:
      path: |
        ~/.pub-cache
        .dart_tool
      key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
      restore-keys: |
        ${{ runner.os }}-pub-

  - run: flutter pub get
  - run: flutter test
Enter fullscreen mode Exit fullscreen mode

Real-world impact:

No cache:    flutter pub get → 45s
With cache:  flutter pub get → 3s  (93% faster)
Full CI run: 5min → 2min
Enter fullscreen mode Exit fullscreen mode

Reusable Workflows: Share CI Logic

# .github/workflows/flutter-ci.yml (called workflow)
on:
  workflow_call:
    inputs:
      flutter-version:
        required: false
        type: string
        default: '3.22.0'
      run-tests:
        required: false
        type: boolean
        default: true
    secrets:
      SUPABASE_URL:
        required: true

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ inputs.flutter-version }}
          cache: true
      - run: flutter pub get
      - if: ${{ inputs.run-tests }}
        run: flutter test
      - run: flutter build web --release
Enter fullscreen mode Exit fullscreen mode
# .github/workflows/deploy.yml (caller)
jobs:
  build-and-test:
    uses: ./.github/workflows/flutter-ci.yml
    with:
      flutter-version: '3.22.0'
      run-tests: true
    secrets:
      SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
Enter fullscreen mode Exit fullscreen mode

Composite Actions: Extract Reusable Steps

# .github/actions/setup-flutter/action.yml
name: 'Setup Flutter'
inputs:
  flutter-version:
    default: '3.22.0'
runs:
  using: composite
  steps:
    - uses: subosito/flutter-action@v2
      with:
        flutter-version: ${{ inputs.flutter-version }}
        cache: true
    - run: flutter pub get
      shell: bash

# Usage in any workflow
steps:
  - uses: ./.github/actions/setup-flutter
    with:
      flutter-version: '3.22.0'
Enter fullscreen mode Exit fullscreen mode

Artifacts: Pass Build Outputs Between Jobs

jobs:
  build:
    steps:
      - run: flutter build web --release
      - uses: actions/upload-artifact@v4
        with:
          name: web-build
          path: build/web/
          retention-days: 7

  deploy:
    needs: build
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: web-build
          path: build/web/
      - run: firebase deploy --only hosting
Enter fullscreen mode Exit fullscreen mode

Summary

Matrix           → parallel OS/version tests — faster + better coverage
Cache            → pub get 45s → 3s (93% faster)
Reusable WF      → share CI logic across repos
Composite Action → shared steps inside a repo
Artifacts        → hand build output between jobs cleanly
Enter fullscreen mode Exit fullscreen mode

GitHub Free includes 2,000 minutes/month. Cache + parallelization keeps you well within that.

Top comments (0)