feat: add Tekton Pipelines for integration testing
CI / CI (pull_request) Failing after 3m38s

Implement Kubernetes-native CI/CD with Tekton Pipelines:

ARCHITECTURE:
- Tekton Task: Runs integration tests in container
- Tekton Pipeline: Orchestrates test execution
- ArgoCD Application: Manages Tekton installation
- CI: Triggers PipelineRun, reads results, promotes image

FLOW:
1. CI builds image:sha
2. CI creates PipelineRun with new image
3. Tekton controller watches PipelineRun
4. Task executes integration tests
5. Results written to PipelineRun status
6. CI reads status, promotes to :latest if pass
7. ArgoCD detects :latest change and deploys

BENEFITS:
✓ Kubernetes-native (CRDs, no external dependencies)
✓ DRY (parameterized Task/Pipeline)
✓ SOLID (single responsibility, clean interfaces)
✓ GitOps (Tekton managed by ArgoCD)
✓ Observable (logs, status, results)
✓ Secure (non-root, resource limits)

FILES:
- k8s/tekton/task-integration-test.yaml: Task definition
- k8s/tekton/pipeline-integration-test.yaml: Pipeline definition
- k8s/tekton/kustomization.yaml: Kustomize management
- k8s/tekton/README.md: Documentation
- k8s/argocd-apps/tekton.yaml: ArgoCD Application
- .gitea/workflows/ci.yaml: Updated CI to use Tekton

NEXT:
1. Merge PR
2. ArgoCD syncs and installs Tekton
3. First git push triggers PipelineRun
4. Integration tests run in cluster
5. Results feedback to CI
This commit is contained in:
Admin Bot
2026-09-13 14:28:51 +09:00
parent 1e8b0c4ad6
commit d27a271c76
7 changed files with 415 additions and 18 deletions
+73 -18
View File
@@ -47,19 +47,15 @@ jobs:
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 Tekton trigger
run: |
mkdir -p ~/.kube
echo "${KUBECONFIG_B64}" | base64 -d > ~/.kube/config
@@ -67,16 +63,75 @@ jobs:
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
continue-on-error: true
- name: Install kubectl
- name: Trigger integration tests via Tekton PipelineRun
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/
echo "Triggering integration tests via Tekton..."
# Create PipelineRun to run integration tests
kubectl create -f - << 'YAML'
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: integration-test-${{ steps.sha.outputs.short_sha }}
namespace: api
labels:
pr-id: "${{ github.event.pull_request.number || 'main' }}"
commit-sha: "${{ steps.sha.outputs.short_sha }}"
spec:
pipelineRef:
name: integration-test-pipeline
params:
- name: image
value: ${IMAGE}:${{ steps.sha.outputs.short_sha }}
- name: test-timeout
value: "5m"
YAML
echo "✓ PipelineRun created: integration-test-${{ steps.sha.outputs.short_sha }}"
# Wait for PipelineRun completion
echo "Waiting for tests to complete (max 10 minutes)..."
kubectl wait --for=condition=Succeeded \
pipelineruns/integration-test-${{ steps.sha.outputs.short_sha }} \
-n api --timeout=10m 2>/dev/null || \
kubectl wait --for=condition=Failed \
pipelineruns/integration-test-${{ steps.sha.outputs.short_sha }} \
-n api --timeout=1s 2>/dev/null || true
# Get test results
echo ""
echo "=== Test Results ==="
RESULT=$(kubectl get pipelinerun integration-test-${{ steps.sha.outputs.short_sha }} \
-n api -o jsonpath='{.status.conditions[0].reason}')
TEST_MESSAGE=$(kubectl get pipelinerun integration-test-${{ steps.sha.outputs.short_sha }} \
-n api -o jsonpath='{.status.taskRuns[*].status.taskResults[?(@.name=="result")].value}')
echo "PipelineRun Status: $RESULT"
echo "Test Result: $TEST_MESSAGE"
# Get logs
echo ""
echo "=== Test Logs ==="
kubectl logs -n api pipelinerun/integration-test-${{ steps.sha.outputs.short_sha }} || true
# Determine if tests passed
if [ "$RESULT" = "Succeeded" ]; then
echo "✓ Integration tests PASSED"
exit 0
else
echo "✗ Integration tests FAILED"
exit 1
fi
continue-on-error: false
- name: Run integration tests against cluster
- name: Promote image to latest (only if tests passed)
if: success()
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
continue-on-error: true
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
if: always()
run: docker image prune -a --force 2>&1 | tail -3 || true