Skip to content


Folders and files

Last commit message
Last commit date

Latest commit



74 Commits

Repository files navigation


Bash functions to release any type of project.

Why and features

  • releaser is a single file, versioned and released after testing the functions
  • Any project can quickly and easily reference the functions by downloading a specific release from github
  • The releaser file is easy to review and hack with, there is no magic framework to learn, just plain bash and git commands. When something does not fit your needs, it is easy to fall back to writing your own script.
  • It works on nearly any setup because of minimal dependencies

Use the functions as you like, but the primary goal is to support following rules regarding project lifecycle:

  1. is the single source of truth about current project version.
    • only when top of changelog has version and date, then current commit is ready for a release
  2. We make a distinction between a source code release (pushing a git tag to the repository) and publishing of the project (which is specific to the language/technology used). Source code release happens before publishing of the project.
  3. Releases are automated, executed by CI-system only after all tests have passed.
  4. Releases are immutable - once a tag is published, there is no way back. This is a guarantee for the users.

A full-blown example of this lifecycle can be found in:


All the releaser functions are available after you source the releaser file.

In a script

If you want to run releaser from a script:

set -Eeuo pipefail


mkdir -p ops
if [[ ! -f $RELEASER_FILE ]];then
  wget --quiet -O $RELEASER_FILE${RELEASER_VERSION}/releaser

Your .gitignore should include ops/.

In current shell

If you want to run releaser in current shell:

releaser::loaded || eval "$(curl${RELEASER_VERSION}/releaser)"

Do not use it in a script as it would always redownload the file.


Following should suffice:

  • Bash
  • Curl
  • Ssh client
  • Git

ops-base provides a full specification of environment in which releaser will work.


If using releaser on Alpine, please run:

apk add -U coreutils

it is needed for sort -V option.


Provide ./tasks file with bash case (switch). It will allow to run a limited number of commands). Example:


case "${command}" in
      releaser::bump_changelog_version "$2" "$3"
      time bats ./test/unit/*.bats
      echo "Invalid command: '${command}'"
      exit 1

Now you can use it:

  • ./tasks set_version
  • ./tasks verify
  • ./tasks unit

Thanks to tasks file it is easy to know which commands to run when working on a project and we run the same commands locally and on CI.

Examples of tasks files:

Releaser functions

The releaser functions should be documented in code, there is no sense to repeat it here.

You can set those environment variables:

  • dryrun=true to avoid writing to files or rsyncing to remote endpoint.
  • RELEASER_LOG_LEVEL=debug for more log messages.


  1. You make changes in a feature branch and git push it.
  2. You run tests:
    • ./tasks unit
    • ./tasks itest
  3. You decide that it is time for GoCD to test and release your code, so you locally:
    • run ./tasks set_version to bump the patch version fragment by 1 or ./tasks set_version 1.2.3 to bump to a particular version. Version is bumped in the
    • merge that branch into master and push to git server
  4. CI pipeline tests and releases releaser.


Copyright 2019 Ewa Czechowska, Tomasz Sętkowski

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.