name: Bump plugin SHAs # Weekly sweep of marketplace.json — for each entry whose upstream repo has # moved past its pinned SHA, open a PR against main with updated SHAs. The # validate-marketplace workflow then runs on the PR to confirm the file is # still well-formed. # # Adapted from claude-plugins-community-internal's bump-plugin-shas.yml # for the single-file marketplace.json format. Key difference: all bumps # are batched into one PR (since they all modify the same file). on: schedule: - cron: '23 7 * * 1' # Monday 07:23 UTC workflow_dispatch: inputs: plugin: description: Only bump this plugin (for testing) required: false max_bumps: description: Cap on plugins bumped this run required: false default: '20' dry_run: description: Discover only, don't open PR type: boolean default: true concurrency: group: bump-plugin-shas cancel-in-progress: false permissions: contents: write pull-requests: write jobs: bump: runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@v4 - name: Check for existing bump PR id: existing env: GH_TOKEN: ${{ github.token }} run: | existing=$(gh pr list --label sha-bump --state open --json number --jq 'length') echo "count=$existing" >> "$GITHUB_OUTPUT" if [ "$existing" -gt 0 ]; then echo "::notice::Open sha-bump PR already exists — skipping" fi - name: Ensure sha-bump label exists if: steps.existing.outputs.count == '0' env: GH_TOKEN: ${{ github.token }} run: gh label create sha-bump --color 0e8a16 --description "Automated SHA bump" 2>/dev/null || true - name: Overlay marketplace data from main if: steps.existing.outputs.count == '0' run: | git fetch origin main --depth=1 --quiet git checkout origin/main -- .claude-plugin/marketplace.json - name: Discover and apply SHA bumps if: steps.existing.outputs.count == '0' id: discover env: GH_TOKEN: ${{ github.token }} PR_BODY_PATH: /tmp/bump-pr-body.md PLUGIN: ${{ inputs.plugin }} MAX_BUMPS: ${{ inputs.max_bumps }} DRY_RUN: ${{ inputs.dry_run }} run: | args=(--max "${MAX_BUMPS:-20}") [[ -n "$PLUGIN" ]] && args+=(--plugin "$PLUGIN") [[ "$DRY_RUN" = "true" ]] && args+=(--dry-run) python3 .github/scripts/discover_bumps.py "${args[@]}" - uses: oven-sh/setup-bun@v2 if: steps.existing.outputs.count == '0' && steps.discover.outputs.count != '0' && inputs.dry_run != true - name: Validate marketplace.json if: steps.existing.outputs.count == '0' && steps.discover.outputs.count != '0' && inputs.dry_run != true run: | bun .github/scripts/validate-marketplace.ts .claude-plugin/marketplace.json bun .github/scripts/check-marketplace-sorted.ts - name: Push bump branch if: steps.existing.outputs.count == '0' && steps.discover.outputs.count != '0' && inputs.dry_run != true id: push run: | branch="auto/bump-shas-$(date +%Y%m%d)" echo "branch=$branch" >> "$GITHUB_OUTPUT" git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git checkout -b "$branch" git add .claude-plugin/marketplace.json git commit -m "Bump SHA pins for ${{ steps.discover.outputs.count }} plugin(s) Plugins: ${{ steps.discover.outputs.bumped_names }}" git push -u origin "$branch" --force-with-lease # GITHUB_TOKEN cannot create PRs (org policy: "Allow GitHub Actions to # create and approve pull requests" is disabled). Use the same GitHub App # that -internal's bump workflow uses. # # Prerequisite: app 2812036 must be installed on this repo. The PEM # secret must exist in this repo's settings (shared with -internal). - name: Generate bot token if: steps.push.outcome == 'success' id: app-token uses: actions/create-github-app-token@v1 with: app-id: 2812036 private-key: ${{ secrets.CLAUDE_DIRECTORY_BOT_PRIVATE_KEY }} owner: ${{ github.repository_owner }} repositories: ${{ github.event.repository.name }} - name: Create pull request if: steps.push.outcome == 'success' env: GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | gh pr create \ --base main \ --head "${{ steps.push.outputs.branch }}" \ --title "Bump SHA pins (${{ steps.discover.outputs.count }} plugins)" \ --body-file /tmp/bump-pr-body.md \ --label sha-bump