diff --git a/.gitea/workflows/production-deploy.yml b/.gitea/workflows/production-deploy.yml index 7a74b734..bc1389a0 100644 --- a/.gitea/workflows/production-deploy.yml +++ b/.gitea/workflows/production-deploy.yml @@ -29,33 +29,76 @@ jobs: if: ${{ !inputs.skip_tests }} steps: - name: Checkout code - uses: actions/checkout@v4 + run: | + REF_NAME="${{ github.ref_name }}" + REPO="${{ github.repository }}" + if [ -z "$REF_NAME" ]; then + REF_NAME="main" + fi + + # Try HTTPS first, fallback to SSH + git clone --depth 1 --branch "$REF_NAME" \ + "https://git.michaelschiemer.de/${REPO}.git" \ + /workspace/repo || \ + git clone --depth 1 --branch "$REF_NAME" \ + "git@git.michaelschiemer.de:${REPO}.git" \ + /workspace/repo || \ + git clone --depth 1 \ + "https://git.michaelschiemer.de/${REPO}.git" \ + /workspace/repo + + cd /workspace/repo - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.3' - extensions: mbstring, xml, pdo, pdo_mysql, zip, gd, intl, sodium, bcmath, redis - coverage: none + run: | + # Install PHP 8.3 and extensions + apt-get update + apt-get install -y \ + php8.3 \ + php8.3-cli \ + php8.3-mbstring \ + php8.3-xml \ + php8.3-pdo \ + php8.3-pdo-mysql \ + php8.3-zip \ + php8.3-gd \ + php8.3-intl \ + php8.3-sodium \ + php8.3-bcmath \ + php8.3-redis \ + composer - - name: Cache Composer dependencies - uses: actions/cache@v3 - with: - path: vendor - key: composer-${{ hashFiles('composer.lock') }} - restore-keys: composer- + - name: Cache Composer dependencies (simple) + run: | + if [ -d "/tmp/composer-cache/vendor" ]; then + echo "📦 Restoring cached dependencies..." + cp -r /tmp/composer-cache/vendor /workspace/repo/vendor || true + fi - name: Install dependencies - run: composer install --no-interaction --prefer-dist --optimize-autoloader + run: | + cd /workspace/repo + composer install --no-interaction --prefer-dist --optimize-autoloader + + - name: Save Composer cache + run: | + mkdir -p /tmp/composer-cache + cp -r /workspace/repo/vendor /tmp/composer-cache/vendor || true - name: Run Pest tests - run: ./vendor/bin/pest --colors=always + run: | + cd /workspace/repo + ./vendor/bin/pest --colors=always - name: Run PHPStan - run: make phpstan + run: | + cd /workspace/repo + make phpstan - name: Code style check - run: composer cs + run: | + cd /workspace/repo + composer cs # Job 2: Build & Push Docker Image build: @@ -65,46 +108,85 @@ jobs: runs-on: ubuntu-latest outputs: image_tag: ${{ steps.meta.outputs.tag }} - commit_sha: ${{ github.sha }} + commit_sha: ${{ steps.meta.outputs.commit_sha }} steps: - name: Checkout code - uses: actions/checkout@v4 + run: | + REF_NAME="${{ github.ref_name }}" + REPO="${{ github.repository }}" + if [ -z "$REF_NAME" ]; then + REF_NAME="main" + fi + + # Try HTTPS first, fallback to SSH + git clone --depth 1 --branch "$REF_NAME" \ + "https://git.michaelschiemer.de/${REPO}.git" \ + /workspace/repo || \ + git clone --depth 1 --branch "$REF_NAME" \ + "git@git.michaelschiemer.de:${REPO}.git" \ + /workspace/repo || \ + git clone --depth 1 \ + "https://git.michaelschiemer.de/${REPO}.git" \ + /workspace/repo + + cd /workspace/repo - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - name: Setup Docker Buildx + run: | + docker buildx create --name builder --use || docker buildx use builder + docker buildx inspect --bootstrap - name: Generate image metadata id: meta run: | - SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7) + cd /workspace/repo + # Gitea Actions supports github.sha for compatibility + COMMIT_SHA="${{ github.sha }}" + if [ -z "$COMMIT_SHA" ]; then + COMMIT_SHA=$(git rev-parse HEAD) + fi + SHORT_SHA=$(echo "$COMMIT_SHA" | cut -c1-7) TAG="${SHORT_SHA}-$(date +%s)" echo "tag=${TAG}" >> $GITHUB_OUTPUT echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "commit_sha=${COMMIT_SHA}" >> $GITHUB_OUTPUT + echo "Generated tag: ${TAG}" - name: Login to Registry run: | echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u ${{ secrets.REGISTRY_USER }} --password-stdin - name: Build and push Docker image - uses: docker/build-push-action@v5 - with: - context: . - file: ./Dockerfile.production - push: true - tags: | - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.tag }} - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:git-${{ steps.meta.outputs.short_sha }} - cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache - cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max - build-args: | - BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') - GIT_COMMIT=${{ github.sha }} - GIT_BRANCH=${{ github.ref_name }} + run: | + cd /workspace/repo + COMMIT_SHA="${{ github.sha }}" + if [ -z "$COMMIT_SHA" ]; then + COMMIT_SHA=$(git rev-parse HEAD) + fi + REF_NAME="${{ github.ref_name }}" + if [ -z "$REF_NAME" ]; then + REF_NAME=$(git rev-parse --abbrev-ref HEAD) + fi + SHORT_SHA=$(echo "$COMMIT_SHA" | cut -c1-7) + TAG="${SHORT_SHA}-$(date +%s)" + + # Build with cache + docker buildx build \ + --platform linux/amd64 \ + --file ./Dockerfile.production \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG} \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:git-${SHORT_SHA} \ + --cache-from type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache \ + --cache-to type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max \ + --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \ + --build-arg GIT_COMMIT=${COMMIT_SHA} \ + --build-arg GIT_BRANCH=${REF_NAME} \ + --push \ + . - name: Image scan for vulnerabilities run: | - # Optional: Add Trivy or similar vulnerability scanning echo "✅ Image built successfully: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.tag }}" # Job 3: Deploy to Production @@ -117,11 +199,29 @@ jobs: url: https://michaelschiemer.de steps: - name: Checkout deployment scripts - uses: actions/checkout@v4 - with: - sparse-checkout: | - deployment/ansible - sparse-checkout-cone-mode: false + run: | + REF_NAME="${GITEA_REF_NAME:-main}" + REPO="${GITEA_REPOSITORY}" + SERVER_URL="${GITEA_SERVER_URL}" + + # Try HTTPS first, fallback to SSH + if [ -n "$REPO" ] && [ -n "$SERVER_URL" ]; then + git clone --depth 1 --branch "$REF_NAME" \ + "https://${SERVER_URL}/${REPO}.git" \ + /workspace/repo || true + fi + + # Fallback to SSH if HTTPS failed + if [ ! -d /workspace/repo ]; then + git clone --depth 1 --branch "$REF_NAME" \ + "git@git.michaelschiemer.de:${REPO}.git" \ + /workspace/repo || \ + git clone --depth 1 \ + "https://git.michaelschiemer.de/${REPO}.git" \ + /workspace/repo + fi + + cd /workspace/repo - name: Setup SSH key run: | @@ -132,12 +232,12 @@ jobs: - name: Install Ansible run: | - sudo apt-get update - sudo apt-get install -y ansible + apt-get update + apt-get install -y ansible - name: Deploy via Ansible run: | - cd deployment/ansible + cd /workspace/repo/deployment/ansible ansible-playbook -i inventory/production.yml \ playbooks/deploy-update.yml \ -e "image_tag=${{ needs.build.outputs.image_tag }}" \ @@ -166,7 +266,7 @@ jobs: - name: Rollback on failure if: failure() && steps.health.outcome == 'failure' run: | - cd deployment/ansible + cd /workspace/repo/deployment/ansible ansible-playbook -i inventory/production.yml \ playbooks/rollback.yml