Skip to content

Instantly share code, notes, and snippets.

@aljp
Created July 16, 2018 05:37
Show Gist options
  • Save aljp/2a18ce7d9e79debda4a6a912f1c9ea9c to your computer and use it in GitHub Desktop.
Save aljp/2a18ce7d9e79debda4a6a912f1c9ea9c to your computer and use it in GitHub Desktop.
Lock CircleCI builds by testing git (any vcs) tags against a regex. I use some git tag suffixes to specify deployment environment, so 1.2.3staging1 will deploy to staging, however it cannot run at the same time as 1.2.3staging2 or 1.2.4staging1.
#!/usr/bin/env bash
# I've made changes to this script so it supports a --version argument
# which can specify a regular expression for the vcs_tag property on circle
# builds.
#
# sets $branch, $tag, $rest
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
-b|--branch) branch="$2" ;;
-t|--tag) tag="$2" ;;
-v|--version) version="$2" ;;
*) break ;;
esac
shift 2
done
rest=("$@")
}
# reads $branch, $tag, $commit_message
should_skip() {
if [[ "$version" && "$CIRCLE_TAG" =~ "$version" ]]; then
echo "Not on $version. Skipping..."
return 0
fi
if [[ "$branch" && "$CIRCLE_BRANCH" != "$branch" ]]; then
echo "Not on branch $branch. Skipping..."
return 0
fi
if [[ "$tag" && "$commit_message" != *\[$tag\]* ]]; then
echo "No [$tag] commit tag found. Skipping..."
return 0
fi
return 1
}
# reads $branch, $tag
# sets $jq_prog
make_jq_prog() {
local jq_filters=""
if [[ $branch ]]; then
jq_filters+=" and .branch == \"$branch\""
fi
if [[ $tag ]]; then
jq_filters+=" and (.subject | contains(\"[$tag]\"))"
fi
if [[ $version ]]; then
jq_filters+=" and (.vcs_tag | test(\"${version//\./\\\\.}\"))"
fi
jq_prog=".[] | select(.build_num < $CIRCLE_BUILD_NUM and (.status | test(\"running|pending|queued\")) $jq_filters) | .build_num"
}
if [[ "$0" != *bats* ]]; then
set -e
set -u
set -o pipefail
branch=""
tag=""
version=""
rest=()
api_url="https://circleci.com/api/v1/project/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME?circle-token=$CIRCLE_TOKEN&limit=100"
parse_args "$@"
commit_message=$(git log -1 --pretty=%B)
if should_skip; then exit 0; fi
make_jq_prog
echo "Checking for running builds..."
while true; do
builds=$(curl -s -H "Accept: application/json" "$api_url" | jq "$jq_prog")
if [[ $builds ]]; then
echo "Waiting on builds:"
echo "$builds"
else
break
fi
echo "Retrying in 5 seconds..."
sleep 5
done
echo "Acquired lock"
if [[ "${#rest[@]}" -ne 0 ]]; then
"${rest[@]}"
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment