Make releases with a single command
Supports the release process for Cucumber repos as documented in RELEASING.md.
It's designed to be run locally on a dev's workstation to make the mechanical changes to package manager manifests and the CHANGELOG.md file neccesary when making a release.
Essentially, when you run polyglot-release X.Y.Z it will:
- run some sanity checks to make sure you don't have unpushed local changes etc.
- modify package manager files in each language version to set the next version to X.Y.Z
- update the CHANGELOG.mdmoving everything in theUnreleasedsection into a section for the X.Y.Z release.
- commit
- tag the commit with vX.Y.Z
- git push to a release/vX.Y.Zbranch on theoriginremote
- modify package manager files in some languages (e.g. Java) to a "post-release / next development / SNAPSHOT" version
- commit again
- push everything to origin/main
If we have a project structure with distinct folders for each language, it will release each language, updating the version number in the different package manager manifests in a single git commit.
$ tree
.
├── CHANGELOG.md
│── android
│   └── gradle.properties
│── c
│   └── VERSION
│── dotnet
│   ├── Project.sln
│   └── Project
│       └── Project.csproj
├── elixir
│   └── mix.exs
├── github-action
│   └── action.yml
├── go
│   └── go.mod
├── javascript
│   └── package.json
├── java
│   └── pom.xml
├── perl
│   ├── cpanfile
│   └── VERSION
├── php
│   └── composer.json
├── python
│   └── pyproject.toml # or setup.py, or pyproject.toml with uv.lock,  
└── ruby
    ├── project.gemspec
    └── VERSION
If certain key files (pom.xml, *.gemspec, package.json, etc.) are present in the root directory, the project is assumed to be a "monoglot" repo and we just release that language.
$ tree
.
├── CHANGELOG.md
├── pom.xml
First, check that /usr/local/bin is writable on your machine:
touch /usr/local/bin/polyglot-release
If this fails, you need to make it writable
To install in a project run:
POLYGLOT_RELEASE_VERSION=1.7.1
curl --silent -o /usr/local/bin/polyglot-release https://raw.githubusercontent.com/cucumber/polyglot-release/v$POLYGLOT_RELEASE_VERSION/polyglot-release
chmod 755 /usr/local/bin/polyglot-release
# Ensure /usr/local/bin is in your $PATH
polyglot-release --helpBefore using polyglot-release to make a release, make sure you have these tools installed:
- Git - version > 2.25
- changelog
- curl
- gpg
- Core Utils (e.g. find,sed,grep,pushd,popd, ect). On MacOS you can install this withbrew install coreutils
Other tools may also be required depending on the language(s) you are trying to release. Polyglot-release will inform you about these as needed.
First, install shellcheck
To run all the tests:
./polyglot-release-test
To run a single test:
./polyglot-release-test <path-to-test-script>
We use an approval testing style for testing this app.
Each test is a shell script in the tests folder. Alongside the test file you will find .expected files that show different kinds of expected outputs and effects from running the test script. If you've run the tests you will also find matching .actual files.
When a test runs, we set up a temporary folder to run it in, with a local git repo and a remote origin repo (sitting in a folder right next to it). The local repo starts with an initial git commit with the contents of one of the tests/fixtures folders. Use a header in your test script to specify the fixture to use (otherwise it will default to the polyglot fixture)
e.g.
# fixture: my-unique-setup
polyglot-release 1.0.0
Sometimes it's helpful to play around with how the tool works in a safe, sandbox environment.
You can start a bash prompt in the same environment as an automated test would run in (with local and origin git repo folders) like this:
polyglot-release-test ./tests/fixtures/<some-fixture>
You can use polyglot-release to release polyglot-release:
./polyglot-release MAJOR.MINOR.PATCH