Skip to content

Commit 02c21c3

Browse files
authored
Merge branch 'main' into feat/hedged-reads
2 parents 104cf23 + e541c6b commit 02c21c3

596 files changed

Lines changed: 71522 additions & 21818 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.

.adr-dir

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docs/adr

.dockerignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Exclude the .git directory and scratch artefacts so the build context stays small
2+
# and reproducible.
3+
.git
4+
.gitignore
5+
.github
6+
7+
# Local config and secrets (env files must never ship in the image).
8+
.env
9+
.env.*
10+
*.pem
11+
*.key
12+
audit.log
13+
coverage.out
14+
coverage.html
15+
16+
# CI / development helpers
17+
scripts
18+
tools
19+
tests/integration
20+
staging
21+
tmp
22+
23+
# Editor / OS junk
24+
.DS_Store
25+
*.swp
26+
*.swo
27+
28+
# Coverage profiles and reports (regenerated in CI).
29+
*.coverprofile
30+
31+
# Built binary (regenerated in Dockerfile).
32+
stellarbill-backend
33+
.git
34+
.github
35+
docs
36+
*.md
37+
LICENSE
38+
Makefile

.github/workflows/benchmarks.yml

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -81,41 +81,26 @@ jobs:
8181
- name: Enforce benchmark thresholds
8282
run: |
8383
go test ./internal/handlers/... -bench=. -benchmem -benchtime=3s -run=^$ 2>&1 | tee threshold_check.txt
84-
84+
8585
# Check PlansSmall
8686
SMALL_LATENCY=$(grep -oP 'Plans/Small\t*\d+\s+ns/op' threshold_check.txt | awk '{print $2}')
8787
if [ -n "$SMALL_LATENCY" ] && [ "$SMALL_LATENCY" -gt 30000 ]; then
8888
echo "❌ Plans Small latency ($SMALL_LATENCY ns) exceeds threshold (30000 ns)"
8989
exit 1
9090
fi
91-
92-
# Check SubscriptionsSmall
91+
92+
# Check SubscriptionsSmall
9393
SUB_LATENCY=$(grep -oP 'Subscriptions/Small\t*\d+\s+ns/op' threshold_check.txt | awk '{print $2}')
9494
if [ -n "$SUB_LATENCY" ] && [ "$SUB_LATENCY" -gt 35000 ]; then
9595
echo "❌ Subscriptions Small latency ($SUB_LATENCY ns) exceeds threshold (35000 ns)"
9696
exit 1
9797
fi
98-
99-
echo "✅ All benchmark thresholds enforced"
100-
101-
- name: Enforce benchmark thresholds
102-
run: |
98+
10399
echo "## Performance Threshold Check" >> $GITHUB_STEP_SUMMARY
104-
105-
# Run threshold-enforcing benchmarks
106-
go test ./internal/handlers/... -run=^TestBenchmarkThresholds -v | tee threshold_check.txt
107-
108-
# Check if thresholds are being met
109-
if grep -q "FAIL\|FAIL" threshold_check.txt; then
110-
echo "❌ Performance thresholds not met"
111-
cat threshold_check.txt >> $GITHUB_STEP_SUMMARY
112-
exit 1
113-
fi
114-
115-
echo "✅ All benchmark thresholds passed"
116100
echo '```' >> $GITHUB_STEP_SUMMARY
117101
cat threshold_check.txt >> $GITHUB_STEP_SUMMARY
118102
echo '```' >> $GITHUB_STEP_SUMMARY
103+
echo "✅ All benchmark thresholds enforced"
119104
120105
- name: Upload results
121106
uses: actions/upload-artifact@v4
@@ -130,17 +115,19 @@ jobs:
130115
uses: actions/upload-artifact@v4
131116
with:
132117
name: benchmark-baseline
133-
path: new.txt
118+
path: |
119+
handlers_new.txt
120+
subscriptions_new.txt
134121
135122
security:
136123
runs-on: ubuntu-latest
137-
124+
138125
steps:
139126
- name: Checkout code
140-
uses: actions/checkout@v3
141-
127+
uses: actions/checkout@v4
128+
142129
- name: Set up Go
143-
uses: actions/setup-go@v4
130+
uses: actions/setup-go@v5
144131
with:
145132
go-version: '1.22'
146133

