Skip to content

Commit 9860995

Browse files
committed
Improved E2E CI runtime
ref #27654 - E2E CI was starting Tinybird for every shard, but only analytics tests need it - splitting main and analytics shards keeps normal test runs lean while preserving analytics coverage - teardown still stops analytics services so switching modes leaves a clean compose project
1 parent 0c4d441 commit 9860995

7 files changed

Lines changed: 106 additions & 15 deletions

File tree

.github/workflows/ci.yml

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,14 +1263,63 @@ jobs:
12631263
use-artifact: ${{ steps.strategy.outputs.use-artifact }}
12641264

12651265
job_e2e_tests:
1266-
name: E2E Tests (${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
1266+
name: E2E Tests (${{ matrix.projectName }} ${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
12671267
runs-on: ubuntu-latest
12681268
needs: [job_build_e2e_image, job_setup]
12691269
strategy:
12701270
fail-fast: true
12711271
matrix:
1272-
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8]
1273-
shardTotal: [8]
1272+
include:
1273+
- projectName: Main
1274+
projects: main
1275+
analytics: 'false'
1276+
shardIndex: 1
1277+
shardTotal: 8
1278+
- projectName: Main
1279+
projects: main
1280+
analytics: 'false'
1281+
shardIndex: 2
1282+
shardTotal: 8
1283+
- projectName: Main
1284+
projects: main
1285+
analytics: 'false'
1286+
shardIndex: 3
1287+
shardTotal: 8
1288+
- projectName: Main
1289+
projects: main
1290+
analytics: 'false'
1291+
shardIndex: 4
1292+
shardTotal: 8
1293+
- projectName: Main
1294+
projects: main
1295+
analytics: 'false'
1296+
shardIndex: 5
1297+
shardTotal: 8
1298+
- projectName: Main
1299+
projects: main
1300+
analytics: 'false'
1301+
shardIndex: 6
1302+
shardTotal: 8
1303+
- projectName: Main
1304+
projects: main
1305+
analytics: 'false'
1306+
shardIndex: 7
1307+
shardTotal: 8
1308+
- projectName: Main
1309+
projects: main
1310+
analytics: 'false'
1311+
shardIndex: 8
1312+
shardTotal: 8
1313+
- projectName: Analytics
1314+
projects: analytics
1315+
analytics: 'true'
1316+
shardIndex: 1
1317+
shardTotal: 2
1318+
- projectName: Analytics
1319+
projects: analytics
1320+
analytics: 'true'
1321+
shardIndex: 2
1322+
shardTotal: 2
12741323
steps:
12751324
- name: Checkout
12761325
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -1279,6 +1328,7 @@ jobs:
12791328
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
12801329

12811330
- name: Pull or build Tinybird CLI Image
1331+
if: matrix.analytics == 'true'
12821332
run: |
12831333
COMPOSE_IMAGE="${COMPOSE_PROJECT_NAME:-ghost-dev}-tb-cli"
12841334
# Try pulling pre-built image from GHCR first (fast path)
@@ -1314,13 +1364,15 @@ jobs:
13141364
env:
13151365
GHOST_E2E_IMAGE: ${{ steps.load.outputs.image-tag }}
13161366
GHOST_E2E_SKIP_IMAGE_BUILD: 'true'
1367+
GHOST_E2E_ANALYTICS: ${{ matrix.analytics }}
13171368
run: bash ./e2e/scripts/prepare-ci-e2e-job.sh
13181369

13191370
- name: Run e2e tests in Playwright container
13201371
env:
13211372
TEST_WORKERS_COUNT: 1
13221373
GHOST_E2E_MODE: build
13231374
GHOST_E2E_IMAGE: ${{ steps.load.outputs.image-tag }}
1375+
E2E_PLAYWRIGHT_PROJECTS: ${{ matrix.projects }}
13241376
E2E_SHARD_INDEX: ${{ matrix.shardIndex }}
13251377
E2E_SHARD_TOTAL: ${{ matrix.shardTotal }}
13261378
E2E_RETRIES: 2
@@ -1332,21 +1384,23 @@ jobs:
13321384

13331385
- name: Stop E2E infra
13341386
if: always()
1387+
env:
1388+
GHOST_E2E_ANALYTICS: ${{ matrix.analytics }}
13351389
run: pnpm --filter @tryghost/e2e infra:down
13361390

13371391
- name: Upload blob report to GitHub Actions Artifacts
13381392
if: failure()
13391393
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
13401394
with:
1341-
name: blob-report-${{ matrix.shardIndex }}
1395+
name: blob-report-${{ matrix.projectName }}-${{ matrix.shardIndex }}
13421396
path: e2e/blob-report
13431397
retention-days: 1
13441398

13451399
- name: Upload test results artifacts
13461400
if: failure()
13471401
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
13481402
with:
1349-
name: test-results-${{ matrix.shardIndex }}
1403+
name: test-results-${{ matrix.projectName }}-${{ matrix.shardIndex }}
13501404
path: e2e/test-results
13511405
retention-days: 7
13521406

e2e/helpers/environment/environment-manager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ type GhostEnvOverrides = GhostConfig | Record<string, string>;
2323
* - dev: Uses dev infrastructure with hot-reloading
2424
* - build: Uses pre-built image (set GHOST_E2E_IMAGE for registry images)
2525
*
26-
* All modes use the same infrastructure (MySQL, Redis, Mailpit, Tinybird)
27-
* started via docker compose. Ghost and gateway containers are created
28-
* dynamically per-worker for test isolation.
26+
* All modes use the same core infrastructure (MySQL, Redis, Mailpit) started
27+
* via docker compose. Analytics/Tinybird services are optional. Ghost and
28+
* gateway containers are created dynamically per-worker for test isolation.
2929
*/
3030
export class EnvironmentManager {
3131
private readonly mode: EnvironmentMode;

e2e/helpers/environment/service-availability.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ async function isServiceAvailable(docker: Docker, serviceName: string) {
2121
* Checks for tinybird-local service in ghost-dev compose project.
2222
*/
2323
export async function isTinybirdAvailable(): Promise<boolean> {
24+
if (process.env.GHOST_E2E_ANALYTICS === 'false') {
25+
debug('Tinybird disabled by GHOST_E2E_ANALYTICS=false');
26+
return false;
27+
}
28+
2429
const docker = new Docker();
2530
const tinybirdAvailable = await isServiceAvailable(docker, TINYBIRD.LOCAL_HOST);
2631
debug(`Tinybird availability for compose project ${DEV_ENVIRONMENT.projectNamespace}:`, tinybirdAvailable);

e2e/scripts/infra-down.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
66

77
cd "$REPO_ROOT"
88

9-
docker compose -f compose.dev.yaml -f compose.dev.analytics.yaml stop \
10-
analytics tb-cli tinybird-local mailpit redis mysql
9+
compose_files=(-f compose.dev.yaml -f compose.dev.analytics.yaml)
10+
services=(analytics tb-cli tinybird-local mailpit redis mysql)
11+
12+
docker compose "${compose_files[@]}" stop "${services[@]}"

e2e/scripts/infra-up.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ cd "$REPO_ROOT"
99

1010
MODE="$(resolve_e2e_mode)"
1111
export GHOST_E2E_MODE="$MODE"
12+
ANALYTICS_ENABLED="${GHOST_E2E_ANALYTICS:-true}"
1213

1314
if [[ "$MODE" != "build" ]]; then
1415
DEV_COMPOSE_PROJECT="${COMPOSE_PROJECT_NAME:-ghost-dev}"
@@ -21,5 +22,12 @@ if [[ "$MODE" != "build" ]]; then
2122
fi
2223
fi
2324

24-
docker compose -f compose.dev.yaml -f compose.dev.analytics.yaml up -d --wait \
25-
mysql redis mailpit tinybird-local analytics
25+
compose_files=(-f compose.dev.yaml)
26+
services=(mysql redis mailpit)
27+
28+
if [[ "$ANALYTICS_ENABLED" == "true" ]]; then
29+
compose_files+=(-f compose.dev.analytics.yaml)
30+
services+=(tinybird-local analytics)
31+
fi
32+
33+
docker compose "${compose_files[@]}" up -d --wait "${services[@]}"

e2e/scripts/prepare-ci-e2e-build-mode.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ set -euo pipefail
33

44
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/load-playwright-container-env.sh"
55
GATEWAY_IMAGE="${GHOST_E2E_GATEWAY_IMAGE:-caddy:2-alpine}"
6+
ANALYTICS_ENABLED="${GHOST_E2E_ANALYTICS:-true}"
67

78
echo "Preparing E2E build-mode runtime"
89
echo "Playwright image: ${PLAYWRIGHT_IMAGE}"
910
echo "Gateway image: ${GATEWAY_IMAGE}"
11+
echo "Analytics enabled: ${ANALYTICS_ENABLED}"
1012

1113
pids=()
1214
labels=()
@@ -25,7 +27,7 @@ run_bg() {
2527

2628
run_bg "pull-gateway-image" docker pull "$GATEWAY_IMAGE"
2729
run_bg "pull-playwright-image" docker pull "$PLAYWRIGHT_IMAGE"
28-
run_bg "start-infra" env GHOST_E2E_MODE=build bash "$REPO_ROOT/e2e/scripts/infra-up.sh"
30+
run_bg "start-infra" env GHOST_E2E_MODE=build GHOST_E2E_ANALYTICS="$ANALYTICS_ENABLED" bash "$REPO_ROOT/e2e/scripts/infra-up.sh"
2931

3032
for i in "${!pids[@]}"; do
3133
if ! wait "${pids[$i]}"; then
@@ -34,4 +36,6 @@ for i in "${!pids[@]}"; do
3436
fi
3537
done
3638

37-
node "$REPO_ROOT/e2e/scripts/sync-tinybird-state.mjs"
39+
if [[ "$ANALYTICS_ENABLED" == "true" ]]; then
40+
node "$REPO_ROOT/e2e/scripts/sync-tinybird-state.mjs"
41+
fi

e2e/scripts/run-playwright-container.sh

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ set -euo pipefail
44
SHARD_INDEX="${E2E_SHARD_INDEX:-}"
55
SHARD_TOTAL="${E2E_SHARD_TOTAL:-}"
66
RETRIES="${E2E_RETRIES:-2}"
7+
PROJECTS="${E2E_PLAYWRIGHT_PROJECTS:-main,analytics}"
78

89
if [[ -z "$SHARD_INDEX" || -z "$SHARD_TOTAL" ]]; then
910
echo "Missing E2E_SHARD_INDEX or E2E_SHARD_TOTAL environment variables" >&2
@@ -12,6 +13,22 @@ fi
1213

1314
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/load-playwright-container-env.sh"
1415

16+
project_args=()
17+
IFS=',' read -ra project_names <<< "$PROJECTS"
18+
for project in "${project_names[@]}"; do
19+
project="${project//[[:space:]]/}"
20+
if [[ -n "$project" ]]; then
21+
project_args+=("--project=${project}")
22+
fi
23+
done
24+
25+
if [[ ${#project_args[@]} -eq 0 ]]; then
26+
echo "No Playwright projects configured in E2E_PLAYWRIGHT_PROJECTS" >&2
27+
exit 1
28+
fi
29+
30+
printf -v project_args_string '%q ' "${project_args[@]}"
31+
1532
docker run --rm --network host --ipc host \
1633
-v /var/run/docker.sock:/var/run/docker.sock \
1734
-v "${WORKSPACE_PATH}:${WORKSPACE_PATH}" \
@@ -22,5 +39,6 @@ docker run --rm --network host --ipc host \
2239
-e GHOST_E2E_MODE="${GHOST_E2E_MODE:-build}" \
2340
-e GHOST_E2E_IMAGE="${GHOST_E2E_IMAGE:-ghost-e2e:local}" \
2441
-e GHOST_E2E_GATEWAY_IMAGE="${GHOST_E2E_GATEWAY_IMAGE:-caddy:2-alpine}" \
42+
-e GHOST_E2E_ANALYTICS="${GHOST_E2E_ANALYTICS:-true}" \
2543
"$PLAYWRIGHT_IMAGE" \
26-
bash -c "corepack enable && pnpm test:all --shard=${SHARD_INDEX}/${SHARD_TOTAL} --retries=${RETRIES}"
44+
bash -c "corepack enable && bash ./scripts/run-playwright-host.sh pnpm exec playwright test ${project_args_string}--shard=${SHARD_INDEX}/${SHARD_TOTAL} --retries=${RETRIES}"

0 commit comments

Comments
 (0)