55 branches :
66 - main
77 - dev
8+ pull_request :
9+ branches :
10+ - main
11+ - dev
812
913permissions :
1014 contents : write
@@ -16,8 +20,96 @@ concurrency:
1620 cancel-in-progress : false
1721
1822jobs :
23+ verify :
24+ name : Verify (lint, unit, build, e2e)
25+ runs-on : ubuntu-latest
26+ steps :
27+ - name : Checkout
28+ uses : actions/checkout@v4
29+ with :
30+ persist-credentials : false
31+
32+ # Required because src/stores/profile.ts imports types from
33+ # ../../../dashboard-app/frontend/types/database.type — see CLAUDE.md.
34+ - name : Checkout sibling dashboard-app
35+ run : git clone --depth 1 https://github.com/codebridger/subturtle-dashboard-app.git ../dashboard-app
36+
37+ - name : Setup Node
38+ uses : actions/setup-node@v4
39+ with :
40+ node-version : 22
41+ cache : yarn
42+
43+ - name : Install dependencies
44+ run : yarn install --frozen-lockfile
45+
46+ - name : Cache Playwright browsers
47+ id : playwright-cache
48+ uses : actions/cache@v4
49+ with :
50+ path : ~/.cache/ms-playwright
51+ key : playwright-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
52+ restore-keys : |
53+ playwright-${{ runner.os }}-
54+
55+ - name : Install Playwright Chromium
56+ if : steps.playwright-cache.outputs.cache-hit != 'true'
57+ run : npx playwright install chromium --with-deps
58+
59+ - name : Install Playwright system deps (cache hit path)
60+ if : steps.playwright-cache.outputs.cache-hit == 'true'
61+ run : npx playwright install-deps chromium
62+
63+ - name : Type check
64+ run : yarn typecheck
65+
66+ - name : Unit tests (Vitest)
67+ run : yarn test
68+
69+ # dotenv-webpack is configured with `safe: true`, so the build needs
70+ # every key in .env.example to exist at build time. We write
71+ # non-empty placeholders rather than copying the empty .env.example
72+ # — `mixpanel.init("")` throws synchronously during the content-script
73+ # import chain, which silently halts every Vue mount and was the root
74+ # cause of e2e tests failing on `#subturtle-{nibble,console-crane}-root`
75+ # never appearing. SUBTURTLE_API_URL points at the local fixtures
76+ # server so any auth/translate calls 404 instead of escaping to the
77+ # real backend.
78+ - name : Stub .env.production for verify build
79+ run : |
80+ cat > .env.production <<'EOF'
81+ MIXPANEL_PROJECT_TOKEN=ci_e2e_stub_token
82+ MIXPANEL_API_HOST=http://localhost:4173/_mixpanel_stub
83+ GOOGLE_TRANSLATE_KEY=ci_e2e_stub_key
84+ GOOGLE_TRANSLATE_PROXY_URL=http://localhost:4173/_translate_proxy_stub
85+ UNINSTALL_FORM_URL=http://localhost:4173/_uninstall_stub
86+ SUBTURTLE_API_URL=http://localhost:4173
87+ SUBTURTLE_DASHBOARD_URL=http://localhost:4173/_dashboard_stub
88+ GOOGLE_OAUTH_CLIENT_ID=ci_e2e_stub_oauth_client
89+ EOF
90+
91+ - name : Build extension
92+ run : yarn build
93+
94+ - name : E2E tests (Playwright)
95+ run : yarn test:e2e
96+
97+ - name : Upload Playwright report
98+ # Run on both success and failure (anything except job cancel) so
99+ # the HTML report is downloadable for green runs too. The
100+ # hashFiles guard skips silently when typecheck or unit tests
101+ # failed before Playwright produced any output.
102+ if : ${{ !cancelled() && hashFiles('playwright-report/**') != '' }}
103+ uses : actions/upload-artifact@v4
104+ with :
105+ name : playwright-report
106+ path : playwright-report/
107+ retention-days : 7
108+
19109 release :
20110 name : Release
111+ needs : verify
112+ if : github.event_name == 'push'
21113 runs-on : ubuntu-latest
22114 environment : ${{ github.ref_name == 'main' && 'prod' || 'dev' }}
23115 steps :
0 commit comments