From a49bf46d2b5536287f3a5ca73461c07525e083a7 Mon Sep 17 00:00:00 2001 From: Andre Mendes Date: Wed, 24 Jun 2026 09:17:36 -0300 Subject: [PATCH] =?UTF-8?q?ci:=20CI=20Checks=20=E2=80=94=20dependency=20re?= =?UTF-8?q?view,=20audits,=20and=20workflow=20improvements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - One install in setup (npm ci / pnpm); lint, typecheck, test, and build restore node_modules from Actions cache - PR security_checks: dependency review and improved package audits (audit-ci on core) - Lockfile check before install; CI Summary; setup-runtime composite wired into setup job (Node.js + native registry cache) Fleet: core. PR title: same as commit subject. --- .github/actions/node-restore-cache/action.yml | 30 ++++++++++-- .github/actions/node-setup-cache/action.yml | 42 ++++++++++++++--- .github/workflows/ci.yml | 47 ++++++++++++++++--- 3 files changed, 103 insertions(+), 16 deletions(-) diff --git a/.github/actions/node-restore-cache/action.yml b/.github/actions/node-restore-cache/action.yml index a6b1016..573fba4 100644 --- a/.github/actions/node-restore-cache/action.yml +++ b/.github/actions/node-restore-cache/action.yml @@ -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 }}- @@ -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 diff --git a/.github/actions/node-setup-cache/action.yml b/.github/actions/node-setup-cache/action.yml index 0a332c4..0ce262f 100644 --- a/.github/actions/node-setup-cache/action.yml +++ b/.github/actions/node-setup-cache/action.yml @@ -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: @@ -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 @@ -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 }}- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ed36e0..6a447d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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: @@ -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 @@ -280,9 +282,18 @@ 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" @@ -290,6 +301,15 @@ jobs: 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 @@ -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 }} @@ -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)"