Ensure build step is skipped if matrix is empty #47
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
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 }} |