Skip to content

ci: add PR previews, update guidelines, fix router basename#166

Open
Atharva0506 wants to merge 3 commits into
StabilityNexus:mainfrom
Atharva0506:ci/gh-pages-preview
Open

ci: add PR previews, update guidelines, fix router basename#166
Atharva0506 wants to merge 3 commits into
StabilityNexus:mainfrom
Atharva0506:ci/gh-pages-preview

Conversation

@Atharva0506

@Atharva0506 Atharva0506 commented Jun 10, 2026

Copy link
Copy Markdown
Member

Addressed Issues:

Fixes #(TODO:issue number)

Adds automated PR preview deployments (with a secure, fork-safe architecture), updates contribution guidelines, and fixes routing bugs.

Description of Changes:

  • New two-workflow PR preview system: Replaced the original single workflow with a fork-safe split architecture to solve the 403 Permission Denied error and securely support secrets.
    • pr-build.yml: Runs on pull_request with read-only permissions. Uploads PR metadata as an artifact.
    • pr-deploy.yml: Runs on workflow_run in the base repository context with write access. Safely checks out PR code (without git credentials), builds the frontend with secrets (so Wallet Connect works in previews), deploys to gh-pages branch, and posts a bot comment with the preview URL.
    • Cleanup: Automatically removes the preview directory from gh-pages and updates the PR comment when the PR is closed or merged.
  • Updated workflow (deploy.yml): Migrated production deploy to use peaceiris/actions-gh-pages to preserve PR preview directories during redeploys.
  • Fixed hardcoded asset paths: Replaced 12+ hardcoded absolute image paths (src="/...") with import.meta.env.BASE_URL for correct resolution in preview subdirectories.
  • Fixed Router bug: Removed unnecessary basename from the HashRouter in App.jsx which would have caused broken routes (404s) in subdirectory deployments.
  • Updated CONTRIBUTING.md: Restructured the document to establish a clear "General Contribution & Review Process", including rules for passing local tests, resolving CodeRabbit reviews, and properly dropping links in the Discord channel.

Architecture & Security Details:

Click to view Architecture & Security details (Why Two Workflows?)

✅ Secure Architecture (Fork-Safe)

flowchart TD
    subgraph "pr-build.yml — Fork Context"
        A["PR opened / updated / closed"] --> B["pull_request trigger"]
        B --> C["🔒 Read-only, no secrets"]
        C --> D["📄 Upload metadata only\n(PR number, SHA, action)"]
    end

    subgraph "pr-deploy.yml — Base Repo Context"
        E["workflow_run trigger\n🔒 Always runs from main"] --> F["Download + validate metadata"]
        F --> G{"action?"}
        G -->|"deploy"| H["Checkout PR code\n(persist-credentials: false)"]
        H --> I["Build with secrets ✅\n(wallet connect works)"]
        I --> J["Deploy to gh-pages\npr-preview/pr-N/"]
        J --> K["💬 Comment preview URL"]
        G -->|"cleanup"| L["🗑️ Remove pr-preview/pr-N/"]
        L --> M["💬 Update: Preview removed"]
    end

    D --> E

    style C fill:#4ecdc4,color:#fff
    style E fill:#45b7d1,color:#fff
    style I fill:#2ecc71,color:#fff
    style J fill:#45b7d1,color:#fff
    style L fill:#f7dc6f,color:#000
Loading

Security Benefits:

  • Fork PRs deploy successfully: We bypass the 403 error (forks get read-only tokens) by doing the actual deploy from the base repo context.
  • Secrets are available: Fork PRs usually don't get secrets, but since the build happens in the base context, VITE_WALLETCONNECT_PROJECT_ID works in previews.
  • Attackers can't modify logic: pr-deploy.yml ALWAYS runs from the main branch. A malicious fork cannot alter the deploy logic or steal the GITHUB_TOKEN.
  • Metadata validation: PR numbers and SHAs passed via artifacts are strictly validated to prevent injection attacks.

Screenshots/Recordings:

Example

image

⚠️ Admin Action Required:

