Skip to content

Instantly share code, notes, and snippets.

@schlagelk
Last active July 14, 2021 15:34
Show Gist options
  • Save schlagelk/c1e1b5d0346eee57f99f0c7bc3519626 to your computer and use it in GitHub Desktop.
Save schlagelk/c1e1b5d0346eee57f99f0c7bc3519626 to your computer and use it in GitHub Desktop.
Fetches failed tests for a CircleCI workflow when rerunning said workflow from failed. This is done by using the current commit hash and checking for existing failed tests at said hash. Results are joined by a `,` so they can be easily passed into `xcodebuild -only-testing`. Requires jq
# Set a limit, helps with system outtages and can help avoid passing in a very long list of failed test to xcodebuild which would have the opposite effect
CCI_FAILED_TESTS_RERUN_LIMIT=11;
# $CIRCLECI_API_TOKEN is a CircleCI API token you presumably set in the project environment variables
if [[ -n "$CIRCLECI_API_TOKEN" && -n "$CIRCLE_SHA1" && -n "$CIRCLE_WORKFLOW_ID" ]]; then
pipeline_url="https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID"
echo "๐Ÿคน๐Ÿผโ€โ™‚๏ธ Fetching pipeline for $CIRCLE_WORKFLOW_ID"
pipeline=$(
curl -H "Circle-Token: $CIRCLECI_API_TOKEN" "$pipeline_url" | jq ' { pipeline_id: .pipeline_id, slug: .project_slug } '
)
pipeline_id=$(echo "${pipeline}" | jq ' .pipeline_id ' | tr -d '"')
slug=$(echo "${pipeline}" | jq ' .slug ' | tr -d '"')
if [[ -n "$pipeline_id" && -n "$slug" ]]; then
pipeline_detail_url="https://circleci.com/api/v2/pipeline/$pipeline_id"
echo "๐Ÿคน๐Ÿผโ€โ™‚๏ธ Fetching pipeline $pipeline_id"
pipeline_hash=$(
curl -H "Circle-Token: $CIRCLECI_API_TOKEN" "$pipeline_detail_url" | jq ' .vcs.revision ' | tr -d '"'
)
if [ "$pipeline_hash" = "$CIRCLE_SHA1" ]; then
# get the most recent failed workflow in this pipeline
workflows_url="https://circleci.com/api/v2/pipeline/$pipeline_id/workflow"
echo "๐Ÿคน๐Ÿผโ€โ™‚๏ธ Fetching workflows for pipeline id $pipeline_id"
failed_workflow_id=$(
curl -H "Circle-Token: $CIRCLECI_API_TOKEN" "$workflows_url" | jq ' .items | first(.[] | select(.status == "failed")) | .id ' | tr -d '"'
)
if [ -n "$failed_workflow_id" ]; then
jobs_url="https://circleci.com/api/v2/workflow/$failed_workflow_id/job"
echo "๐Ÿคน๐Ÿผโ€โ™‚๏ธ Fetching job for workflow id $failed_workflow_id"
job_details=$(
curl -H "Circle-Token: $CIRCLECI_API_TOKEN" "$jobs_url" | jq ' .items | first(.[] | select(.name == "'"$CIRCLE_JOB"'")) '
)
job_id=$(echo "${job_details}" | jq ' .job_number ' | tr -d '"' )
job_status=$(echo "${job_details}" | jq ' .status ' | tr -d '"' )
if [ -n "$job_id" ]; then
if [ "$job_status" = "failed" ]; then
tests_url="https://circleci.com/api/v2/project/$slug/$job_id/tests"
echo "๐Ÿคน๐Ÿผโ€โ™‚๏ธ Fetching failed tests for for job id $job_id"
failed_tests=$(
curl -H "Circle-Token: $CIRCLECI_API_TOKEN" "$tests_url" | jq ' [.items[]? | select(.result == "failure")] | (.[].classname) |=(split(".") | .[0] |=split("_") |.[0] |=join("-") | join("/")) | map(.classname+"/"+.name) | join(",") '
)
if [ -n "$failed_tests" ]; then
failed_tests_count=$(echo "${failed_tests}" | jq ' split(",") | length ' )
if (( failed_tests_count < CCI_FAILED_TESTS_RERUN_LIMIT )); then
echo "CCI_FAILED_TESTS: $failed_tests"
echo CCI_FAILED_TESTS="$failed_tests" >> ${BASH_ENV}
fi
else
echo "๐Ÿ„๐Ÿฝโ€โ™‚๏ธ Did not find failed tests for commit hash $CIRCLE_SHA1, moving on"
fi
fi
else
echo "๐Ÿ„๐Ÿฝโ€โ™‚๏ธ Did not have a job id in $job_details"
fi
fi
fi
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment