From a1cb4eb6a271d4df5c8079a5fad2b22c06dd7a05 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Thu, 8 Oct 2026 18:34:44 +0500 Subject: [PATCH] fix(skills-sync): use the skills-sync environment; don't bump the pin for no-op upstream commits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Declare `environment: skills-sync` on the job. The app private key is an environment secret there; the merged workflow lacked the declaration, so the key was empty and the app-token step was skipped. - `mirror-skills --update` moved the pin to bugsee-for-ai main on every run, so any upstream commit (CI, README, ...) opened a sync PR whose only change was scripts/skills-source.json. Now the pin moves only when the generated files change; the older pin keeps producing identical files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: Ide7ed6aa6fc94a78ef3e502e3d7e248dea2ca09c --- .github/workflows/sync-agent-skills.yml | 5 ++++- scripts/mirror-skills.mjs | 11 +++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync-agent-skills.yml b/.github/workflows/sync-agent-skills.yml index 3c96c5e..f9c7e19 100644 --- a/.github/workflows/sync-agent-skills.yml +++ b/.github/workflows/sync-agent-skills.yml @@ -15,7 +15,8 @@ name: Sync agent skills # * Settings > Actions > General > "Allow GitHub Actions to create and approve pull requests". # * Recommended: a GitHub App (owned by the org, not a person) installed on this repo with # Contents + Pull requests: write. Set its client ID as the repository VARIABLE -# SYNC_APP_CLIENT_ID and its private key as the repository SECRET SYNC_APP_PRIVATE_KEY. The job +# SYNC_APP_CLIENT_ID and its private key as the SECRET SYNC_APP_PRIVATE_KEY of the "skills-sync" +# environment (restricted to the main branch, so a feature-branch workflow cannot read it). The job # then mints a short-lived token per run, and the sync PR gets the normal "Build and Deploy" # checks. Without the app it falls back to GITHUB_TOKEN: PRs opened that way do not trigger # other workflows, so this job runs the spell check and the site build itself and opens the PR @@ -39,6 +40,8 @@ concurrency: jobs: sync: runs-on: ubuntu-latest + # The app's private key lives in this environment, which only the main branch may use. + environment: skills-sync env: SYNC_APP_CLIENT_ID: ${{ vars.SYNC_APP_CLIENT_ID }} SYNC_APP_PRIVATE_KEY: ${{ secrets.SYNC_APP_PRIVATE_KEY }} diff --git a/scripts/mirror-skills.mjs b/scripts/mirror-skills.mjs index eff2744..b31a617 100644 --- a/scripts/mirror-skills.mjs +++ b/scripts/mirror-skills.mjs @@ -191,8 +191,15 @@ function main() { changed++; } for (const p of orphans) { rmSync(p); changed++; } - if (!localSource && flag('--update')) writeFileSync(PIN_PATH, JSON.stringify({ ref }, null, 2) + '\n'); - console.log(`Mirrored ${files.size} skills from bugsee-for-ai@${ref.slice(0, 7)}; ${changed} file${changed === 1 ? '' : 's'} changed.`); + // Move the pin only when the generated output actually changed. The older pin stays valid (it + // produces identical files), and a bugsee-for-ai commit that touches no skill content (CI, + // README, ...) must not open a sync PR whose only change is the pin. + const pinned = JSON.parse(readFileSync(PIN_PATH, 'utf8')).ref; + const updating = !localSource && flag('--update'); + if (updating && changed > 0) writeFileSync(PIN_PATH, JSON.stringify({ ref }, null, 2) + '\n'); + const kept = updating && changed === 0 && ref !== pinned; + console.log(`Mirrored ${files.size} skills from bugsee-for-ai@${ref.slice(0, 7)}; ${changed} file${changed === 1 ? '' : 's'} changed.` + + (kept ? ` No skill content changed since @${pinned.slice(0, 7)}; pin kept.` : '')); } if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) main();