Is there any way to programmatically cancel a workflow without making it "Failed" status?

Hi, I’m trying to achieve similar effect from this question. My run command looks like below:

COUNT=$(git diff --name-only HEAD HEAD~1 | grep ^mobile/ | wc -l | xargs )
echo 'Changed file count from mobile directory:'
echo $COUNT

if [ $COUNT == 0 ]; then
  echo 'No change from mobile directory: end build'
  curl --request POST \
    --url https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/cancel \
    --header "Circle-Token: ${CIRCLE_TOKEN}"
  exit 0
fi

While it does stop further running of workflow, the call of suggested API (or using circleci-agent step halt) turns workflow status into ‘Failed’, not ‘Cancelled’, with output:

Exited with code exit status 1
CircleCI received exit code 1

I’d be much happier if there’s some way to make it ‘Cancelled’, so that I don’t have to manually check if ‘Failed’ build has actually failed due to a real problem, or it’s simply just skipped build.

Is there any way that I could cancel the workflow within itself, and make it ‘Cancelled’ status?

Well never mind, I just found out that my bash script is what’s causing the exit code to be non-zero… What a silly mistake :sob:

I ran into the same situation and this is what I did:

curl …
sleep 30  # Give cancellation a chance to run. This script then won't continue running.
exit 1  # If cancellation didn't run for some reason, fail the build.

I also want to clarify that whereas the CIRCLE_WORKFLOW_ID is provided for you automatically, CIRCLE_TOKEN isn’t. So you need to generate such a token and then add it to your environment variables config.