I am trying to configure a GitHub Actions workflow to conditionally build and push Docker images based on changes in specific directories. I only want to build the images associated with the changed paths and skip the others. Here’s a simplified version of my workflow. I want to build all images when there is a change in the library, and build only the relevant image based on the file changes. For example, build the collector image only if there is a change in the collector.
The matrix includes a job Build and push Docker Images (false)
for instance when there is a change library (needs.changes.outputs.library == ‘true’)
How can I properly configure the matrix so that it only includes images for which their corresponding path has changed, based on the output from the changes job?
jobs:
changes:
name: Detect changes
runs-on: ubuntu-latest
outputs:
library: ${{ steps.filter.outputs.library }}
workers: ${{ steps.filter.outputs.workers }}
collector: ${{ steps.filter.outputs.collector }}
api: ${{ steps.filter.outputs.api }}
webhook: ${{ steps.filter.outputs.webhook }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Filter paths
uses: dorny/paths-filter@v2
id: filter
with:
token: ${{ secrets.GITHUB_TOKEN }}
filters: |
library:
- 'package.json'
- 'package-lock.json'
- 'shared/**'
workers:
- 'workers/**'
- 'prisma/**'
collector:
- 'collector/**'
api:
- 'api/**'
webhook:
- 'webhook/**'
docker:
name: Build and push Docker Images
runs-on: ubuntu-latest
needs: changes
strategy:
matrix:
image:
- collector
- workers
- api
- webhook
include:
- image: ${{ needs.changes.outputs.collector == 'true' || needs.changes.outputs.library == 'true' && 'collector' }}
- image: ${{ needs.changes.outputs.workers == 'true' || needs.changes.outputs.library == 'true' && 'workers' }}
- image: ${{ needs.changes.outputs.api == 'true' || needs.changes.outputs.library == 'true' && 'api' }}
- image: ${{ needs.changes.outputs.collector == 'true' || needs.changes.outputs.webhook == 'true' && 'webhook' }}
exclude:
- image: ${{ needs.changes.outputs.collector == 'false' || needs.changes.outputs.library == 'false' && 'collector' }}
- image: ${{ needs.changes.outputs.workers == 'false' || needs.changes.outputs.library == 'false' && 'workers' }}
- image: ${{ needs.changes.outputs.api == 'false' || needs.changes.outputs.library == 'false' && 'api' }}
- image: ${{ needs.changes.outputs.collector == 'false' || needs.changes.outputs.webhook == 'false' && 'webhook' }}
steps:
- name: Build and push
run: |
echo "Building and pushing Docker image ${{ matrix.image }}"