Skip to content

Ensure build step is skipped if matrix is empty #47

Ensure build step is skipped if matrix is empty

Ensure build step is skipped if matrix is empty #47

---
name: Build and Deploy
on:
push:
branches:
- main
jobs:
define_images:
# Define a build matrix based on all changed *.hcl files so we can run packer only for image definitions that have actually changed
# So if e.g. ubuntu/focal/variables.auto.pkrvars.hcl or ubuntu/focal/src-ubuntu.pkr.hcl changes, add "ubuntu/focal" to the matrix
# Also ensure that if an image template (for instance, the general template for ubuntu images 'ubuntu/src-ubuntu.pkr.hcl') changes,
# an entry is added to the matrix for each image definition that relies on (i.e. symlinks) it.
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: "${{ github.repository }}"
- name: Get changed image definitions
# Find changed .hcl files in all <os>/<version> directories
id: changed-images-yaml
uses: tj-actions/changed-files@v39
with:
path: "${{ github.repository }}"
dir_names: true
dir_names_max_depth: 3
quotepath: false
files_yaml: |
images:
- '*/*/*.hcl'
- name: Get changed image definition templates
# Find all changed base templates in all <os>/ directories
id: changed-symlink-yaml
uses: tj-actions/changed-files@v39
with:
path: "${{ github.repository }}"
quotepath: false
files_yaml: |
symlinks:
- '*/*.hcl'
- name: Get image directories based on changed templates
# For every changed template in an <os> directory, collect all <os>/<version> directories that contain a symlink to the template.
# For instance, if ubuntu/src-ubunut.pkr.hcl changes, find all subdirectories of 'ubuntu' that contain links to that file
# -> the result would be e.g. 'ubuntu/focal ubuntu/jammy ubuntu/focal_desktop'
id: get-symlink-dirs
working-directory: "${{ github.repository }}"
run: |
for file in ${{ steps.changed-symlink-yaml.outputs.symlinks_all_changed_files }}; do
dir=$(dirname $file)
links=$(find "$dir" -type l)
for link in $links; do
if [[ $(readlink -f "$link") == $(realpath "$file") ]]; then
CHANGED="$CHANGED $(dirname $link)"
fi
done
done
echo changed_dirs="$CHANGED" >> "$GITHUB_OUTPUT"
- id: set-images-matrix
run: | # Add together the directories found in the changed-images-yaml and get-symlink-dirs steps into a single matrix
ALL_DIRS="${{ steps.changed-images-yaml.outputs.images_all_changed_files }} ${{ steps.get-symlink-dirs.outputs.changed_dirs }}"
MATRIX=($(echo "$ALL_DIRS" | xargs -n 1 | sort -u)) # Construct a unique array out of ALL_DIRS
MATRIX=$(printf '%s\n' "${MATRIX[@]}" | jq -R . | jq -c -s .) # Construct a valid json array out of the bash array
echo images=$MATRIX >> $GITHUB_OUTPUT
echo matrix={\"images\": $MATRIX} >> $GITHUB_OUTPUT
outputs:
images: ${{ steps.set-images-matrix.outputs.images }}
images_matrix: ${{ steps.set-images-matrix.outputs.matrix }}
build_and_deploy:
needs: define_images
runs-on: ubuntu-latest
if: ${{ needs.define_images.outputs.images != '[""]' && needs.define_images.outputs.images_matrix != '' }}
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.define_images.outputs.images_matrix) }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image
id: build-image
run: IMG=${{ matrix.images }} ./pack.sh docker
- name: Get image name and tag # grep in the image directory's variables file to find the image name/tag to push to
id: get-image-name
run: |
echo "docker_repo=`grep docker_repo ${{ matrix.images }}/variables.auto.pkrvars.hcl | awk '{print $3}'`" >> "$GITHUB_OUTPUT"
- name: Push image
run: docker push ${{ steps.get-image-name.outputs.docker_repo }}