To set up the question - I am currently using a workflow in which [ci skip] is added to commit messages to skip CircleCI runs as suggested by the documentation. In some cases though, we do want to force the CircleCI run of our branches with these commits without having to rebase or push a new commit. [ci skip] is too strict for us.
Rather than using [ci skip], I’d like to use a custom condition for the commit message and manually cancel the workflow based upon the message. Is there a way to programmatically end or cancel the workflow? I am struggling to find this documented.
(P.S. I’ve seen it documented in multiple places that you should be able to rerun workflows that were skipped with [ci skip], but it does not seem to be possible. You can only rerun with SSH but that does not finish the full workflow)
Yes it’s possible to conditionally cancel workflows.
- checkout
- run: |
commit_message=$(git log -1 HEAD --pretty=format:%s)
if [[ $commit_message == *"custom-identifier"* ]]; then
curl --request POST \
--url https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/cancel \
--header "Circle-Token: ${CIRCLE_TOKEN}"
fi
Basically after you run a checkout this pulls the latest commit message into a variable. Then it check to see if your custom-identifier exists anywhere in the commit message. If so, it makes a request to our API to cancel the workflow. It uses the CIRCLE_WORKFLOW_ID envar that we automatically include in the job, and a CircleCI user API token (CIRCLE_TOKEN) that you would need to manually add to the project in your project settings page.
I’m not sure how robust this is for your development workflow, as it would only check the HEAD commit for the string. But at the very least it’s a basic example of how to conditionally cancel a workflow.