Skip to content

Commit fef086e

Browse files
authored
Enable PR previews (#13841)
1 parent 7ef2453 commit fef086e

3 files changed

Lines changed: 177 additions & 1 deletion

File tree

.github/workflows/web.yml

Lines changed: 161 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,6 @@ jobs:
277277
name: Web Build
278278
runs-on: ubuntu-latest
279279
needs: [web-init, web-lint, web-typecheck]
280-
if: github.ref == 'refs/heads/main'
281280
steps:
282281
- name: Checkout code
283282
uses: actions/checkout@v4
@@ -361,6 +360,167 @@ jobs:
361360
packages/web/build-production
362361
packages/web/build-ssr-production
363362
363+
web-deploy-preview:
364+
name: Web Deploy Preview
365+
runs-on: ubuntu-latest
366+
needs: web-build
367+
if: github.event_name == 'pull_request'
368+
permissions:
369+
contents: read
370+
pull-requests: write
371+
steps:
372+
- name: Checkout code
373+
uses: actions/checkout@v4
374+
375+
- name: Setup Node.js
376+
uses: actions/setup-node@v4
377+
with:
378+
node-version: ${{ env.NODE_VERSION }}
379+
cache: 'npm'
380+
cache-dependency-path: package-lock.json
381+
382+
- name: Create concatenated patch file
383+
id: patch-file
384+
run: |
385+
ls -d -- packages/*/patches/*.patch 2>/dev/null | xargs cat > combined-patch-file.txt || touch combined-patch-file.txt
386+
echo "patch_checksum=$(sha256sum combined-patch-file.txt | cut -d' ' -f1)" >> $GITHUB_OUTPUT
387+
388+
- name: Cache node modules
389+
id: cache-node-modules
390+
uses: actions/cache@v4
391+
with:
392+
path: |
393+
node_modules
394+
packages/web/node_modules
395+
packages/harmony/node_modules
396+
packages/common/node_modules
397+
packages/libs/node_modules
398+
packages/sdk/node_modules
399+
key: npm-cache-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}-${{ steps.patch-file.outputs.patch_checksum }}
400+
restore-keys: |
401+
npm-cache-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}-
402+
403+
- name: Install dependencies (if cache miss)
404+
if: steps.cache-node-modules.outputs.cache-hit != 'true'
405+
env:
406+
CI: true
407+
SKIP_POD_INSTALL: true
408+
SKIP_ANDROID_INSTALL: true
409+
ANDROID_HOME: /tmp/android-sdk-dummy
410+
NODE_OPTIONS: --max-old-space-size=8192
411+
run: |
412+
mkdir -p /tmp/android-sdk-dummy
413+
npm cache clean --force || true
414+
npm ci --prefer-offline || npm install --prefer-offline
415+
416+
- name: Run postinstall (if cache hit)
417+
if: steps.cache-node-modules.outputs.cache-hit == 'true'
418+
env:
419+
CI: true
420+
SKIP_POD_INSTALL: true
421+
SKIP_ANDROID_INSTALL: true
422+
ANDROID_HOME: /tmp/android-sdk-dummy
423+
NODE_OPTIONS: --max-old-space-size=8192
424+
run: |
425+
mkdir -p /tmp/android-sdk-dummy
426+
npm run postinstall
427+
428+
- name: Download builds
429+
uses: actions/download-artifact@v4
430+
with:
431+
name: builds
432+
path: packages/web
433+
434+
- name: Move build
435+
run: |
436+
cd packages/web
437+
mv build-production build
438+
mv build-ssr-production build-ssr
439+
440+
- name: Copy robots.txt
441+
run: |
442+
cd packages/web
443+
cp ./robots.txt build
444+
cp ./robots.txt build-ssr/client
445+
446+
- name: Copy .well-known files
447+
run: |
448+
cd packages/web
449+
cp -r ./public/.well-known build 2>/dev/null || true
450+
451+
- name: Deploy to Cloudflare (Preview)
452+
id: deploy
453+
env:
454+
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
455+
PR_NUM: ${{ github.event.pull_request.number }}
456+
run: |
457+
cd packages/web
458+
SSR_NAME="audius-web-ssr-preview-pr-${PR_NUM}"
459+
MAIN_NAME="audius-web-preview-pr-${PR_NUM}"
460+
npm_config_yes=true npx wrangler@4.54.0 deploy --config ./src/ssr/wrangler.toml --env preview --name "$SSR_NAME"
461+
cp wrangler.toml wrangler.preview.pr.toml
462+
sed -i "s/audius-web-ssr-preview/audius-web-ssr-preview-pr-${PR_NUM}/g; s/audius-web-preview/audius-web-preview-pr-${PR_NUM}/g" wrangler.preview.pr.toml
463+
npm_config_yes=true npx wrangler@4.54.0 deploy --config ./wrangler.preview.pr.toml --env preview 2>&1 | tee deploy.log
464+
echo "url=https://${MAIN_NAME}.audius.workers.dev" >> $GITHUB_OUTPUT
465+
466+
- name: Comment on PR with preview URL
467+
uses: actions/github-script@v7
468+
if: steps.deploy.outcome == 'success' && github.event_name == 'pull_request'
469+
with:
470+
script: |
471+
const previewUrl = '${{ steps.deploy.outputs.url }}' || 'https://audius-web-preview.audius.workers.dev';
472+
const body = `## 🌐 Web preview ready
473+
474+
**Preview URL:** ${previewUrl}
475+
476+
Unique preview for this PR (deployed from this branch).
477+
_[Workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})_`;
478+
const marker = '<!-- audius-web-preview -->';
479+
const bodyWithMarker = body + '\n' + marker;
480+
const { data: comments } = await github.rest.issues.listComments({
481+
owner: context.repo.owner,
482+
repo: context.repo.repo,
483+
issue_number: context.issue.number
484+
});
485+
const existing = comments.find(c => c.body && c.body.includes(marker) && c.user.type === 'Bot');
486+
if (existing) {
487+
await github.rest.issues.updateComment({
488+
owner: context.repo.owner,
489+
repo: context.repo.repo,
490+
comment_id: existing.id,
491+
body: bodyWithMarker
492+
});
493+
} else {
494+
await github.rest.issues.createComment({
495+
owner: context.repo.owner,
496+
repo: context.repo.repo,
497+
issue_number: context.issue.number,
498+
body: bodyWithMarker
499+
});
500+
}
501+
env:
502+
GH_TOKEN: ${{ github.token }}
503+
504+
web-cleanup-preview:
505+
name: Cleanup PR preview workers
506+
runs-on: ubuntu-latest
507+
if: github.event_name == 'pull_request' && github.event.action == 'closed'
508+
steps:
509+
- name: Checkout code
510+
uses: actions/checkout@v4
511+
512+
- name: Delete PR preview workers
513+
env:
514+
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
515+
PR_NUM: ${{ github.event.pull_request.number }}
516+
run: |
517+
cd packages/web
518+
MAIN_NAME="audius-web-preview-pr-${PR_NUM}"
519+
SSR_NAME="audius-web-ssr-preview-pr-${PR_NUM}"
520+
npx wrangler@4.54.0 delete --name "$MAIN_NAME" --config ./wrangler.toml --force 2>/dev/null || true
521+
npx wrangler@4.54.0 delete --name "$SSR_NAME" --config ./src/ssr/wrangler.toml --force 2>/dev/null || true
522+
continue-on-error: true
523+
364524
web-check-ssr-bundlesize:
365525
name: Web Check SSR Bundlesize
366526
runs-on: ubuntu-latest

packages/web/src/ssr/wrangler.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ vars = { SENTRY_DSN = "https://4db9c77b0bd7ae6a935f8bd58c06dad3@o260428.ingest.s
1818
"https://api.audius.co"
1919
] }
2020

21+
# Preview environment for PR deployments (GitHub Actions)
22+
[env.preview]
23+
name = "audius-web-ssr-preview"
24+
vars = { DISCOVERY_NODE_ALLOWLIST = [
25+
"https://api.audius.co"
26+
] }
27+
2128
# Test environment, replace `test` with subdomain
2229
# Invoke with npx wrangler dev --env test
2330
[env.test]

packages/web/wrangler.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ services = [
2020
]
2121
vars = { ENVIRONMENT = "production", EMBED = "https://embed.audius.workers.dev", API_URL = "https://api.audius.co", DISCOVERY_NODES = "https://api.audius.co" }
2222

23+
# Preview environment for PR deployments (GitHub Actions)
24+
# Deployed on every PR; single preview URL overwritten per build
25+
[env.preview]
26+
name = "audius-web-preview"
27+
services = [
28+
{ binding = "SSR", service = "audius-web-ssr-preview" }
29+
]
30+
vars = { ENVIRONMENT = "production", EMBED = "https://embed.audius.workers.dev", API_URL = "https://api.audius.co", DISCOVERY_NODES = "https://api.audius.co" }
31+
2332
# Test environment, replace `test` with subdomain
2433
# Invoke with npx wrangler dev --env test
2534
[env.test]

0 commit comments

Comments
 (0)