Cancel all of the Approval jobs in the branch

CircleCI has a feature to hold a job until someone approves it. However, when users commits a lot, each workflow will remain on hold until canceled, and if there are many workflows, the canceling might be time-consuming. Especially when a terraform-related jobs; user would like to cancel the workflow to ensure no one accidentally approves the workflow.

  1. The following script will require you to set some parameter depending on your project and will retrive the initial request to get the required pipeline information. CircleCI API
org_name='nanophate'            # Organization Name
prj_name='circleci-template'    # Project / Repository Name
branch_name='main'              # Branch Name

initail_req=$(curl -s -H "Circle-Token: ${CIRCLECI_PERSONAL_TOKEN}" "https://circleci.com/api/v2/project/gh/${org_name}/${prj_name}/pipeline?branch=${branch_name}")
pipeline_ids+=$(echo $initail_req | jq -r '.items[].id')
next_page_token=$(echo $initail_req | jq -r '.next_page_token')
  1. During the start pipeline while phase it would retrive and store all of the pipeline_id into pipeline_ids to further use it in the code.
  2. After completing the above start workflow while now requires to retrive all the workflow id with on_hold status. The .items[].status == "on_hold" might be needed to a adjust depending on your approval job’s name.
  3. Finally from the workflow_ids the cancel API gets called and each workflow would be canceled.
while [ "$next_page_token" != "null" ]
do
  echo "start pipeline while"
  echo $next_page_token
  reqs=$(curl -s -H "Circle-Token: ${CIRCLECI_PERSONAL_TOKEN}" "https://circleci.com/api/v2/project/gh/${org_name}/${prj_name}/pipeline?page-token=${next_page_token}")
  pipeline_ids="${pipeline_ids}\n$(echo $reqs | jq -r '.items[].id')"
  next_page_token=$(echo $reqs | jq -r '.next_page_token')
  echo $next_page_token
  echo "end pipeline while"
done

echo ${pipeline_ids} | while read pip_id; do 
  initail_wf_req=$(curl -s -H "Circle-Token: ${CIRCLECI_PERSONAL_TOKEN}" "https://circleci.com/api/v2/pipeline/${pip_id}/workflow")
  workflow_ids+="$(echo $initail_wf_req | jq -r 'select(.items[].status == "on_hold") | .items[].pipeline_id')"
  

  while [ "$wf_next_page_token" != "null" ]
  do
    echo "start workflow while"
    echo $wf_next_page_token
    echo $pip_id
    wf_reqs=$(curl -s -H "Circle-Token: ${CIRCLECI_PERSONAL_TOKEN}" "https://circleci.com/api/v2/pipeline/${pip_id}/workflow?page-token=${next_page_token}")
    workflow_ids+="$(echo $initail_wf_req | jq -r 'select(.items[].status == "on_hold") | .items[].pipeline_id')"
    wf_next_page_token=$(echo $wf_reqs | jq -r '.next_page_token')
    echo $wf_next_page_token
    echo "end workflow while"
  done
done

echo ${workflow_ids} | while read wf_id; do curl -fsS -X POST -H "Circle-Token: ${CIRCLECI_PERSONAL_TOKEN}" "https://circleci.com/api/v2/workflow/${wf_id}/cancel"; done

2 Likes

Can confirm this has been an issue at a former company, where an app deployment from earlier in the day was later approved and ended up causing an outage, as later changes introduced breaking changes with previous versions. It would be great if a linear approval history could be enforced.