Skip to content

Instantly share code, notes, and snippets.

@acmcelwee
Last active April 9, 2020 16:01
Show Gist options
  • Save acmcelwee/6f488f3d74b2734ca159d105d2927a9e to your computer and use it in GitHub Desktop.
Save acmcelwee/6f488f3d74b2734ca159d105d2927a9e to your computer and use it in GitHub Desktop.

Revisions

  1. acmcelwee revised this gist Feb 19, 2020. 1 changed file with 24 additions and 6 deletions.
    30 changes: 24 additions & 6 deletions circle-lock.sh
    Original file line number Diff line number Diff line change
    @@ -55,7 +55,7 @@ make_jq_prog() {
    fi

    if [[ $job_name ]]; then
    jq_filters+=" and .workflows?.job_name? == \"$job_name\""
    jq_filters+=" and (.workflows?.job_name? == \"$job_name\" or .build_parameters?.CIRCLE_JOB? == \"$job_name\")"
    fi

    if [[ $tag ]]; then
    @@ -67,12 +67,13 @@ make_jq_prog() {


    if [[ "$0" != *bats* ]]; then
    set -e
    set -u
    set -o pipefail
    set -e
    set -u
    set -o pipefail

    branch=""
    tag=""
    job_name=""
    rest=()
    api_url="https://circleci.com/api/v1/project/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME?circle-token=$CIRCLE_TOKEN&limit=100"

    @@ -83,14 +84,31 @@ set -o pipefail

    echo "Checking for running builds..."

    # unset errexit so we can detect and handle temporary circleci api failures
    set +e
    consecutive_failures=0
    while true; do
    builds=$(curl -s -H "Accept: application/json" "$api_url" | jq "$jq_prog")
    if [[ $builds ]]; then
    builds=$(curl --fail --silent --connect-timeout 5 --max-time 10 -H "Accept: application/json" "$api_url" | jq "$jq_prog")

    if [[ $? -ne 0 ]]; then
    echo "CircleCI api call failed"
    consecutive_failures=$(($consecutive_failures + 1))
    elif [[ ! -z ${builds} ]]; then
    # reset failure counter
    consecutive_failures=0

    echo "Waiting on builds:"
    echo "$builds"
    else
    break
    fi

    # limit the number of consecutive failures that we're willing to tolerate
    if [[ ${consecutive_failures} -gt 5 ]]; then
    echo "Failed $consecutive_failures consecutive attempts...giving up"
    exit 1
    fi

    echo "Retrying in 10 seconds..."
    sleep 10
    done
  2. acmcelwee revised this gist Jun 28, 2017. No changes.
  3. acmcelwee created this gist Jun 28, 2017.
    103 changes: 103 additions & 0 deletions circle-lock.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,103 @@
    #!/usr/bin/env bash

    set -o xtrace -o errexit -o pipefail -o nounset

    ########################################################################################
    # CircleCI's current recommendation for roughly serializing a subset
    # of build commands for a given branch
    #
    # circle discussion thread - https://discuss.circleci.com/t/serializing-deployments/153
    # Code from - https://github.com/bellkev/circle-lock-test
    ########################################################################################


    # sets $branch, $job_name, $tag, $rest
    parse_args() {
    while [[ $# -gt 0 ]]; do
    case $1 in
    -b|--branch) branch="$2" ;;
    -j|--job-name) job_name="$2" ;;
    -t|--tag) tag="$2" ;;
    *) break ;;
    esac
    shift 2
    done
    rest=("$@")
    }

    # reads $branch, $tag, $commit_message
    should_skip() {
    if [[ "$branch" && "$CIRCLE_BRANCH" != "$branch" ]]; then
    echo "Not on branch $branch. Skipping..."
    return 0
    fi

    if [[ "$job_name" && "$CIRCLE_JOB" != "$job_name" ]]; then
    echo "Not running $job_name. Skipping..."
    return 0
    fi

    if [[ "$tag" && "$commit_message" != *\[$tag\]* ]]; then
    echo "No [$tag] commit tag found. Skipping..."
    return 0
    fi

    return 1
    }

    # reads $branch, $job_name, $tag
    # sets $jq_prog
    make_jq_prog() {
    local jq_filters=""

    if [[ $branch ]]; then
    jq_filters+=" and .branch == \"$branch\""
    fi

    if [[ $job_name ]]; then
    jq_filters+=" and .workflows?.job_name? == \"$job_name\""
    fi

    if [[ $tag ]]; then
    jq_filters+=" and (.subject | contains(\"[$tag]\"))"
    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=""
    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 10 seconds..."
    sleep 10
    done

    echo "Acquired lock"

    if [[ "${#rest[@]}" -ne 0 ]]; then
    "${rest[@]}"
    fi
    fi