📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-07-29 07:59:17 +00:00
parent 60364c6660
commit 0c634043e3
427 changed files with 26138 additions and 2336 deletions
+33 -30
View File
@@ -5,7 +5,7 @@
This guide details the exact procedures for maintaining `agentic-awesome-skills`.
It covers the **Quality Bar**, **Documentation Consistency**, and **Release Workflows**.
**Maintainer shortcuts:** [Merge a PR](#b-when-you-merge-a-pr-step-by-step) · [Reopen & merge a closed PR](#if-a-pr-was-closed-after-local-integration-reopen-and-merge) · [Post-merge credits sync](#c-post-merge-credits-sync-mandatory-after-every-pr-merge) · [Close issues](#when-to-close-an-issue) · [Create a release](#4-release-workflow)
**Maintainer shortcuts:** [Merge a PR](#b-when-you-merge-a-pr-step-by-step) · [Reopen & merge a closed PR](#if-a-pr-was-closed-after-local-integration-reopen-and-merge) · [Post-batch credits verification](#c-post-batch-credits-verification) · [Close issues](#when-to-close-an-issue) · [Create a release](#4-release-workflow)
---
@@ -39,7 +39,7 @@ If you touch **any of these**:
…then you **MUST** run the Validation Chain **BEFORE** committing.
- Running `npm run chain` is **NOT optional**.
- Running `npm run catalog` is **NOT optional**.
- `npm run chain` already includes catalog generation; do not invoke `npm run catalog` again immediately afterward.
For contributor PRs, the contract is now **source-only**:
@@ -113,17 +113,11 @@ Before ANY commit that adds/modifies skills, run the chain:
This verifies that changed skills with declared external upstream repos already have the required README credit under `### Official Sources` or `### Community Contributors`.
The first rollout is warning-first for missing structured metadata: if a changed skill clearly looks externally sourced but still lacks `source_repo`, the check warns instead of failing. Once `source_repo` is declared, README coverage is mandatory.
4. **Build catalog**:
```bash
npm run catalog
```
5. **Optional maintainer sweep shortcut**:
4. **Optional maintainer sweep shortcut**:
```bash
npm run sync:repo-state
```
This wraps `chain + catalog + sync:web-assets + sync:contributors + audit:consistency` for a full local repo-state refresh.
This wraps `chain + sync:web-assets + sync:contributors + audit:consistency` for a full local repo-state refresh; `chain` already generates the catalog.
The scheduled GitHub Actions workflow `Repo Hygiene` runs this same sweep weekly to catch slow drift on `main`.
It also enforces the frozen validation warning budget, so new warnings do not creep in silently while the legacy `135` known warnings remain accepted.
@@ -139,10 +133,9 @@ Before ANY commit that adds/modifies skills, run the chain:
```
Risk labels are declared metadata. Validate the declared value and review ambiguous `risk: unknown` cases semantically; do not infer or rewrite risk from isolated words.
6. **PROVE GENERATED STATE, BUT KEEP SOURCE PRS SOURCE-ONLY**:
5. **PROVE GENERATED STATE, BUT KEEP SOURCE PRS SOURCE-ONLY**:
```bash
npm run chain
npm run catalog
git status --short
```
> 🔴 **CRITICAL for maintainer pull requests**: Inspect the generated delta as validation, then exclude derived registries, plugin mirrors, marketplaces, and other generated outputs from the source PR. The protected `automation/canonical-repo-state` PR owns that state after source merge.
@@ -165,6 +158,14 @@ For every canonical `SKILL.md` or tracked bundle-file change, run validation, re
3. **Quality Bar** — PR description confirms the [Quality Bar Checklist](.github/PULL_REQUEST_TEMPLATE.md) (metadata, risk label, credits if applicable).
4. **Issue link** — If the PR fixes an issue, the PR description should contain `Closes #N` or `Fixes #N` so GitHub auto-closes the issue on merge.
**Required-CI execution contract:**
- `pr-policy` executes the fork-safety intake with code materialized from the exact protected base before the dependent required jobs start. This is an early, unprivileged rejection of unsafe fork diffs; `merge:batch` still recomputes the trusted decision and remains the only fork-run approval and merge authority.
- The reported `impact_profile` is shadow telemetry only. It does not skip, downgrade, or satisfy any required check.
- For an ordinary source PR, `source-validation` performs the generated-state refresh once and publishes a manifest bound to the exact repository, workflow/run attempt, and PR head SHA. `artifact-preview` verifies that manifest and its digest; it does not regenerate the same source-PR tree.
- For the protected canonical-sync PR, `pr-policy` reproduces the exact tree from trusted `main`, `source-validation` records a lightweight boundary, and `artifact-preview` confirms that regeneration leaves no drift. The merged commit still receives the explicit final `main` CI and CodeQL runs.
- The test runner emits timing telemetry for measurement. Deterministic sharding is an explicit local opt-in through `npm run test:local -- --shard-index N --shard-count M`; required CI continues to run the complete unsharded `npm run test` gate.
**How you merge:**
- **Always merge with `npm run merge:batch`**, which uses GitHub's immediate squash-merge endpoint so the PR shows as **Merged** and the contributor gets credit. Do **not** integrate locally, use a raw merge command, or close the PR after copying its changes.
@@ -192,7 +193,9 @@ Use this playbook:
2. **Treat the checklist as guidance, not evidence.** A missing checklist emits a notice; objective path, blob, validation, reference, provenance, security, test, and exact-head review gates determine mergeability.
3. **Let `merge:batch` approve action-required fork runs.** GitHub Actions materializes those runs asynchronously, so an empty first lookup is not evidence that approval is unnecessary. Do not approve them directly by run ID; the command binds every approval to the current PR, exact head SHA, allowlisted workflow, locally recomputed diff, and immutable PR tuple.
4. **Wait for the required checks.** Merge only after `pr-policy`, `pr-evidence`, `source-validation`, `artifact-preview`, and a truthful skill-review outcome for any change under `skills/**` or `plugins/**/skills/**`. `review` means Tessl semantic review actually passed or reused a successful result for the identical complete skill-directory fingerprint. `manual-review-required` means credentials or credits were unavailable, or Tessl did not produce a passing result; it requires the exact-SHA maintainer judgment above. Never describe `manual-review-required` as “Tessl passed,” and never rerun Tessl merely because the PR head or base moved when the complete changed skill content is identical.
5. **If the merge endpoint says `Base branch was modified`**, refresh the PR state and retry. This is normal when you are merging a batch and `main` moved between attempts.
5. **If the merge endpoint says `Base branch was modified`**, stop that invocation, discard its stale evidence, refresh the checkout to the current `origin/main`, and rerun `merge:batch`. The command does not retry base drift automatically.
`merge:batch` evaluates the PR as it exists. It does not rewrite or normalize the PR body, and it does not close or reopen the PR to manufacture replacement workflow runs. The reopen procedure below is only for repairing a PR that was historically closed after unsupported local integration.
**If a PR was closed after local integration (reopen and merge):**
@@ -233,47 +236,47 @@ We used this flow for PRs [#220](https://github.com/sickn33/agentic-awesome-skil
```text
Fixed in #<PR_NUMBER>. Shipped in release vX.Y.Z.
```
3. **Run the Post-Merge Credits Sync below** — this is mandatory after every PR merge, including single-PR merges.
3. **Complete the post-batch credits verification below** after the source batch, including a one-PR batch.
**Maintainer shortcut for batched PRs:**
- Use `npm run merge:batch -- --prs 450,449,446,451` to automate the ordered maintainer flow for multiple PRs. See [docs/maintainers/merge-batch.md](../docs/maintainers/merge-batch.md) for the short usage guide.
- Pages is release-only: ordinary pushes to `main` never deploy it. Dispatch `.github/workflows/pages.yml` explicitly only at an approved publication gate. Canonical-sync merges still use `--skip-pages` and carry `[skip pages]` as a durable audit marker; the four routine app-bound checks and CodeQL remain enforced. The supported Core preview uses the targeted packed smoke workflow; retired certified-v1 verifier harnesses are not part of the repository workflow.
- The script keeps the GitHub-only squash merge rule, handles fork-run approvals and stale PR metadata refresh, waits only on fresh required checks, retries `Base branch was modified`, and runs the mandatory post-merge `sync:contributors` follow-up on `main`. Sensitive repository-wide source changes use the same-repository exception only when the PR is authored by the repository owner and its exact full head SHA is attested; collaborator-authored sensitive PRs remain under the external safety policy.
- Pages is release-only: ordinary pushes to `main` never deploy it. Dispatch `.github/workflows/pages.yml` only from the exact immutable `vX.Y.Z` tag at an approved publication gate, never from `main` or another branch. Canonical-sync merges still use `--skip-pages` and carry `[skip pages]` as a durable audit marker; the four routine app-bound checks and CodeQL remain enforced. The supported Core preview uses the targeted packed smoke workflow; retired certified-v1 verifier harnesses are not part of the repository workflow.
- The script keeps the GitHub-only squash merge rule, handles guarded fork-run approvals, waits on required checks bound to the current PR and exact head, and hands contributor/generated drift to the protected canonical-sync lane. It does not run `sync:contributors` itself, mutate PR metadata, close/reopen PRs, or retry base drift; rerun it from fresh `origin/main` whenever the base or head moves. Sensitive repository-wide source changes use the same-repository exception only when the PR is authored by the repository owner and its exact full head SHA is attested; collaborator-authored sensitive PRs remain under the external safety policy.
- It is intentionally not a conflict resolver. If a PR is conflicting, stop and follow the manual conflict playbook.
### C. Post-Merge Credits Sync (Mandatory After Every PR Merge)
### C. Post-Batch Credits Verification
This section is **not optional**. Every time a PR is merged, you must ensure both README credit surfaces are correct on `main`:
After every source batch, including a one-PR batch, verify that both README credit surfaces converge correctly on protected `main`:
- `### Community Contributors` / `## Credits & Sources` for external repositories referenced by the merged work
- `## Repo Contributors` for the human contributor list
Do this **immediately after each PR merge**. Do not defer it to release prep.
Do not run a local generator after every individual merge. The trusted `main` workflow coalesces contributor and generated drift in the protected canonical-sync PR after the source batch.
1. **Pull the merged `main` state locally**:
1. **Pull the final source-batch state locally**:
```bash
git checkout main
git pull --ff-only origin main
```
2. **Sync `Repo Contributors`**:
- Run: `npm run sync:contributors`
- This refreshes `## Repo Contributors` in `README.md` from the live GitHub contributor list while preserving custom bot/app links.
- If you are already doing a full maintainer sweep, `npm run sync:repo-state` is also acceptable.
2. **Verify the canonical-sync handoff**:
- Let the trusted workflow run `sync:repo-state`, which includes `sync:contributors`, and open or update `automation/canonical-repo-state` when drift exists.
- Verify that the protected canonical PR contains the expected `## Repo Contributors` update while preserving custom bot/app links.
- Do not commit generated or contributor drift to an ordinary source PR and do not push it directly to `main`.
3. **Audit external-source credits for the merged PR**:
- Read the merged PR description, changed files, linked issues, and any release-note draft text you plan to ship.
- If the PR added skills, references, or content sourced from an external GitHub repo that is not already credited in `README.md`, add it immediately.
3. **Audit external-source credits for the source batch**:
- Read the merged PR descriptions, changed files, linked issues, and any release-note draft text you plan to ship.
- External-source credits should already have passed the source-PR credit gate. If the batch still reveals a missing or inaccurate README credit, treat that as unmanaged source repair rather than generated canonical drift.
- Treat skill frontmatter `source_repo` + `source_type` as the primary source of truth when present.
- If the repo is from an official organization/project source, place it under `### Official Sources`.
- If the repo is a non-official ecosystem/community source, place it under `### Community Contributors`.
- If the PR reveals that a credited repo is dead, renamed, archived, or overstated, fix the README entry in the same follow-up pass instead of leaving stale metadata behind.
- Release notes are not a substitute for README attribution. If a repo appears in the merged work or planned release notes and belongs in credits, add it to the README at merge time.
4. **Publish README credit updates through the protected sync lane**:
- After the source batch, let the trusted canonical-sync workflow open or update `automation/canonical-repo-state` and merge that PR after its required checks.
- If an unmanaged credit repair is still required, make it on a topic branch and merge it by pull request; never push the follow-up directly to `main`.
4. **Complete convergence through the correct protected lane**:
- Merge the managed-only canonical-sync PR after its required checks.
- If an unmanaged external-source credit repair is still required, make it on a topic branch and merge it by pull request; never add it to the canonical-sync PR or push it directly to `main`.
- Do not leave contributor or community-credit drift until the next release.
5. **Then continue with normal maintenance**:
@@ -18,6 +18,10 @@ on:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || format('run-{0}', github.run_id) }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
candidate:
name: preview candidate
@@ -14,6 +14,10 @@ on:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || format('run-{0}', github.run_id) }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
actionlint:
runs-on: ubuntu-latest
+113 -27
View File
@@ -19,6 +19,10 @@ permissions:
env:
IS_TRUSTED_CANONICAL_SYNC_PR: ${{ inputs.canonical_sync_pr == true || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.head_ref == 'automation/canonical-repo-state' && github.event.pull_request.user.login == 'github-actions[bot]') }}
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || format('run-{0}', github.run_id) }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
pr-policy:
if: github.event_name == 'pull_request' || inputs.canonical_sync_pr == true
@@ -30,6 +34,9 @@ jobs:
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 }}
fork_approval_safe: ${{ steps.intake.outputs.fork_approval_safe }}
impact_profile: ${{ steps.intake.outputs.impact_profile }}
impact_reasons: ${{ steps.intake.outputs.impact_reasons }}
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
@@ -52,10 +59,14 @@ jobs:
id: intake
if: github.event_name == 'pull_request' && env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: |
node tools/scripts/pr_preflight.cjs \
--base "origin/${{ github.base_ref }}" \
--head "HEAD" \
trusted_root="$RUNNER_TEMP/pr-policy-main"
git worktree add --detach "$trusted_root" "${{ github.event.pull_request.base.sha }}"
NODE_PATH="$GITHUB_WORKSPACE/node_modules" node "$trusted_root/tools/scripts/pr_preflight.cjs" \
--repo "$GITHUB_WORKSPACE" \
--base "${{ github.event.pull_request.base.sha }}" \
--head "${{ github.event.pull_request.head.sha }}" \
--event-path "$GITHUB_EVENT_PATH" \
--check-fork-safety \
--no-run \
--write-github-output \
--write-step-summary
@@ -107,10 +118,6 @@ jobs:
actual_tree=$(git -C "$GITHUB_WORKSPACE" rev-parse 'HEAD^{tree}')
test "$expected_tree" = "$actual_tree"
- name: Install npm dependencies
if: env.IS_TRUSTED_CANONICAL_SYNC_PR == 'true'
run: npm ci --ignore-scripts
- name: Enforce PR source-only contract
if: github.event_name == 'pull_request' && env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
env:
@@ -137,32 +144,43 @@ jobs:
source-validation:
if: github.event_name == 'pull_request' || inputs.canonical_sync_pr == true
runs-on: ubuntu-latest
needs: [pr-policy, pr-evidence]
needs: pr-policy
outputs:
preview_manifest_digest: ${{ steps.preview_manifest.outputs.manifest_digest }}
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
persist-credentials: false
- name: Set up Python
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.10"
- name: Install Python dependencies
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: pip install -r tools/requirements.txt
- name: Set up Node
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
with:
node-version: "lts/*"
- name: Fetch base branch
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: git fetch origin "${{ github.base_ref || 'main' }}"
- name: Install npm dependencies
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: npm ci
- name: Verify directory structure
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: |
test -d skills/
test -d apps/web-app/
@@ -172,9 +190,11 @@ jobs:
test -f CONTRIBUTING.md
- name: Validate source changes
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: npm run validate
- name: Enforce validation warning budget
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: npm run check:warning-budget
- name: Verify README source credits for changed skills
@@ -182,44 +202,98 @@ jobs:
run: npm run check:readme-credits -- --base "origin/${{ github.base_ref }}" --head HEAD
- name: Validate references
if: needs.pr-policy.outputs.requires_references == 'true'
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true' && needs.pr-policy.outputs.requires_references == 'true'
run: npm run validate:references
- name: Refresh ephemeral derived sources for tests
run: npm run plugin-compat:sync && npm run index && npm run bundles:sync && npm run sync:metadata && npm run catalog && npm run build:aas-v1-catalog
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: npm run plugin-compat:sync && npm run index && npm run bundles:sync && npm run sync:metadata && npm run catalog && npm run build:aas-v1-catalog && npm run sync:web-assets
- name: Run tests
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: npm run test
- name: Run docs security checks
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: npm run security:docs
- name: Create exact-head artifact preview manifest
id: preview_manifest
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
env:
CATEGORIES_CSV: ${{ needs.pr-policy.outputs.categories }}
PRIMARY_CATEGORY: ${{ needs.pr-policy.outputs.primary_category }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
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
mapfile -d '' -t drift_files < <(git diff --name-only -z -- "${managed_files[@]}")
categories_json=$(node -e 'process.stdout.write(JSON.stringify(process.argv[1].split(",").filter(Boolean).sort()))' "$CATEGORIES_CSV")
args=()
for drift_file in "${drift_files[@]}"; do
args+=(--drift-file "$drift_file")
done
node tools/scripts/ci_artifact_preview.cjs create \
--output .tmp/artifact-preview/manifest.json \
--mode source-preview \
--repository "$GITHUB_REPOSITORY" \
--run-id "$GITHUB_RUN_ID" \
--run-attempt "$GITHUB_RUN_ATTEMPT" \
--workflow-sha "$GITHUB_WORKFLOW_SHA" \
--head-sha "$PR_HEAD_SHA" \
--primary-category "$PRIMARY_CATEGORY" \
--categories-json "$categories_json" \
"${args[@]}" \
--write-github-output
- name: Upload exact-head artifact preview manifest
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: source-preview-${{ github.run_id }}-${{ github.run_attempt }}
path: .tmp/artifact-preview/manifest.json
if-no-files-found: error
retention-days: 14
- name: Record canonical source-validation boundary
if: env.IS_TRUSTED_CANONICAL_SYNC_PR == 'true'
run: echo "Canonical source state and exact generated tree were reproduced by required pr-policy."
pr-evidence:
if: github.event_name == 'pull_request' || inputs.canonical_sync_pr == true
runs-on: ubuntu-latest
needs: pr-policy
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Python
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.10"
- name: Set up Node
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
with:
node-version: "lts/*"
- name: Install trusted dependencies
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: |
pip install -r tools/requirements.txt
npm ci --ignore-scripts
- name: Fetch base branch
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
run: git fetch origin "${{ github.base_ref || 'main' }}"
- name: Generate PR intake JSON
@@ -294,31 +368,52 @@ jobs:
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0
persist-credentials: false
- name: Set up Python
if: env.IS_TRUSTED_CANONICAL_SYNC_PR == 'true'
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.10"
- name: Install Python dependencies
if: env.IS_TRUSTED_CANONICAL_SYNC_PR == 'true'
run: pip install -r tools/requirements.txt
- name: Set up Node
if: env.IS_TRUSTED_CANONICAL_SYNC_PR == 'true'
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
with:
node-version: "lts/*"
- name: Install npm dependencies
if: env.IS_TRUSTED_CANONICAL_SYNC_PR == 'true'
run: npm ci
- name: Generate canonical artifacts preview
- name: Download exact-head artifact preview manifest
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: source-preview-${{ github.run_id }}-${{ github.run_attempt }}
path: .tmp/artifact-preview
- name: Verify and report exact-head artifact preview
if: env.IS_TRUSTED_CANONICAL_SYNC_PR != 'true'
env:
EXPECTED_DIGEST: ${{ needs.source-validation.outputs.preview_manifest_digest }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
npm run chain
npm run catalog
npm run sync:web-assets
node "$GITHUB_WORKSPACE/tools/scripts/ci_artifact_preview.cjs" verify-summary \
--manifest .tmp/artifact-preview/manifest.json \
--expected-repository "$GITHUB_REPOSITORY" \
--expected-run-id "$GITHUB_RUN_ID" \
--expected-run-attempt "$GITHUB_RUN_ATTEMPT" \
--expected-workflow-sha "$GITHUB_WORKFLOW_SHA" \
--expected-head-sha "$PR_HEAD_SHA" \
--expected-digest "$EXPECTED_DIGEST" \
--write-step-summary
- name: Reproduce canonical-sync PR from main
if: env.IS_TRUSTED_CANONICAL_SYNC_PR == 'true'
@@ -327,6 +422,7 @@ jobs:
run: npm run sync:repo-state
- name: Report generated drift
if: env.IS_TRUSTED_CANONICAL_SYNC_PR == 'true'
run: |
mapfile -t managed_files < <(node tools/scripts/generated_files.js --include-mixed)
if [ "${#managed_files[@]}" -eq 0 ]; then
@@ -350,19 +446,9 @@ jobs:
exit 0
fi
if [ "$IS_TRUSTED_CANONICAL_SYNC_PR" = "true" ]; then
echo "::error::Canonical-sync PR is not byte-for-byte reproducible from main."
printf '%s\n' "$drift_files"
exit 1
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"
echo "::error::Canonical-sync PR is not byte-for-byte reproducible from main."
printf '%s\n' "$drift_files"
exit 1
main-validation-and-sync:
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.canonical_sync_pr != true && github.ref == 'refs/heads/main')
@@ -14,6 +14,10 @@ permissions:
contents: read
security-events: write
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || format('run-{0}', github.run_id) }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
analyze:
name: Analyze (${{ matrix.language }})
@@ -7,6 +7,10 @@ on:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || format('run-{0}', github.run_id) }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
dependency-review:
runs-on: ubuntu-latest
+38
View File
@@ -29,6 +29,44 @@ jobs:
fetch-depth: 0
persist-credentials: false
- name: Verify release provenance
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
if [[ "${GITHUB_REF_TYPE}" != "tag" ]]; then
echo "Pages deployment must be dispatched from an immutable release tag." >&2
exit 1
fi
if [[ ! "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Pages deployment tag must match vX.Y.Z exactly: ${GITHUB_REF_NAME}" >&2
exit 1
fi
package_version="$(jq -r '.version // empty' package.json)"
expected_tag="v${package_version}"
if [[ "${GITHUB_REF_NAME}" != "${expected_tag}" ]]; then
echo "Pages deployment tag ${GITHUB_REF_NAME} does not match package.json ${expected_tag}." >&2
exit 1
fi
tag_commit="$(git rev-parse "refs/tags/${GITHUB_REF_NAME}^{commit}")"
head_commit="$(git rev-parse HEAD)"
if [[ "${tag_commit}" != "${GITHUB_SHA}" || "${head_commit}" != "${GITHUB_SHA}" ]]; then
echo "Pages deployment tag, checkout, and workflow SHA must resolve to the same commit." >&2
exit 1
fi
release_json="$(gh api --method GET "repos/${GITHUB_REPOSITORY}/releases/tags/${GITHUB_REF_NAME}")"
if ! jq -e --arg tag "${GITHUB_REF_NAME}" \
'.tag_name == $tag and .draft == false and (.published_at | type == "string" and length > 0)' \
<<<"${release_json}" >/dev/null; then
echo "Pages deployment requires a published, non-draft GitHub Release for ${GITHUB_REF_NAME}." >&2
exit 1
fi
- name: Setup Node
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
with:
@@ -1,86 +0,0 @@
# Build and deploy the web app to GitHub Pages.
# Enable in repo: Settings → Pages → Source: GitHub Actions.
# Site URL: https://<owner>.github.io/<repo>/
name: Deploy Web App to GitHub Pages
on:
push:
branches: ["main", "master"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Setup Node
uses: actions/setup-node@v5
with:
node-version: "lts/*"
cache: "npm"
- name: Install root dependencies
run: npm ci
- name: Prepare web app (index + skills)
run: npm run app:setup
- name: Install web-app dependencies
run: cd apps/web-app && npm ci
- name: Build web app for GitHub Pages
run: cd apps/web-app && npm run build
env:
VITE_BASE_PATH: /${{ github.event.repository.name }}/
SEO_SITE_URL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}
- name: Validate SEO artifact quality
run: cd apps/web-app && npm run verify:seo
- name: Validate generated sitemap and asset consistency
run: |
cd apps/web-app
test -f dist/robots.txt
test -f dist/sitemap.xml
test -f dist/site.webmanifest
- name: Prepare artifact (404 + .nojekyll)
run: |
cd apps/web-app/dist
cp index.html 404.html
touch .nojekyll
test -f 404.html
- name: Configure GitHub Pages
uses: actions/configure-pages@v5
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v4
with:
path: apps/web-app/dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deploy
uses: actions/deploy-pages@v4
@@ -8,6 +8,10 @@ on:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || format('run-{0}', github.run_id) }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
review-state:
runs-on: ubuntu-latest