Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions .github/workflows/deploy-pr-preview-netlify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Deploy PR Preview to Netlify

on:
workflow_run:
workflows: ["Build PR Preview"]
types:
- completed

permissions:
contents: read
pull-requests: write
actions: read

jobs:
deploy-preview:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Get PR number
id: pr
uses: actions/github-script@v7
with:
script: |
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }},
});

const prNumberArtifact = artifacts.data.artifacts.find(
artifact => artifact.name.startsWith('pr-number-')
);

if (!prNumberArtifact) {
core.setFailed('Could not find PR number artifact');
return;
}

const prNumber = prNumberArtifact.name.replace('pr-number-', '');
core.setOutput('pr_number', prNumber);
core.setOutput('artifact_name', `pr-preview-${prNumber}`);

- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: ${{ steps.pr.outputs.artifact_name }}
path: ./dist
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

- name: Deploy to Netlify
id: netlify
uses: nwtgck/actions-netlify@v3
with:
publish-dir: './dist'
production-deploy: false
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-message: "PR Preview #${{ steps.pr.outputs.pr_number }}"
alias: pr-${{ steps.pr.outputs.pr_number }}
enable-pull-request-comment: false
enable-commit-comment: false
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

- name: Comment PR with Preview URL
uses: actions/github-script@v7
with:
script: |
const prNumber = parseInt('${{ steps.pr.outputs.pr_number }}');
const deployUrl = '${{ steps.netlify.outputs.deploy-url }}';
const body = `🚀 **Preview:** ${deployUrl}\n📝 **Commit:** \`${{ github.event.workflow_run.head_sha }}\``;

// Find existing comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});

const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Preview:')
);

if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: body
});
}
68 changes: 16 additions & 52 deletions .github/workflows/deploy-pr-preview.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
name: Deploy PR Preview to Netlify
name: Build PR Preview

on:
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened]

permissions:
contents: read
pull-requests: write

jobs:
deploy-preview:
build-preview:
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand All @@ -22,60 +20,26 @@ jobs:
node-version: '22'
cache: 'npm'
cache-dependency-path: './package-lock.json'

- name: Update npm to v11
run: npm install -g npm@11

- name: Build Staging
run: ./scripts/build-staging.sh

- name: Deploy to Netlify
id: netlify
uses: nwtgck/actions-netlify@v3
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
publish-dir: './dist'
production-deploy: false
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-message: "PR Preview - ${{ github.event.pull_request.title || github.ref_name }}"
alias: pr-${{ github.event.pull_request.number || github.run_id }}
enable-pull-request-comment: false
enable-commit-comment: false
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
name: pr-preview-${{ github.event.pull_request.number }}
path: ./dist
retention-days: 1

- name: Save PR number
run: echo "${{ github.event.pull_request.number }}" > pr_number.txt

- name: Comment PR with Preview URL
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
- name: Upload PR number
uses: actions/upload-artifact@v4
with:
script: |
const deployUrl = '${{ steps.netlify.outputs.deploy-url }}';
const body = `🚀 **Preview:** ${deployUrl}\n📝 **Commit:** \`${{ github.sha }}\``;

// Find existing comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});

const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Preview:')
);

if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
}
name: pr-number-${{ github.event.pull_request.number }}
path: pr_number.txt
retention-days: 1
2 changes: 2 additions & 0 deletions src/components/LazyComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const Mempool = lazy(() => import("./pages/Mempool"));
const Settings = lazy(() => import("./pages/Settings"));
const DevTools = lazy(() => import("./pages/DevTools"));
const About = lazy(() => import("./pages/About"));
const Subscriptions = lazy(() => import("./pages/Subscriptions"));

// Higher-order component to wrap lazy components with Suspense
// biome-ignore lint/suspicious/noExplicitAny: <TODO>
Expand All @@ -39,5 +40,6 @@ export const LazyMempool = withSuspense(Mempool);
export const LazySettings = withSuspense(Settings);
export const LazyDevTools = withSuspense(DevTools);
export const LazyAbout = withSuspense(About);
export const LazySubscriptions = withSuspense(Subscriptions);
// Default exports for backward compatibility
export { Home };
26 changes: 26 additions & 0 deletions src/components/common/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,32 @@ const Navbar = () => {
</svg>
</button>
</li>
<li>
{/* biome-ignore lint/a11y/useButtonType: nav buttons don't submit forms */}
<button
onClick={() => navigate("/subscriptions")}
className="navbar-toggle-btn"
aria-label="Subscriptions"
title="Subscriptions"
>
{/* biome-ignore lint/a11y/noSvgWithoutTitle: aria-label on button provides accessible name */}
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</button>
</li>
<li>
{/** biome-ignore lint/a11y/useButtonType: <TODO> */}
<button
Expand Down
Loading