diff --git a/.gitea/workflows/ci-cd.yaml b/.gitea/workflows/ci-cd.yaml index b72518f..8bf5f8d 100644 --- a/.gitea/workflows/ci-cd.yaml +++ b/.gitea/workflows/ci-cd.yaml @@ -57,8 +57,69 @@ env: CI_REGISTRY: "gitea.arcodange.lab" jobs: + build-cache: + name: Build Docker Cache + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[skip ci]') && github.actor != 'ci-bot'" + outputs: + deps_hash: ${{ steps.calculate_hash.outputs.deps_hash }} + cache_hit: ${{ steps.check_cache.outputs.cache_hit }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Calculate dependency hash + id: calculate_hash + run: | + # Calculate hash of go.mod + go.sum + DEPS_HASH=$(sha256sum go.mod go.sum | sha256sum | cut -d' ' -f1 | head -c 12) + echo "Dependency hash: $DEPS_HASH" + echo "deps_hash=$DEPS_HASH" >> $GITHUB_OUTPUT + + - name: Check for existing cache + id: check_cache + run: | + # Check if image exists in registry + IMAGE_NAME="${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}-build-cache:${{ steps.calculate_hash.outputs.deps_hash }}" + + # Try to pull the image to see if it exists + if docker pull "$IMAGE_NAME" >/dev/null 2>&1; then + echo "✅ Cache hit - using existing build cache" + echo "cache_hit=true" >> $GITHUB_OUTPUT + else + echo "⚠️ Cache miss - will build new cache image" + echo "cache_hit=false" >> $GITHUB_OUTPUT + fi + + - name: Login to Gitea Container Registry + if: steps.check_cache.outputs.cache_hit == 'false' + uses: docker/login-action@v3 + with: + registry: ${{ env.CI_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.PACKAGES_TOKEN }} + + - name: Set up Docker Buildx + if: steps.check_cache.outputs.cache_hit == 'false' + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker cache image + if: steps.check_cache.outputs.cache_hit == 'false' + run: | + IMAGE_NAME="${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}-build-cache:${{ steps.calculate_hash.outputs.deps_hash }}" + echo "Building cache image: $IMAGE_NAME" + + docker buildx build \ + --file Dockerfile.build \ + --tag "$IMAGE_NAME" \ + --push \ + . + + echo "✅ Build cache image pushed successfully" + ci-pipeline: name: CI Pipeline + needs: build-cache runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, '[skip ci]') && github.actor != 'ci-bot'" @@ -66,6 +127,22 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Gitea Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.CI_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.PACKAGES_TOKEN }} + + - name: Pull Docker build cache + run: | + IMAGE_NAME="${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}-build-cache:${{ needs.build-cache.outputs.deps_hash }}" + echo "Using build cache image: $IMAGE_NAME" + docker pull "$IMAGE_NAME" || echo "Cache pull failed, will use regular setup" + - name: Set up Go uses: actions/setup-go@v4 with: diff --git a/Dockerfile.build b/Dockerfile.build new file mode 100644 index 0000000..09781ea --- /dev/null +++ b/Dockerfile.build @@ -0,0 +1,39 @@ +# Build environment Dockerfile with pre-installed Go tools and dependencies +# Optimized for CI/CD pipeline speed + +FROM golang:1.26.1-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + bash \ + curl \ + make \ + gcc \ + musl-dev \ + bc \ + grep \ + sed \ + jq \ + ca-certificates + +# Set up Go environment +ENV GOPATH=/go +ENV PATH=$GOPATH/bin:/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin +WORKDIR /go/src/dance-lessons-coach + +# Install common Go tools +RUN go install github.com/swaggo/swag/cmd/swag@latest && \ + go install golang.org/x/tools/cmd/goimports@latest && \ + go install honnef.co/go/tools/cmd/staticcheck@latest + +# Copy only go.mod and go.sum first for dependency caching +COPY go.mod go.sum ./ +RUN go mod download && go mod verify + +# Copy the rest of the source (this happens in CI) +# COPY . . + +# Build command (will be run in CI) +# RUN go build -o /out/server ./cmd/server && \ +# go build -o /out/greet ./cmd/greet \ No newline at end of file diff --git a/scripts/ci-calculate-deps-hash.sh b/scripts/ci-calculate-deps-hash.sh new file mode 100755 index 0000000..4db8df9 --- /dev/null +++ b/scripts/ci-calculate-deps-hash.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# Calculate hash for go.mod + go.sum to use as Docker tag +# Usage: scripts/ci-calculate-deps-hash.sh + +set -e + +# Calculate SHA256 hash of go.mod and go.sum combined +DEPS_HASH=$(sha256sum go.mod go.sum | sha256sum | cut -d' ' -f1 | head -c 12) +echo "Dependency hash: $DEPS_HASH" +echo "$DEPS_HASH" > .deps_hash + +echo "::set-output name=deps_hash::$DEPS_HASH" \ No newline at end of file