Because we are deploying to gh-pages from a GitHub Action, a repository administrator must update the Workflow permissions before the PR preview action will succeed.

Steps to apply:

  1. Go to Settings > Actions > General on the StabilityNexus repository.
  2. Scroll down to Workflow permissions.
  3. Select "Read and write permissions" and check "Allow GitHub Actions to create and approve pull requests".
  4. Click Save.

(Note: This only raises the maximum allowed permission. The pr-build.yml workflow still explicitly restricts itself to contents: read to remain secure.)

AI Usage Disclosure:

We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact. AI slop is strongly discouraged and may lead to banning and blocking. Do not spam our repos with AI slop.

Check one of the checkboxes below:

  • This PR does not contain AI-generated code at all.
  • This PR contains AI-generated code. I have read the AI Usage Policy and this PR complies with this policy. I have tested the code locally and I am responsible for it.

I have used the following AI models and tools: I used AI to generate and explore edge cases for CI testing, and to architect a secure, fork-safe two-workflow deployment pipeline.

Checklist

  • My PR addresses a single issue, fixes a single bug or makes a single improvement.
  • My code follows the project's code style and conventions
  • If applicable, I have made corresponding changes or additions to the documentation
  • If applicable, I have made corresponding changes or additions to tests
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contribution Guidelines
  • Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.
  • I have filled this PR template completely and carefully, and I understand that my PR may be closed without review otherwise.

Summary by CodeRabbit

  • New Features

    • Automatic preview deployments for frontend pull requests with per‑PR preview URLs and cleanup behavior.
  • Chores

    • Main frontend deployment switched to direct gh-pages publishing with safer permissions and updated concurrency.
    • Build now injects runtime Vite secrets and preserves per‑PR preview content during deploy.
    • Asset paths updated to respect the app's configurable base URL.
  • Documentation

    • Contribution guide expanded with PR preview and frontend asset guidance.

- Migrate production deploy from actions/deploy-pages API to gh-pages branch
  via peaceiris/actions-gh-pages (preserves pr-preview/ directories)
- Add new preview-pages.yml workflow for automated PR previews
  - Builds frontend with correct base path for subdirectory routing
  - Posts/updates PR comment with live preview URL
  - Cleans up preview directory when PR is closed or merged
- Fix 12+ hardcoded absolute image paths (src='/...') to use
  import.meta.env.BASE_URL for correct resolution in subdirectories
- Remove unnecessary \�asename\ from HashRouter in App.jsx to prevent 404
  routing issues in PR preview subdirectory deployments
- Restructure CONTRIBUTING.md to establish clear General, Smart Contract,
  and Frontend contribution standards (including PR preview guidelines)
@Atharva0506 Atharva0506 marked this pull request as draft June 10, 2026 17:01
…tecture

The original single-workflow PR preview (preview-pages.yml) failed on the
StabilityNexus org with 'Permission denied to github-actions[bot]' because
org-level settings restrict GITHUB_TOKEN to read-only.

Split into two workflows:
- pr-build.yml: runs on pull_request with read-only permissions (fork-safe),
  uploads only metadata — no build, no secrets needed.
- pr-deploy.yml: runs on workflow_run in base repo context with write access.
  Checks out PR code, builds with secrets (wallet connect works in previews),
  deploys to gh-pages, and comments preview URL on the PR.

Security:
- pr-deploy.yml always runs from main — forks cannot modify deploy logic
- PR code checked out with persist-credentials: false
- GITHUB_TOKEN only passed to peaceiris deploy action, never to build steps
- Metadata validated (PR number, action, SHA) to prevent injection

Cleanup:
- On PR close/merge: removes pr-preview/pr-N/ from gh-pages
- Updates PR comment to indicate preview removal

Production impact: None. deploy.yml restores pr-preview/ dirs before
deploying, and PR previews use keep_files: true.

Requires org admin to enable 'Read and write permissions' for GITHUB_TOKEN
at Settings > Actions > General > Workflow permissions.
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds CI workflows for PR preview build and deploy, refactors main deploy to use peaceiris/actions-gh-pages, removes Router basename, and updates frontend image paths and PDF logo loading to use import.meta.env.BASE_URL.

