diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 008b0cc..7ad70e8 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -43,23 +43,26 @@ jobs: 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 }}" \ - -t "${IMAGE}:latest" \ -f Dockerfile . + echo "Built image: ${IMAGE}:${{ steps.sha.outputs.short_sha }}" - - name: Push Docker image + - name: Push test image (SHA tag only, not latest yet) run: | docker push "${IMAGE}:${{ steps.sha.outputs.short_sha }}" - docker push "${IMAGE}:latest" - echo "✓ Pushed: ${IMAGE}:${{ steps.sha.outputs.short_sha }}" + echo "✓ Pushed test image: ${IMAGE}:${{ steps.sha.outputs.short_sha }}" - - name: Prune unused images - run: docker image prune -a --force 2>&1 | tail -3 || true - - - name: Setup kubeconfig + - name: Setup kubeconfig for test pod run: | mkdir -p ~/.kube echo "${KUBECONFIG_B64}" | base64 -d > ~/.kube/config @@ -73,10 +76,51 @@ jobs: chmod +x kubectl sudo mv kubectl /usr/local/bin/ - - name: Run integration tests against cluster + - name: Deploy test pod from new image run: | - echo "Running integration tests against production cluster..." - go test -v -tags=integration ./internal/integration/... || true - env: - GATEWAY_URL: http://api-gateway.api.svc.cluster.local:8080 + 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 \ + --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 diff --git a/internal/integration/integration_test.go b/internal/integration/integration_test.go index cf0d7d9..9e851f8 100644 --- a/internal/integration/integration_test.go +++ b/internal/integration/integration_test.go @@ -247,7 +247,7 @@ func TestIntegrationIAMService(t *testing.T) { } defer resp.Body.Close() - body, _ := io.ReadAll(resp.Body) + _, _ = io.ReadAll(resp.Body) t.Logf("IAM list users response: %d", resp.StatusCode) // IAM (Authentik) should respond - 200, 404, or auth error all prove routing works