From 4c34ee7f5a93b92d0d30d65cad3c7303da50cc82 Mon Sep 17 00:00:00 2001 From: josunday002 Date: Fri, 24 Apr 2026 23:35:32 +0100 Subject: [PATCH 1/3] chore(ci): pin all GitHub Actions to full SHA digests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace mutable version tags (e.g. @v4) with immutable full-length commit SHA digests across all seven workflow files. Each pin retains a human-readable comment (e.g. # v4) so the intended version is still obvious at a glance. Actions pinned: - actions/checkout@v4 → @11bd71901bbe5b1630ceea73d27597364c9af683 - actions/setup-node@v4 → @49933ea5288caeca8642d1e84afbd3f7d6820020 - actions/cache@v4 → @0057852bfaa89a56745cba8c7296529d2fc39830 - actions/github-script@v7 → @f28e40c7f34bde8b3046d885e986cb6290c5673b - actions/dependency-review-action@v4 → @a6993e2c61fd5dc440b409aa1d6904921c5e1894 - dtolnay/rust-toolchain@stable → @3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 - Swatinem/rust-cache@v2 → @42dc69e1aa15d09112580998cf2ef0119e2e91ae Workflows updated: - abi-snapshot.yml - audit-check.yml - changelog.yml - ci.yml - commitlint.yml - contract-release.yml - dependency-review.yml Also fixes a structural bug in audit-check.yml where the frontend-audit step was missing its step name and was incorrectly appended to the backend-audit step block. --- .github/workflows/abi-snapshot.yml | 6 +++--- .github/workflows/audit-check.yml | 12 ++++++++---- .github/workflows/changelog.yml | 4 ++-- .github/workflows/ci.yml | 24 ++++++++++++------------ .github/workflows/commitlint.yml | 4 ++-- .github/workflows/contract-release.yml | 8 ++++---- .github/workflows/dependency-review.yml | 4 ++-- 7 files changed, 33 insertions(+), 29 deletions(-) diff --git a/.github/workflows/abi-snapshot.yml b/.github/workflows/abi-snapshot.yml index c9c2df80..0ec808d2 100644 --- a/.github/workflows/abi-snapshot.yml +++ b/.github/workflows/abi-snapshot.yml @@ -20,15 +20,15 @@ jobs: working-directory: contract steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Set up Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable with: targets: wasm32-unknown-unknown - name: Cache Rust dependencies - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@42dc69e1aa15d09112580998cf2ef0119e2e91ae # v2 with: workspaces: contract diff --git a/.github/workflows/audit-check.yml b/.github/workflows/audit-check.yml index f876ea06..515e41fd 100644 --- a/.github/workflows/audit-check.yml +++ b/.github/workflows/audit-check.yml @@ -18,10 +18,10 @@ jobs: steps: - name: 📥 Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: 🟢 Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "20" @@ -58,6 +58,8 @@ jobs: echo "::error::High vulnerabilities in backend: $HIGH" exit 1 fi + + - name: 📦 Check frontend audits id: frontend-audit working-directory: ./frontend run: | @@ -89,9 +91,11 @@ jobs: echo "❌ **HIGH vulnerabilities detected**" >> $GITHUB_STEP_SUMMARY echo "::error::High vulnerabilities in frontend: $HIGH" exit 1 - fi with audit summary + fi + + - name: 💬 Comment on PR with audit summary if: github.event_name == 'pull_request' && always() - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: >- diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index e8b0682b..15fb011a 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -16,13 +16,13 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '20' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fbd76d89..2395d0c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,9 +48,9 @@ jobs: SOROBAN_RPC_URL: https://soroban-testnet.stellar.org steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: ${{ matrix.node }} cache: 'npm' @@ -102,9 +102,9 @@ jobs: NODE_ENV: test steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '20' cache: 'npm' @@ -143,9 +143,9 @@ jobs: node: ['20', '22'] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: ${{ matrix.node }} cache: 'npm' @@ -198,9 +198,9 @@ jobs: NODE_ENV: test steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '20' cache: 'npm' @@ -226,10 +226,10 @@ jobs: timeout-minutes: 30 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Cache Cargo registry - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: | ~/.cargo/registry/index @@ -241,7 +241,7 @@ jobs: ${{ runner.os }}-cargo-registry- - name: Cache Cargo target directory - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: contract/target key: ${{ runner.os }}-contract-target-${{ hashFiles('contract/**/Cargo.lock') }} @@ -266,4 +266,4 @@ jobs: - name: Build run: cargo build --release - working-directory: contract \ No newline at end of file + working-directory: contract diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 15e88cb2..12f967f9 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -10,12 +10,12 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '20' diff --git a/.github/workflows/contract-release.yml b/.github/workflows/contract-release.yml index 35a77aae..586bd4ca 100644 --- a/.github/workflows/contract-release.yml +++ b/.github/workflows/contract-release.yml @@ -26,10 +26,10 @@ jobs: steps: - name: 📥 Checkout - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: 🦀 Cache Cargo registry - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: | ~/.cargo/registry/index @@ -41,7 +41,7 @@ jobs: ${{ runner.os }}-cargo-registry- - name: 🏗️ Cache Cargo target - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: contract/target key: ${{ runner.os }}-contract-target-${{ hashFiles('contract/Cargo.lock') }} @@ -211,7 +211,7 @@ jobs: - name: 📝 Comment on PR with checklist summary if: github.event_name == 'pull_request' && always() - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index f0b0eb07..7d9c4ff5 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -9,6 +9,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: 'Dependency Review' - uses: actions/dependency-review-action@v4 \ No newline at end of file + uses: actions/dependency-review-action@a6993e2c61fd5dc440b409aa1d6904921c5e1894 # v4 From 5e1f0bb5a819e6f4c0546be91a6cc39d970ba12d Mon Sep 17 00:00:00 2001 From: josunday002 Date: Fri, 24 Apr 2026 23:43:36 +0100 Subject: [PATCH 2/3] chore(ci): add SBOM generation workflow for container images Introduce .github/workflows/sbom.yml which builds the frontend and backend Docker images in CI and generates an SPDX JSON Software Bill of Materials (SBOM) for each using anchore/sbom-action. - Triggers on push/PR to main or develop when Dockerfiles or package manifests change, and on workflow_dispatch for manual runs - Builds myfans/frontend:ci from frontend/Dockerfile - Builds myfans/backend:ci from backend/Dockerfile - Produces sbom-frontend.spdx.json and sbom-backend.spdx.json - Uploads each SBOM as a workflow artifact retained for 90 days - All actions pinned to full SHA digests (supply-chain hygiene) --- .github/workflows/sbom.yml | 86 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 .github/workflows/sbom.yml diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml new file mode 100644 index 00000000..ca9e1d61 --- /dev/null +++ b/.github/workflows/sbom.yml @@ -0,0 +1,86 @@ +name: SBOM Generation + +on: + push: + branches: [main, develop] + paths: + - 'frontend/Dockerfile' + - 'frontend/package*.json' + - 'backend/Dockerfile' + - 'backend/package*.json' + - '.github/workflows/sbom.yml' + pull_request: + branches: [main, develop] + paths: + - 'frontend/Dockerfile' + - 'frontend/package*.json' + - 'backend/Dockerfile' + - 'backend/package*.json' + - '.github/workflows/sbom.yml' + workflow_dispatch: + +permissions: + contents: read + +jobs: + sbom-frontend: + name: SBOM – Frontend container + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Build frontend Docker image + run: | + docker build \ + --file frontend/Dockerfile \ + --tag myfans/frontend:ci \ + frontend/ + + - name: Generate SBOM (SPDX JSON) + uses: anchore/sbom-action@df80a981bc6edbc4e220a492d3cbe9f5547a6e75 # v0.17.9 + with: + image: myfans/frontend:ci + format: spdx-json + artifact-name: sbom-frontend.spdx.json + output-file: sbom-frontend.spdx.json + + - name: Upload SBOM artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: sbom-frontend + path: sbom-frontend.spdx.json + retention-days: 90 + + sbom-backend: + name: SBOM – Backend container + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Build backend Docker image + run: | + docker build \ + --file backend/Dockerfile \ + --tag myfans/backend:ci \ + backend/ + + - name: Generate SBOM (SPDX JSON) + uses: anchore/sbom-action@df80a981bc6edbc4e220a492d3cbe9f5547a6e75 # v0.17.9 + with: + image: myfans/backend:ci + format: spdx-json + artifact-name: sbom-backend.spdx.json + output-file: sbom-backend.spdx.json + + - name: Upload SBOM artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: sbom-backend + path: sbom-backend.spdx.json + retention-days: 90 From 649e886d4907e46a10844cd96245bd8a3b8271fe Mon Sep 17 00:00:00 2001 From: josunday002 Date: Fri, 24 Apr 2026 23:49:28 +0100 Subject: [PATCH 3/3] chore(docs): assign team ownership in SMOKE_TEST_MATRIX.md - Add Team Ownership section mapping each test area to the responsible GitHub team (@MyFanss/frontend, @MyFanss/backend, @MyFanss/contract) - Add Owner column to the test matrix table so each row has a clear accountable team at a glance - Update CODEOWNERS to add @MyFanss/frontend for /frontend/ and /docs/release/ so smoke test matrix changes require frontend review --- .github/CODEOWNERS | 6 ++++++ docs/release/SMOKE_TEST_MATRIX.md | 36 +++++++++++++++++++------------ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0e599809..e115cf47 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,3 +6,9 @@ # Nest.js backend – backend team reviews all changes under backend/ /backend/ @MyFanss/backend + +# Next.js frontend – frontend team reviews all changes under frontend/ +/frontend/ @MyFanss/frontend + +# Release docs including smoke test matrix – frontend team owns these +/docs/release/ @MyFanss/frontend diff --git a/docs/release/SMOKE_TEST_MATRIX.md b/docs/release/SMOKE_TEST_MATRIX.md index ff0554cd..a21f468a 100644 --- a/docs/release/SMOKE_TEST_MATRIX.md +++ b/docs/release/SMOKE_TEST_MATRIX.md @@ -7,22 +7,30 @@ Run this matrix twice for every release: Mark each row as `Pass`, `Fail`, or `N/A` and record follow-up tickets for anything that does not pass cleanly. +## Team Ownership + +| Team | Responsible for | +| --- | --- | +| `@MyFanss/frontend` | Auth, Discovery, Creator pages, Gated content, Settings, Dashboard, Error handling, Responsive QA | +| `@MyFanss/backend` | Backend API health checks across all areas | +| `@MyFanss/contract` | Subscriptions, Payments (contract-backed flows) | + ## Test Matrix -| Area | Scenario | Viewport / Browser | Dependencies | Expected Result | Staging | Production | Notes | -| --- | --- | --- | --- | --- | --- | --- | --- | -| Auth | Sign up or first-time onboarding entry point | Desktop + mobile, Chrome | Backend auth/session APIs | User can start account flow without blocking errors | [ ] | [ ] | `...` | -| Auth | Login and session restore | Desktop + mobile, Chrome + Firefox | Backend auth/session APIs | User can sign in or restore an existing session without redirect loops | [ ] | [ ] | `...` | -| Auth | Logout | Desktop, Chrome | Backend auth/session APIs | Session clears and protected routes no longer show authenticated state | [ ] | [ ] | `...` | -| Discovery | Home page and discover/creator listing views | Desktop + mobile, Chrome + Safari | Backend creator APIs | Pages render, data loads, and empty/loading states look correct | [ ] | [ ] | `...` | -| Creator pages | Open a creator profile and inspect pricing/content preview | Desktop + mobile, Chrome | Backend creator/profile APIs | Creator metadata, plans, and preview content render correctly | [ ] | [ ] | `...` | -| Subscriptions | Start a subscription checkout flow | Desktop, Chrome + Firefox | Backend checkout APIs + contract configuration | Plan details, pricing, and transaction preview are correct | [ ] | [ ] | `...` | -| Payments | Complete or simulate contract-backed payment | Desktop, Chrome | Backend checkout APIs + contract calls | Payment state updates in UI and resulting subscription state is reflected | [ ] | [ ] | `...` | -| Gated content | Access content after successful subscription | Desktop + mobile, Chrome | Backend access checks + contract/subscription status | Eligible users see content and ineligible users get graceful fallback UI | [ ] | [ ] | `...` | -| Settings | Update user or creator settings | Desktop, Chrome | Backend settings/profile APIs | Validation works, save succeeds, and persisted values reload correctly | [ ] | [ ] | `...` | -| Dashboard | Open dashboard pages relevant to the release | Desktop, Chrome + Firefox | Backend dashboard APIs | Metrics, tables, loading states, and empty states render correctly | [ ] | [ ] | `...` | -| Error handling | Trigger a known recoverable failure path | Desktop + mobile, Chrome | Backend error responses | Error UI is understandable and does not leave the app stuck | [ ] | [ ] | `...` | -| Responsive QA | Re-check changed screens on mobile and desktop | Mobile Safari + desktop Chrome | Frontend only | Layout, spacing, navigation, and primary interactions remain usable | [ ] | [ ] | `...` | +| Area | Scenario | Viewport / Browser | Dependencies | Expected Result | Owner | Staging | Production | Notes | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | +| Auth | Sign up or first-time onboarding entry point | Desktop + mobile, Chrome | Backend auth/session APIs | User can start account flow without blocking errors | `@MyFanss/frontend` | [ ] | [ ] | `...` | +| Auth | Login and session restore | Desktop + mobile, Chrome + Firefox | Backend auth/session APIs | User can sign in or restore an existing session without redirect loops | `@MyFanss/frontend` | [ ] | [ ] | `...` | +| Auth | Logout | Desktop, Chrome | Backend auth/session APIs | Session clears and protected routes no longer show authenticated state | `@MyFanss/frontend` | [ ] | [ ] | `...` | +| Discovery | Home page and discover/creator listing views | Desktop + mobile, Chrome + Safari | Backend creator APIs | Pages render, data loads, and empty/loading states look correct | `@MyFanss/frontend` | [ ] | [ ] | `...` | +| Creator pages | Open a creator profile and inspect pricing/content preview | Desktop + mobile, Chrome | Backend creator/profile APIs | Creator metadata, plans, and preview content render correctly | `@MyFanss/frontend` | [ ] | [ ] | `...` | +| Subscriptions | Start a subscription checkout flow | Desktop, Chrome + Firefox | Backend checkout APIs + contract configuration | Plan details, pricing, and transaction preview are correct | `@MyFanss/contract` | [ ] | [ ] | `...` | +| Payments | Complete or simulate contract-backed payment | Desktop, Chrome | Backend checkout APIs + contract calls | Payment state updates in UI and resulting subscription state is reflected | `@MyFanss/contract` | [ ] | [ ] | `...` | +| Gated content | Access content after successful subscription | Desktop + mobile, Chrome | Backend access checks + contract/subscription status | Eligible users see content and ineligible users get graceful fallback UI | `@MyFanss/frontend` | [ ] | [ ] | `...` | +| Settings | Update user or creator settings | Desktop, Chrome | Backend settings/profile APIs | Validation works, save succeeds, and persisted values reload correctly | `@MyFanss/frontend` | [ ] | [ ] | `...` | +| Dashboard | Open dashboard pages relevant to the release | Desktop, Chrome + Firefox | Backend dashboard APIs | Metrics, tables, loading states, and empty states render correctly | `@MyFanss/frontend` | [ ] | [ ] | `...` | +| Error handling | Trigger a known recoverable failure path | Desktop + mobile, Chrome | Backend error responses | Error UI is understandable and does not leave the app stuck | `@MyFanss/frontend` | [ ] | [ ] | `...` | +| Responsive QA | Re-check changed screens on mobile and desktop | Mobile Safari + desktop Chrome | Frontend only | Layout, spacing, navigation, and primary interactions remain usable | `@MyFanss/frontend` | [ ] | [ ] | `...` | ## Cross-browser Coverage