Skip to content

Better docs

Better docs #51

---
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 symlinks
# 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: |
# Loop over each changed <os>/*.hcl file
for file in ${{ steps.changed-symlink-yaml.outputs.symlinks_all_changed_files }}; do
dir=$(dirname $file)
links=$(find "$dir" -type l) # Find all symlinks under the current $file's directory
for link in $links; do
# If this link has $file as a target, add the link's directory to the array of changed template directories
if [[ $(readlink -f "$link") == $(realpath "$file") ]]; then
CHANGED="$CHANGED $(dirname $link)"
fi
done
done
# Store the results
echo changed_dirs="$CHANGED" >> "$GITHUB_OUTPUT"
- id: set-images-matrix
run: |
# First add together the directories found in the changed-images-yaml and changed-templates-yaml steps into a single array
ALL_DIRS="${{ steps.changed-images-yaml.outputs.images_all_changed_files }} ${{ steps.get-changed-templates.outputs.changed_dirs }}"
# Now construct a unique array out of ALL_DIRS
MATRIX=($(echo "$ALL_DIRS" | xargs -n 1 | sort -u))
# Next create a valid json array out of the bash array using jq
MATRIX=$(printf '%s\n' "${MATRIX[@]}" | jq -R . | jq -c -s .)
# Store the results
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 }}