# How the bump‑plugin‑shas Action Refreshes Plugin SHAs Without a GitHub App

> Discover how the bump-plugin-shas action refreshes plugin SHAs using only GitHub Actions GITHUB_TOKEN. Learn to update pinned plugin commit SHAs without a GitHub App or extra secrets.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: how-to-guide
- Published: 2026-08-30

---

**The bump‑plugin‑shas workflow updates pinned plugin commit SHAs using only the built‑in `GITHUB_TOKEN` provided by GitHub Actions, eliminating the need for a custom GitHub App or additional secrets.**

The `bump-plugin-shas` action in the `anthropics/claude-plugins-community` repository automates the maintenance of SHA pins for external Claude plugins. Instead of relying on a dedicated GitHub App installation, the workflow leverages the automatically injected `GITHUB_TOKEN` to validate upstream changes, create signed commits, and open pull requests. This approach simplifies authentication while maintaining security through GitHub’s native workflow permissions.

## Native Token Authentication Model

The workflow operates entirely within GitHub’s standard permission model by declaring explicit write access in its permissions block.

In [`.github/workflows/bump-plugin-shas.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/workflows/bump-plugin-shas.yml), the job specifies:

```yaml
permissions:
  contents: write
  pull-requests: write

```

These permissions allow the default token to read the repository, push new branches, create commits, and open pull requests. All API calls execute as `github-actions[bot]`, ensuring commits are properly signed and satisfy organizational requirements such as `required_signatures` rules.

The custom action `./.github/actions/bump-plugin-shas` (invoked at step 80) performs a *create‑commit‑on‑branch* operation authenticated via `${{ github.token }}`. This produces verified commits without requiring external SSH keys or App-based authentication certificates.

## The SHA Refresh Logic

The action follows a strict validation pipeline before updating any plugin pin.

**Reading the manifest** – The workflow parses [`.claude-plugin/marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json) to identify each plugin’s currently pinned SHA. It compares these values against the latest upstream HEAD commits.

**Validation at HEAD** – When an upstream repository has advanced past the pinned commit, the workflow executes `claude plugin validate` using the latest Claude CLI against the new SHA. This ensures plugin compatibility before the pin moves forward.

**Isolated branch creation** – For each plugin requiring an update, the action creates a dedicated branch named `bump/<plugin-name>`. This isolation prevents a single failing validation from blocking updates for other plugins.

**Commit and PR generation** – After writing the new SHA back to the marketplace manifest, the action commits the change to the bump branch and opens a corresponding pull request. The process repeats for up to 30 plugins per run (configurable via the `max_bumps` input).

## The Freeze List Safety Mechanism

To prevent perpetual CI failures, the workflow maintains a static exclusion list at [`.github/freeze-shas.txt`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/freeze-shas.txt).

The bump process loads this file (steps 63‑74) and filters out any plugins listed within it. This allows maintainers to temporarily exclude broken plugins from the automatic bump cycle without modifying workflow code. The workflow skips these entries entirely, ensuring only healthy plugins receive update PRs.

## Post‑Bump Validation Dispatch

After creating per-entry pull requests, the workflow triggers additional validation checks using the same native token.

In steps 90‑99, the workflow dispatches the [`validate-plugins.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/validate-plugins.yml) workflow against each new bump branch:

```yaml
- name: Dispatch validate per per-entry PR
  if: steps.bump.outputs.pr-urls != '' && steps.bump.outputs.pr-urls != '[]'
  env:
    GH_TOKEN: ${{ github.token }}
    PR_URLS: ${{ steps.bump.outputs.pr-urls }}
  run: |
    set -euo pipefail
    jq -c '.[]' <<<"$PR_URLS" | while read -r entry; do
      branch=$(jq -r '.branch' <<<"$entry")
      name=$(jq -r '.name' <<<"$entry")
      gh workflow run validate-plugins.yml --ref "$branch"
    done

```

This dispatch uses `GH_TOKEN: ${{ github.token }}` to authenticate the `gh workflow run` command. The validation workflow must complete successfully before the bump PR can merge, ensuring that only verified plugin versions enter the marketplace.

## Manual Triggering and Configuration

Maintainers can run the workflow on demand or schedule it via cron. The workflow supports two key inputs defined in [`.github/workflows/bump-plugin-shas.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/workflows/bump-plugin-shas.yml):

- **`max_bumps`** – Limits the number of plugins updated in a single run (default: 30)
- **`plugin`** – When specified, bumps only the named plugin, enabling targeted hotfixes

```yaml
on:
  schedule:
    - cron: '23 7 * * *'      # daily run

  workflow_dispatch:
    inputs:
      max_bumps:
        description: "Cap on plugins bumped this run"
        default: '30'
      plugin:
        description: "Bump ONLY this plugin name"
        default: ''

```

The custom action accepts these inputs along with the freeze list:

```yaml
- uses: ./.github/actions/bump-plugin-shas
  with:
    marketplace-path: .claude-plugin/marketplace.json
    max-bumps: ${{ inputs.max_bumps || '30' }}
    freeze-shas: ${{ steps.freeze.outputs.list }}
    only: ${{ inputs.plugin }}
    pr-mode: per-entry
    claude-cli-version: latest

```

## Summary

- **No GitHub App required** – The workflow uses GitHub’s auto‑provided `GITHUB_TOKEN` with `contents: write` and `pull-requests: write` permissions to perform all repository operations.
- **Signed commits by default** – The `create-commit-on-branch` API calls generate commits signed by `github-actions[bot]`, satisfying branch protection rules without additional configuration.
- **Per-plugin isolation** – Each bumped plugin receives its own `bump/<name>` branch and PR, preventing cross-contamination of validation failures.
- **Safety exclusions** – The [`.github/freeze-shas.txt`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/freeze-shas.txt) file allows maintainers to exclude broken plugins from automatic updates.
- **Validation gating** – Post-creation dispatch of [`validate-plugins.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/validate-plugins.yml) ensures all bumped SHAs pass CLI validation before merge.

## Frequently Asked Questions

### Why does the action not require a GitHub App?

The action relies on the `GITHUB_TOKEN` secret that GitHub automatically generates for every workflow run. According to the source code in `anthropics/claude-plugins-community`, granting this token `write` permissions for `contents` and `pull-requests` provides sufficient scope to create branches, commit changes, and open pull requests. Since the repository trusts the `github-actions[bot]` actor, no external App identity is necessary.

### How does the freeze list prevent broken plugins from updating?

The workflow reads [`.github/freeze-shas.txt`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/freeze-shas.txt) at runtime and excludes any plugin names found within that file from the bump process. This allows maintainers to manually curate a list of plugins known to be incompatible with the latest upstream HEAD, preventing the workflow from generating failing PRs for those specific entries while continuing to update healthy plugins.

### Can I run the bump process for a single plugin instead of all outdated ones?

Yes. The workflow supports a `plugin` input parameter available through `workflow_dispatch` triggers. When you provide a specific plugin name to this input, the `./.github/actions/bump-plugin-shas` action filters its processing to only that entry, creating a targeted bump branch and PR regardless of the `max_bumps` limit or other pending updates.

### How are the commits signed without an App’s private key?

The workflow uses GitHub’s *create‑commit‑on‑branch* GraphQL mutation or equivalent REST API calls authenticated with the default `GITHUB_TOKEN`. Commits created through GitHub’s API using this token are automatically signed by GitHub and attributed to `github-actions[bot]`, satisfying the repository’s `required_signatures` branch protection rules without requiring manual GPG keys or App certificates.