Pair with the worker-side simplification on the librefang PR — the worker is now a pure transport (no key material, no signing) and this repo's CI takes over signature production. scripts/sign-plugins-index.mjs reads REGISTRY_PRIVATE_KEY from a GitHub Actions secret, signs plugins-index.json with Ed25519, and writes plugins-index.json.sig alongside it. Aborts loudly when the secret is missing so a misconfigured CI can't silently ship an unsigned payload. The workflow now runs build → sign → commit (.json + .sig) → push → poke worker /refresh. The worker fetches the committed .json + .sig verbatim and stores both — the daemon then verifies against the embedded pubkey it ships with. Closes PR review CRITICAL #1: the worker is no longer a sign-anything oracle reachable via REGISTRY_REFRESH_TOKEN. Trust root is now this repo's branch protection + Actions secret scope, not a token any CI job that can talk to stats.librefang.ai can use to mint signatures. Note: the keypair was rotated as part of this change (PR not yet merged so no daemon TOFU pins exist). New pubkey: ClGa0Ucap8NdrKAy1rw9Tt6A9I8eg4zJ53+xIuKMuq0= The plugins-index.json.sig committed here is signed with the matching new private key, in lockstep with the daemon EMBEDDED_REGISTRY_PUBKEY constant and all three worker [vars] entries.
83 lines
2.7 KiB
YAML
83 lines
2.7 KiB
YAML
name: Refresh registry-worker cache
|
|
|
|
# On every push that changes any registry content, regenerate the two
|
|
# in-repo indexes the registry-worker ingests:
|
|
# plugins-index.json — daemon-shaped flat plugins array (signed)
|
|
# registry-index.json — dict-shaped dashboard payload (unsigned)
|
|
# then poke the worker's forced-refresh endpoint so it pulls both
|
|
# (2 subrequests total, regardless of registry size — important under
|
|
# Workers Free's 50-subrequest budget) and re-signs / stores them.
|
|
#
|
|
# Without this, dashboard + daemon would have to wait for the next
|
|
# 02:00 UTC cron tick to see content changes (up to ~24h delay).
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- 'plugins/**'
|
|
- 'agents/**'
|
|
- 'skills/**'
|
|
- 'hands/**'
|
|
- 'channels/**'
|
|
- 'providers/**'
|
|
- 'workflows/**'
|
|
- 'mcp/**'
|
|
- 'scripts/build-plugins-index.mjs'
|
|
- 'scripts/build-registry-index.mjs'
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: write # commit regenerated index files back
|
|
|
|
jobs:
|
|
refresh:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
- name: Rebuild indexes
|
|
run: |
|
|
node scripts/build-plugins-index.mjs
|
|
node scripts/build-registry-index.mjs
|
|
|
|
- name: Sign plugins-index.json
|
|
env:
|
|
REGISTRY_PRIVATE_KEY: ${{ secrets.REGISTRY_PRIVATE_KEY }}
|
|
run: node scripts/sign-plugins-index.mjs
|
|
|
|
- name: Commit regenerated indexes if changed
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add plugins-index.json plugins-index.json.sig registry-index.json
|
|
if git diff --cached --quiet; then
|
|
echo "indexes already up-to-date"
|
|
else
|
|
git commit -m "chore: regenerate registry indexes"
|
|
git push
|
|
fi
|
|
|
|
- name: Trigger worker refresh
|
|
env:
|
|
REGISTRY_REFRESH_TOKEN: ${{ secrets.REGISTRY_REFRESH_TOKEN }}
|
|
run: |
|
|
if [ -z "$REGISTRY_REFRESH_TOKEN" ]; then
|
|
echo "::error::REGISTRY_REFRESH_TOKEN secret is not set on this repo"
|
|
exit 1
|
|
fi
|
|
response=$(curl -fsS -X POST \
|
|
-H "Authorization: Bearer $REGISTRY_REFRESH_TOKEN" \
|
|
-w "\nHTTP_CODE:%{http_code}" \
|
|
https://stats.librefang.ai/api/registry/refresh)
|
|
echo "$response"
|
|
code=$(echo "$response" | grep -oE 'HTTP_CODE:[0-9]+' | cut -d: -f2)
|
|
if [ "$code" != "200" ]; then
|
|
echo "::error::worker returned $code"
|
|
exit 1
|
|
fi
|