Files
sickn33 80c0ebd668 ci(actions): Update workflow setup actions
Bump GitHub Actions checkout, setup-node, and setup-python to
Node 24-compatible major versions across the maintained workflows.
This removes the runner deprecation warning without changing the
workflow logic itself.
2026-04-09 14:02:41 +02:00

311 lines
9.4 KiB
YAML

name: Skills Registry CI
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
jobs:
pr-policy:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
outputs:
primary_category: ${{ steps.intake.outputs.primary_category }}
categories: ${{ steps.intake.outputs.categories }}
requires_references: ${{ steps.intake.outputs.requires_references }}
direct_derived_changes_count: ${{ steps.intake.outputs.direct_derived_changes_count }}
has_quality_checklist: ${{ steps.intake.outputs.has_quality_checklist }}
has_issue_link: ${{ steps.intake.outputs.has_issue_link }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Node
uses: actions/setup-node@v5
with:
node-version: "lts/*"
- name: Fetch base branch
run: git fetch origin "${{ github.base_ref }}"
- name: Intake PR change
id: intake
run: |
node tools/scripts/pr_preflight.cjs \
--base "origin/${{ github.base_ref }}" \
--head "HEAD" \
--event-path "$GITHUB_EVENT_PATH" \
--no-run \
--write-github-output \
--write-step-summary
- name: Enforce PR source-only contract
run: |
if [ "${{ steps.intake.outputs.direct_derived_changes_count }}" != "0" ]; then
echo "Pull requests must stay source-only."
echo "Remove derived files and let main regenerate them after merge."
exit 1
fi
if [ "${{ steps.intake.outputs.has_quality_checklist }}" != "true" ]; then
echo "PR body must include the Quality Bar Checklist from the template."
exit 1
fi
if [ "${{ steps.intake.outputs.has_issue_link }}" != "true" ]; then
echo "::notice::No Closes/Fixes issue link detected in the PR body."
fi
source-validation:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
needs: pr-policy
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Install Python dependencies
run: pip install -r tools/requirements.txt
- name: Set up Node
uses: actions/setup-node@v5
with:
node-version: "lts/*"
- name: Fetch base branch
run: git fetch origin "${{ github.base_ref }}"
- name: Install npm dependencies
run: npm ci
- name: Verify directory structure
run: |
test -d skills/
test -d apps/web-app/
test -d tools/scripts/
test -d tools/lib/
test -f README.md
test -f CONTRIBUTING.md
- name: Validate source changes
run: npm run validate
- name: Enforce validation warning budget
run: npm run check:warning-budget
- name: Verify README source credits for changed skills
run: npm run check:readme-credits -- --base "origin/${{ github.base_ref }}" --head HEAD
- name: Validate references
if: needs.pr-policy.outputs.requires_references == 'true'
run: npm run validate:references
- name: Audit npm dependencies
run: npm audit --audit-level=high
- name: Run tests
env:
ENABLE_NETWORK_TESTS: "1"
run: npm run test
- name: Install web-app dependencies
run: npm run app:install
- name: Run web app coverage
run: npm run app:test:coverage
- name: Run docs security checks
run: npm run security:docs
artifact-preview:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
needs: [pr-policy, source-validation]
steps:
- uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Install Python dependencies
run: pip install -r tools/requirements.txt
- name: Set up Node
uses: actions/setup-node@v5
with:
node-version: "lts/*"
- name: Install npm dependencies
run: npm ci
- name: Generate canonical artifacts preview
run: |
npm run chain
npm run catalog
- name: Report generated drift
run: |
mapfile -t managed_files < <(node tools/scripts/generated_files.js --include-mixed)
if [ "${#managed_files[@]}" -eq 0 ]; then
echo "::error::No managed files resolved from generated_files contract."
exit 1
fi
drift_files=$(git diff --name-only -- "${managed_files[@]}")
{
echo "## Artifact Preview"
echo
echo "- Primary change: \`${{ needs.pr-policy.outputs.primary_category }}\`"
echo "- Categories: \`${{ needs.pr-policy.outputs.categories }}\`"
echo "- Derived-file policy: PRs remain source-only; main will canonicalize final generated outputs."
echo
} >> "$GITHUB_STEP_SUMMARY"
if [ -z "$drift_files" ]; then
echo "No generated drift detected after preview."
echo "- Generated drift: none" >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
echo "::notice::Generated drift detected in artifact preview."
{
echo "- Generated drift: detected"
echo
echo "Predicted file updates:"
printf '%s\n' "$drift_files" | sed "s/^/- \`/; s/\$/\`/"
} >> "$GITHUB_STEP_SUMMARY"
main-validation-and-sync:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
concurrency:
group: canonical-main-sync
cancel-in-progress: false
permissions:
contents: write
env:
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Install Python dependencies
run: pip install -r tools/requirements.txt
- name: Set up Node
uses: actions/setup-node@v5
with:
node-version: "lts/*"
- name: Install npm dependencies
run: npm ci
- name: Verify directory structure
run: |
test -d skills/
test -d apps/web-app/
test -d tools/scripts/
test -d tools/lib/
test -f README.md
test -f CONTRIBUTING.md
- name: Validate references
run: npm run validate:references
- name: Run repo-state sync
run: npm run sync:repo-state
- name: Audit npm dependencies
run: npm audit --audit-level=high
- name: Run tests
env:
ENABLE_NETWORK_TESTS: "1"
run: npm run test
- name: Install web-app dependencies
run: npm run app:install
- name: Run web app coverage
run: npm run app:test:coverage
- name: Run docs security checks
run: npm run security:docs
- name: Set up GitHub credentials
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
set -euo pipefail
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
git fetch origin main
- name: Auto-commit canonical artifacts
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
set -euo pipefail
mapfile -t managed_files < <(node tools/scripts/generated_files.js --include-mixed)
if [ "${#managed_files[@]}" -eq 0 ]; then
echo "No managed files resolved from generated_files contract."
exit 1
fi
if git diff --quiet && [ -z "$(git ls-files --others --exclude-standard)" ]; then
echo "No canonical repo-state drift detected."
exit 0
fi
git add -- "${managed_files[@]}" || true
if git diff --cached --quiet; then
echo "Repo-state sync produced unmanaged drift only."
git status --short
exit 1
fi
if [ -n "$(git diff --name-only)" ] || [ -n "$(git ls-files --others --exclude-standard)" ]; then
echo "Repo-state sync produced unmanaged drift alongside canonical changes."
git status --short
exit 1
fi
git commit -m "chore: sync repo state [ci skip]"
git pull origin main --rebase
git push origin HEAD
- name: Check for uncommitted drift
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
if ! git diff --quiet || [ -n "$(git ls-files --others --exclude-standard)" ]; then
echo "❌ Detected leftover drift after the canonical bot sync."
echo
echo "The bot may only commit managed canonical files and must leave a clean tree."
echo "To fix locally, run the canonical maintainer flow:"
echo " npm run release:preflight"
echo " npm run sync:repo-state"
echo " git status"
git status --short
exit 1
fi