Changes

PR Preview Deployment & Asset Base Paths

Layer / File(s) Summary
Contribution Guidelines
CONTRIBUTING.md
Documentation expanded with project-wide contribution guidance and frontend-specific BASE_URL asset-path rules.
Main Deploy Workflow Refactor
.github/workflows/deploy.yml
Switches to peaceiris/actions-gh-pages, restricts permissions to contents: write, changes concurrency to gh-pages-deploy (no cancel), preserves existing pr-preview/ content, adds .nojekyll, and embeds commit SHA in deploy commit.
PR Build Signaling Workflow
.github/workflows/pr-build.yml
New workflow triggered on pull_request events for frontend/**; writes PR metadata and uploads artifact pr-metadata-<PR> with a deploy or cleanup marker and 1-day retention.
PR Deploy Workflow
.github/workflows/pr-deploy.yml
New workflow triggered on completion of PR Build; downloads and validates pr-metadata; deploy path checks out PR SHA, builds with PR-scoped base path and VITE secrets, deploys to gh-pages/pr-preview/pr-<N>/, and posts/updates a PR comment; cleanup path removes preview directory and updates the comment.
Frontend Router Configuration
frontend/src/App.jsx
Removed basename={import.meta.env.BASE_URL} from top-level <Router>, changing route matching to rely on the browser URL.
Asset URL Migration
frontend/src/components/Navbar.jsx, frontend/src/components/InvoicePreview.jsx, frontend/src/page/About.jsx, frontend/src/page/BatchPayment.jsx, frontend/src/page/Landing.jsx, frontend/src/page/ReceivedInvoice.jsx, frontend/src/page/SentInvoice.jsx, frontend/src/utils/generateInvoicePDF.js
Replaced root-relative /... image paths with ${import.meta.env.BASE_URL}... across components and the PDF generator (DOM query, fetch, and image load fallbacks).

Sequence Diagram

sequenceDiagram
  participant PR as Pull Request
  participant BuildWF as "PR Preview: Build"
  participant DeployWF as "PR Preview: Deploy"
  participant GHPages as "gh-pages branch"
  PR->>BuildWF: open/synchronize/reopen/close (frontend/**)
  BuildWF->>BuildWF: write pr-metadata artifact (PR#, SHA, action)
  BuildWF->>DeployWF: workflow_run completed (artifact available)
  DeployWF->>DeployWF: download pr-metadata, validate PR#/SHA/action
  alt action == deploy
    DeployWF->>DeployWF: checkout PR SHA, build (VITE secrets, base /pr-preview/pr-N/)
    DeployWF->>GHPages: deploy frontend/dist to pr-preview/pr-N/ (keep other files)
    DeployWF->>PR: post or update preview comment with URL and short SHA
  else action == cleanup
    DeployWF->>GHPages: remove pr-preview/pr-N/ if present
    DeployWF->>PR: update existing preview comment to "preview removed"
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

Typescript Lang, Documentation

Suggested reviewers

  • Zahnentferner
  • adityabhattad2021

Poem

🐰 A rabbit hops through workflows new,
PR previews bloom in view,
BASE_URL guides each logo’s trail,
Routes align and tests set sail,
Tiny builds make big dreams true.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly summarizes the three main changes: CI improvements (PR previews), updated contribution guidelines, and a router basename fix.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Atharva0506 Atharva0506 force-pushed the ci/gh-pages-preview branch from 9fa0b90 to ddc4823 Compare June 11, 2026 11:01
@Atharva0506 Atharva0506 marked this pull request as ready for review June 11, 2026 11:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/components/InvoicePreview.jsx (1)

246-247: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Root cause: incomplete base-path migration for token fallback assets.

These locations still hardcode "/tokenImages/generic.png" while the app now targets subpath deployments (PR preview/gh-pages). Convert all token fallback asset paths to ${import.meta.env.BASE_URL}tokenImages/generic.png to avoid 404s outside root hosting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/InvoicePreview.jsx` around lines 246 - 247, Replace
the hardcoded fallback path "/tokenImages/generic.png" used when setting
e.target.src in the image error handler inside the InvoicePreview component with
the BASE_URL-aware path by using import.meta.env.BASE_URL +
"tokenImages/generic.png" (i.e. set e.target.src to
`${import.meta.env.BASE_URL}tokenImages/generic.png`), ensuring all occurrences
in InvoicePreview.jsx that assign e.target.src on error or fallback use this
BASE_URL-prefixed path so subpath deployments don't 404.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/deploy.yml:
- Line 79: Multiple workflow steps reference mutable action tags
(peaceiris/actions-gh-pages@v4, actions/upload-artifact@v4,
actions/github-script@v7, actions/checkout@v4, actions/setup-node@v4); replace
each tag reference with the corresponding commit SHA from the action's GitHub
repo to pin to an immutable commit, updating all occurrences across the
workflows (e.g., every peaceiris/actions-gh-pages@v4,
actions/upload-artifact@v4, actions/github-script@v7, actions/checkout@v4,
actions/setup-node@v4 instances), and add a note or config to enable
Dependabot/renovate to regularly update these SHAs going forward.
- Line 13: Add an inline explanatory comment next to the workflow-level
permission declaration `contents: write` in the deploy workflow to state that
this permission is required so `peaceiris/actions-gh-pages` can push to the
gh-pages branch and to call out the security boundary (e.g., only used for
publishing, not for other repo data). Locate the `permissions` block containing
`contents: write` and add a brief comment referencing
`peaceiris/actions-gh-pages` and why write access is limited/required.

---

Outside diff comments:
In `@frontend/src/components/InvoicePreview.jsx`:
- Around line 246-247: Replace the hardcoded fallback path
"/tokenImages/generic.png" used when setting e.target.src in the image error
handler inside the InvoicePreview component with the BASE_URL-aware path by
using import.meta.env.BASE_URL + "tokenImages/generic.png" (i.e. set
e.target.src to `${import.meta.env.BASE_URL}tokenImages/generic.png`), ensuring
all occurrences in InvoicePreview.jsx that assign e.target.src on error or
fallback use this BASE_URL-prefixed path so subpath deployments don't 404.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7baf445b-3546-4532-b3f5-c9f5e4ac7f99

📥 Commits

Reviewing files that changed from the base of the PR and between a57c60e and ddc4823.

📒 Files selected for processing (13)
  • .github/workflows/deploy.yml
  • .github/workflows/pr-build.yml
  • .github/workflows/pr-deploy.yml
  • CONTRIBUTING.md
  • frontend/src/App.jsx
  • frontend/src/components/InvoicePreview.jsx
  • frontend/src/components/Navbar.jsx
  • frontend/src/page/About.jsx
  • frontend/src/page/BatchPayment.jsx
  • frontend/src/page/Landing.jsx
  • frontend/src/page/ReceivedInvoice.jsx
  • frontend/src/page/SentInvoice.jsx
  • frontend/src/utils/generateInvoicePDF.js

Comment thread .github/workflows/deploy.yml
Comment thread .github/workflows/deploy.yml
@Atharva0506

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/deploy.yml (2)

67-72: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Misleading error message when copy fails.

The error message "No pr-preview directory on gh-pages yet" is printed both when git checkout fails (pr-preview doesn't exist) and when checkout succeeds but cp or rm fails. If the copy fails, this message is inaccurate and the build state may be incomplete.

♻️ Refactor to distinguish failure modes
-          git checkout origin/gh-pages -- pr-preview/ 2>/dev/null && {
+          if git checkout origin/gh-pages -- pr-preview/ 2>/dev/null; then
+            echo "Found pr-preview directory on gh-pages, restoring..."
             cp -r pr-preview ./frontend/dist/pr-preview
             rm -rf pr-preview
-          } || {
+          else
             echo "No pr-preview directory on gh-pages yet — skipping restore."
-          }
+          fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/deploy.yml around lines 67 - 72, The current block prints
the same "No pr-preview..." message for both a failed git checkout and failures
of the subsequent cp/rm steps; update the logic to distinguish those cases by
first attempting git checkout origin/gh-pages -- pr-preview and if that fails
print the existing "No pr-preview directory on gh-pages yet — skipping restore."
message, but if checkout succeeds then run cp -r pr-preview
./frontend/dist/pr-preview and rm -rf pr-preview and check their exit statuses
separately, emitting a different, accurate error message (and non-zero exit if
desired) when the copy or remove commands fail; reference the commands "git
checkout origin/gh-pages -- pr-preview", "cp -r pr-preview
./frontend/dist/pr-preview", and "rm -rf pr-preview" when making these checks.

56-85: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Race condition: production gh-pages deploy can overwrite concurrent PR previews

In .github/workflows/deploy.yml, production deploy runs Restore PR preview directories from gh-pages (git fetch origin gh-pages and copy pr-preview/ into ./frontend/dist/pr-preview, then deletes the local pr-preview/). It then publishes ./frontend/dist to gh-pages via peaceiris/actions-gh-pages@v4 without keep_files: true, so whatever gets pushed in the meantime can be lost.

concurrency groups don’t coordinate across workflows (deploy.yml: gh-pages-deploy; pr-deploy.yml: pr-preview-deploy), so these can run concurrently. Meanwhile, PR previews are deployed to pr-preview/pr-${{ env.PR_NUMBER }} with keep_files: true.

Race window

  1. Main deploy fetches/restores pr-preview/ from gh-pages.
  2. PR deploy publishes/updates pr-preview/pr-N/.
  3. Main deploy publishes the refreshed production publish_dir to gh-pages, overwriting the branch contents with the older pr-preview/ snapshot from step 1.

Potential impact

  • PR preview links can 404/break until the next update.
  • Preview deployments may appear “lost” temporarily.

Mitigation options

  • Use a shared concurrency.group across both deploy.yml and pr-deploy.yml to serialize gh-pages writes.
  • Alternatively, set keep_files: true on the production peaceiris/actions-gh-pages@v4 step (requires evaluating stale-file behavior).
  • If intentionally accepted, document the overwrite window and expected frequency.

The two-workflow setup is security-conscious, but this overwrite risk should be explicitly addressed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/deploy.yml around lines 56 - 85, Add protection against
gh-pages race by configuring the peaceiris/actions-gh-pages@v4 publish to
preserve existing files and by serializing gh-pages writes across workflows: in
the "Deploy to gh-pages branch" step add with: keep_files: true to ensure
restored pr-preview dirs aren’t clobbered, and add a shared concurrency.group
(e.g. gh-pages-deploy) to both this workflow and the PR preview workflow
(pr-deploy.yml) so gh-pages publishes are serialized.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/deploy.yml:
- Around line 67-72: The current block prints the same "No pr-preview..."
message for both a failed git checkout and failures of the subsequent cp/rm
steps; update the logic to distinguish those cases by first attempting git
checkout origin/gh-pages -- pr-preview and if that fails print the existing "No
pr-preview directory on gh-pages yet — skipping restore." message, but if
checkout succeeds then run cp -r pr-preview ./frontend/dist/pr-preview and rm
-rf pr-preview and check their exit statuses separately, emitting a different,
accurate error message (and non-zero exit if desired) when the copy or remove
commands fail; reference the commands "git checkout origin/gh-pages --
pr-preview", "cp -r pr-preview ./frontend/dist/pr-preview", and "rm -rf
pr-preview" when making these checks.
- Around line 56-85: Add protection against gh-pages race by configuring the
peaceiris/actions-gh-pages@v4 publish to preserve existing files and by
serializing gh-pages writes across workflows: in the "Deploy to gh-pages branch"
step add with: keep_files: true to ensure restored pr-preview dirs aren’t
clobbered, and add a shared concurrency.group (e.g. gh-pages-deploy) to both
this workflow and the PR preview workflow (pr-deploy.yml) so gh-pages publishes
are serialized.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8a4d91fa-ceea-475f-bd94-8089f2101bd7

📥 Commits

Reviewing files that changed from the base of the PR and between ddc4823 and 705677d.

📒 Files selected for processing (1)
  • .github/workflows/deploy.yml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant