Skip to content
Open
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
30 changes: 27 additions & 3 deletions .github/actions/node-restore-cache/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,32 @@ inputs:
node-version:
description: Node.js version (must match setup job)
required: true
working-directory:
description: Directory containing package.json (use . for repo root)
required: false
default: '.'

runs:
using: composite
steps:
- name: Resolve node_modules path
id: paths
shell: bash
env:
PKG_DIR: ${{ inputs.working-directory }}
run: |
WD="${PKG_DIR:-.}"
if [ "$WD" = "." ]; then
echo "node-modules-path=node_modules" >> "$GITHUB_OUTPUT"
else
echo "node-modules-path=${WD}/node_modules" >> "$GITHUB_OUTPUT"
fi

- name: Restore node_modules cache
id: cache-node-modules
uses: actions/cache/restore@v4
with:
path: node_modules
path: ${{ steps.paths.outputs.node-modules-path }}
key: ${{ inputs.cache-key }}
restore-keys: |
node-modules-${{ runner.os }}-
Expand All @@ -29,9 +46,16 @@ runs:
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
shell: bash
env:
PKG_DIR: ${{ inputs.working-directory }}
run: |
set -euo pipefail
WD="${PKG_DIR:-.}"
if [ "$WD" != "." ]; then
cd "$WD"
fi
if [ -f package-lock.json ]; then
npm ci
npm ci --ignore-scripts --no-audit --no-fund
else
npm install
npm install --ignore-scripts --no-audit --no-fund
fi
42 changes: 35 additions & 7 deletions .github/actions/node-setup-cache/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ inputs:
description: Run npm ci before saving cache
required: false
default: 'true'
working-directory:
description: Directory containing package.json and package-lock.json (use . for repo root)
required: false
default: '.'

outputs:
cache-key:
Expand All @@ -24,12 +28,31 @@ runs:
- name: Generate cache keys
id: cache-keys
shell: bash
env:
PKG_DIR: ${{ inputs.working-directory }}
run: |
NODE_VERSION="${{ inputs.node-version }}"
BASE_KEY="node-modules-${{ runner.os }}-${NODE_VERSION}"
HASH_KEY="${BASE_KEY}-${{ hashFiles('package-lock.json', 'package.json') }}"
WD="${PKG_DIR:-.}"
if [ "$WD" = "." ]; then
SLUG="root"
LOCK="package-lock.json"
PKG="package.json"
NM="node_modules"
else
SLUG="${WD//\//-}"
LOCK="${WD}/package-lock.json"
PKG="${WD}/package.json"
NM="${WD}/node_modules"
fi
BASE_KEY="node-modules-${{ runner.os }}-${NODE_VERSION}-${SLUG}"
FINGERPRINT=""
[ -f "$LOCK" ] && FINGERPRINT+=$(sha256sum "$LOCK" | awk '{print $1}')
[ -f "$PKG" ] && FINGERPRINT+=$(sha256sum "$PKG" | awk '{print $1}')
[ -z "$FINGERPRINT" ] && FINGERPRINT="no-lock"
HASH_KEY="${BASE_KEY}-${FINGERPRINT:0:24}"
echo "cache-key=${HASH_KEY}" >> "$GITHUB_OUTPUT"
echo "base-key=${BASE_KEY}" >> "$GITHUB_OUTPUT"
echo "node-modules-path=${NM}" >> "$GITHUB_OUTPUT"

- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
Expand All @@ -39,18 +62,23 @@ runs:
- name: Install dependencies
if: inputs.install-dependencies == 'true'
shell: bash
env:
PKG_DIR: ${{ inputs.working-directory }}
run: |
set -euo pipefail
WD="${PKG_DIR:-.}"
if [ "$WD" != "." ]; then
cd "$WD"
fi
if [ -f package-lock.json ]; then
npm ci
npm ci --ignore-scripts --no-audit --no-fund
else
npm install
npm install --ignore-scripts --no-audit --no-fund
fi

- name: Save node_modules cache
id: cache-node-modules
uses: actions/cache@v4
with:
path: node_modules
path: ${{ steps.cache-keys.outputs.node-modules-path }}
key: ${{ steps.cache-keys.outputs.cache-key }}
restore-keys: |
${{ steps.cache-keys.outputs.base-key }}-
47 changes: 41 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI Checks

on:
push:
branches: [main, develop, staging]
branches: [main, develop, staging, "release/**"]
pull_request:
branches: [main, develop, staging]
branches: [main, develop, staging, "release/**"]
types: [opened, reopened, synchronize]

permissions:
Expand Down Expand Up @@ -109,10 +109,12 @@ jobs:
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- name: Setup runtime
uses: ./.github/actions/setup-runtime
with:
node-version: ${{ env.NODE_VERSION }}
node_version: ${{ env.NODE_VERSION }}
package_manager: npm
cache_dependency_path: package-lock.json

- name: Lockfile consistency check
id: lockfile
Expand Down Expand Up @@ -280,16 +282,34 @@ jobs:
shell: bash
run: |
set -euo pipefail
npm run build
BUILD_LOG="${RUNNER_TEMP}/build.log"
npm run build 2>&1 | tee "${BUILD_LOG}"
{
echo "## Build report"
echo ""
echo '```text'
sed 's/\x1b\[[0-9;]*m//g' "${BUILD_LOG}" | tail -n 80
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
if node -e "const s=require('./package.json').scripts||{}; process.exit(s.size?0:1)"; then
{
echo ""
echo "## Bundle Size Report"
echo ""
} >> "$GITHUB_STEP_SUMMARY"
set +e
npm run size -- --markdown 2>&1 | tee -a "$GITHUB_STEP_SUMMARY"
fi

- name: Upload build log for summary job
if: always() && steps.build-gate.outputs.build-ran == 'true'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ci-build-log
path: ${{ runner.temp }}/build.log
retention-days: 1
if-no-files-found: ignore

summary:
name: 📋 CI Summary
runs-on: ubuntu-latest
Expand All @@ -305,6 +325,13 @@ jobs:
fetch-depth: 1
persist-credentials: false

- name: Download build log
if: always() && needs.build.outputs.build-ran == 'true'
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
continue-on-error: true
with:
name: ci-build-log

- name: Write job summary
env:
R_SECURITY: ${{ needs.security_checks.result }}
Expand Down Expand Up @@ -370,6 +397,14 @@ jobs:
echo "| 🧪 Test & coverage | $(ic "${R_TEST}") \`${R_TEST}\` |"
echo "| 🏗️ Build & bundle | $(ic "${R_BUILD_DISPLAY}") \`${R_BUILD_DISPLAY}\` |"
echo ""
if [ "${BUILD_RAN}" = "true" ] && [ -f build.log ]; then
echo "### 🏗️ Build output"
echo ""
echo '```text'
sed 's/\x1b\[[0-9;]*m//g' build.log | tail -n 80
echo '```'
echo ""
fi
echo "### ✅ What ran"
echo "- **One \`npm ci\` per workflow** in setup; downstream jobs restore \`node_modules\` from cache"
echo "- **PR:** dependency review + \`npm audit\` / \`audit-ci\` (reuse cached deps)"
Expand Down
Loading