A generic version tracking and update tool.
Bump can be used to automate version updates where other version and package management system does not fit or can't be used. This can be for example when having versions of dependencies in Makefile:s, Dockerfile:s, scripts or other kinds of texts.
For example this is a Bumpfile where we want to keep the Dockerfile base image version updated to the latest exact alpine 3 version.
$ cat Bumpfile
# Configuration for "alpine"
alpine /FROM alpine:([\d.]+)/ docker:alpine|^3
alpine link "Release notes" https://alpinelinux.org/posts/Alpine-$LATEST-released.html
# Look for matches in Dockerfile
Dockerfile
# See current versions
$ bump current
Dockerfile:1: alpine 3.9.2
# See possible updates
$ bump check
alpine 3.21.0
# See what will be changed
$ bump diff
--- Dockerfile
+++ Dockerfile
@@ -1,2 +1,2 @@
-FROM alpine:3.9.2 AS builder
+FROM alpine:3.21.0 AS builder
# Write changes
$ bump update
It's also possible to have configuration embedded in source code comments etc and it's also possible to specify files to check instead of using a Bumpfile
.
A real world example is the Dockerfile used by wader/static-ffmpeg where important libraries are automatically kept up to date using the bump github action.
Bump can be used as a github action using the action wader/bump/action@master
or by providing it and referencing yourself
Here is a workflow that will read Bumpfile
and look for new versions and creates PRs once per day at 9 UTC:
name: 'Automatic version updates'
on:
schedule:
# minute hour dom month dow (UTC)
- cron: '0 9 * * *'
# enable manual trigger of version updates
workflow_dispatch:
jobs:
bump:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: wader/bump/action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
See action.yml for input arguments.
Note that if you want bump PRs to trigger other actions like CI builds
you currently have to use a personal access token
with repo access and add it as a secret. For example
add a secret named BUMP_TOKEN
and do GITHUB_TOKEN: ${{ secrets.BUMP_TOKEN }}
.
These actions with different environments are available:
wader/bump/action@master
alpine with git and curl
wader/bump/action/go@master
alpine with git, curl and go
Image from docker hub:
docker run --rm -v "$PWD:$PWD" -w "$PWD" mwader/bump help
Build image:
docker build -t bump .
Install go and run command below and it will be installed at
$(go env GOPATH)/bin/bump
.
go get github.com/wader/bump/cmd/bump
$ bump help
Usage: bump [OPTIONS] COMMAND
OPTIONS:
-e Comma separated names to exclude
-f Bumpfile to read (Bumpfile)
-i Comma separated names to include
-r Run update commands (false)
-v Verbose (false)
COMMANDS:
version Show version of bump itself (dev)
help [FILTER] Show help or help for a filter
list [FILE...] Show bump configurations
current [FILE...] Show current versions
check [FILE...] Check for possible version updates
update [FILE...] Update versions
diff [FILE...] Show diff of what an update would change
pipeline PIPELINE Run a filter pipeline
BUMPFILE is a file with CONFIG:s or glob patterns of FILE:s
FILE is a file with EMBEDCONFIG:s or versions to be checked and updated
EMBEDCONFIG is "bump: CONFIG"
CONFIG is
NAME /REGEXP/ PIPELINE |
NAME command COMMAND |
NAME after COMMAND |
NAME message MESSAGE |
NAME link TITLE URL
NAME is a configuration name
REGEXP is a regexp with one submatch to find current version
PIPELINE is a filter pipeline: FILTER|FILTER|...
FILTER
git:<repo> | <repo.git>
gitrefs:<repo>
depsdev:<system>:<package>
docker:<image>
svn:<repo>
fetch:<url> | <http://> | <https://>
semver:<constraint> | semver:<n.n.n-pre+build> | <constraint> | <n.n.n-pre+build>
re:/<regexp>/ | re:/<regexp>/<template>/ | /<regexp>/ | /<regexp>/<template>/
sort
key:<name> | @<name>
static:<name[:key=value:...]>,...
err:<error>
NAME
is a name of the configuration.
REGEXP
is a golang regexp with
one submatch/capture group to find the current version.
PIPELINE
is a pipeline of filters that describes how to find the latest
suitable version. The syntax is similar to pipes in a shell filter|filter|...
where filter
is either in the form name:argument
like re:/[\d.]+/
,
semver:^4
or a shorter form like /[\d.]+/
, ^4
etc.
Default bump
looks for a file named Bumpfile
in the current directory.
Each line is a comment, configuration or a glob pattern of files to
read embedded configuration from.
# comment
NAME /REGEXP/ PIPELINE
NAME [command|after] COMMAND
NAME message MESSAGE
NAME link TITLE URL
filename
glob/*
Example Bumpfile:
# a bump configuration
alpine /FROM alpine:([\d.]+)/ docker:alpine|^3
alpine message Make sure to also test with abc
alpine link "Release notes" https://alpinelinux.org/posts/Alpine-$LATEST-released.html
# read configuration, check and update version in Dockerfile
Dockerfile
Embedded configuration can be used to include bump configuration inside files containing versions to be checked or updated.
Embedded configuration looks like this:
bump: NAME /REGEXP/ PIPELINE
Example Dockerfile with embedded configuration:
# bump: alpine /FROM alpine:([\d.]+)/ docker:alpine|^3
FROM alpine:3.9.3 AS builder
bump: NAME [command|after] COMMAND
COMMAND
will run with these environment variables set:
$NAME
is configuration name
$CURRENT
is current version
$LATEST
is latest version available
There are two kinds of shell commands, command
and after
. command
will be executed
instead bump doing the changes. after
will always be executed after bump has done any changes.
If you have multiple commands they will be executed in the same order as they are configured.
Example Bumpfile using command
to run go get
to change go.mod
and go.sum
:
module program
go 1.12
require (
// bump: leaktest /github.com\/fortytw2\/leaktest v(.*)/ git:https://github.com/fortytw2/leaktest.git|^1
// bump: leaktest command go get -d github.com/fortytw2/leaktest@v$LATEST && go mod tidy
github.com/fortytw2/leaktest v1.2.0
)
Example Bumpfile using after
to run a script to update download hashes:
libvorbis after ./hashupdate Dockerfile VORBIS $LATEST
NAME message MESSAGE
NAME link "TITLE" URL
These variable are available in MESSAGE
, TITLE
and URL
:
$NAME
is configuration name
$CURRENT
is current version
$LATEST
is latest version available
You can include messages and links in commit messages and pull requests by using one or
more message
and link
configurations.
Example:
libvorbis link "CHANGES file" https://github.com/xiph/vorbis/blob/master/CHANGES
libvorbis link "Source diff $CURRENT..$LATEST" https://github.com/xiph/vorbis/compare/v$CURRENT..v$LATEST
A pipeline consist of one or more filters executed in sequence. Usually it starts with a filter that produces versions from some source like a git repository. After that one or more filters can select, transform and sort versions to narrow it down to one version. If a pipeline ends up producing more than one version the first will be used.
A version is a dictionary of key/value pairs, the "name" key is either the version number
like "1.2.3" or some symbolic name like "master". In addition a version can have other keys
like "commit", "version" etc depending on the source. You can use the key filter key:<name>
or @<name>
to use them.
Default all filters operate on the default key which is the "name". This can be changed
along a pipeline using key:<name>
or @<name>
.
In the examples bump pipeline PIPELINE
is used to test run a pipeline and show
the result. Use bump -v pipeline PIPELINE
for even more verbose output that
can be helpful when testing pipelines.
# Latest 4.0 ffmpeg version
$ bump pipeline 'https://github.com/FFmpeg/FFmpeg.git|^4'
4.4.5
# Commit hash of the latest 4.0 ffmpeg version
$ bump pipeline 'https://github.com/FFmpeg/FFmpeg.git|^4|@commit'
9cf854a0c8827823df99e9924b84a2adb3dc98a5
# Latest 1.0 golang docker build image
$ bump pipeline 'docker:golang|^1'
1.23.4
# Latest mp3lame version
$ bump pipeline 'svn:http://svn.code.sf.net/p/lame/svn|/^RELEASE__(.*)$/|/_/./|*'
3.100
Filter are used to produce, transform and filter versions. Some filters like git
produces versions, re
and semver
transforms and filters.
git git:<repo>
or <repo.git>
gitrefs gitrefs:<repo>
depsdev depsdev:<system>:<package>
docker docker:<image>
svn svn:<repo>
fetch fetch:<url>
, <http://>
or <https://>
semver semver:<constraint>
, semver:<n.n.n-pre+build>
, <constraint>
or <n.n.n-pre+build>
re re:/<regexp>/
, re:/<regexp>/<template>/
, /<regexp>/
or /<regexp>/<template>/
sort sort
key key:<name>
or @<name>
static static:<name[:key=value:...]>,...
err err:<error>
git:<repo>
or <repo.git>
Produce versions from tags for a git repository. Name will be the version found in the tag, commit the commit hash or tag object.
Use gitrefs filter to get all refs unfiltered.
$ bump pipeline 'https://github.com/git/git.git|*'
2.47.1
gitrefs:<repo>
Produce versions from all refs for a git repository. Name will be the whole ref like "refs/tags/v2.7.3" and commit will be the commit hash.
Use git filter to get versions from only tags.
$ bump pipeline 'gitrefs:https://github.com/git/git.git'
HEAD
depsdev:<system>:<package>
Produce versions from https://deps.dev.
Supported package systems npm, go, maven, pypi and cargo.
$ bump pipeline 'depsdev:npm:react|*'
19.0.0
$ bump pipeline 'depsdev:go:golang.org/x/net'
0.0.0-20150423015207-d175081df37e
$ bump pipeline 'depsdev:maven:log4j:log4j|^1'
1.2.17
$ bump pipeline 'depsdev:pypi:av|*'
14.0.1
$ bump pipeline 'depsdev:cargo:serde|*'
1.0.215
docker:<image>
Produce versions from a image on docker hub or other registry. Currently only supports anonymous access.
$ bump pipeline 'docker:alpine|^3'
3.21.0
$ bump pipeline 'docker:mwader/static-ffmpeg|^4'
4.4.1
$ bump pipeline 'docker:ghcr.io/nginx-proxy/nginx-proxy|^0.9'
0.9.3
svn:<repo>
Produce versions from tags and branches from a subversion repository. Name will be the tag or branch name, version the revision.
$ bump pipeline 'svn:https://svn.apache.org/repos/asf/subversion|*'
1.14.5
fetch:<url>
, <http://>
or <https://>
Fetch a URL and produce one version with the content as the key "name".
$ bump pipeline 'fetch:http://libjpeg.sourceforge.net|/latest release is version (\w+)/'
6b
semver:<constraint>
, semver:<n.n.n-pre+build>
, <constraint>
or <n.n.n-pre+build>
Use semver to filter or transform versions.
When a constraint is provided it will be used to find the latest version fulfilling the constraint.
When a version pattern is provided it will be used to transform a version.
# find latest major 1 version
$ bump pipeline 'static:1.1.2,1.1.3,1.2.0|semver:^1'
1.2.0
# find latest minor 1.1 version
$ bump pipeline 'static:1.1.2,1.1.3,1.2.0|~1.1'
1.1.3
# transform into just major.minor
$ bump pipeline 'static:1.2.3|n.n'
1.2
re:/<regexp>/
, re:/<regexp>/<template>/
, /<regexp>/
or /<regexp>/<template>/
An alternative regex/template delimited can specified by changing the first / into some other character, for example: re:#regexp#template#.
Filter name using a golang regexp. If name does not match regexp the version will be skipped.
If only a regexp and no template is provided and no submatches are defined the name will not be changed.
If submatches are defined a submatch named "name" or "value" will be used as name and value otherwise first submatch will be used as name.
If a template is defined and no submatches was defined it will be used as a
replacement string. If submatches are defined it will be used as a template
to expand
A regexp can match many times. Use ^$ anchors or (?m:) to match just one time or per line.
# just filter
$ bump pipeline 'static:a,b|/b/'
b
# simple replace
$ bump pipeline 'static:aaa|re:/a/b/'
bbb
# simple replace with # as delimiter
$ bump pipeline 'static:aaa|re:#a#b#'
bbb
# name as first submatch
$ bump pipeline 'static:ab|re:/a(.)/'
b
# multiple submatch replace
$ bump pipeline 'static:ab:1|/(.)(.)/${0}$2$1/'
abba
# named submatch as name and value
$ bump pipeline 'static:ab|re:/(?P<name>.)(?P<value>.)/'
a
$ bump pipeline 'static:ab|re:/(?P<name>.)(?P<value>.)/|@value'
b
sort
Sort versions reverse alphabetically.
$ bump pipeline 'static:a,b,c|sort'
c
key:<name>
or @<name>
Change default key for a pipeline. Useful to have last in a pipeline to use git commit hash instead of tag name etc or in the middle of a pipeline if you want to regexp filter on something else than name.
$ bump pipeline 'static:1.0:hello=world|@hello'
world
$ bump pipeline 'static:1.0:hello=world|@name'
1.0
$ bump pipeline 'static:1.0:hello=world|key:hello'
world
static:<name[:key=value:...]>,...
Produce versions from filter argument.
$ bump pipeline 'static:1,2,3,4:key=value:a=b|sort'
4
err:<error>
Fail with error message. Used for testing.
$ bump pipeline 'err:test'
test
- GitHub action: PR labels
- GitHub action: some kind of tests
- Configuration templates, go package etc?
- Proper version number for bump itself
- How to use with hg
- docker filter: value should be layer hash
- docker filter: support non-anon-auth
- Named pipelines, "ffmpeg|^4", generate URLs to changelog/diff?
- Allow to escape
|
in filter argument - Sort filter: make smarter? natural sort?
- Custom verison sort filter somehow, similar to
sort -k
etc? - Some kind of cache to better handle multiple invocations
- HTTP service to run pipelines?
- bump-ng: Use jq or some other pipe-friednly langauge
- Some kind help to build URLs that have major.mainor etc, ex: https://host/name-1.2/name-1.3.4.tar.gz