name: php-fpm-build on: push: branches: [main] pull_request: branches: [main] workflow_dispatch: inputs: lane: description: 'Lane to build (e.g. 7.4). Use "all" to build all lanes.' required: false default: "" workflow_call: secrets: REGISTRY_TOKEN: required: true description: "Token for registry authentication." jobs: plan: runs-on: ubuntu-latest outputs: matrix: ${{ steps.compute.outputs.matrix }} should_build: ${{ steps.compute.outputs.should_build }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - id: compute shell: bash run: | set -euo pipefail # discover lanes under php-fpm/* that contain a Dockerfile mapfile -t ALL_LANES < <(find php-fpm -mindepth 1 -maxdepth 1 -type d | sort) FILTERED=() for d in "${ALL_LANES[@]}"; do if [[ -f "${d}/Dockerfile" ]]; then FILTERED+=("${d}") fi done ALL_LANES=("${FILTERED[@]}") if [[ ${#ALL_LANES[@]} -eq 0 ]]; then echo "No php-fpm lanes found. Nothing to do." echo "should_build=false" >> $GITHUB_OUTPUT echo 'matrix={"dir":[]}' >> $GITHUB_OUTPUT exit 0 fi # allow workflow_dispatch lane selection SELECTED=() REQ_LANE="${{ github.event.inputs.lane || '' }}" if [[ -n "$REQ_LANE" ]]; then if [[ "$REQ_LANE" == "all" ]]; then SELECTED=("${ALL_LANES[@]}") else candidate="php-fpm/$REQ_LANE" if [[ -d "$candidate" && -f "$candidate/Dockerfile" ]]; then SELECTED=("$candidate") else echo "ERROR: Requested lane '$REQ_LANE' not found under php-fpm/" >&2 exit 1 fi fi else # Determine changed files if [[ "${{ github.event_name }}" == "push" ]]; then BASE_SHA="$(git rev-parse HEAD~1 2>/dev/null || true)" HEAD_SHA="$(git rev-parse HEAD 2>/dev/null || true)" elif [[ "${{ github.event_name }}" == "pull_request" ]]; then BASE_SHA="${{ github.event.pull_request.base.sha }}" HEAD_SHA="${{ github.event.pull_request.head.sha }}" else BASE_SHA="" HEAD_SHA="$(git rev-parse HEAD 2>/dev/null || true)" fi if [[ -n "$BASE_SHA" ]]; then CHANGED=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA") else CHANGED=$(git ls-files) fi # If workflow files changed, rebuild all lanes if grep -q "^.github/workflows/" <<< "$CHANGED"; then SELECTED=("${ALL_LANES[@]}") else for d in "${ALL_LANES[@]}"; do if grep -q "^${d}/" <<< "$CHANGED"; then SELECTED+=("${d}") fi done fi fi # Dedupe and validate mapfile -t SELECTED < <(printf "%s\n" "${SELECTED[@]}" | awk 'NF && !x[$0]++') if [[ ${#SELECTED[@]} -eq 0 ]]; then echo "No php-fpm lanes to build." echo "should_build=false" >> $GITHUB_OUTPUT echo 'matrix={"dir":[]}' >> $GITHUB_OUTPUT exit 0 fi JSON=$(jq -nc --argjson arr "$(printf '%s\n' "${SELECTED[@]}" | jq -R . | jq -s .)" '{dir: $arr}') echo "Matrix: $JSON" echo "should_build=true" >> $GITHUB_OUTPUT echo "matrix=$JSON" >> $GITHUB_OUTPUT build: needs: plan if: needs.plan.outputs.should_build == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: registry: gitea.auvem.com username: ${{ vars.REGISTRY_USER || github.actor }} password: ${{ secrets.REGISTRY_TOKEN }} - name: Show plan matrix run: | echo "Plan matrix: $MATRIX_JSON" jq -C . dir <<< "$MATRIX_JSON" 2>/dev/null || true env: MATRIX_JSON: ${{ needs.plan.outputs.matrix }} - name: Build lanes shell: bash env: MATRIX_JSON: ${{ needs.plan.outputs.matrix }} GIT_SHA_SHORT: ${GITHUB_SHA::7} run: | set -euo pipefail lanes=$(jq -r '.dir[]' <<< "$MATRIX_JSON") for lane in $lanes; do echo "Building lane: $lane" if [[ ! -f "$lane/Dockerfile" ]]; then echo "ERROR: missing Dockerfile for $lane" >&2 exit 1 fi NAME=$(basename "$lane") if [[ ! "$NAME" =~ ^([0-9]+\.?[0-9]*)$ ]]; then echo "ERROR: php-fpm lane name '$NAME' is not a numeric version" >&2 exit 1 fi IMAGE="gitea.auvem.com/auvem/wordpress-docker/php-fpm" TAG="$NAME" echo "Computed: image=${IMAGE}, tags=${IMAGE}:${TAG},${IMAGE}:git-${GIT_SHA_SHORT}" docker buildx build --push --platform linux/amd64 \ --tag "${IMAGE}:${TAG}" \ --tag "${IMAGE}:git-${GIT_SHA_SHORT}" \ --file "$lane/Dockerfile" . done