Skip to content

Commit 3ee803b

Browse files
committed
feat: First commit to main branch
0 parents  commit 3ee803b

204 files changed

Lines changed: 19544 additions & 0 deletions

File tree

Some content is hidden

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

.github/workflows/ci.yml

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main]
8+
9+
concurrency:
10+
group: ci-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
permissions:
14+
contents: read
15+
16+
jobs:
17+
detect-changes:
18+
name: Detect Changes
19+
runs-on: ubuntu-latest
20+
outputs:
21+
operator: ${{ steps.filter.outputs.operator }}
22+
helm: ${{ steps.filter.outputs.helm }}
23+
ansible: ${{ steps.filter.outputs.ansible }}
24+
compose: ${{ steps.filter.outputs.compose }}
25+
docs: ${{ steps.filter.outputs.docs }}
26+
steps:
27+
- uses: actions/checkout@v4
28+
29+
- name: Detect changed paths
30+
id: filter
31+
uses: dorny/paths-filter@v3
32+
with:
33+
filters: |
34+
operator:
35+
- 'operator/**'
36+
helm:
37+
- 'helm/**'
38+
ansible:
39+
- 'ansible/**'
40+
- 'ansible-k8s/**'
41+
compose:
42+
- 'docker-compose.yml'
43+
docs:
44+
- '**/*.md'
45+
46+
lint-helm:
47+
name: Lint Helm Chart
48+
runs-on: ubuntu-latest
49+
needs: [detect-changes]
50+
if: needs.detect-changes.outputs.helm == 'true' || github.event_name == 'push'
51+
steps:
52+
- uses: actions/checkout@v4
53+
54+
- name: Set up Helm
55+
uses: azure/setup-helm@v4
56+
with:
57+
version: v3.14.0
58+
59+
- name: Helm Lint
60+
run: helm lint helm/telemetryflow --strict
61+
62+
- name: Helm Template (Debug)
63+
run: |
64+
helm template telemetryflow helm/telemetryflow \
65+
--namespace telemetryflow \
66+
-f helm/telemetryflow/values.yaml \
67+
-f helm/telemetryflow/manifest/tfo-staging.yaml \
68+
--debug > /dev/null
69+
70+
lint-ansible:
71+
name: Lint Ansible Playbooks
72+
runs-on: ubuntu-latest
73+
needs: [detect-changes]
74+
if: needs.detect-changes.outputs.ansible == 'true' || github.event_name == 'push'
75+
steps:
76+
- uses: actions/checkout@v4
77+
78+
- name: Lint ansible/
79+
uses: ansible/ansible-lint-action@v6
80+
with:
81+
working-directory: ansible
82+
83+
- name: Lint ansible-k8s/
84+
uses: ansible/ansible-lint-action@v6
85+
with:
86+
working-directory: ansible-k8s
87+
88+
lint-operator:
89+
name: Lint Operator (Go)
90+
runs-on: ubuntu-latest
91+
needs: [detect-changes]
92+
if: needs.detect-changes.outputs.operator == 'true'
93+
steps:
94+
- uses: actions/checkout@v4
95+
96+
- name: Set up Go
97+
uses: actions/setup-go@v5
98+
with:
99+
go-version: "1.26"
100+
cache-dependency-path: operator/go.sum
101+
102+
- name: Go Vet
103+
working-directory: operator
104+
run: go vet ./...
105+
106+
- name: Go Fmt Check
107+
working-directory: operator
108+
run: |
109+
fmt_output="$(gofmt -l .)"
110+
if [ -n "$fmt_output" ]; then
111+
echo "::error::Files not formatted: $fmt_output"
112+
exit 1
113+
fi
114+
115+
test-operator:
116+
name: Test Operator (envtest)
117+
runs-on: ubuntu-latest
118+
needs: [detect-changes]
119+
if: needs.detect-changes.outputs.operator == 'true'
120+
steps:
121+
- uses: actions/checkout@v4
122+
123+
- name: Set up Go
124+
uses: actions/setup-go@v5
125+
with:
126+
go-version: "1.26"
127+
cache-dependency-path: operator/go.sum
128+
129+
- name: Run Tests
130+
working-directory: operator
131+
run: make test
132+
133+
validate-compose:
134+
name: Validate Docker Compose
135+
runs-on: ubuntu-latest
136+
needs: [detect-changes]
137+
if: needs.detect-changes.outputs.compose == 'true' || github.event_name == 'push'
138+
steps:
139+
- uses: actions/checkout@v4
140+
141+
- name: Validate docker-compose.yml
142+
run: docker compose -f docker-compose.yml config --quiet
143+
144+
security-scan:
145+
name: Scan for Secrets
146+
runs-on: ubuntu-latest
147+
steps:
148+
- uses: actions/checkout@v4
149+
with:
150+
fetch-depth: 0
151+
152+
- name: Gitleaks Scan
153+
uses: gitleaks/gitleaks-action@v2
154+
env:
155+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
156+
157+
validate-docs:
158+
name: Validate Documentation
159+
runs-on: ubuntu-latest
160+
needs: [detect-changes]
161+
if: needs.detect-changes.outputs.docs == 'true' || github.event_name == 'push'
162+
steps:
163+
- uses: actions/checkout@v4
164+
165+
- name: Check Markdown Files Exist
166+
run: |
167+
REQUIRED_FILES=("README.md" "CHANGELOG.md" "CONTRIBUTING.md" "SECURITY.md")
168+
for f in "${REQUIRED_FILES[@]}"; do
169+
if [ ! -f "$f" ]; then
170+
echo "::error::Required file missing: $f"
171+
exit 1
172+
fi
173+
done
174+
175+
- name: Check Markdown Links
176+
uses: tcort/github-action-markdown-link-check@v1
177+
with:
178+
use-quiet-mode: yes
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Deploy EKS Production
2+
#
3+
# Triggered after CI passes on the main branch.
4+
# Uses GitHub Environment "eks-production" with strict protection rules:
5+
# - Required reviewers: enabled (must approve before deployment proceeds)
6+
# - Wait timer: 5 minutes
7+
# - Separate environment secrets
8+
#
9+
# APPROVAL EMAIL NOTIFICATION:
10+
# GitHub automatically sends email notifications to all designated environment
11+
# reviewers when a deployment is pending approval. Configure reviewers in:
12+
# Settings > Environments > eks-production > Required reviewers
13+
#
14+
# ROLLBACK:
15+
# To rollback, run manually:
16+
# helm rollback telemetryflow [REVISION] -n telemetryflow
17+
# Or re-run this workflow from a previous commit on main.
18+
19+
name: Deploy EKS Production
20+
21+
on:
22+
workflow_run:
23+
workflows: [CI]
24+
types: [completed]
25+
branches: [main]
26+
27+
concurrency:
28+
group: deploy_eks_production
29+
cancel-in-progress: false
30+
31+
permissions:
32+
contents: read
33+
id-token: write
34+
35+
env:
36+
HELM_CHART: helm/telemetryflow
37+
RELEASE_NAME: telemetryflow
38+
NAMESPACE: telemetryflow
39+
40+
jobs:
41+
deploy:
42+
name: Deploy to EKS Production
43+
runs-on: ubuntu-latest
44+
environment:
45+
name: eks-production
46+
# Protection rules configured in GitHub Settings > Environments:
47+
# - Required reviewers: enabled
48+
# - Wait timer: 5 minutes
49+
steps:
50+
- uses: actions/checkout@v4
51+
52+
- name: Configure AWS Credentials
53+
uses: aws-actions/configure-aws-credentials@v4
54+
with:
55+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
56+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
57+
aws-region: ${{ secrets.AWS_REGION }}
58+
59+
- name: Login to Amazon ECR
60+
uses: aws-actions/amazon-ecr-login@v2
61+
62+
- name: Set up Helm
63+
uses: azure/setup-helm@v4
64+
with:
65+
version: v3.14.0
66+
67+
- name: Set up kubectl
68+
uses: azure/setup-kubectl@v3
69+
70+
- name: Update kubeconfig for EKS
71+
run: |
72+
aws eks update-kubeconfig --name ${{ secrets.EKS_CLUSTER_NAME }} --region ${{ secrets.AWS_REGION }}
73+
74+
- name: Verify Required Secrets in Namespace
75+
run: |
76+
REQUIRED_SECRETS=(
77+
"JWT_SECRET"
78+
"SESSION_SECRET"
79+
"ENCRYPTION_KEY"
80+
"POSTGRES_PASSWORD"
81+
"CLICKHOUSE_PASSWORD"
82+
"REDIS_PASSWORD"
83+
)
84+
MISSING=0
85+
for secret in "${REQUIRED_SECRETS[@]}"; do
86+
if ! kubectl get secret telemetryflow-secrets -n "$NAMESPACE" -o jsonpath="{.data.$secret}" &>/dev/null; then
87+
echo "::warning::Secret '$secret' not found in telemetryflow-secrets"
88+
MISSING=1
89+
fi
90+
done
91+
if [ "$MISSING" -eq 1 ]; then
92+
echo "::error::Required secrets are missing. Run scripts/generate-secrets.sh first."
93+
exit 1
94+
fi
95+
96+
- name: Install CRDs
97+
run: bash scripts/install-crds.sh
98+
99+
- name: Deploy via Helm
100+
run: |
101+
helm upgrade "$RELEASE_NAME" "$HELM_CHART" \
102+
--install \
103+
--namespace "$NAMESPACE" \
104+
--create-namespace \
105+
-f helm/telemetryflow/values.yaml \
106+
-f helm/telemetryflow/manifest/tfo-eks-production.yaml \
107+
--timeout 10m \
108+
--wait \
109+
--history-max 5
110+
111+
- name: Smoke Test
112+
run: |
113+
BACKEND_URL="$(kubectl get svc "$RELEASE_NAME"-tfo-backend -n "$NAMESPACE" -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' 2>/dev/null || echo "")"
114+
if [ -z "$BACKEND_URL" ]; then
115+
echo "No external hostname found, skipping smoke test"
116+
exit 0
117+
fi
118+
HTTP_CODE="$(curl -s -o /dev/null -w "%{http_code}" "http://${BACKEND_URL}:8080/health/live" --max-time 10 || echo "000")"
119+
if [ "$HTTP_CODE" -ne 200 ]; then
120+
echo "::warning::Smoke test returned HTTP $HTTP_CODE"
121+
else
122+
echo "Smoke test passed (HTTP 200)"
123+
fi
124+
125+
- name: Print Pod Status
126+
if: always()
127+
run: kubectl get pods -n "$NAMESPACE" -l app.kubernetes.io/instance="$RELEASE_NAME"
128+
129+
- name: Print HPA Status
130+
if: always()
131+
run: kubectl get hpa -n "$NAMESPACE" || echo "No HPA resources found"

0 commit comments

Comments
 (0)