name: Build and Push Docker Images on: push: branches: - main jobs: build: runs-on: ubuntu-latest permissions: packages: write contents: read steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push images env: REGISTRY: ghcr.io IMAGE_NAME_PREFIX: ${{ github.repository_owner }} run: | set -eux find . -name 'Dockerfile' -path '*/devops/*' -print0 | while IFS= read -r -d $'\0' dockerfile; do dir=$(dirname "$dockerfile") project=$(basename "$(dirname "$dir")") image="$REGISTRY/$IMAGE_NAME_PREFIX/$project:latest" echo "Building $image using $dockerfile" # Check if an image with the same tag already exists manifest=$(curl -s -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -u "${{ github.repository_owner }}:${{ secrets.GITHUB_TOKEN }}" "https://ghcr.io/v2/$IMAGE_NAME_PREFIX/$project/manifests/latest" 2> /dev/null) if [[ -z "$manifest" ]]; then echo "No existing image found for $project, building..." docker buildx build --push --platform linux/amd64,linux/arm64 -t "$image" -f "$dockerfile" "$dir" else echo "Found existing image for $project, checking for changes..." # Determine the last commit hash that resulted in a successful build last_commit=$(git log -n 1 --pretty=format:%H) # Get the list of changed files changed_files=$(git diff --name-only "$last_commit" HEAD "$dir" || true) # Check if the project has changed if [[ -n "$changed_files" ]] || [[ $(git diff --quiet HEAD "$dir" || echo "changed") != "" ]]; then echo "Changes detected for $project, building..." docker buildx build --push --platform linux/amd64,linux/arm64 -t "$image" -f "$dockerfile" "$dir" else echo "No changes detected for $project, skipping build." fi fi done