Skip to content

Merge pull request #81 from UseJunior/ci/sha-pin-actions #204

Merge pull request #81 from UseJunior/ci/sha-pin-actions

Merge pull request #81 from UseJunior/ci/sha-pin-actions #204

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
actionlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: rhysd/actionlint@393031adb9afb225ee52ae2ccd7a5af5525e03e8 # v1.7.11
gemini-manifest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
- name: Validate Gemini extension manifest
run: node scripts/check_gemini_extension_manifest.mjs
workspace-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Build workspaces
run: npm run build
- name: Lint/typecheck workspaces
run: npm run lint:workspaces
spec-coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Validate OpenSpec traceability coverage
run: npm run check:spec-coverage
site-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Install site dependencies
run: npm --prefix site ci
- name: Build site and validate internal links
run: npm run check:site
tool-docs-freshness:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Regenerate and verify tool reference docs are committed
run: npm run check:tool-docs
mcpb-manifest-contract:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Validate MCPB manifest/tool contract
run: npm run check:mcpb-manifest
allure-labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Validate Allure hierarchy labels
run: npm run check:allure-labels
- name: Enforce Allure filename migration policy
run: npm run check:allure-filenames
allure-quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Validate Allure quality conventions
run: npm run check:allure-quality
codeql:
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Initialize CodeQL
uses: github/codeql-action/init@5c8a8a642e79153f5d047b10ec1cba1d1cc65699 # v3
with:
languages: javascript-typescript
config-file: ./.github/codeql/codeql-config.yml
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Build workspaces
run: npm run build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@5c8a8a642e79153f5d047b10ec1cba1d1cc65699 # v3
semgrep:
uses: ./.github/workflows/semgrep.yml
permissions:
actions: read
contents: read
security-events: write
workspace-test:
runs-on: ubuntu-latest
needs: workspace-lint
permissions:
contents: read
id-token: write
strategy:
matrix:
node-version: [20, 22]
include:
- node-version: 20
coverage: true
- node-version: 22
coverage: false
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Build workspaces
run: npm run build
- name: Isolated package runtime smoke test
if: matrix.coverage
run: |
pack_dir="$(mktemp -d)"
run_dir="$(mktemp -d)"
core_tgz="$(cd packages/docx-core && npm pack --silent --pack-destination "$pack_dir")"
mcp_tgz="$(cd packages/docx-mcp && npm pack --silent --pack-destination "$pack_dir")"
safe_tgz="$(cd packages/safe-docx && npm pack --silent --pack-destination "$pack_dir")"
pushd "$run_dir"
npm init -y >/dev/null
for attempt in 1 2 3; do
echo "runtime smoke attempt ${attempt}/3"
rm -rf node_modules package-lock.json
if npm install --no-audit --no-fund "$pack_dir/$core_tgz" "$pack_dir/$mcp_tgz" "$pack_dir/$safe_tgz" >/dev/null \
&& ./node_modules/.bin/safe-docx --help; then
popd
rm -rf "$pack_dir" "$run_dir"
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
popd
rm -rf "$pack_dir" "$run_dir"
echo "runtime smoke failed after 3 attempts"
exit 1
- name: Test workspaces (with coverage)
if: matrix.coverage
run: |
npm run test:coverage -w @usejunior/docx-core
npm run test:coverage -w @usejunior/docx-mcp
npm run test:run -w @usejunior/safe-docx
npm run test:run -w @usejunior/safedocx-mcpb
- name: Test workspaces
if: ${{ !matrix.coverage }}
run: npm run test
- name: Generate package coverage dashboard + enforce ratchet
if: matrix.coverage
run: |
mkdir -p coverage
npm run coverage:packages:check > coverage/package-coverage-table.txt
cat coverage/package-coverage-table.txt
- name: Upload package coverage artifacts
if: ${{ matrix.coverage && always() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: package-coverage
if-no-files-found: error
path: |
coverage/package-coverage-baseline.json
coverage/package-coverage-summary.json
coverage/package-coverage-table.txt
packages/docx-core/coverage/coverage-summary.json
packages/docx-mcp/coverage/coverage-summary.json
packages/docx-core/coverage/lcov.info
packages/docx-mcp/coverage/lcov.info
- name: Upload coverage to Codecov
if: ${{ matrix.coverage && !cancelled() }}
continue-on-error: true
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5
with:
files: ./packages/docx-core/coverage/lcov.info,./packages/docx-mcp/coverage/lcov.info
disable_search: true
use_oidc: true
fail_ci_if_error: false
verbose: true
- name: Upload allure results
if: matrix.coverage
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: allure-results
if-no-files-found: error
path: |
packages/docx-core/allure-results/
packages/docx-mcp/allure-results/
mcpb-bundle:
runs-on: ubuntu-latest
needs: workspace-test
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Sanitize npm auth for public npx fetches
run: |
unset NODE_AUTH_TOKEN
npm config delete //registry.npmjs.org/:_authToken || true
- name: Build and pack safe-docx MCP bundle
run: npm run pack:mcpb
- name: Upload MCPB bundle artifact (main only)
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: safe-docx-mcpb
if-no-files-found: error
path: packages/safe-docx-mcpb/safe-docx.mcpb
deploy-allure:
if: github.ref == 'refs/heads/main'
needs: workspace-test
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
concurrency:
group: pages
cancel-in-progress: true
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
cache: npm
- name: Install dependencies (npm ci with retry)
run: |
for attempt in 1 2 3; do
echo "npm ci attempt ${attempt}/3"
if npm ci; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
sleep $((attempt * 20))
fi
done
echo "npm ci failed after 3 attempts"
exit 1
- name: Download allure results
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: allure-results
path: packages
- name: Generate Allure report
run: npm run allure:generate
- name: Brand Allure report
run: npm run allure:brand
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
with:
path: allure-report-repo
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4