Skip to content

Commit 9cbc6e0

Browse files
committed
Merge branch 'master' into cmanallen/implement-scm-platform
2 parents 5f6b103 + 720bb11 commit 9cbc6e0

File tree

723 files changed

+26701
-10336
lines changed

Some content is hidden

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

723 files changed

+26701
-10336
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
356356
/static/app/components/arithmeticBuilder/ @getsentry/data-browsing
357357

358358
/static/app/components/charts/ @getsentry/data-browsing
359+
/static/app/chartcuterie/timeseries.tsx @getsentry/data-browsing
359360

360361
/static/app/views/insights/ @getsentry/dashboards
361362

.github/workflows/acceptance.yml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ jobs:
6363
# XXX: MATRIX_INSTANCE_TOTAL must match the matrix size (5 for backend changes, 10 for frontend-only)
6464
MATRIX_INSTANCE_TOTAL: ${{ needs.files-changed.outputs.backend_all == 'true' && '5' || '10' }}
6565
TEST_GROUP_STRATEGY: roundrobin
66+
PYTHONHASHSEED: '0'
67+
XDIST_PER_WORKER_SNUBA: '1'
68+
XDIST_WORKERS: '2'
6669

6770
steps:
6871
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
@@ -74,6 +77,13 @@ jobs:
7477
with:
7578
mode: acceptance-ci
7679

80+
- name: Start Snuba bootstrap
81+
if: env.XDIST_PER_WORKER_SNUBA == '1'
82+
run: |
83+
# Start in background early so it overlaps with webpack and sentry env setup.
84+
# The script polls for ClickHouse readiness itself.
85+
python3 ./.github/actions/setup-devservices/bootstrap-snuba.py &
86+
7787
- name: Step configurations
7888
id: config
7989
run: |
@@ -111,8 +121,20 @@ jobs:
111121
sentry init
112122
./.github/actions/setup-devservices/wait.sh
113123
124+
- name: Wait for Snuba bootstrap
125+
if: env.XDIST_PER_WORKER_SNUBA == '1'
126+
run: |
127+
timeout 600 bash -c 'until [ -f /tmp/snuba-bootstrap-exit ]; do sleep 2; done' ||
128+
{ echo "::error::Timed out waiting for Snuba bootstrap after 600s"; exit 1; }
129+
rc=$(</tmp/snuba-bootstrap-exit)
130+
[ "$rc" -eq 0 ] || { echo "::error::Snuba per-worker bootstrap failed"; exit "$rc"; }
131+
114132
- name: Run acceptance tests (#${{ steps.setup.outputs.matrix-instance-number }} of ${{ steps.setup.outputs.matrix-instance-total }})
115-
run: make run-acceptance
133+
run: |
134+
export PYTEST_ADDOPTS="$PYTEST_ADDOPTS -n ${XDIST_WORKERS} --dist=loadfile"
135+
timeout 1200 make run-acceptance || rc=$?
136+
[ "${rc:-0}" -ne 124 ] || echo "::error::Test run timed out after 20 minutes (possible xdist hang)"
137+
exit "${rc:-0}"
116138
117139
- name: Inspect failure
118140
if: failure()
@@ -126,6 +148,13 @@ jobs:
126148
devservices logs
127149
fi
128150
151+
if [ "${XDIST_PER_WORKER_SNUBA}" = "1" ]; then
152+
for i in $(seq 0 $(( ${XDIST_WORKERS} - 1 ))); do
153+
echo "--- snuba-gw${i} logs ---"
154+
docker logs "snuba-gw${i}" 2>&1 | tail -30 || true
155+
done
156+
fi
157+
129158
- name: Collect test data
130159
uses: ./.github/actions/collect-test-data
131160
if: ${{ !cancelled() }}

.github/workflows/codeql.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ on:
1414
schedule:
1515
- cron: '44 12 * * 1'
1616

17+
concurrency:
18+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
19+
cancel-in-progress: true
20+
1721
jobs:
1822
analyze:
1923
name: Analyze

.github/workflows/enforce-license-compliance.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ name: Enforce License Compliance
33
on:
44
pull_request:
55

6+
concurrency:
7+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
8+
cancel-in-progress: true
9+
610
jobs:
711
enforce-license-compliance:
812
runs-on: ubuntu-latest

.github/workflows/migrations-drift.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
run: make apply-migrations
5252

5353
- name: capture database schema before
54-
run: docker exec postgres-postgres-1 bash -c 'pg_dumpall -U postgres -s' > schema-before
54+
run: docker exec postgres-postgres-1 bash -c 'pg_dumpall -U postgres -s --restrict-key=driftcheck' > schema-before
5555

5656
- name: clear db
5757
run: make drop-db create-db
@@ -65,7 +65,7 @@ jobs:
6565
run: make drop-db apply-migrations
6666

6767
- name: capture database schema after
68-
run: docker exec postgres-postgres-1 bash -c 'pg_dumpall -U postgres -s' > schema-after
68+
run: docker exec postgres-postgres-1 bash -c 'pg_dumpall -U postgres -s --restrict-key=driftcheck' > schema-after
6969

7070
- name: compare schema
7171
run: python3 -um tools.migrations.compare --color schema-before schema-after

.github/workflows/scripts/compute-sentry-selected-tests.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@
8686
re.compile(r"^tests/(acceptance|apidocs|js|tools)/"),
8787
]
8888

