Skip to content

Commit 36218ca

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/package-repo-tiebreak
Signed-off-by: anilb <epipav@gmail.com> # Conflicts: # services/libs/data-access-layer/src/osspckgs/api.ts
2 parents ecab2d3 + 637c408 commit 36218ca

852 files changed

Lines changed: 71764 additions & 5260 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.

.claude/rules/skill-guidance.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ This project has guided skills for common workflows. **Proactively suggest the r
1818
| `/scaffold-snowflake-connector` | Add a new Snowflake-connector data source or integration |
1919
| `/packages-worker-setup` | First-time setup of packages-db and github-repos-enricher for a new engineer |
2020
| `/packages-worker-add-entrypoint` | Scaffold a new sibling worker inside packages_worker (npm, OSV, scorecard, etc.) |
21+
| `/write-unit-tests` | Add or improve Vitest unit tests for business logic, DAL, or server modules |
22+
| `/write-api-e2e-tests` | Add or change Public API e2e / smoke / contract tests |
2123

2224
## Trigger Phrases
2325

@@ -57,3 +59,14 @@ This project has guided skills for common workflows. **Proactively suggest the r
5759
- "Add a new packages worker", "scaffold a sibling worker", "new entry point in packages_worker"
5860
- "Add npm ingestion", "add OSV worker", "add scorecard runner"
5961
- Any request to create a new `src/bin/*.ts` worker inside `packages_worker`
62+
63+
**`/write-unit-tests`** — match any of these intents:
64+
- "Write unit tests", "add a unit test", "cover this with Vitest"
65+
- "Test this function", "add DAL tests", "unit test for affiliations/merges/inference"
66+
- Any request for focused server/unit test coverage (not HTTP/API contract tests)
67+
- Not for `packages_worker` (excluded from `pnpm test:server` for now)
68+
69+
**`/write-api-e2e-tests`** — match any of these intents:
70+
- "Write API e2e tests", "add smoke tests", "Public API contract tests"
71+
- "Cover this endpoint end-to-end", "API regression test"
72+
- Any request for HTTP/API e2e coverage of Public API behaviour
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
name: write-api-e2e-tests
3+
description: >
4+
Write API end-to-end tests. Use when adding or changing API endpoints, or when
5+
the user asks for API e2e, smoke, or contract tests.
6+
allowed-tools: Bash, Read, Glob, Grep, Edit, Write, AskUserQuestion
7+
---
8+
9+
# Write API end-to-end tests
10+
11+
Write or extend API end-to-end tests.
12+
13+
## When to use
14+
15+
- New or changed API endpoints.
16+
- User asks for API e2e, smoke, or contract tests.
17+
- Critical API behaviour needs regression coverage.
18+
19+
## When not to use
20+
21+
- Domain or SQL correctness → use `write-unit-tests`.
22+
- Temporal, OpenSearch, or other eventual side effects outside the documented API e2e scope.
23+
- Creating a new testing framework or suite style.
24+
25+
## Source of truth
26+
27+
Read before writing. Follow these ADRs and existing suite structure; do not
28+
invent a parallel testing style.
29+
30+
- [ADR-0012](../../../docs/adr/0012-api-e2e-test-architecture.md) — runtime, isolation, supported surfaces, scope, and assertions.
31+
- [ADR-0013](../../../docs/adr/0013-api-e2e-test-suite-design.md) — suite organisation, helpers, and conventions.
32+
33+
Current default entrypoint:
34+
35+
- `.github/scripts/public-api-e2e-tests.sh`
36+
37+
## Workflow
38+
39+
1. Identify the API surface. Default to Public API unless the user specifies otherwise.
40+
2. Read ADR-0012 and ADR-0013.
41+
3. Add or extend the appropriate suite and register it if required.
42+
4. Run the affected suite locally and fix failures until green.
43+
5. If required fixtures cannot be created through the API, prefer testing supported scenarios and explain any coverage gaps instead of seeding the database directly.
44+
6. Suggest production testability improvements only when they make the API easier to test, and ask before changing production code.
45+
46+
## Run
47+
48+
Export the environment variables required by the suite entrypoint.
49+
50+
```bash
51+
bash .github/scripts/public-api-e2e-tests.sh
52+
```
53+
54+
Refer to ADR-0012 and the suite entrypoint for environment setup, reset behaviour,
55+
and local development workflows.
56+
57+
## Guardrails
58+
59+
- Keep tests focused on observable API behaviour.
60+
61+
## Output
62+
63+
- Suites and cases added
64+
- How to re-run
65+
- Coverage gaps, if any
66+
- Optional testability suggestions
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
name: write-unit-tests
3+
description: >
4+
Write focused Vitest unit tests. Use when adding or improving unit tests for
5+
business logic, data access, common services, or other server modules.
6+
allowed-tools: Bash, Read, Glob, Grep, Edit, Write, AskUserQuestion
7+
---
8+
9+
# Write unit tests
10+
11+
Write focused unit tests that follow the project's testing conventions.
12+
13+
## When to use
14+
15+
- User asks to add or improve unit tests.
16+
- A change touches high-blast-radius logic (affiliations, merges, identity resolution, timelines, inference).
17+
- A PR needs confidence in a pure or Postgres-backed function.
18+
19+
## When not to use
20+
21+
- Public or HTTP contract coverage → use `write-api-e2e-tests`.
22+
- `packages_worker` (excluded from `pnpm test:server` for now; own vitest/packages-db).
23+
- Temporal, Redis, or OpenSearch fixtures (not available yet).
24+
- Broad "increase coverage %" requests without a clear unit under test.
25+
26+
## Source of truth
27+
28+
Read before writing. Follow these ADRs; do not invent a parallel testing style.
29+
30+
- [ADR-0008](../../../docs/adr/0008-how-we-write-unit-tests.md) — scenarios, `describe` grouping, assertions, mocking, and shared setup.
31+
- [ADR-0007](../../../docs/adr/0007-test-factory-primitives-and-defaults.md) — factories and defaults.
32+
33+
## Workflow
34+
35+
1. Identify the unit under test (one function or decision path). Colocate tests as `<file>.test.ts`.
36+
2. Read ADR-0007 and ADR-0008. Skim the nearest existing test in the same area if one exists.
37+
3. Compose fixtures using `@crowd/test-kit` (`withQx` for Postgres-backed tests; factories and opt-in defaults per ADR-0007).
38+
4. Write focused scenarios following ADR-0008 (grouping, naming, assertions, and mocking).
39+
5. Run the affected tests and fix failures until green.
40+
6. If production code is difficult to test, suggest a small testability seam and ask before changing production code.
41+
42+
## Run
43+
44+
Start the test database when needed:
45+
46+
```bash
47+
./scripts/cli scaffold up-test
48+
```
49+
50+
Run a focused test file:
51+
52+
```bash
53+
pnpm test:server -- path/to/file.test.ts
54+
```
55+
56+
Optional:
57+
58+
```bash
59+
pnpm test:changed
60+
pnpm test:watch -- path/to/file.test.ts
61+
```
62+
63+
## Guardrails
64+
65+
- Prefer critical behaviours over trivial getters, setters, and thin wrappers.
66+
- Keep production behaviour unchanged unless the user explicitly asks for a testability improvement.
67+
68+
## Output
69+
70+
- Scenarios covered
71+
- How to re-run
72+
- Optional testability suggestions

