Unify main-branch maintenance around repo-state and release-state commands so generated docs, contributor acknowledgements, tracked web assets, and canonical artifacts stay aligned across CI and scheduled hygiene runs. Harden release publication by reusing deterministic sync commands, adding package dry-run verification, and covering the new workflow contract with regression tests.
260 lines
7.6 KiB
YAML
260 lines
7.6 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@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v4
|
|
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@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.10"
|
|
|
|
- name: Install Python dependencies
|
|
run: pip install pyyaml
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v4
|
|
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 source changes
|
|
run: npm run validate
|
|
|
|
- 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
|
|
continue-on-error: true
|
|
|
|
- name: Run tests
|
|
env:
|
|
ENABLE_NETWORK_TESTS: "1"
|
|
run: npm run test
|
|
|
|
- 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@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.10"
|
|
|
|
- name: Install Python dependencies
|
|
run: pip install pyyaml
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v4
|
|
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: |
|
|
managed_files=$(node tools/scripts/generated_files.js --shell --include-mixed)
|
|
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
|
|
permissions:
|
|
contents: write
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.10"
|
|
|
|
- name: Install Python dependencies
|
|
run: pip install pyyaml
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v4
|
|
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
|
|
continue-on-error: true
|
|
|
|
- name: Run tests
|
|
env:
|
|
ENABLE_NETWORK_TESTS: "1"
|
|
run: npm run test
|
|
|
|
- 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: |
|
|
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
|
|
|
|
- name: Auto-commit canonical artifacts
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
run: |
|
|
managed_files=$(node tools/scripts/generated_files.js --shell --include-mixed)
|
|
|
|
git diff --quiet && exit 0
|
|
|
|
git add $managed_files || true
|
|
|
|
git diff --cached --quiet && exit 0
|
|
|
|
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; then
|
|
echo "❌ Detected uncommitted changes produced by registry/readme/catalog scripts."
|
|
echo
|
|
echo "Main must be self-healing after the auto-sync step."
|
|
echo "To fix locally, run the canonical maintainer flow:"
|
|
echo " npm run release:preflight"
|
|
echo " npm run sync:repo-state"
|
|
echo " git status"
|
|
exit 1
|
|
fi
|