Files
dance-lessons-coach/.gitea/workflows/ci-cd.yaml
Gabriel Radureau 77b7416d1f
Some checks failed
CI/CD Pipeline / CI Pipeline (pull_request) Has been cancelled
🔄 fix: ensure sequential pushes work from updated HEAD
2026-04-07 08:18:19 +02:00

257 lines
9.1 KiB
YAML

---
# dance-lessons-coach Unified CI/CD Workflow
# Single, optimized workflow that replaces all previous workflows
# Fast execution with minimal repetition and maximum artifact sharing
name: CI/CD Pipeline
on:
workflow_dispatch: {}
push:
branches:
- main
- 'ci/**'
- 'feature/**'
- 'fix/**'
- 'refactor/**'
paths-ignore:
- 'README.md'
- 'doc/**'
- 'adr/**'
- '.gitea/**'
- 'documentation/**'
- '*.md'
- '.vibe/**'
- 'features/**'
pull_request:
branches:
- main
types: [opened, synchronize, reopened, labeled]
paths-ignore:
- 'README.md'
- 'doc/**'
- 'adr/**'
- '.gitea/**'
- 'documentation/**'
- '*.md'
- '.vibe/**'
- 'features/**'
# cancel any previously-started runs of this workflow on the same branch
concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true
# Arcodange-specific environment variables
env:
GITEA_INTERNAL: "https://gitea.arcodange.lab/"
GITEA_EXTERNAL: "https://gitea.arcodange.fr/"
GITEA_ORG: "arcodange"
GITEA_REPO: "dance-lessons-coach"
CI_REGISTRY: "gitea.arcodange.lab"
jobs:
ci-pipeline:
name: CI Pipeline
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]') && github.actor != 'ci-bot'"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.26.1'
cache: true
- name: Install dependencies
run: go mod tidy
# SINGLE swag installation - reused for all steps
- name: Install swag (once)
run: go install github.com/swaggo/swag/cmd/swag@latest
- name: Generate Swagger Docs
run: cd pkg/server && go generate
- name: Build all packages
run: go build ./...
- name: Run tests with coverage
run: |
# Run tests with coverage
go test ./... -coverprofile=coverage.out -v
go tool cover -func=coverage.out > coverage.txt
# Extract coverage percentage
COVERAGE=$(grep "total:" coverage.txt | grep -oP '\d+\.\d+' | head -1)
echo "Coverage: ${COVERAGE}%"
# Determine badge color
if (( $(echo "$COVERAGE >= 80" | bc -l) )); then
COLOR="brightgreen"
elif (( $(echo "$COVERAGE >= 50" | bc -l) )); then
COLOR="yellow"
else
COLOR="red"
fi
# Update README with new badge
BADGE_URL="https://img.shields.io/badge/coverage-${COVERAGE}%-${COLOR}?style=flat-square"
sed -i "s|https://img.shields.io/badge/coverage-.*-.*?style=flat-square|${BADGE_URL}|" README.md
# Set up git authentication and commit
git config --global user.name "CI Bot"
git config --global user.email "ci@arcodange.fr"
# Set up credentials using Gitea token
git config --global credential.helper store
echo "https://${{ secrets.PACKAGES_TOKEN }}@gitea.arcodange.lab" > ~/.git-credentials
# Only update if coverage has actually changed
if grep -q "coverage-${COVERAGE}%" README.md; then
echo "Coverage badge already up to date at ${COVERAGE}%"
else
git add README.md
git commit -m "🤖 chore: update coverage badge to ${COVERAGE}% [skip ci]" || echo "No coverage change to commit"
# Try push with retry logic for race conditions
for i in 1 2 3; do
if git push; then
echo "Successfully updated coverage badge to ${COVERAGE}%"
# Update local repo to the new HEAD after successful push
git fetch origin
git reset --hard origin/${{ github.ref_name }}
break
else
echo "Push attempt $i failed, retrying..."
if [ $i -eq 3 ]; then
echo "Final push attempt failed - another job may have updated the badge"
git pull --rebase || true
git push || echo "Recovery push also failed"
# Ensure we're on the latest commit even if push failed
git fetch origin
git reset --hard origin/${{ github.ref_name }}
fi
sleep 2
fi
done
fi
- name: Run go fmt
run: go fmt ./...
- name: Run swag fmt
run: swag fmt
- name: Build binaries
run: ./scripts/build.sh
# NOTE: Artifact upload disabled - actions/upload-artifact@v4 not available on Gitea
# TODO: Replace with Gitea-specific upload action when available
# - name: Upload Swagger documentation
# uses: actions/upload-artifact@v4
# with:
# name: swagger-docs
# path: pkg/server/docs/swagger.json
# retention-days: 1
# Version management and Docker build (main branch only)
- name: Version management and Docker build
if: github.ref == 'refs/heads/main'
run: |
# Analyze last commit message
LAST_COMMIT=$(git log -1 --pretty=%B | head -1)
VERSION_BUMPED="false"
# Automatic version bump based on commit type
if echo "$LAST_COMMIT" | grep -q "^✨ feat:"; then
echo "🎯 Feature commit detected - bumping MINOR version"
./scripts/version-bump.sh minor
VERSION_BUMPED="true"
elif echo "$LAST_COMMIT" | grep -q "^🐛 fix:"; then
echo "🐛 Fix commit detected - bumping PATCH version"
./scripts/version-bump.sh patch
VERSION_BUMPED="true"
elif echo "$LAST_COMMIT" | grep -q "BREAKING CHANGE"; then
echo "💥 Breaking change detected - bumping MAJOR version"
./scripts/version-bump.sh major
VERSION_BUMPED="true"
else
echo "⏭️ No automatic version bump needed"
fi
# Update swagger version regardless of bump
source VERSION
NEW_VERSION="$MAJOR.$MINOR.$PATCH${PRERELEASE:+-$PRERELEASE}"
sed -i "s|// @version [0-9.]*|// @version $NEW_VERSION|" cmd/server/main.go
# Commit version changes if bumped
if [ "$VERSION_BUMPED" = "true" ]; then
git config --global user.name "CI Bot"
git config --global user.email "ci@arcodange.fr"
# Set up credentials using Gitea token
git config --global credential.helper store
echo "https://${{ secrets.PACKAGES_TOKEN }}@gitea.arcodange.lab" > ~/.git-credentials
git add VERSION cmd/server/main.go README.md
git commit -m "chore: auto version bump [skip ci]" || echo "No changes to commit"
# Try push with retry logic for race conditions
for i in 1 2 3; do
if git push; then
echo "Successfully bumped version"
break
else
echo "Version bump push attempt $i failed, retrying..."
if [ $i -eq 3 ]; then
echo "Final version bump push attempt failed - another job may have bumped version"
git pull --rebase || true
git push || echo "Version bump recovery push also failed"
fi
sleep 2
fi
done
fi
- name: Login to Gitea Container Registry
if: github.ref == 'refs/heads/main'
uses: docker/login-action@v3
with:
registry: ${{ env.CI_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.PACKAGES_TOKEN }}
- name: Set up Docker Buildx
if: github.ref == 'refs/heads/main'
uses: docker/setup-buildx-action@v3
- name: Build and push Docker image
if: github.ref == 'refs/heads/main'
run: |
source VERSION
IMAGE_VERSION="$MAJOR.$MINOR.$PATCH${PRERELEASE:+-$PRERELEASE}"
TAGS="$IMAGE_VERSION latest ${{ github.sha }}"
echo "Building Docker image with tags: $TAGS"
docker build -t dance-lessons-coach .
for TAG in $TAGS; do
IMAGE_NAME="${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:$TAG"
echo "Tagging and pushing: $IMAGE_NAME"
docker tag dance-lessons-coach "$IMAGE_NAME"
docker push "$IMAGE_NAME"
done
- name: Show published images
if: github.ref == 'refs/heads/main'
run: |
source VERSION
IMAGE_VERSION="$MAJOR.$MINOR.$PATCH${PRERELEASE:+-$PRERELEASE}"
echo "📦 Published Docker images:"
echo " - ${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:$IMAGE_VERSION"
echo " - ${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:latest"
echo " - ${{ env.CI_REGISTRY }}/${{ env.GITEA_ORG }}/${{ env.GITEA_REPO }}:${{ github.sha }}"