name: Build and Push Docker Images on: push: branches: [main] paths: - 'images/**' workflow_dispatch: inputs: image: description: 'Image to build (e.g., terraform-ci)' required: false env: REGISTRY: gitea.arnodo.fr jobs: # ============================================================================ # Job 1 : Detect modified images # ============================================================================ detect-changes: runs-on: docker container: image: alpine:3.20 outputs: matrix: ${{ steps.changes.outputs.matrix }} has_changes: ${{ steps.changes.outputs.has_changes }} steps: - name: Install dependencies run: apk add --no-cache git jq - name: Checkout repository run: | git clone --depth 2 https://gitea.arnodo.fr/${{ gitea.repository }}.git . git checkout ${{ gitea.sha }} - name: Detect changed images id: changes env: INPUT_IMAGE: ${{ inputs.image }} run: | # 1. Handle Manual Input if [ -n "$INPUT_IMAGE" ]; then # Clean input IMAGE=$(echo "$INPUT_IMAGE" | xargs) echo "DEBUG: Processing manual input image: '$IMAGE'" if [ -n "$IMAGE" ]; then if [ -d "images/$IMAGE" ] && [ -f "images/$IMAGE/Dockerfile" ]; then echo "DEBUG: Image directory and Dockerfile exist." # Use printf for safer output printf "matrix=[\"%s\"]\n" "$IMAGE" >> $GITHUB_OUTPUT echo "has_changes=true" >> $GITHUB_OUTPUT echo "DEBUG: Set matrix=['$IMAGE']" exit 0 else echo "Error: Image '$IMAGE' not found or missing Dockerfile at images/$IMAGE/Dockerfile" echo "has_changes=false" >> $GITHUB_OUTPUT echo "matrix=[]" >> $GITHUB_OUTPUT exit 0 fi else echo "DEBUG: Input image name was empty after trimming." echo "has_changes=false" >> $GITHUB_OUTPUT echo "matrix=[]" >> $GITHUB_OUTPUT exit 0 fi fi # 2. Handle Automatic Detection (Git Diff) echo "DEBUG: Running git diff detection..." > valid_images.txt CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD -- images/ 2>/dev/null || true) CANDIDATES=$(echo "$CHANGED_FILES" | cut -d'/' -f2 | sort -u | grep -v '^$') for CANDIDATE in $CANDIDATES; do if [ -d "images/$CANDIDATE" ] && [ -f "images/$CANDIDATE/Dockerfile" ]; then echo "$CANDIDATE" >> valid_images.txt fi done if [ ! -s valid_images.txt ]; then echo "No valid images detected." echo "has_changes=false" >> $GITHUB_OUTPUT echo "matrix=[]" >> $GITHUB_OUTPUT else # Convert list to JSON array using jq JSON=$(cat valid_images.txt | jq -R -s -c 'split("\n") | map(select(length > 0))') echo "Detected images: $JSON" echo "matrix=$JSON" >> $GITHUB_OUTPUT echo "has_changes=true" >> $GITHUB_OUTPUT fi - name: Show detected changes run: | echo "Matrix: ${{ steps.changes.outputs.matrix }}" echo "Has changes: ${{ steps.changes.outputs.has_changes }}" # ============================================================================ # Job 2 : Build and Push (Standard Docker) # ============================================================================ build: needs: detect-changes if: needs.detect-changes.outputs.has_changes == 'true' runs-on: docker container: image: docker:cli strategy: matrix: image: ${{ fromJson(needs.detect-changes.outputs.matrix) }} fail-fast: false steps: - name: Install dependencies run: apk add --no-cache git - name: Checkout repository run: | git clone --depth 2 https://gitea.arnodo.fr/${{ gitea.repository }}.git . git checkout ${{ gitea.sha }} - name: Login to Registry run: | echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ${{ env.REGISTRY }} -u ${{ gitea.actor }} --password-stdin - name: Build and Push env: IMAGE_NAME: ${{ env.REGISTRY }}/damien/${{ matrix.image }} IMAGE_PATH: images/${{ matrix.image }} run: | echo "Debug: Matrix Image is '${{ matrix.image }}'" if [ -z "${{ matrix.image }}" ]; then echo "Skipping empty image name" exit 0 fi echo "Building $IMAGE_NAME:latest from $IMAGE_PATH ..." if [ ! -d "$IMAGE_PATH" ]; then echo "Error: Directory $IMAGE_PATH does not exist." exit 1 fi if [ ! -f "$IMAGE_PATH/Dockerfile" ]; then echo "Error: Dockerfile not found in $IMAGE_PATH." exit 1 fi # Use standard docker build docker build -t "$IMAGE_NAME:latest" "$IMAGE_PATH" docker push "$IMAGE_NAME:latest" echo "✅ Pushed $IMAGE_NAME:latest"