Skip to content

Commit 8a5c2a6

Browse files
committed
feat: add enhanced testing infrastructure and deployment automation
- Add comprehensive testing strategy with integration, E2E, and performance tests - Create Docker multi-stage builds with development and production configurations - Implement Kubernetes manifests for multi-environment deployment (dev/staging/prod) - Add GitHub Actions workflows for CI/CD with Docker builds and Kubernetes deployment - Create monitoring stack with Prometheus, Grafana, and Loki for observability - Update package.json with new test scripts and dependencies - Add test utilities and helpers for comprehensive testing coverage
1 parent fe229ba commit 8a5c2a6

45 files changed

Lines changed: 7619 additions & 94 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/cd-docker.yml

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
name: CD - Docker Build and Push
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
tags: ['v*']
7+
pull_request:
8+
branches: [main]
9+
workflow_dispatch:
10+
11+
env:
12+
REGISTRY: ghcr.io
13+
IMAGE_NAME: ${{ github.repository }}
14+
15+
jobs:
16+
build-and-push:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
packages: write
21+
id-token: write
22+
23+
steps:
24+
- name: Checkout repository
25+
uses: actions/checkout@v4
26+
27+
- name: Set up Docker Buildx
28+
uses: docker/setup-buildx-action@v3
29+
30+
- name: Log in to Container Registry
31+
uses: docker/login-action@v3
32+
with:
33+
registry: ${{ env.REGISTRY }}
34+
username: ${{ github.actor }}
35+
password: ${{ secrets.GITHUB_TOKEN }}
36+
37+
- name: Extract metadata for Docker
38+
id: meta
39+
uses: docker/metadata-action@v5
40+
with:
41+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
42+
tags: |
43+
type=ref,event=branch
44+
type=ref,event=pr
45+
type=semver,pattern={{version}}
46+
type=semver,pattern={{major}}.{{minor}}
47+
type=sha,prefix={{branch}}-
48+
type=raw,value=latest,enable={{is_default_branch}}
49+
50+
- name: Build and push Docker image
51+
uses: docker/build-push-action@v5
52+
with:
53+
context: .
54+
push: ${{ github.event_name != 'pull_request' }}
55+
tags: ${{ steps.meta.outputs.tags }}
56+
labels: ${{ steps.meta.outputs.labels }}
57+
cache-from: type=gha
58+
cache-to: type=gha,mode=max
59+
platforms: linux/amd64,linux/arm64
60+
61+
- name: Run security scan
62+
if: github.event_name != 'pull_request'
63+
uses: aquasecurity/trivy-action@master
64+
with:
65+
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
66+
format: 'sarif'
67+
output: 'trivy-results.sarif'
68+
severity: 'CRITICAL,HIGH'
69+
70+
- name: Upload security scan results
71+
if: github.event_name != 'pull_request'
72+
uses: github/codeql-action/upload-sarif@v3
73+
with:
74+
sarif_file: 'trivy-results.sarif'
75+
76+
test-docker:
77+
runs-on: ubuntu-latest
78+
needs: build-and-push
79+
if: github.event_name != 'pull_request'
80+
81+
steps:
82+
- name: Checkout repository
83+
uses: actions/checkout@v4
84+
85+
- name: Set up Docker Buildx
86+
uses: docker/setup-buildx-action@v3
87+
88+
- name: Log in to Container Registry
89+
uses: docker/login-action@v3
90+
with:
91+
registry: ${{ env.REGISTRY }}
92+
username: ${{ github.actor }}
93+
password: ${{ secrets.GITHUB_TOKEN }}
94+
95+
- name: Run container tests
96+
run: |
97+
# Pull the built image
98+
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
99+
100+
# Test 1: Container starts
101+
docker run --rm -d --name test-container \
102+
-p 3000:3000 \
103+
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
104+
105+
# Wait for container to start
106+
sleep 10
107+
108+
# Test 2: Health check
109+
curl -f http://localhost:3000/health || exit 1
110+
111+
# Test 3: Stop container
112+
docker stop test-container
113+
114+
# Test 4: Run with different configurations
115+
docker run --rm --name test-debug \
116+
-e NODE_ENV=development \
117+
-e DEBUG_ENABLED=true \
118+
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
119+
node --version
120+
121+
echo "✅ All Docker tests passed"
122+
123+
deploy-staging:
124+
runs-on: ubuntu-latest
125+
needs: [build-and-push, test-docker]
126+
if: github.ref == 'refs/heads/develop' || github.event_name == 'workflow_dispatch'
127+
environment: staging
128+
129+
steps:
130+
- name: Checkout repository
131+
uses: actions/checkout@v4
132+
133+
- name: Set up kubectl
134+
uses: azure/setup-kubectl@v3
135+
with:
136+
version: 'latest'
137+
138+
- name: Configure kubectl
139+
run: |
140+
mkdir -p $HOME/.kube
141+
echo "${{ secrets.KUBECONFIG_STAGING }}" | base64 --decode > $HOME/.kube/config
142+
kubectl config use-context ${{ secrets.KUBERNETES_CONTEXT_STAGING }}
143+
144+
- name: Deploy to staging
145+
run: |
146+
# Update image tag in kustomization
147+
cd k8s/overlays/staging
148+
kustomize edit set image everything-opencode=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
149+
150+
# Apply configuration
151+
kubectl apply -k . --namespace everything-opencode-staging
152+
153+
# Wait for rollout
154+
kubectl rollout status deployment/everything-opencode --namespace everything-opencode-staging --timeout=300s
155+
kubectl rollout status deployment/pinescript-debug --namespace everything-opencode-staging --timeout=300s
156+
kubectl rollout status deployment/command-runners --namespace everything-opencode-staging --timeout=300s
157+
158+
- name: Run staging tests
159+
run: |
160+
# Get staging ingress URL
161+
STAGING_URL=$(kubectl get ingress everything-opencode --namespace everything-opencode-staging -o jsonpath='{.spec.rules[0].host}')
162+
163+
# Wait for service to be ready
164+
sleep 30
165+
166+
# Run smoke tests
167+
curl -f https://$STAGING_URL/health || exit 1
168+
echo "✅ Staging deployment successful"
169+
170+
deploy-production:
171+
runs-on: ubuntu-latest
172+
needs: [build-and-push, test-docker, deploy-staging]
173+
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
174+
environment: production
175+
176+
steps:
177+
- name: Checkout repository
178+
uses: actions/checkout@v4
179+
180+
- name: Set up kubectl
181+
uses: azure/setup-kubectl@v3
182+
with:
183+
version: 'latest'
184+
185+
- name: Configure kubectl
186+
run: |
187+
mkdir -p $HOME/.kube
188+
echo "${{ secrets.KUBECONFIG_PRODUCTION }}" | base64 --decode > $HOME/.kube/config
189+
kubectl config use-context ${{ secrets.KUBERNETES_CONTEXT_PRODUCTION }}
190+
191+
- name: Extract version
192+
id: version
193+
run: |
194+
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
195+
VERSION=${GITHUB_REF#refs/tags/v}
196+
else
197+
VERSION=$(date +%Y%m%d-%H%M%S)
198+
fi
199+
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
200+
echo "TAG=v$VERSION" >> $GITHUB_OUTPUT
201+
202+
- name: Deploy to production
203+
run: |
204+
# Update image tag in kustomization
205+
cd k8s/overlays/prod
206+
kustomize edit set image everything-opencode=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.TAG }}
207+
208+
# Apply configuration
209+
kubectl apply -k . --namespace everything-opencode
210+
211+
# Wait for rollout
212+
kubectl rollout status deployment/everything-opencode --namespace everything-opencode --timeout=300s
213+
kubectl rollout status deployment/pinescript-debug --namespace everything-opencode --timeout=300s
214+
kubectl rollout status deployment/command-runners --namespace everything-opencode --timeout=300s
215+
216+
- name: Run production tests
217+
run: |
218+
# Get production ingress URL
219+
PROD_URL=$(kubectl get ingress everything-opencode --namespace everything-opencode -o jsonpath='{.spec.rules[0].host}')
220+
221+
# Wait for service to be ready
222+
sleep 60
223+
224+
# Run comprehensive tests
225+
curl -f https://$PROD_URL/health || exit 1
226+
227+
# Test main endpoints
228+
curl -f https://$PROD_URL/api/status || exit 1
229+
230+
echo "✅ Production deployment successful"
231+
232+
- name: Create GitHub release
233+
if: startsWith(github.ref, 'refs/tags/v')
234+
uses: softprops/action-gh-release@v1
235+
with:
236+
generate_release_notes: true
237+
files: |
238+
k8s/overlays/prod/*
239+
tag_name: ${{ steps.version.outputs.TAG }}
240+
env:
241+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)