Skip to content

Commit

Permalink
Implement sem-semantic-release (#358)
Browse files Browse the repository at this point in the history
* Implement sem-semantic-release

* Convert function to a bash script

* Update sem-semantic-release.bats

* Fix sem-semantic-release tests

* Fix unbound variable issues

* Switch returns to exits while interrupting script

* Add interoperability test with sem-context

* Refactor tests and usage printing

* Add extra information to sem-context

Co-authored-by: Igor Šarčević <igor@renderedtext.com>
  • Loading branch information
mattrym and shiroyasha authored Aug 18, 2022
1 parent 9079d98 commit aa7079b
Show file tree
Hide file tree
Showing 4 changed files with 337 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .semaphore/semaphore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ blocks:
- 'shellcheck cache -f gcc | wc -l && [[ "$(shellcheck cache -f gcc | wc -l)" -le 152 ]]'
- 'shellcheck libcheckout -f gcc | wc -l && [[ "$(shellcheck libcheckout -f gcc | wc -l)" -le 85 ]]'
- shellcheck install-package
- shellcheck sem-semantic-release
- name: PowerShell check
commands:
- make pwsh.lint
Expand Down Expand Up @@ -194,6 +195,7 @@ blocks:
- tests/artifacts.bats
- tests/test-results.bats
- tests/macOS_sem_version.bats
- tests/sem-semantic-release.bats
- tests/macos_cache.bats
- tests/macos_autocache.bats
- tests/libcheckout.bats
Expand Down Expand Up @@ -313,6 +315,7 @@ blocks:
- tests/compiler.bats
- tests/test-results.bats
- tests/enetwork.bats
- tests/sem-semantic-release.bats
- tests/autocache.bats
- tests/cache.bats
- tests/libcheckout.bats
Expand Down
9 changes: 9 additions & 0 deletions install-toolbox
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ else
echo "toolbox_install_error{module='sem-service-check-params'} 1" >> /tmp/toolbox_metrics
fi

install_cmd ln -sf ~/.toolbox/sem-semantic-release $INSTALL_PATH/sem-semantic-release
install_cmd chmod +x $INSTALL_PATH/sem-semantic-release
if [[ $? -eq 0 ]];then
echo "sem-semantic-release installed"
else
echo "toolbox_install_error{module='sem-semantic-release'} 1" >> /tmp/toolbox_metrics
fi

install_cmd ln -sf ~/.toolbox/install-package $INSTALL_PATH/install-package
install_cmd ln -sf ~/.toolbox/install-package $INSTALL_PATH/install-package.sh
install_cmd chmod +x $INSTALL_PATH/install-package
Expand Down Expand Up @@ -117,6 +125,7 @@ else
echo "toolbox_install_error{module='test-results'} 1" >> /tmp/toolbox_metrics
fi


if [[ `uname` != "Darwin" ]]; then

echo "Installing the SPC CLI"
Expand Down
169 changes: 169 additions & 0 deletions sem-semantic-release
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#!/usr/bin/env bash

set -euo pipefail

semantic-release::print_usage() {
printf "Usage: sem-semantic-release [OPTION]...\n\n"
printf "Options:\n"
printf " --dry-run \t runs semantic-release without publishing version\n"
printf " --plugins \t npm plugins and extensions to be installed\n"
printf " --branches \t branches to run semantic release for\n"
printf " --version \t semantic-release version\n"
}

semantic-release::parse_args() {
local PARSING_PLUGINS=1
local PARSING_BRANCHES=1
local DRY_RUN=1

local SEMANTIC_RELEASE_PLUGIN_LIST=()
local SEMANTIC_RELEASE_BRANCH_LIST=()

set -f

while [[ $# -gt 0 ]]; do
case $1 in
--help)
semantic-release::print_usage
exit 0
;;

--version)
PARSING_PLUGINS=1
PARSING_BRANCHES=1

SEMANTIC_RELEASE_VERSION="$2"
shift # past argument
shift # past value
;;

--plugins)
PARSING_PLUGINS=0
PARSING_BRANCHES=1
shift
;;

--branches)
PARSING_PLUGINS=1
PARSING_BRANCHES=0
shift
;;

--dry-run)
DRY_RUN=0;
shift
;;

-*)
semantic-release::print_usage
exit 1
;;

*)
if [[ $PARSING_PLUGINS == 0 ]];
then
SEMANTIC_RELEASE_PLUGIN_LIST+=("$1");
fi
if [[ $PARSING_BRANCHES == 0 ]];
then
SEMANTIC_RELEASE_BRANCH_LIST+=("$1");
fi
shift
;;
esac
done

