Skip to content

Repository files navigation


██████╗ ██╗   ██╗███╗   ███╗██████╗ ███████╗██╗      ██████╗ ██╗    ██╗
██╔══██╗██║   ██║████╗ ████║██╔══██╗██╔════╝██║     ██╔═══██╗██║    ██║
██████╔╝██║   ██║██╔████╔██║██████╔╝█████╗  ██║     ██║   ██║██║ █╗ ██║
██╔══██╗██║   ██║██║╚██╔╝██║██╔═══╝ ██╔══╝  ██║     ██║   ██║██║███╗██║
██████╔╝╚██████╔╝██║ ╚═╝ ██║██║     ██║     ███████╗╚██████╔╝╚███╔███╔╝
╚═════╝  ╚═════╝ ╚═╝     ╚═╝╚═╝     ╚═╝     ╚══════╝ ╚═════╝  ╚══╝╚══╝ 

test Go Report Card Go version

bumpflow — Bump GitHub Actions Workflows

A CLI tool that scans .github/workflows/ for outdated GitHub Actions and interactively (or silently) updates them. Also can replace current version (actions/checkout@v4) with the commit tag (34e114876b0b11c390a56381ad16ebd13914f8d5). Prevent those pesky clawed clankers from hijacking your workflows!

Install

go install github.com/hatedabamboo/bumpflow@latest

Or build from source:

git clone https://github.com/hatedabamboo/bumpflow
cd bumpflow
make
make install

Usage

Run from the root of a git repository:

bumpflow [options]

Options

Flag Long form Description
-a --action Update only the specified action (owner/repo)
-A --update-all Update all outdated actions without prompting (uses hash by default; respects -t or -s)
-C --no-cache Disable caching of fetched repo versions in ~/.cache/bumpflow (caching is on by default)
--cache-age Max age before a cached entry is refreshed (default 7d); once older, falls straight through to the API
-d --dry-run Preview what would be updated without modifying any files
-f --file Update only actions in the specified workflow file
-n --count Number of latest tags to fetch (default 10)
-r --replace Convert pinned tags↔SHAs without upgrading versions
-s --sha Always use commit hashes when updating (skips the prompt)
-t --tags Always use tags when updating (skips the prompt)
-v --verbose Enable verbose logging
-V --version Show version
-h --help Show usage

-t and -s are mutually exclusive. -A and -r are mutually exclusive.

Caching

bumpflow caches fetched tag/SHA data in ~/.cache/bumpflow/repos.json — a plain JSON file — to cut down on GitHub API calls across repeated runs, which matters most for anonymous requests (60/hour). Caching is on by default; pass -C/--no-cache (or set cache: false in .bumpflow.yaml) to disable it.

Each cached entry is keyed by repo and stamped with the time it was fetched. On the next run, an entry is reused only if it's within the configured max age and holds at least as many tags as requested (via -n/--count); otherwise bumpflow goes straight to the GitHub API and refreshes it. The max age defaults to 7d and can be changed with --cache-age (or cache_age in the config file), accepting either a day count with a d suffix (3d) or a Go duration string (12h, 90m).

Config file

Persistent defaults can be set in a .bumpflow.yaml file at the repo root. CLI flags always take precedence.

always_sha: true    # same as -s
always_tag: false   # same as -t
cache: true         # set to false to disable, same as -C
cache_age: 7d       # same as --cache-age
count: 5            # same as -n
dry_run: false      # same as -d
target_action: ""   # same as -a
target_file: ""     # same as -f
update_all: false   # same as -A
verbose: false      # same as -v

Only the keys you want to override need to be present.

Authentication

Set GH_TOKEN to a GitHub personal access token for authenticated API calls:

export GH_TOKEN="ghp_..."
bumpflow

Without a token, GitHub limits anonymous requests to 60/hour. If you hit the limit, either set GH_TOKEN or use a VPN.

Example workflow usage

To utilize bumpflow capabilities in automatic fashion, you must create Fine-grained Personal Access Token with the following settings:

  • Name: WORKFLOW_TOKEN (can be any)
  • Expiration: any (recommended to set to 90 days)
  • Repository access: select only repository you want to update the workflows in
  • Permissions:
    • Contents: Read and write
    • Metadata (Required): Read-only
    • Pull requests: Read and write
    • Workflows: Read and write

Add the token to the repository secrets under the name WORKFLOW_TOKEN (can be any, but this name is used in the example). Copy the example workflow and save it under .github/workflows/upgrade-workflows.yaml (or any name you like).

---
name: Upgrade workflows

on:
  schedule:
    - cron: "0 9 * * 1" # trigger every Monday at 9:00 UTC
  workflow_dispatch:    # or manually

permissions:
  contents: write
  pull-requests: write

jobs:
  upgrade:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
        with:
          # necessary to not conflict with peter-evans/create-pull-request action
          persist-credentials: false

      - name: Setup Go
        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
        with:
          go-version: stable

      - name: Install bumpflow
        run: go install github.com/hatedabamboo/bumpflow@latest

      - name: Upgrade workflows
        run: |
          "$(go env GOPATH)/bin/bumpflow" -A # upgrade all automatically

      - name: Create labels
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          gh label create chore --color bfdadc --force
          gh label create dependencies --color bfd4f2 --force
          gh label create automation --color fef2c0 --force

      - name: Create pull request
        uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1
        with:
          token: ${{ secrets.WORKFLOW_TOKEN }}
          commit-message: "chore: upgrade workflow action versions"
          branch: chore/upgrade-workflow-actions
          delete-branch: true
          title: "chore: upgrade workflow action versions"
          body: |
            Automated upgrade of GitHub Actions versions by [bumpflow](https://github.com/hatedabamboo/bumpflow).
          labels: chore,dependencies,automation

Example interactive usage

$ bumpflow
Fetching 4 repo(s)...

  Action                                        Installed version              Latest version
  ------                                        -----------------              --------------
  actions/checkout                              de0fac2                        v6.0.2 (de0fac2)
  actions/deploy-pages                          v4                             v5.0.0 (cd2ce8f)
  actions/setup-node                            v5                             v6.4.0 (48b55a0)
  actions/upload-pages-artifact                 v4                             v5.0.0 (fc324d3)

Outdated action(s) remaining: 3

  [1] actions/deploy-pages: v4 → v5.0.0 (cd2ce8f)  (committed on 2026-03-24)
  [2] actions/setup-node: v5 → v6.4.0 (48b55a0)  (committed on 2026-04-20)
  [3] actions/upload-pages-artifact: v4 → v5.0.0 (fc324d3)  (committed on 2026-04-08)

Which action to update? (number, or q to quit): 1

Updating actions/deploy-pages:
  [1]		v5.0.0	(cd2ce8f)
  [2]		v4.0.0	(1e31a15)
  [Enter]	Skip
  Select version (number): 1
  [t] Tag:  v5.0.0
  [s] SHA:  cd2ce8fcbc39b97be8ca5fce6e763baed58fa128
  Use tag or hash? (t/s): s

  Updated .github/workflows/pages.yaml

    Done.

Outdated action(s) remaining: 2

  [1] actions/setup-node: v5 → v6.4.0 (48b55a0)  (committed on 2026-04-20)
  [2] actions/upload-pages-artifact: v4 → v5.0.0 (fc324d3)  (committed on 2026-04-08)

Which action to update? (number, or q to quit): q

About

Command-line utility to update GitHub Action versions

Topics

Resources

Contributing

Stars

6 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages