Skip to content

Merge pull request #70 from luislavena/dynamic-builds #272

Merge pull request #70 from luislavena/dynamic-builds

Merge pull request #70 from luislavena/dynamic-builds #272

Workflow file for this run

name: CI
on:
pull_request:
push:
branches:
- "main"
workflow_dispatch:
inputs:
version:
description: 'Crystal version to build (e.g., 1.17) or "all" for all versions'
required: false
default: 'all'
jobs:
detect-changes:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
has_changes: ${{ steps.set-matrix.outputs.has_changes }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect changed docker directories
if: github.event_name != 'workflow_dispatch'
uses: dorny/paths-filter@v3
id: filter
with:
list-files: json
filters: |
docker:
- 'docker/**'
- name: Generate build matrix
id: set-matrix
run: |
VERSIONS_FILE=".github/versions.json"
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
# Manual trigger - build specified version or all
INPUT_VERSION="${{ github.event.inputs.version }}"
if [[ "$INPUT_VERSION" == "all" || -z "$INPUT_VERSION" ]]; then
CHANGED_DIRS=$(jq -r 'keys[]' "$VERSIONS_FILE")
else
CHANGED_DIRS="$INPUT_VERSION"
fi
else
# Automatic trigger - only changed directories
CHANGED_FILES='${{ steps.filter.outputs.docker_files }}'
if [[ "$CHANGED_FILES" == "[]" || -z "$CHANGED_FILES" ]]; then
echo "matrix={\"include\":[]}" >> $GITHUB_OUTPUT
echo "has_changes=false" >> $GITHUB_OUTPUT
exit 0
fi
CHANGED_DIRS=$(echo "$CHANGED_FILES" | jq -r '.[]' | sed -n 's|^docker/\([^/]*\)/.*|\1|p' | sort -u)
fi
# Build matrix from changed directories
MATRIX_INCLUDE="[]"
for DIR in $CHANGED_DIRS; do
if jq -e --arg v "$DIR" '.[$v]' "$VERSIONS_FILE" > /dev/null 2>&1; then
ENTRY=$(jq -c --arg v "$DIR" '{
crystal_major_minor: $v,
crystal_full: .[$v].crystal_full,
concurrency_group: "compile-crystal"
}' "$VERSIONS_FILE")
MATRIX_INCLUDE=$(echo "$MATRIX_INCLUDE" | jq -c --argjson e "$ENTRY" '. + [$e]')
fi
done
echo "matrix={\"include\":$MATRIX_INCLUDE}" >> $GITHUB_OUTPUT
if [[ "$MATRIX_INCLUDE" == "[]" ]]; then
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "has_changes=true" >> $GITHUB_OUTPUT
fi
build:
needs: detect-changes
if: needs.detect-changes.outputs.has_changes == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.detect-changes.outputs.matrix) }}
name: >-
Crystal ${{ matrix.crystal_full }} (${{ matrix.crystal_major_minor }})
concurrency:
group: ${{ matrix.concurrency_group || format('{0}-{1}', github.run_id, matrix.crystal_full) }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Define build number
run: |
echo "HYDROFOIL_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Set up Depot CLI
uses: depot/setup-action@v1
- name: Docker GitHub Registry Login
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker Metadata action
id: meta
uses: docker/metadata-action@v5
with:
flavor: |
latest=false
images: |
ghcr.io/luislavena/hydrofoil-crystal
tags: |
type=raw,${{ matrix.crystal_full }}
type=raw,${{ matrix.crystal_full }}-${{ env.HYDROFOIL_COMMIT }}
type=raw,${{ matrix.crystal_major_minor }}
- name: Setup Docker BuildKit cache strategy
uses: int128/docker-build-cache-config-action@v1
id: cache
with:
image: ghcr.io/${{ github.repository }}/build-cache
flavor: prefix=crystal-${{ matrix.crystal_major_minor }}--
- name: Build Docker images
uses: depot/build-push-action@v1
with:
project: ${{ secrets.DEPOT_PROJECT_ID }}
token: ${{ secrets.DEPOT_PROJECT_TOKEN }}
context: docker/${{ matrix.crystal_major_minor }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
cache-from: ${{ steps.cache.outputs.cache-from }}
cache-to: ${{ steps.cache.outputs.cache-to }}
# - name: Install Goss
# uses: e1himself/goss-installation-action@v1.0.4
# with:
# version: 'v0.3.16'
# - name: Test Docker image
# run: dgoss run local-image:ci sleep infinity
# FIXME: Use latest version of Dive
# - name: Analyze image efficiency
# uses: yuichielectric/dive-action@0.0.4
# with:
# image: local-image:ci
# config-file: ${{ github.workspace }}/.dive-ci.yml