.github/workflows/buf.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Buf Lint
2+
3+
# Runs Buf lint and breaking-change detection on every push and PR.
4+
# Proto files live in proto/; OpenAPI linting is handled via buf plugins
5+
# when a buf.build/community/stephanain-openapi plugin is configured.
6+
#
7+
# This job is intentionally separate from ci.yml so it can be required
8+
# independently on branch protection rules.
9+
10+
on:
11+
push:
12+
branches: [main, master, develop]
13+
paths:
14+
- 'proto/**'
15+
- 'openapi/**'
16+
- 'buf.yaml'
17+
- 'buf.gen.yaml'
18+
- '.github/workflows/buf.yml'
19+
pull_request:
20+
branches: [main, master, develop]
21+
paths:
22+
- 'proto/**'
23+
- 'openapi/**'
24+
- 'buf.yaml'
25+
- 'buf.gen.yaml'
26+
- '.github/workflows/buf.yml'
27+
28+
concurrency:
29+
group: buf-${{ github.ref }}
30+
cancel-in-progress: true
31+
32+
jobs:
33+
buf-lint:
34+
name: Buf Lint & Breaking Check
35+
runs-on: ubuntu-latest
36+
steps:
37+
- name: Checkout
38+
uses: actions/checkout@v4
39+
with:
40+
# Full history required for breaking-change detection against main.
41+
fetch-depth: 0
42+
43+
- name: Set up Buf
44+
uses: bufbuild/buf-setup-action@v1
45+
with:
46+
version: '1.32.2'
47+
github_token: ${{ secrets.GITHUB_TOKEN }}
48+
49+
- name: Buf lint
50+
run: buf lint
51+
# Lint always runs; an empty proto/ dir with no .proto files
52+
# is valid — buf exits 0 when there is nothing to lint.
53+
54+
- name: Buf breaking-change detection
55+
# Only run on pull_request so we always have a clear base branch.
56+
if: github.event_name == 'pull_request'
57+
run: |
58+
buf breaking --against '.git#branch=${{ github.base_ref }}'
59+
# This step FAILS if a field is removed, a type is changed, or an
60+
# enum value is removed relative to the base branch.
61+
# Use `buf breaking --error-format=json` for machine-parseable output.
62+
63+
- name: Buf lint report (summary)
64+
if: failure()
65+
run: |
66+
echo "## Buf Lint Report" >> "$GITHUB_STEP_SUMMARY"
67+
echo '```' >> "$GITHUB_STEP_SUMMARY"
68+
buf lint --error-format=text 2>&1 || true >> "$GITHUB_STEP_SUMMARY"
69+
echo '```' >> "$GITHUB_STEP_SUMMARY"
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Chaos Migration Drill
2+
3+
# Nightly chaos drill: starts a migration, kills Postgres mid-flight,
4+
# restarts it, and verifies the runner recovers cleanly.
5+
#
6+
# SAFETY: runs only on ephemeral containers — never against a shared DB.
7+
# The workflow does NOT require DATABASE_URL from secrets; it spins up
8+
# a throwaway Postgres container on the runner itself.
9+
10+
on:
11+
schedule:
12+
# Nightly at 02:00 UTC (low-traffic window)
13+
- cron: '0 2 * * *'
14+
workflow_dispatch:
15+
inputs:
16+
kill_delay_min:
17+
description: 'Min seconds before kill (float)'
18+
default: '0.05'
19+
required: false
20+
kill_delay_max:
21+
description: 'Max seconds before kill (float)'
22+
default: '2.0'
23+
required: false
24+
pull_request:
25+
branches: [main, master, develop]
26+
paths:
27+
- 'internal/migrations/**'
28+
- 'scripts/drills/kill_pg_migration.sh'
29+
- '.github/workflows/chaos-migration-drill.yml'
30+
- 'migrations/**'
31+
32+
concurrency:
33+
group: chaos-drill-${{ github.ref }}
34+
cancel-in-progress: true
35+
36+
jobs:
37+
chaos-migration-drill:
38+
name: Kill-During-Migration Drill
39+
runs-on: ubuntu-latest
40+
# Hard timeout: the drill should complete well within 10 minutes.
41+
timeout-minutes: 10
42+
43+
steps:
44+
- name: Checkout
45+
uses: actions/checkout@v4
46+
47+
- name: Set up Go
48+
uses: actions/setup-go@v5
49+
with:
50+
go-version-file: go.mod
51+
cache: true
52+
53+
- name: Run chaos migration drill
54+
env:
55+
POSTGRES_IMAGE: postgres:17-alpine
56+
POSTGRES_CONTAINER: stellabill-chaos-pg
57+
POSTGRES_USER: drill
58+
POSTGRES_PASSWORD: drill
59+
POSTGRES_DB: drill
60+
POSTGRES_PORT: '15432'
61+
KILL_DELAY_MIN: ${{ github.event.inputs.kill_delay_min || '0.05' }}
62+
KILL_DELAY_MAX: ${{ github.event.inputs.kill_delay_max || '2.0' }}
63+
RESULTS_CSV: drill-results.csv
64+
SLACK_WEBHOOK_URL: ${{ secrets.CHAOS_DRILL_SLACK_WEBHOOK }}
65+
run: bash scripts/drills/kill_pg_migration.sh
66+
67+
- name: Upload drill results artifact
68+
if: always()
69+
uses: actions/upload-artifact@v4
70+
with:
71+
name: chaos-drill-results-${{ github.run_id }}
72+
path: |
73+
drill-results.csv
74+
/tmp/drill-migrate-pre.log
75+
/tmp/drill-migrate-post.log
76+
retention-days: 30
77+
78+
- name: Summarise result
79+
if: always()
80+
run: |
81+
echo "## Chaos Migration Drill Results" >> "$GITHUB_STEP_SUMMARY"
82+
echo '```' >> "$GITHUB_STEP_SUMMARY"
83+
cat drill-results.csv 2>/dev/null || echo "(no results file)"
84+
echo '```' >> "$GITHUB_STEP_SUMMARY"
85+
86+
- name: Notify on failure (no Slack webhook configured)
87+
if: failure() && env.SLACK_WEBHOOK_URL == ''
88+
run: |
89+
echo "::warning::Chaos drill failed. Configure CHAOS_DRILL_SLACK_WEBHOOK secret for Slack notifications."
90+
env:
91+
SLACK_WEBHOOK_URL: ${{ secrets.CHAOS_DRILL_SLACK_WEBHOOK }}

0 commit comments

Comments
 (0)