name: CI on: push: branches: [main] pull_request: branches: [main] workflow_dispatch: env: REGISTRY: forgejo.riotpiao.com IMAGE: forgejo.riotpiao.com/rock/api-gateway DOCKER_HOST: tcp://localhost:2375 jobs: ci: name: CI runs-on: golang steps: - name: Install Node.js and Docker run: | apt-get update apt-get install -y nodejs docker.io - name: Checkout code uses: actions/checkout@v4 - name: Go vet run: go vet ./... - name: Go test run: go test ./... - name: Get short SHA id: sha run: echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - name: Registry login run: | echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" \ --username "${REGISTRY_USER}" --password-stdin env: REGISTRY_USER: ${{ secrets.FORGEJO_REGISTRY_USER }} REGISTRY_TOKEN: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} - name: Test build only (unit tests) run: | echo "Running unit tests..." go test ./... echo "Running static analysis..." go vet ./... - name: Build Docker image run: | docker build --no-cache \ -t "${IMAGE}:${{ steps.sha.outputs.short_sha }}" \ -f Dockerfile . echo "Built image: ${IMAGE}:${{ steps.sha.outputs.short_sha }}" - name: Push test image (SHA tag only, not latest yet) run: | docker push "${IMAGE}:${{ steps.sha.outputs.short_sha }}" echo "✓ Pushed test image: ${IMAGE}:${{ steps.sha.outputs.short_sha }}" - name: Setup kubeconfig for test pod run: | mkdir -p ~/.kube echo "${KUBECONFIG_B64}" | base64 -d > ~/.kube/config env: KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }} continue-on-error: true - name: Install kubectl run: | curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl sudo mv kubectl /usr/local/bin/ - name: Deploy test pod from new image run: | echo "Deploying test pod with new image: ${IMAGE}:${{ steps.sha.outputs.short_sha }}" kubectl run api-gateway-test-${{ steps.sha.outputs.short_sha }} \ --image="${IMAGE}:${{ steps.sha.outputs.short_sha }}" \ --namespace=api \ --restart=Never \ --port=8080 \ --labels="app=api-gateway,managed-by=argocd,role=test,test-run=${{ steps.sha.outputs.short_sha }}" \ --overrides='{"spec":{"containers":[{"name":"gateway","securityContext":{"runAsNonRoot":true,"runAsUser":65532,"allowPrivilegeEscalation":false}}]}}' echo "Waiting for test pod to be ready..." kubectl wait --for=condition=ready pod -l run=api-gateway-test-${{ steps.sha.outputs.short_sha }} -n api --timeout=60s continue-on-error: true - name: Run integration tests against test pod run: | echo "Running integration tests against test pod..." # Port-forward to test pod kubectl port-forward -n api pod/api-gateway-test-${{ steps.sha.outputs.short_sha }} 8080:8080 & PF_PID=$! sleep 3 # Run tests TEST_RESULT=0 go test -v -tags=integration -timeout=5m ./internal/integration/... || TEST_RESULT=$? kill $PF_PID || true exit $TEST_RESULT env: GATEWAY_URL: http://localhost:8080 continue-on-error: false - name: Promote image to latest (only if tests passed) if: success() run: | docker pull "${IMAGE}:${{ steps.sha.outputs.short_sha }}" docker tag "${IMAGE}:${{ steps.sha.outputs.short_sha }}" "${IMAGE}:latest" docker push "${IMAGE}:latest" echo "✓ Promoted ${IMAGE}:${{ steps.sha.outputs.short_sha }} to latest" - name: Cleanup test pod if: always() run: | kubectl delete pod api-gateway-test-${{ steps.sha.outputs.short_sha }} -n api 2>/dev/null || true continue-on-error: true - name: Prune unused images run: docker image prune -a --force 2>&1 | tail -3 || true