89+
# Tests that should always be run even if not explicitly selected.
90+
ALWAYS_RUN_TESTS: set[str] = {
91+
"tests/sentry/taskworker/test_config.py",
92+
}
93+
8994

9095
def _is_test(path: str) -> bool:
9196
return any(path.startswith(d) for d in TEST_DIRS)
@@ -225,6 +230,9 @@ def main() -> int:
225230
print(f"Including {len(existing_changed)} directly changed test files")
226231
affected_test_files.update(existing_changed)
227232

233+
# Always run these tests
234+
affected_test_files.update(ALWAYS_RUN_TESTS)
235+
228236
# Filter to sentry tests only (drop any getsentry tests from coverage)
229237
affected_test_files = {f for f in affected_test_files if _is_test(f)}
230238

.github/workflows/scripts/test_compute_sentry_selected_tests.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
sys.modules["compute_sentry_selected_tests"] = _mod
2020
_spec.loader.exec_module(_mod)
2121

22-
from compute_sentry_selected_tests import _query_coverage, main
22+
from compute_sentry_selected_tests import ALWAYS_RUN_TESTS, _query_coverage, main
2323

2424

2525
def _create_coverage_db(path: str, file_to_contexts: dict[str, list[str]]) -> None:
@@ -178,8 +178,9 @@ def test_selective_returns_matched_tests(self, tmp_path):
178178

179179
gh = gh_output.read_text()
180180
assert "has-selected-tests=true" in gh
181-
assert "test-count=1" in gh
182-
assert output.read_text().strip() == "tests/sentry/test_org.py"
181+
assert f"test-count={1 + len(ALWAYS_RUN_TESTS)}" in gh
182+
expected_output = sorted({"tests/sentry/test_org.py"} | ALWAYS_RUN_TESTS)
183+
assert output.read_text().splitlines() == expected_output
183184

184185
def test_getsentry_tests_filtered_out(self, tmp_path):
185186
"""Coverage may return getsentry tests — they should be filtered."""
@@ -211,8 +212,9 @@ def test_getsentry_tests_filtered_out(self, tmp_path):
211212
{"GITHUB_OUTPUT": str(gh_output)},
212213
)
213214

