Skip to content

Commit

Permalink
feat: add cancel-redundant-workflows command (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
ankorstore-haddowg authored Mar 30, 2023
1 parent f595138 commit fda098a
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/commands/cancel-redundant-workflows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
description: >
Cancels any previous running or on-hold workflows for the same branch.
CircleCI can do this automatically when this feature is enabled in project settings for all branches EXCEPT the default branch.
There is however no way to filter what branches are affected or to include the default branch.
This command can be used with an appropriate `when` step to do this.
This command requires a CIRCLE_TOKEN env var to be set with a valid CircleCi API Token.
steps:
- run:
name: Cancelling redundant workflows
command: << include(scripts/cancel-redundant-workflows.sh) >>
42 changes: 42 additions & 0 deletions src/scripts/cancel-redundant-workflows.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

if [ -z "$BASH" ]; then
echo "Bash not installed. Aborting."
exit 1
fi
hash curl 2>/dev/null || { echo >&2 "curl is not installed. Aborting."; exit 1; }
if [ -z "$CIRCLE_TOKEN" ]; then
echo "CIRCLE_TOKEN env not set. Please set a valid CircleCi API Token in the env var CIRCLE_TOKEN";
exit 1;
fi

# Get the name of the workflow and the related pipeline number
CURRENT_WORKFLOW_URL="https://circleci.com/api/v2/workflow/${CIRCLE_WORKFLOW_ID}?circle-token=$CIRCLE_TOKEN"
curl -f -s --retry 3 --retry-all-errors "$CURRENT_WORKFLOW_URL" > /tmp/aks/current_wf.json
WORKFLOW_NAME="$(jq -r '.name' /tmp/aks/current_wf.json)"
CURRENT_PIPELINE_NUM="$(jq -r '.pipeline_number' /tmp/aks/current_wf.json)"

# Get the IDs of pipelines created for the same branch. (Only consider pipelines that have a pipeline number smaller than the current pipeline)
PIPELINES_URL="https://circleci.com/api/v2/project/gh/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pipeline?circle-token=$CIRCLE_TOKEN&branch=$CIRCLE_BRANCH"
curl -f -s --retry 3 --retry-all-errors "$PIPELINES_URL" >> /tmp/aks/pipelines.json
PIPELINE_IDS=$(jq -r --argjson CURRENT_PIPELINE_NUM "$CURRENT_PIPELINE_NUM" '.items[]|select(.state == "created")|select(.number < $CURRENT_PIPELINE_NUM)|.id | values')

## Get the IDs of currently running/on_hold workflows that have the same name as the current workflow, in all previously created pipelines.
if [ -n "$PIPELINE_IDS" ]; then
for PIPELINE_ID in $PIPELINE_IDS
do
curl -f -s --retry 3 --retry-all-errors "https://circleci.com/api/v2/pipeline/${PIPELINE_ID}/workflow?circle-token=$CIRCLE_TOKEN" | jq -r --arg workflow_name "${WORKFLOW_NAME}" '.items[] | select(.status == "on_hold" or .status == "running") | select(.name == $workflow_name) | .id | values' >> /tmp/aks/wf_to_cancel
done
fi

## Cancel any currently running/on_hold workflow with the same name
if [ -s /tmp/aks/wf_to_cancel ]; then
echo "Cancelling the following redundant workflow(s):"
cat /tmp/aks/wf_to_cancel
while read -r WORKFLOW_ID;
do
curl -f -s --retry 3 --retry-all-errors --header "Circle-Token: $CIRCLE_TOKEN" --request POST "https://circleci.com/api/v2/workflow/$WORKFLOW_ID/cancel"
done < /tmp/aks/wf_to_cancel
else
echo "Nothing to cancel"
fi

0 comments on commit fda098a

Please sign in to comment.