From 0002dd4095f7aa4714ab03e636ffd114d3ae769b Mon Sep 17 00:00:00 2001 From: afeez Date: Tue, 20 Oct 2026 10:23:38 +0100 Subject: [PATCH] ci: load workflow scripts as .cjs docforum-web's package.json sets "type": "module", so Node loaded .github/scripts/*.js as ES modules and both workflows failed with "module is not defined in ES module scope". .cjs is always CommonJS regardless of package.json, so the scripts work in every repo. Renamed in all three repos to keep them identical. Co-Authored-By: Claude Opus 5.5 --- .../{pr-conflict-notifier.js => pr-conflict-notifier.cjs} | 0 .github/scripts/{pr-malware-scan.js => pr-malware-scan.cjs} | 2 +- .github/workflows/pr-conflict-notifier.yml | 2 +- .github/workflows/pr-malware-scan.yml | 4 ++-- ROADMAP.md | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) rename .github/scripts/{pr-conflict-notifier.js => pr-conflict-notifier.cjs} (100%) rename .github/scripts/{pr-malware-scan.js => pr-malware-scan.cjs} (99%) diff --git a/.github/scripts/pr-conflict-notifier.js b/.github/scripts/pr-conflict-notifier.cjs similarity index 100% rename from .github/scripts/pr-conflict-notifier.js rename to .github/scripts/pr-conflict-notifier.cjs diff --git a/.github/scripts/pr-malware-scan.js b/.github/scripts/pr-malware-scan.cjs similarity index 99% rename from .github/scripts/pr-malware-scan.js rename to .github/scripts/pr-malware-scan.cjs index 86b31736..192ac07f 100644 --- a/.github/scripts/pr-malware-scan.js +++ b/.github/scripts/pr-malware-scan.cjs @@ -37,7 +37,7 @@ const MEDIA_EXT = /\.(woff2?|ttf|otf|eot|png|jpe?g|gif|ico|webp|bmp|pdf|mp3|mp4| const DOC_EXT = /\.(md|mdx|txt)$/i; const GENERATED = /(^|\/)(package-lock\.json|Cargo\.lock|yarn\.lock|pnpm-lock\.yaml)$|(^|\/)test_snapshots\/|(^|\/)generated\/|\.snap$|\.min\.(js|css)$|\.svg$/; const JS_LIKE = /\brequire\s*\(|\bimport\s+[\w{*]|=>|\bfunction\s*\(|\beval\s*\(|\bprocess\.(env|argv)|module\.exports|child_process/; -const SELF = '.github/scripts/pr-malware-scan.js'; +const SELF = '.github/scripts/pr-malware-scan.cjs'; // Code patterns checked on every added line. Docs only get WARN for these, // since READMEs legitimately show install one-liners. diff --git a/.github/workflows/pr-conflict-notifier.yml b/.github/workflows/pr-conflict-notifier.yml index bd338715..c4d9cdce 100644 --- a/.github/workflows/pr-conflict-notifier.yml +++ b/.github/workflows/pr-conflict-notifier.yml @@ -42,5 +42,5 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const notify = require('./.github/scripts/pr-conflict-notifier.js'); + const notify = require('./.github/scripts/pr-conflict-notifier.cjs'); await notify({ github, context, core, dryRun: context.eventName === 'workflow_dispatch' && `${{ inputs.dry_run }}` === 'true' }); diff --git a/.github/workflows/pr-malware-scan.yml b/.github/workflows/pr-malware-scan.yml index 663d98bf..bc567b18 100644 --- a/.github/workflows/pr-malware-scan.yml +++ b/.github/workflows/pr-malware-scan.yml @@ -1,7 +1,7 @@ name: PR malware scan # Scans every PR for malware and supply-chain tricks (see -# .github/scripts/pr-malware-scan.js). High-severity findings fail this check, +# .github/scripts/pr-malware-scan.cjs). High-severity findings fail this check, # label the PR `security-review` and @mention the author. # # Why pull_request_target: it is the only trigger that runs on fork PRs @@ -40,5 +40,5 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const scan = require('./.github/scripts/pr-malware-scan.js'); + const scan = require('./.github/scripts/pr-malware-scan.cjs'); await scan({ github, context, core }); diff --git a/ROADMAP.md b/ROADMAP.md index f2aad947..5fd27ccc 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -125,13 +125,13 @@ for status and issue links. ## Phase 9 — Deploy & CI **Status: Not started for real production. A Render free-tier preview exists — see note. Remaining items scoped into issues #21–#22.** -- [x] **PR malware scan** — `.github/workflows/pr-malware-scan.yml` + `.github/scripts/pr-malware-scan.js`, on every PR push. Flags editor/devcontainer autorun tasks, npm install hooks, typosquatted packages and Actions, non-registry dependency sources, payloads disguised as fonts/images, base64/whitespace obfuscation, exfiltration endpoints, reverse shells and miners. HIGH findings fail the `Malware scan` check, label the PR `security-review` and @mention the author; one comment per PR, updated in place. Reads the PR as data only (never checks out or runs it). Added 2026-10-20 after a VS Code autorun payload (escrow #163) and a typosquatted action (escrow #176). +- [x] **PR malware scan** — `.github/workflows/pr-malware-scan.yml` + `.github/scripts/pr-malware-scan.cjs`, on every PR push. Flags editor/devcontainer autorun tasks, npm install hooks, typosquatted packages and Actions, non-registry dependency sources, payloads disguised as fonts/images, base64/whitespace obfuscation, exfiltration endpoints, reverse shells and miners. HIGH findings fail the `Malware scan` check, label the PR `security-review` and @mention the author; one comment per PR, updated in place. Reads the PR as data only (never checks out or runs it). Added 2026-10-20 after a VS Code autorun payload (escrow #163) and a typosquatted action (escrow #176). - [ ] Choose deployment target (ARCHITECTURE.md §8 open decision) — record as an ADR. **Still not resolved.** A Render free-tier web service + Postgres now runs `backend/`, so `docforum-web`'s GitHub Pages preview has a live API to call — see `docs/adr/0003-render-preview-deployment.md`. This is explicitly a preview, not the production decision: no secrets manager, no backups, no staging/prod split, free-tier Postgres expires 2026-11-06 (renewed 2026-10-07; 30 days, 14-day grace period) unless recreated/upgraded before then — renewal steps in ADR 0003's "Renewing the free database" section. Tracked as [issue #22](https://github.com/DocForum/docforum-core/issues/22) (Medium, 150 pts). - [x] Real CI pipeline (replaced `.github/workflows/ci.yml` placeholder — was `pull_request`-only, `echo "TODO"`, never once run). Now runs on push to `main` and on PRs: `npm audit --omit=dev` at high severity (`audit:prod`, Phase 8 issue #47) → `prisma:generate` → `typecheck` → unit tests → **integration tests (the self-contained embedded-Postgres double-booking proof)** → `build`. Verified locally end-to-end before pushing (14 unit + 1 integration test passing) and confirmed green in Actions. No lint script exists yet in `backend/package.json` — not added; `tsc --noEmit` is the closest static check currently available. Lint now tracked as [issue #28](https://github.com/DocForum/docforum-core/issues/28) (Trivial, 100 pts). Closes [issue #21](https://github.com/DocForum/docforum-core/issues/21) (Medium, 150 pts). - [ ] Staging environment. Blocked on issue #22's decision landing first — not yet scoped into its own issue. - [ ] Production environment + secrets management. Blocked on issue #22's decision landing first — not yet scoped into its own issue. - [x] Docs site deployed — `docs/site/` (VitePress) via `.github/workflows/deploy-docs.yml`, live at https://docforum.github.io/docforum-core/. Unrelated to the production-deploy decision above; this is a static site with no backend of its own. -- [x] **PR conflict notifier** — `.github/workflows/pr-conflict-notifier.yml` + `.github/scripts/pr-conflict-notifier.js`. On every push to `main` (and every 3h) it labels open PRs that conflict with `main` as `needs-rebase` and @mentions the author once per push with rebase steps; the label clears itself when the conflict is resolved. Runs from `main` only and never checks out PR code. +- [x] **PR conflict notifier** — `.github/workflows/pr-conflict-notifier.yml` + `.github/scripts/pr-conflict-notifier.cjs`. On every push to `main` (and every 3h) it labels open PRs that conflict with `main` as `needs-rebase` and @mentions the author once per push with rebase steps; the label clears itself when the conflict is resolved. Runs from `main` only and never checks out PR code. ## Explicitly deferred (not on this roadmap, tracked so they aren't forgotten) - In-app video/voice consultation (PRD OQ-1 — v1 assumes in-person + async messaging).