DEV Community

Cover image for Bump your VERSION file
Andrei Merlescu
Andrei Merlescu

Posted on

Bump your VERSION file

I have upgraded the bump package on GitHub to v1.1.0 that includes added support for corner cases that the new tests cover and pass. The test suite is extensive and the combination of the Makefile, the test.sh and the *_test.go files that captures unit, benchmark, fuzzy and integration tests.

go install github.com:andreimerlescu/bump@latest
which bump
Enter fullscreen mode Exit fullscreen mode

You can also download the binaries directly from GitHub.

System Size  
macOS 2.69 MB Download arm64 Silicon →
  2.74 MB Download amd64 Intel →
Linux 2.7 MB Download amd64 →
  2.69 MB Download arm64 →
Windows 2.83 MB Download bump.exe →

darwin/arm64 checksum sha256:1a337fabffe689934cce33509661f591b65b3446893634d3de5dab16f8842b09
darwin/amd64 checksum sha256:2750ec871a9d161e16ec8c0f7c4c3b1099de4b5f56963015cf343153faa3b1aa
linux/amd64 checksum sha256:5f504765ee8912a76ea07cb84b2df52d3a7e3f69a53b48d87e746ce93764d078
linux/arm64 checksum sha256:1457d9c431d8ee9e9981174d9b19be37dcb1e68d1af21b53ad055c300c184bc4
windows/amd64 bump.exe checksum sha256:f9425a8d4f03da7f8c5513a5f22e2528feb617509cd5edfd1f682392fa887e15

What you can do with bump

This package is designed to take a string, like v1.0.0 and allow you to bump it with the command line.

The -in argument is the Input File and it defaults to ./VERSION from the current working directory of where bump is being invoked.

The bump binary can intelligently bump -in files like go.mod, package.json, pom.xml, Chart.yml and Dockerfile.

The bump binary can have its default runtime manipulated using Environment Variables.

The bump binary leverages the Exit Code 0 or Exit Code 1 in order to use bump in a DevOps pipeline.

The bump binary offers you -json for JSON Encoded output.

Version Format Priority

The bump package can parse multiple version formats. To ensure accuracy, it checks for formats in a specific order, from most complex to least complex. This prevents a detailed pre-release version from being incorrectly identified as a simpler one.

The priority is as follows:

  1. v1.2.3-beta.4-alpha.5 (Beta with Alpha)
  2. v1.2.3-alpha.1 (Alpha)
  3. v1.2.3-beta.2 (Beta)
  4. v1.2.3-rc.1 (Release Candidate)
  5. v1.2.3-preview.7 (Preview)
  6. v1.2.3 (Standard)

Using bump in your future Go applications

Whenever you use a VERSION file you can easily begin using your file in your binary directly with:

//go:embed VERSION
var versionBytes []byte 

func Version() string {
    return strings.TrimSpace(string(versionBytes))
}
Enter fullscreen mode Exit fullscreen mode

Testing Suite

I want to speak about the testing suite.

make test

# SAME AS

make test-cli
make test-unit
make test-bench
make test-fuzz      # 3s run
make test-fuzz-long # 30s run # not part of `make test`
make test-integration
Enter fullscreen mode Exit fullscreen mode

When each of these files are executed a corresponding test-results/results.<test>.md file is created.

Test Log File Status
test-unit test-results/results.unit.md
test-bench test-results/results.benchmark.md
test-fuzz test-results/results.fuzz.md
test-fuzz-long test-results/results.fuzz.md
test-integration test-results/results.integration.md
test-cli test-results/results.cli.md

When combined this is six 6 test strategies applied. Short fuzzy and long fuzzy are different types of tests and they measure different results.

From the console you can run:

./test.sh
Enter fullscreen mode Exit fullscreen mode

And this will run the bump in a test environment and verify that the binary behaves in the shell in an expected manner.

The actual shell test suite is built on the concept of scenarios where they are executed in series inside the test.sh script and built from the test_funcs.sh and then verbosely described in test_scenarios.sh.

As scenarios are added, they get added to this list of strings.

declare -a tests=(
 "${scenario_01[@]}"
 // other scenarios
 "${scenario_14[@]}"
)

for t in "${tests[@]}"; do
  run "${t}"
done

echo "All $(counter -name $counterName) tests PASS!"

cleanup
Enter fullscreen mode Exit fullscreen mode

Then each scenario can be described like so:

# Start with a populated VERSION file and bump its alpha
declare -a scenario_01=(
  "echo \"v1.0.0\" > VERSION"
  "bump -check"
  "cat VERSION"
  "grep 'v1.0.0' VERSION"
  "bump -alpha"
  "grep 'v1.0.0' VERSION"
  "cat VERSION"
  "bump -alpha -write"
  "cat VERSION"
  "grep 'v1.0.0-alpha.1' VERSION"
  "rm VERSION"
)
Enter fullscreen mode Exit fullscreen mode

When this runs, you are going to see the results in the results.cli.md file:

andrei@bump.git:test.sh ⚡ Test #1 ⇒  echo "v1.0.0" > VERSION
andrei@bump.git:test.sh ⚡ Test #2 ⇒  bump -check
v1.0.0
andrei@bump.git:test.sh ⚡ Test #3 ⇒  cat VERSION
v1.0.0
Enter fullscreen mode Exit fullscreen mode

These tests are how you would use bump in the wild.

In order for me to find these missing test cases, I asked AI to scan the entire code base using the summarize summary of the "snapshot in time between commits" and identify where the tests were missing coverage of native ways that people would use bump and it added a bunch of new tests that exposed the bugs and in v1.1.0 they were squashed.

The bump package

Did you know that you can take a bump.Version{} and use it in your own application?

// Example:
//  version := bump.New()
func New() *Version {
    return &Version{
        parsed: make(map[string]interface{}),
        mu:     &sync.RWMutex{},
    }
}
Enter fullscreen mode Exit fullscreen mode

Then from your application your version object can be interacted with in a manner that has extensive testing attached to it. The helpers in the application are built to support igo in your use of bump.

What you can do with the bump.Version{} struct:

  • func BumpMajor
  • func BumpMinor
  • func BumpPatch
  • func BumpRC
  • func BumpAlpha
  • func BumpBeta
  • func BumpPreview
  • func Fix() error
  • func Format(withPrefix string) string
  • func LoadFile(path string) error
  • func ParseFile(path string) error
  • func Parse() error
  • func Save(path string) error
  • func Validate() error
  • func String() string
  • func Raw() string
  • func SetRaw(raw []byte)
  • func NoPrefix() bool
  • func Compare(*bump.Version) int

And you can create new bump structures using:

  • bump.New() *bump.Version
  • bump.Parse(version string) (*bump.Version, error)
  • bump.Create(version, path string) (*bump.Version, error)

The example of the .Create method is:

path := filepath.Join(os.TempDir(), "VERSION")
version, err := bump.Create("v1.2.3-beta.4", path)
if err != nil {
   log.Fatal(err)
}
Enter fullscreen mode Exit fullscreen mode

But, its designed to be a go-to way of interacting with your VERSION file in a go-to manner that is consistent across projects. I like using it, and I add it to my igo custom extra packages on every install so its always accessible to me on every Go version that gets installed on my system.

Top comments (0)