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 : Détection des images modifiées # ============================================================================ 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 run: | if [ -n "${{ inputs.image }}" ]; then echo "matrix=[\"${{ inputs.image }}\"]" >> $GITHUB_OUTPUT echo "has_changes=true" >> $GITHUB_OUTPUT else CHANGED=$(git diff --name-only HEAD~1 HEAD -- images/ 2>/dev/null | cut -d'/' -f2 | sort -u | grep -v '^$' || true) if [ -z "$CHANGED" ]; then echo "has_changes=false" >> $GITHUB_OUTPUT echo "matrix=[]" >> $GITHUB_OUTPUT else JSON=$(echo "$CHANGED" | jq -R -s -c 'split("\n") | map(select(length > 0))') echo "matrix=$JSON" >> $GITHUB_OUTPUT echo "has_changes=true" >> $GITHUB_OUTPUT fi fi - name: Show detected changes run: | echo "Matrix: ${{ steps.changes.outputs.matrix }}" echo "Has changes: ${{ steps.changes.outputs.has_changes }}" # ============================================================================ # Job 2 : Build avec Buildkit via Docker socket # ============================================================================ 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) }} steps: - name: Install git and checkout run: | apk add --no-cache git git clone --depth 1 https://gitea.arnodo.fr/${{ gitea.repository }}.git /src - name: Build and push with Buildkit env: REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} REGISTRY_USER: ${{ gitea.actor }} run: | IMAGE_NAME="${{ env.REGISTRY }}/damien/${{ matrix.image }}" echo "Building ${IMAGE_NAME}:latest ..." # Create a unique volume name for this build VOLUME_NAME="buildkit-ctx-$$" # Create a docker volume and copy source into it docker volume create ${VOLUME_NAME} docker run --rm -v ${VOLUME_NAME}:/context -v /src/images/${{ matrix.image }}:/src:ro alpine sh -c "cp -r /src/* /context/" # Create auth config in another volume AUTH_VOLUME="buildkit-auth-$$" docker volume create ${AUTH_VOLUME} AUTH=$(echo -n "${REGISTRY_USER}:${REGISTRY_TOKEN}" | base64 | tr -d '\n') docker run --rm -v ${AUTH_VOLUME}:/auth alpine sh -c "mkdir -p /auth && cat > /auth/config.json << 'AUTHEOF' { \"auths\": { \"${{ env.REGISTRY }}\": { \"auth\": \"${AUTH}\" } } } AUTHEOF" # Debug: show context content echo "Context content:" docker run --rm -v ${VOLUME_NAME}:/context alpine ls -la /context/ # Run buildkit in daemonless mode docker run --rm \ --privileged \ -v ${VOLUME_NAME}:/context:ro \ -v ${AUTH_VOLUME}:/root/.docker:ro \ --entrypoint buildctl-daemonless.sh \ moby/buildkit:master \ build \ --frontend dockerfile.v0 \ --local context=/context \ --local dockerfile=/context \ --output type=image,name=${IMAGE_NAME}:latest,push=true # Cleanup volumes docker volume rm ${VOLUME_NAME} ${AUTH_VOLUME} || true echo "✅ Pushed ${IMAGE_NAME}:latest"