Skip to content

Commit 20918f0

Browse files
committed
Migrate release process to GitHub Actions
Initial migration to GitHub Actions that allows a release to be staged. See gh-411
1 parent dee7ea8 commit 20918f0

18 files changed

+655
-23
lines changed

Diff for: .github/actions/.bats/bats

Submodule bats added at 902578d

Diff for: .github/actions/.bats/test_helper/bats-assert

Submodule bats-assert added at e2d855b

Diff for: .github/actions/.bats/test_helper/bats-support

Submodule bats-support added at 9bf10e8

Diff for: .github/actions/deduce-versions/action.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: 'Deduce Versions'
2+
description: 'Deduce the version to stage and the next SNAPSHOT version'
3+
inputs:
4+
current-version:
5+
required: true
6+
release-type:
7+
required: true
8+
outputs:
9+
release-version:
10+
value: ${{ steps.deduce-versions.outputs.release-version }}
11+
next-version:
12+
value: ${{ steps.deduce-versions.outputs.next-version }}
13+
runs:
14+
using: composite
15+
steps:
16+
- name: Deduce Versions
17+
id: deduce-versions
18+
shell: bash
19+
run: . ${{ github.action_path }}/deduce-versions.sh; deduce_versions
20+
env:
21+
CURRENT_VERSION: "${{ inputs.current-version }}"
22+
RELEASE_TYPE: "${{ inputs.release-type }}"

