diff --git a/.github/scripts/dependency-inspector.js b/.github/scripts/dependency-inspector.js index 27945305047..2a9f9c84b2e 100755 --- a/.github/scripts/dependency-inspector.js +++ b/.github/scripts/dependency-inspector.js @@ -12,7 +12,10 @@ const { execSync } = require('child_process'); * [packageName, current, wanted, latest, dependencyType] tuples. * * pnpm's JSON output is an object keyed by package name: - * { "pkg": { "current": "1.0.0", "wanted": "1.0.1", "latest": "2.0.0", "dependencyType": "dependencies" } } + * { "pkg": { "wanted": "1.0.1", "latest": "2.0.0", "dependencyType": "dependencies" } } + * + * pnpm's JSON output does not include a "current" field — "wanted" + * represents the lockfile-resolved version, so we use it as current. */ function parsePnpmOutdatedOutput(stdout) { if (!stdout || !stdout.trim()) { @@ -22,7 +25,7 @@ function parsePnpmOutdatedOutput(stdout) { const data = JSON.parse(stdout); return Object.entries(data).map(([name, info]) => [ name, - info.current, + info.wanted, info.wanted, info.latest, info.dependencyType @@ -632,7 +635,7 @@ With a severity flag, shows all packages with that update type. } /** - * Run yarn audit and display a vulnerability summary + * Run pnpm audit and display a vulnerability summary */ displayAuditSummary() { console.log('🔒 SECURITY AUDIT:\n'); @@ -640,40 +643,36 @@ With a severity flag, shows all packages with that update type. try { let stdout = ''; try { - stdout = execSync('yarn audit --json 2>/dev/null', { + stdout = execSync('pnpm audit --json', { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 }); } catch (error) { - // yarn audit exits with non-zero when vulnerabilities are found + // pnpm audit exits with non-zero when vulnerabilities are found stdout = error.stdout || ''; } - // Find the auditSummary line - const lines = stdout.trim().split('\n'); - for (const line of lines) { - try { - const data = JSON.parse(line); - if (data.type === 'auditSummary' && data.data && data.data.vulnerabilities) { - const v = data.data.vulnerabilities; - const total = v.info + v.low + v.moderate + v.high + v.critical; - console.log(` Total vulnerabilities: ${total}`); - console.log(` 🔴 Critical: ${v.critical}`); - console.log(` 🟠 High: ${v.high}`); - console.log(` 🟡 Moderate: ${v.moderate}`); - console.log(` đŸŸĸ Low: ${v.low}`); - if (v.info > 0) { - console.log(` â„šī¸ Info: ${v.info}`); - } - console.log(` Total dependencies scanned: ${data.data.totalDependencies}\n`); - return; - } - } catch (e) { - // Skip non-JSON lines - } + if (!stdout || !stdout.trim()) { + console.log(' âš ī¸ Could not parse audit summary\n'); + return; } - console.log(' âš ī¸ Could not parse audit summary\n'); + const data = JSON.parse(stdout); + if (data.metadata && data.metadata.vulnerabilities) { + const v = data.metadata.vulnerabilities; + const total = v.info + v.low + v.moderate + v.high + v.critical; + console.log(` Total vulnerabilities: ${total}`); + console.log(` 🔴 Critical: ${v.critical}`); + console.log(` 🟠 High: ${v.high}`); + console.log(` 🟡 Moderate: ${v.moderate}`); + console.log(` đŸŸĸ Low: ${v.low}`); + if (v.info > 0) { + console.log(` â„šī¸ Info: ${v.info}`); + } + console.log(` Total dependencies scanned: ${data.metadata.totalDependencies}\n`); + } else { + console.log(' âš ī¸ Could not parse audit summary\n'); + } } catch (error) { console.log(` âš ī¸ Audit failed: ${error.message}\n`); } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 84d121f9ef2..a505a787aa5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -452,9 +452,6 @@ jobs: env: DEPENDENCY_CACHE_KEY: ${{ needs.job_setup.outputs.dependency_cache_key }} - - name: Build TS packages - run: pnpm nx run-many -t build --exclude=ghost-admin - - name: Set timezone (non-UTC) uses: szenius/set-timezone@1f9716b0f7120e344f0c62bb7b1ee98819aefd42 # v2.0 with: @@ -472,12 +469,10 @@ jobs: echo "database__connection__password=root" >> $GITHUB_ENV - name: E2E tests - working-directory: ghost/core - run: pnpm test:ci:e2e + run: pnpm nx run ghost:test:ci:e2e - name: Integration tests - working-directory: ghost/core - run: pnpm test:ci:integration + run: pnpm nx run ghost:test:ci:integration - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 if: matrix.node == env.NODE_VERSION && contains(matrix.env.DB, 'mysql') @@ -543,9 +538,6 @@ jobs: env: DEPENDENCY_CACHE_KEY: ${{ needs.job_setup.outputs.dependency_cache_key }} - - name: Build TS packages - run: pnpm nx run-many -t build --exclude=ghost-admin - - name: Set env vars (SQLite) if: contains(matrix.env.DB, 'sqlite') run: echo "database__connection__filename=/dev/shm/ghost-test.db" >> $GITHUB_ENV @@ -558,8 +550,7 @@ jobs: echo "database__connection__password=root" >> $GITHUB_ENV - name: Legacy tests - working-directory: ghost/core - run: pnpm test:ci:legacy + run: pnpm nx run ghost:test:ci:legacy - uses: tryghost/actions/actions/slack-build@0cbdcbeb9030f46b109d5e6e44c14933026d8ca5 # main if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' @@ -754,7 +745,7 @@ jobs: - name: Test project run: tb test run - name: Trigger and watch traffic analytics infra Tinybird workflow - if: github.repository == 'TryGhost/Ghost' + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository env: GH_TOKEN: ${{ secrets.TRAFFIC_ANALYTICS_GITHUB_TOKEN }} uses: ./.github/actions/dispatch-workflow