214-
assert "test-count=1" in gh_output.read_text()
215-
assert output.read_text().strip() == "tests/sentry/test_org.py"
215+
assert f"test-count={1 + len(ALWAYS_RUN_TESTS)}" in gh_output.read_text()
216+
expected_output = sorted({"tests/sentry/test_org.py"} | ALWAYS_RUN_TESTS)
217+
assert output.read_text().splitlines() == expected_output
216218

217219
def test_changed_test_file_included(self, tmp_path):
218220
db_path = tmp_path / "coverage.db"
@@ -236,7 +238,7 @@ def test_changed_test_file_included(self, tmp_path):
236238

237239
gh = gh_output.read_text()
238240
assert "has-selected-tests=true" in gh
239-
assert "test-count=1" in gh
241+
assert f"test-count={1 + len(ALWAYS_RUN_TESTS)}" in gh
240242

241243
def test_excluded_test_dirs_skipped(self, tmp_path):
242244
"""Tests in acceptance/apidocs/js/tools should not be selected."""
@@ -257,10 +259,10 @@ def test_excluded_test_dirs_skipped(self, tmp_path):
257259
{"GITHUB_OUTPUT": str(gh_output)},
258260
)
259261

260-
assert "test-count=0" in gh_output.read_text()
262+
assert f"test-count={len(ALWAYS_RUN_TESTS)}" in gh_output.read_text()
261263

262-
def test_zero_tests_signals_selective_applied(self, tmp_path):
263-
"""0 tests after filtering should signal 'run nothing', not full suite."""
264+
def test_zero_coverage_matches_still_runs_always_run_tests(self, tmp_path):
265+
"""No coverage matches should still run ALWAYS_RUN_TESTS, not the full suite."""
264266
db_path = tmp_path / "coverage.db"
265267
_create_coverage_db(str(db_path), {})
266268
output = tmp_path / "output.txt"
@@ -282,8 +284,8 @@ def test_zero_tests_signals_selective_applied(self, tmp_path):
282284

283285
gh = gh_output.read_text()
284286
assert "has-selected-tests=true" in gh
285-
assert "test-count=0" in gh
286-
assert output.read_text() == ""
287+
assert f"test-count={len(ALWAYS_RUN_TESTS)}" in gh
288+
assert set(output.read_text().splitlines()) == ALWAYS_RUN_TESTS
287289

288290
def test_renamed_file_queries_old_path(self, tmp_path):
289291
"""When a file is renamed, the old path should be queried against the coverage DB."""
@@ -319,8 +321,9 @@ def test_renamed_file_queries_old_path(self, tmp_path):
319321

320322
gh = gh_output.read_text()
321323
assert "has-selected-tests=true" in gh
322-
assert "test-count=1" in gh
323-
assert output.read_text().strip() == "tests/sentry/test_old_name.py"
324+
assert f"test-count={1 + len(ALWAYS_RUN_TESTS)}" in gh
325+
expected_output = sorted({"tests/sentry/test_old_name.py"} | ALWAYS_RUN_TESTS)
326+
assert output.read_text().splitlines() == expected_output
324327

325328
def test_renamed_file_without_previous_misses_coverage(self, tmp_path):
326329
"""Without --previous-filenames, a renamed file gets no coverage hits."""
@@ -349,7 +352,7 @@ def test_renamed_file_without_previous_misses_coverage(self, tmp_path):
349352

350353
gh = gh_output.read_text()
351354
assert "has-selected-tests=true" in gh
352-
assert "test-count=0" in gh
355+
assert f"test-count={len(ALWAYS_RUN_TESTS)}" in gh
353356

354357
def test_missing_db_returns_error(self):
355358
ret = _run(["--coverage-db", "/nonexistent/coverage.db", "--changed-files", "foo.py"])

.github/workflows/sentry-pull-request-bot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ on:
88
pull_request:
99
types: [opened, edited]
1010

11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
13+
cancel-in-progress: true
14+
1115
jobs:
1216
# TODO(billy): Move this into an external action as we add more functionality
1317
test-getsentry:

0 commit comments

Comments
 (0)