Skip to content

Commit 2cd4590

Browse files
committed
infra test for preview pr
1 parent 5dd2dee commit 2cd4590

2 files changed

Lines changed: 238 additions & 0 deletions

File tree

.github/lighthouserc.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
let previewBaseUrl = '';
2+
try {
3+
const previewUrlBase64 = process.env.LHCI_PREVIEW_URL_BASE64;
4+
console.log("environemtnt variable LHCI_PREVIEW_URL:", previewUrlBase64);
5+
if (previewUrlBase64) {
6+
const decodedUrl = Buffer.from(previewUrlBase64, 'base64').toString('utf-8');
7+
console.log("Decoded preview URL:", decodedUrl);
8+
previewBaseUrl = decodedUrl;
9+
} else {
10+
console.error("LHCI_PREVIEW_URL_BASE64 environment variable is not set.");
11+
}
12+
} catch (error) {
13+
console.error("Error decoding LHCI_PREVIEW_URL_BASE64:", error);
14+
}
15+
16+
module.exports = {
17+
ci: {
18+
collect: {
19+
url: [
20+
`${previewBaseUrl}/`,
21+
`${previewBaseUrl}/feeds`,
22+
`${previewBaseUrl}/feeds/gtfs/mdb-2126`,
23+
`${previewBaseUrl}/feeds/gtfs_rt/mdb-2585`,
24+
`${previewBaseUrl}/gbfs/gbfs-flamingo_porirua`
25+
],
26+
numberOfRuns: 1, // 1 to speed up the CI process but can be increased for more reliable results
27+
settings: {
28+
formFactor: 'desktop',
29+
throttlingMethod: 'provided',
30+
skipAudits: ['robots-txt', 'is-crawlable'],
31+
screenEmulation: {
32+
mobile: false,
33+
width: 1350,
34+
height: 940,
35+
deviceScaleRatio: 1,
36+
disabled: false
37+
}
38+
}
39+
},
40+
upload: {
41+
target: 'temporary-public-storage'
42+
}
43+
}
44+
};
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
name: Vercel Preview (PR)
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
types: [opened, synchronize, reopened]
7+
8+
concurrency:
9+
group: vercel-preview-${{ github.event.pull_request.number }}
10+
cancel-in-progress: true
11+
12+
jobs:
13+
deploy_preview:
14+
# ✅ Only run for same-repo PRs (not forks)
15+
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
16+
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
pull-requests: write
21+
22+
steps:
23+
- name: Checkout PR
24+
uses: actions/checkout@v4
25+
26+
- name: 1Password - Load Secrets
27+
uses: 1Password/load-secrets-action@v2.0.0
28+
with:
29+
export-env: true
30+
env:
31+
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
32+
VERCEL_TOKEN: "op://TECHNOLOGIES/kjzkrs62v42mvsvw23cewbyemi/VERCEL_TOKEN-MobilityDatabase-web-it-account"
33+
VERCEL_PROJECT_ID: "op://TECHNOLOGIES/kjzkrs62v42mvsvw23cewbyemi/VERCEL_PROJECT_ID-MobilityDatabase-web"
34+
VERCEL_ORG_ID: "op://TECHNOLOGIES/kjzkrs62v42mvsvw23cewbyemi/VERCEL_ORG_ID-MobilityDatabase-web"
35+
36+
- name: Setup Node
37+
uses: actions/setup-node@v4
38+
with:
39+
node-version: 24.12.0
40+
cache: yarn
41+
42+
- name: Install dependencies
43+
run: yarn install --frozen-lockfile --prefer-offline
44+
45+
- name: Cache Cypress binary
46+
uses: actions/cache@v4
47+
with:
48+
path: ~/.cache/Cypress
49+
key: cypress-${{ runner.os }}-binary-${{ hashFiles('**/package-lock.json') }}
50+
restore-keys: |
51+
cypress-${{ runner.os }}-binary-
52+
53+
- name: Lint
54+
run: yarn lint
55+
56+
- name: Unit tests
57+
run: yarn test:ci
58+
59+
- name: Cypress test
60+
uses: cypress-io/github-action@v6
61+
with:
62+
start: |
63+
yarn e2e:setup
64+
yarn e2e:run
65+
wait-on: npx wait-on --timeout 120000 http://127.0.0.1:3001 http://127.0.0.1:9099
66+
67+
- uses: actions/upload-artifact@v4
68+
if: failure()
69+
with:
70+
name: cypress-screenshots
71+
path: ./cypress/screenshots
72+
73+
- uses: actions/upload-artifact@v4
74+
if: always()
75+
with:
76+
name: cypress-videos
77+
path: ./cypress/videos
78+
79+
- name: Install Vercel CLI
80+
run: npm i -g vercel@latest
81+
82+
- name: Pull Vercel settings (preview)
83+
run: vercel pull --yes --environment=preview --token=${{ env.VERCEL_TOKEN }}
84+
env:
85+
VERCEL_ORG_ID: ${{ env.VERCEL_ORG_ID }}
86+
VERCEL_PROJECT_ID: ${{ env.VERCEL_PROJECT_ID }}
87+
VERCEL_TELEMETRY_DISABLED: 1
88+
89+
- name: Build (preview)
90+
run: vercel build --token=${{ env.VERCEL_TOKEN }}
91+
env:
92+
VERCEL_ORG_ID: ${{ env.VERCEL_ORG_ID }}
93+
VERCEL_PROJECT_ID: ${{ env.VERCEL_PROJECT_ID }}
94+
VERCEL_TELEMETRY_DISABLED: 1
95+
96+
- name: Deploy (preview) and capture URL
97+
id: deploy
98+
run: |
99+
URL=$(vercel deploy --prebuilt --token=${{ env.VERCEL_TOKEN }})
100+
echo "preview_url=$URL" >> $GITHUB_OUTPUT
101+
env:
102+
VERCEL_ORG_ID: ${{ env.VERCEL_ORG_ID }}
103+
VERCEL_PROJECT_ID: ${{ env.VERCEL_PROJECT_ID }}
104+
VERCEL_TELEMETRY_DISABLED: 1
105+
106+
- name: Comment on PR with Preview URL (update existing)
107+
uses: actions/github-script@v7
108+
env:
109+
PREVIEW_URL: ${{ steps.deploy.outputs.preview_url }}
110+
with:
111+
script: |
112+
const { owner, repo } = context.repo;
113+
const issue_number = context.payload.pull_request.number;
114+
115+
const marker = "<!-- vercel-preview-url -->";
116+
const sha = context.payload.pull_request.head.sha.slice(0,7);
117+
118+
const body =
119+
`${marker}\n` +
120+
`✅ **Vercel Preview ready**\n\n` +
121+
`- Preview: ${process.env.PREVIEW_URL}\n` +
122+
`- Commit: \`${sha}\`\n`;
123+
124+
const comments = await github.paginate(
125+
github.rest.issues.listComments,
126+
{ owner, repo, issue_number, per_page: 100 }
127+
);
128+
129+
const existing = comments.find(c => c.body?.includes(marker));
130+
131+
if (existing) {
132+
await github.rest.issues.updateComment({
133+
owner, repo,
134+
comment_id: existing.id,
135+
body
136+
});
137+
} else {
138+
await github.rest.issues.createComment({
139+
owner, repo,
140+
issue_number,
141+
body
142+
});
143+
}
144+
145+
- name: Lighthouse Check
146+
id: lighthouse-check
147+
uses: treosh/lighthouse-ci-action@v12
148+
# Runs on: Homepage, Search page, GTFS page, GTFS-RT page, and GBFS page
149+
with:
150+
configPath: ./.github/lighthouserc.js
151+
temporaryPublicStorage: true
152+
env:
153+
LHCI_PREVIEW_URL_BASE64: ${{ steps.deploy.outputs.preview_url }}
154+
155+
- name: Format lighthouse score
156+
id: format_lighthouse_score
157+
uses: actions/github-script@v3
158+
with:
159+
github-token: ${{secrets.GITHUB_TOKEN}}
160+
script: |
161+
const results = ${{ steps.lighthouse-check.outputs.manifest }}
162+
const links = ${{ steps.lighthouse-check.outputs.links }}
163+
let comment = []
164+
results.forEach((resultData, index) => {
165+
const result = resultData.summary;
166+
167+
const formatResult = (res) => Math.round((res * 100))
168+
Object.keys(result).forEach(key => result[key] = formatResult(result[key]))
169+
170+
const score = res => res >= 90 ? '🟢' : res >= 50 ? '🟠' : '🔴'
171+
const link = Object.keys(links)[index] ?? 'Unknown URL';
172+
const linkUrl = links[link] ?? '#';
173+
comment = comment.concat(...[
174+
`*Lighthouse ran on ${link} * (Desktop)`,
175+
`⚡️ HTML Report [Lighthouse report](${linkUrl}) for the changes in this PR:`,
176+
'| Performance | Accessibility | Best Practices | SEO |',
177+
'| --- | --- | --- | --- |',
178+
`| ${score(result.performance)} ${result.performance} | ${score(result.accessibility)} ${result.accessibility} | ${score(result['best-practices'])} ${result['best-practices']} | ${score(result.seo)} ${result.seo} |`,
179+
' ',
180+
' ',
181+
])
182+
})
183+
const finalComment = comment.join('\n')
184+
core.setOutput("comment", finalComment);
185+
186+
- name: Add lighthouse comment to PR
187+
id: comment_to_pr
188+
uses: marocchino/sticky-pull-request-comment@v1
189+
with:
190+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
191+
number: ${{ github.event.issue.number }}
192+
header: lighthouse
193+
message: |
194+
${{ steps.format_lighthouse_score.outputs.comment }}

0 commit comments

Comments
 (0)