Diff for: .github/actions/deduce-versions/deduce-versions.sh

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env bash
2+
3+
# Get the next milestone release for the given number by inspecting current tags
4+
get_next_milestone_release() {
5+
[[ -n $1 ]] || { echo "missing get_next_milestone_release() version argument" >&2; return 1; }
6+
get_next_tag_based_release "$1" "M"
7+
}
8+
9+
# Get the next RC release for the given number by inspecting current tags
10+
get_next_rc_release() {
11+
[[ -n $1 ]] || { echo "missing get_next_rc_release() version argument" >&2; return 1; }
12+
get_next_tag_based_release "$1" "RC"
13+
}
14+
15+
# Get the next release for the given number
16+
get_next_release() {
17+
[[ -n $1 ]] || { echo "missing get_next_release() version argument" >&2; return 1; }
18+
if [[ $1 =~ ^(.*)\.BUILD-SNAPSHOT$ ]]; then
19+
local join="."
20+
else
21+
local join="-"
22+
fi
23+
local version
24+
local result
25+
version=$( strip_snapshot_suffix "$1" )
26+
if [[ -n $2 ]]; then
27+
result="${version}${join}${2}"
28+
else
29+
result="${version}"
30+
fi
31+
echo $result
32+
}
33+
34+
# Get the next milestone or RC release for the given number by inspecting current tags
35+
get_next_tag_based_release() {
36+
[[ -n $1 ]] || { echo "missing get_next_tag_based_release() version argument" >&2; return 1; }
37+
[[ -n $2 ]] || { echo "missing get_next_tag_based_release() tag type argument" >&2; return 1; }
38+
if [[ $1 =~ ^(.*)\.BUILD-SNAPSHOT$ ]]; then
39+
local join="."
40+
else
41+
local join="-"
42+
fi
43+
local version
44+
local last
45+
version=$( strip_snapshot_suffix "$1" )
46+
git fetch --tags --all > /dev/null
47+
last=$( git tag --list "v${version}${join}${2}*" | sed -E "s/^.*${2}([0-9]+)$/\1/g" | sort -rn | head -n1 )
48+
if [[ -z $last ]]; then
49+
last="0"
50+
fi
51+
last="${version}${join}${2}${last}"
52+
bump_version_number "$last"
53+
}
54+
55+
# Remove any "-SNAPSHOT" or ".BUILD-SNAPSHOT" suffix
56+
strip_snapshot_suffix() {
57+
[[ -n $1 ]] || { echo "missing get_relase_version() argument" >&2; return 1; }
58+
if [[ $1 =~ ^(.*)\.BUILD-SNAPSHOT$ ]]; then
59+
echo "${BASH_REMATCH[1]}"
60+
elif [[ $1 =~ ^(.*)-SNAPSHOT$ ]]; then
61+
echo "${BASH_REMATCH[1]}"
62+
else
63+
echo "$1"
64+
fi
65+
}
66+
67+
# Bump version number by incrementing the last numeric, RC or M token
68+
bump_version_number() {
69+
local version=$1
70+
[[ -n $version ]] || { echo "missing bump_version_number() argument" >&2; return 1; }
71+
if [[ $version =~ ^(.*(\.|-)([A-Za-z]+))([0-9]+)$ ]]; then
72+
local prefix=${BASH_REMATCH[1]}
73+
local suffix=${BASH_REMATCH[4]}
74+
(( suffix++ ))
75+
echo "${prefix}${suffix}"
76+
return 0;
77+
fi
78+
local suffix
79+
if [[ $version =~ ^(.*)(\-SNAPSHOT)$ ]]; then
80+
version=${BASH_REMATCH[1]}
81+
suffix="-SNAPSHOT"
82+
fi
83+
tokens=(${version//\./ })
84+
local bumpIndex
85+
for i in "${!tokens[@]}"; do
86+
if [[ "${tokens[$i]}" =~ ^[0-9]+$ ]] ; then
87+
bumpIndex=$i
88+
fi
89+
done
90+
[[ -n $bumpIndex ]] || { echo "unsupported version number" >&2; return 1; }
91+
(( tokens[bumpIndex]++ ))
92+
local bumpedVersion
93+
IFS=. eval 'bumpedVersion="${tokens[*]}"'
94+
echo "${bumpedVersion}${suffix}"
95+
}
96+
97+
# Deduce versions
98+
deduce_versions() {
99+
[[ -n ${GITHUB_OUTPUT} ]] || { echo "missing GITHUB_OUTPUT environment variable" >&2; return 1; }
100+
[[ -n ${CURRENT_VERSION} ]] || { echo "missing CURRENT_VERSION environment variable" >&2; return 1; }
101+
[[ -n ${RELEASE_TYPE} ]] || { echo "missing RELEASE_TYPE environment variable" >&2; return 1; }
102+
if [[ ${RELEASE_TYPE,,} = "milestone" ]]; then
103+
releaseVersion=$( get_next_milestone_release ${CURRENT_VERSION})
104+
nextVersion=${CURRENT_VERSION}
105+
elif [[ ${RELEASE_TYPE,,} = "release-candidate" ]]; then
106+
releaseVersion=$( get_next_rc_release ${CURRENT_VERSION})
107+
nextVersion=${CURRENT_VERSION}
108+
elif [[ ${RELEASE_TYPE,,} = "release" ]]; then
109+
releaseVersion=$( get_next_release ${CURRENT_VERSION})
110+
nextVersion=$( bump_version_number ${CURRENT_VERSION})
111+
else
112+
echo "Unknown release type '${RELEASE_TYPE}'" >&2; exit 1;
113+
fi
114+
echo "release-version=${releaseVersion}" >> "$GITHUB_OUTPUT"
115+
echo "next-version=${nextVersion}" >> "$GITHUB_OUTPUT"
116+
}

Diff for: .github/actions/deduce-versions/test.sh

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../.bats/bats/bin/bats test/*.bats
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!./test/libs/bats/bin/bats
2+
3+
load '../../.bats/test_helper/bats-support/load'
4+
load '../../.bats/test_helper/bats-assert/load'
5+
6+
source "$PWD/deduce-versions.sh"
7+
8+
@test "bump_version_number() should bump '.M'" {
9+
run bump_version_number "1.2.0.M2"
10+
assert_output "1.2.0.M3"
11+
}
12+
13+
@test "bump_version_number() should bump '.RC'" {
14+
run bump_version_number "1.2.0.RC3"
15+
assert_output "1.2.0.RC4"
16+
}
17+
18+
@test "bump_version_number() should bump '-M'" {
19+
run bump_version_number "1.2.0-M2"
20+
assert_output "1.2.0-M3"
21+
}
22+
23+
@test "bump_version_number() should bump '-RC'" {
24+
run bump_version_number "1.2.0-RC3"
25+
assert_output "1.2.0-RC4"
26+
}
27+
28+
@test "bump_version_number() should bump without suffix" {
29+
run bump_version_number "1.2.0"
30+
assert_output "1.2.1"
31+
}
32+
33+
@test "bump_version_number() should bump '.RELEASE'" {
34+
run bump_version_number "1.2.0.RELEASE"
35+
assert_output "1.2.1.RELEASE"
36+
}
37+
38+
@test "bump_version_number() should bump '-SNAPSHOT'" {
39+
run bump_version_number "1.2.0-SNAPSHOT"
40+
assert_output "1.2.1-SNAPSHOT"
41+
}
42+
43+
@test "bump_version_number() should bump '.BUILD-SNAPSHOT'" {
44+
run bump_version_number "1.2.0.BUILD-SNAPSHOT"
45+
assert_output "1.2.1.BUILD-SNAPSHOT"
46+
}
47+
48+
@test "bump_version_number() when missing argument should fail" {
49+
run bump_version_number
50+
assert_output "missing bump_version_number() argument"
51+
assert [ "$status" -eq 1 ]
52+
}
53+
54+
@test "bump_version_number() when bad argument should fail" {
55+
run bump_version_number "foo.bar.baz"
56+
assert_output "unsupported version number"
57+
assert [ "$status" -eq 1 ]
58+
}
+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!./test/libs/bats/bin/bats
2+
3+
load '../../.bats/test_helper/bats-support/load'
4+
load '../../.bats/test_helper/bats-assert/load'
5+
6+
source "$PWD/deduce-versions.sh"
7+
8+
teardown() {
9+
rm .githuboutput | true
10+
}
11+
12+
@test "deduce_versions() when 'milestone' should export versions" {
13+
repo=$( mock_git_repo "v1.2.3-M1" )
14+
cd "$repo"
15+
GITHUB_OUTPUT=".githuboutput"
16+
CURRENT_VERSION="1.2.3-SNAPSHOT"
17+
RELEASE_TYPE="milestone"
18+
run deduce_versions
19+
readarray -t githuboutput < .githuboutput
20+
assert [ "$status" -eq 0 ]
21+
assert [ "${githuboutput[0]}" = "release-version=1.2.3-M2" ]
22+
assert [ "${githuboutput[1]}" = "next-version=1.2.3-SNAPSHOT" ]
23+
}
24+
25+
@test "deduce_versions() when 'release-candidate' should export versions" {
26+
repo=$( mock_git_repo "v1.2.3-M1" "v1.2.3-M2" "v1.2.3-RC1" )
27+
cd "$repo"
28+
GITHUB_OUTPUT=".githuboutput"
29+
CURRENT_VERSION="1.2.3-SNAPSHOT"
30+
RELEASE_TYPE="release-candidate"
31+
run deduce_versions
32+
readarray -t githuboutput < .githuboutput
33+
assert [ "$status" -eq 0 ]
34+
assert [ "${githuboutput[0]}" = "release-version=1.2.3-RC2" ]
35+
assert [ "${githuboutput[1]}" = "next-version=1.2.3-SNAPSHOT" ]
36+
}
37+
38+
@test "deduce_versions() when 'release' should export versions" {
39+
repo=$( mock_git_repo "v1.2.3-M1" "v1.2.3-M2" "v1.2.3-RC1" )
40+
cd "$repo"
41+
GITHUB_OUTPUT=".githuboutput"
42+
CURRENT_VERSION="1.2.3-SNAPSHOT"
43+
RELEASE_TYPE="release"
44+
run deduce_versions
45+
readarray -t githuboutput < .githuboutput
46+
assert [ "$status" -eq 0 ]
47+
assert [ "${githuboutput[0]}" = "release-version=1.2.3" ]
48+
assert [ "${githuboutput[1]}" = "next-version=1.2.4-SNAPSHOT" ]
49+
}
50+
51+
@test "deduce_versions() when no GITHUB_OUTPUT should fail" {
52+
CURRENT_VERSION="1.2.3-SNAPSHOT"
53+
RELEASE_TYPE="release"
54+
run deduce_versions
55+
assert [ "$status" -eq 1 ]
56+
assert_output "missing GITHUB_OUTPUT environment variable"
57+
}
58+
59+
@test "deduce_versions() when no CURRENT_VERSION should fail" {
60+
GITHUB_OUTPUT=".githuboutput"
61+
RELEASE_TYPE="release"
62+
run deduce_versions
63+
assert [ "$status" -eq 1 ]
64+
assert_output "missing CURRENT_VERSION environment variable"
65+
}
66+
67+
@test "deduce_versions() when no RELEASE_TYPE should fail" {
68+
GITHUB_OUTPUT=".githuboutput"
69+
CURRENT_VERSION="1.2.3-SNAPSHOT"
70+
run deduce_versions
71+
assert [ "$status" -eq 1 ]
72+
assert_output "missing RELEASE_TYPE environment variable"
73+
}
74+
75+
@test "deduce_versions() when wrong RELEASE_TYPE should fail" {
76+
GITHUB_OUTPUT=".githuboutput"
77+
CURRENT_VERSION="1.2.3-SNAPSHOT"
78+
RELEASE_TYPE="nope"
79+
run deduce_versions
80+
assert [ "$status" -eq 1 ]
81+
assert_output "Unknown release type 'nope'"
82+
}
83+
84+
mock_git_repo() {
85+
local tmpdir=$(mktemp -d $BATS_TMPDIR/gitrepo.XXXXXX) >&2
86+
mkdir -p "$tmpdir" >&2
87+
cd "$tmpdir" >&2
88+
git init >&2
89+
echo "foo" > foo.txt
90+
git add foo.txt >&2
91+
git commit -m'Initial commit' >&2
92+
for tag in "$@"; do
93+
git tag "$tag" >&2
94+
done
95+
echo "$tmpdir"
96+
}

0 commit comments

Comments
 (0)