.env.test

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
NODE_ENV=test
2+
DB_HOST=localhost
3+
DB_PORT=5434
4+
DB_USER=postgres
5+
DB_PASSWORD=example
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
: "${SLACK_WEBHOOK_URL:?}"
5+
: "${RUN_URL:?}"
6+
: "${EVENT_NAME:?}"
7+
: "${ALERT_TITLE:?}"
8+
9+
failed_step() {
10+
local pairs=(
11+
"${OUTCOME_RESOLVE_TAG}:Resolve deploy image tag"
12+
"${OUTCOME_DEPLOY}:Deploy api-e2e"
13+
"${OUTCOME_HEALTH}:Wait for api-e2e service to be ready"
14+
"${OUTCOME_E2E}:Run e2e tests"
15+
)
16+
local pair outcome label
17+
for pair in "${pairs[@]}"; do
18+
outcome="${pair%%:*}"
19+
label="${pair#*:}"
20+
if [[ "$outcome" == "failure" ]]; then
21+
printf '%s\n' "$label"
22+
return
23+
fi
24+
done
25+
printf 'unknown\n'
26+
}
27+
28+
read_summary() {
29+
local path="${E2E_SUMMARY_PATH:-e2e.summary}"
30+
results=""
31+
failures=""
32+
33+
[[ -f "$path" ]] || return 0
34+
35+
local passed failed
36+
passed="$(awk -F= '/^passed=/{print $2; exit}' "$path")"
37+
failed="$(awk -F= '/^failed=/{print $2; exit}' "$path")"
38+
if [[ -n "${passed}" || -n "${failed}" ]]; then
39+
results="Passed: ${passed:-?} / Failed: ${failed:-?}"
40+
fi
41+
failures="$(awk '/^FAIL /{print; if (++n == 10) exit}' "$path")"
42+
}
43+
44+
sha_short="${DEPLOY_TAG:-unknown}"
45+
sha_short="${sha_short:0:12}"
46+
47+
read_summary
48+
49+
lines=(
50+
":rotating_light: *${ALERT_TITLE}*"
51+
"*Event:* \`${EVENT_NAME}\`"
52+
"*Failed step:* \`$(failed_step)\`"
53+
"*Deploy SHA:* \`${sha_short}\`"
54+
"*Run:* <${RUN_URL}|View run>"
55+
)
56+
57+
[[ -n "${results}" ]] && lines+=("*Results:* ${results}")
58+
59+
if [[ -n "${failures}" ]]; then
60+
lines+=("*Failed tests:*" $'```\n'"${failures}"$'\n```')
61+
fi
62+
63+
text="$(printf '%s\n' "${lines[@]}")"
64+
payload="$(jq -n --arg text "$text" '{text: $text}')"
65+
66+
curl -fsS -X POST "$SLACK_WEBHOOK_URL" \
67+
-H 'Content-Type: application/json' \
68+
-d "$payload"
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
6+
# shellcheck source=scripts/utils
7+
source "${REPO_ROOT}/scripts/utils"
8+
9+
: "${DB_HOST:?DB_HOST is required}"
10+
: "${DB_PORT:?DB_PORT is required}"
11+
: "${DB_USER:?DB_USER is required}"
12+
: "${DB_PASSWORD:?DB_PASSWORD is required}"
13+
14+
say "Applying Sequin bootstrap SQL..."
15+
docker run --rm --network host \
16+
-v "${REPO_ROOT}/scripts/scaffold/sequin/postgres-docker-entrypoint-initdb.d/create-sequin-database.sql:/bootstrap.sql:ro" \
17+
-e "PGPASSWORD=${DB_PASSWORD}" \
18+
postgres:14-alpine \
19+
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d postgres -v ON_ERROR_STOP=1 -f /bootstrap.sql
20+
21+
say "Recreating test_template..."
22+
docker run --rm --network host \
23+
-e "PGPASSWORD=${DB_PASSWORD}" \
24+
postgres:14-alpine \
25+
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d postgres -v ON_ERROR_STOP=1 \
26+
-c "DROP DATABASE IF EXISTS test_template;" \
27+
-c "CREATE DATABASE test_template;"
28+
29+
if [[ "${SKIP_FLYWAY_BUILD:-0}" == "1" ]]; then
30+
say "Using pre-built crowd_flyway image."
31+
else
32+
say "Building flyway image..."
33+
docker build -t crowd_flyway -f "${REPO_ROOT}/backend/src/database/Dockerfile.flyway" "${REPO_ROOT}/backend/src/database"
34+
fi
35+
36+
say "Migrating test_template..."
37+
docker run --rm --network host \
38+
-e "PGHOST=${DB_HOST}" \
39+
-e "PGPORT=${DB_PORT}" \
40+
-e "PGUSER=${DB_USER}" \
41+
-e "PGPASSWORD=${DB_PASSWORD}" \
42+
-e PGDATABASE=test_template \
43+
crowd_flyway
44+
45+
say "Test template database ready."

0 commit comments

Comments
 (0)