set +f

if [[ $DRY_RUN -eq 0 ]]
then
SEMANTIC_RELEASE_OPTIONS+="--dry-run ";
fi
if [[ ${#SEMANTIC_RELEASE_PLUGIN_LIST[@]} -ne 0 ]]
then
SEMANTIC_RELEASE_PLUGINS="${SEMANTIC_RELEASE_PLUGIN_LIST[*]} "
else
SEMANTIC_RELEASE_PLUGINS=""
fi
if [[ ${#SEMANTIC_RELEASE_BRANCH_LIST[@]} -ne 0 ]]
then
SEMANTIC_RELEASE_OPTIONS+="--branches ${SEMANTIC_RELEASE_BRANCH_LIST[*]} "
fi

set -f

if [[ -n $BATS_VERSION ]]; then
echo "semantic-release version: $SEMANTIC_RELEASE_VERSION"
echo "semantic-release plugins: $SEMANTIC_RELEASE_PLUGINS"
echo "semantic-release options: $SEMANTIC_RELEASE_OPTIONS"
fi
}

semantic-release::install() {
if [[ -n $SEMANTIC_RELEASE_VERSION ]]
then
SEMANTIC_RELEASE_PACKAGE="semantic-release@$SEMANTIC_RELEASE_VERSION"
else
SEMANTIC_RELEASE_PACKAGE="semantic-release"
fi

npm install "$SEMANTIC_RELEASE_PACKAGE" --silent ||
{ echo "sem-semantic-release: Unsupported semantic-release version: $SEMANTIC_RELEASE_VERSION"; exit 1; }

if [[ -n $SEMANTIC_RELEASE_PLUGINS ]]
then
# we cannot use arrays here (because of set -u) and
# we must not prevent word splitting in that case
# shellcheck disable=SC2086
npm install $SEMANTIC_RELEASE_PLUGINS --silent ||
{ echo "sem-semantic-release: Unable to install plugins: $SEMANTIC_RELEASE_PLUGINS"; exit 1; }
fi
}

semantic-release::scrape_version() {
local RELEASE_VERSION=""
local RELEASE_NUMBERS=()

RELEASE_VERSION=$(grep "The next release version" /tmp/semantic-release.log | grep -oE '([0-9]+\.[0-9]+\.[0-9]+)')

if [[ -n $RELEASE_VERSION ]]
then
IFS='.' read -ra RELEASE_NUMBERS <<< "$RELEASE_VERSION"

sem-context put ReleasePublished="true"
sem-context put ReleaseVersion="$RELEASE_VERSION"
sem-context put ReleaseMajorVersion="${RELEASE_NUMBERS[0]}"
sem-context put ReleaseMinorVersion="${RELEASE_NUMBERS[1]}"
sem-context put ReleasePatchVersion="${RELEASE_NUMBERS[2]}"

echo "sem-semantic-release: Release $RELEASE_VERSION has been generated."
else
sem-context put ReleasePublished="false"

echo "sem-semantic-release: New release hasn't been generated."
fi
}

semantic-release::main() {
semantic-release::parse_args "$@"
semantic-release::install

if [[ -n $SEMANTIC_RELEASE_OPTIONS ]]
then
npx semantic-release "$SEMANTIC_RELEASE_OPTIONS" | tee /tmp/semantic-release.log
else
npx semantic-release | tee /tmp/semantic-release.log
fi
if [[ ! $? ]]; then return $?; fi

semantic-release::scrape_version
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
SEMANTIC_RELEASE_PLUGINS=()
SEMANTIC_RELEASE_OPTIONS=""
SEMANTIC_RELEASE_VERSION=""
BATS_VERSION=""

semantic-release::main "$@"
fi
156 changes: 156 additions & 0 deletions tests/sem-semantic-release.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#!/usr/bin/env bats

load "support/bats-support/load"
load "support/bats-assert/load"

setup() {
export SEMANTIC_RELEASE_PLUGINS=""
export SEMANTIC_RELEASE_OPTIONS=""
export SEMANTIC_RELEASE_VERSION=""
}

@test "semantic-release::parse_args --help" {
source ~/.toolbox/sem-semantic-release
run semantic-release::parse_args --help

assert_success
assert_output --partial "Usage: sem-semantic-release [OPTION]..."
}

@test "semantic-release::parse_args --dry-run" {
source ~/.toolbox/sem-semantic-release
run semantic-release::parse_args --dry-run

assert_success
assert_output --partial "semantic-release options: --dry-run "
}

@test "semantic-release::parse_args --version" {
source ~/.toolbox/sem-semantic-release
run semantic-release::parse_args --version 19.0.2

assert_success
assert_output --partial "semantic-release version: 19.0.2"
}

@test "semantic-release::parse_args --plugins" {
source ~/.toolbox/sem-semantic-release
run semantic-release::parse_args --plugins @semantic-release/foo @semantic-release-bar

assert_success
assert_output --partial "semantic-release plugins: @semantic-release/foo @semantic-release-bar"
}

@test "semantic-release::parse_args --branches" {
source ~/.toolbox/sem-semantic-release
run semantic-release::parse_args --branches master develop release/\*

assert_success
assert_output --partial "semantic-release options: --branches master develop release/* "
}

@test "semantic-release::parse_args all options" {
source ~/.toolbox/sem-semantic-release
run semantic-release::parse_args --dry-run --version 19.0.2 --plugins @semantic-release/git --branches master

assert_success
assert_output --partial "semantic-release version: 19.0.2"
assert_output --partial "semantic-release plugins: @semantic-release/git"
assert_output --partial "semantic-release options: --dry-run --branches master"
}

@test "semantic-release::install with empty version" {
source ~/.toolbox/sem-semantic-release
export SEMANTIC_RELEASE_PLUGINS=""
run semantic-release::install

assert_success
assert [ -e "package.json" ]
assert [ ! -z $(npx semantic-release --version) ]

run rm -rf ./node_modules ./package.json ./package-lock.json
}

@test "semantic-release::install with non-empty version" {
source ~/.toolbox/sem-semantic-release
export SEMANTIC_RELEASE_PLUGINS=""
export SEMANTIC_RELEASE_VERSION=19.0.1
run semantic-release::install

assert_success
assert [ -e "package.json" ]
assert [ $(npx semantic-release --version) = "19.0.1" ]

run rm -rf ./node_modules ./package.json ./package-lock.json
}

@test "semantic-release::install with invalid version" {
source ~/.toolbox/sem-semantic-release
export SEMANTIC_RELEASE_PLUGINS=""
export SEMANTIC_RELEASE_VERSION=2122.0.1
run semantic-release::install

assert_failure
assert_output "sem-semantic-release: Unsupported semantic-release version: 2122.0.1"

run rm -rf ./node_modules ./package.json ./package-lock.json
}

@test "semantic-release::install with plugins" {
source ~/.toolbox/sem-semantic-release
export SEMANTIC_RELEASE_PLUGINS="@semantic-release/git@10.0.1 @semantic-release/changelog"
run semantic-release::install

assert_success
assert [ -e "package.json" ]

assert [ -n $(npm view @semantic-release/changelog version) ]
assert [ $(npm view @semantic-release/git version) = "10.0.1" ]

run rm -rf ./node_modules ./package.json ./package-lock.json
}

@test "semantic-release::install with wrong plugins" {
source ~/.toolbox/sem-semantic-release
export SEMANTIC_RELEASE_PLUGINS="@semantic-release/foo@1.0.0"
run semantic-release::install

assert_failure
assert_output "sem-semantic-release: Unable to install plugins: @semantic-release/foo@1.0.0"

run rm -rf ./node_modules ./package.json ./package-lock.json
}

@test "semantic-release::scrape_version with existing version line" {
source ~/.toolbox/sem-semantic-release
echo "The next release version is 2.0.3" > /tmp/semantic-release.log
export SEMANTIC_RELEASE_RESULT=0
run semantic-release::scrape_version

assert_success
assert_output --partial "Release 2.0.3 has been generated"
}

@test "semantic-release::scrape_version with sem-context get" {
source ~/.toolbox/sem-semantic-release
echo "The next release version is 2.0.3" > /tmp/semantic-release.log
export SEMANTIC_RELEASE_RESULT=0
run semantic-release::scrape_version

assert_success
assert [ $(sem-context get ReleasePublished) = "true" ]
assert [ $(sem-context get ReleaseVersion) = "2.0.3" ]
assert [ $(sem-context get ReleaseMajorVersion) = "2" ]
assert [ $(sem-context get ReleaseMinorVersion) = "0" ]
assert [ $(sem-context get ReleasePatchVersion) = "3" ]
}

@test "semantic-release::scrape_version with non-existing version line" {
source ~/.toolbox/sem-semantic-release
echo "Nothing really happens..." > /tmp/semantic-release.log
export SEMANTIC_RELEASE_RESULT=0
run semantic-release::scrape_version

assert_success
assert_output --partial "New release hasn't been generated"
}

0 comments on commit aa7079b

Please sign in to comment.