Last active
October 3, 2020 10:59
-
-
Save ndbroadbent/9b5742e6b0835323d45e6e33dcce8d85 to your computer and use it in GitHub Desktop.
Find all the failed RSpec examples in GitLab CI pipeline logs and run them all locally
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eo pipefail | |
CURRENT_DIR="$(realpath $(dirname "$0"))" | |
ROOT_DIR="$(realpath $CURRENT_DIR/..)" | |
# https://gitlab.com/docspring/docspring | |
PROJECT_ID="1908805" | |
GITLAB_TOKEN=$(cat $ROOT_DIR/.gitlab-api-token) | |
PIPELINE_ID="$1" | |
if [ -z "$PIPELINE_ID" ]; then | |
CURRENT_GIT_BRANCH="$(git rev-parse --abbrev-ref HEAD)" | |
echo "Fetching latest failed pipeline ID for '$CURRENT_GIT_BRANCH'..." | |
ESCAPED_BRANCH=$(ruby -r cgi -e "puts CGI.escape('$CURRENT_GIT_BRANCH')") | |
LATEST_PIPELINE_RESPONSE=$(curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ | |
"https://gitlab.com/api/v4/projects/$PROJECT_ID/pipelines?ref=$ESCAPED_BRANCH&status=failed&per_page=1&page=1") | |
PIPELINE_ID="$(echo $LATEST_PIPELINE_RESPONSE | jq -r '.[0].id')" | |
echo "Found latest failed pipeline ID: $PIPELINE_ID" | |
echo | |
echo $LATEST_PIPELINE_RESPONSE | jq -r '" * " + .[0].web_url' | |
echo | |
fi | |
PIPELINE_CACHE_DIR="$ROOT_DIR/tmp/gitlab_pipeline_results/$PIPELINE_ID" | |
mkdir -p "$PIPELINE_CACHE_DIR" | |
JOB_IDS_FILE="$PIPELINE_CACHE_DIR/job_ids.json" | |
if [ -f "$JOB_IDS_FILE" ]; then | |
echo "Found jobs for GitLab CI Pipeline $PIPELINE_ID in $JOB_IDS_FILE" | |
FAILED_PIPELINE_JOBS_RESPONSE="$(cat "$JOB_IDS_FILE")" | |
else | |
echo "Listing jobs for GitLab CI Pipeline $PIPELINE_ID..." | |
FAILED_PIPELINE_JOBS_RESPONSE="$(curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ | |
"https://gitlab.com/api/v4/projects/$PROJECT_ID/pipelines/$PIPELINE_ID/jobs?scope[]=failed")" | |
echo "$FAILED_PIPELINE_JOBS_RESPONSE" > "$JOB_IDS_FILE" | |
fi | |
FAILED_PIPELINE_JOB_COUNT=$(echo "$FAILED_PIPELINE_JOBS_RESPONSE" | \ | |
jq -r '. | map(select(.name | contains ("rspec"))) | map(.id) | length') | |
echo "Found $FAILED_PIPELINE_JOB_COUNT failed RSpec job(s):" | |
if [ "$FAILED_PIPELINE_JOB_COUNT" == "0" ]; then exit; fi | |
echo | |
echo "$FAILED_PIPELINE_JOBS_RESPONSE" | \ | |
jq -r '. | map(select(.name | contains ("rspec"))) | map(" * " + .web_url) | .[]' | |
echo | |
FAILED_PIPELINE_JOB_IDS=$(echo "$FAILED_PIPELINE_JOBS_RESPONSE" | \ | |
jq -r '. | map(select(.name | contains ("rspec"))) | map(.id) | .[]') | |
for JOB_ID in $FAILED_PIPELINE_JOB_IDS; do | |
JOB_LOGS_FILE="$PIPELINE_CACHE_DIR/job_$JOB_ID.txt" | |
if [ -f "$JOB_LOGS_FILE" ]; then | |
echo "Found logs for failed RSpec job $JOB_ID in $JOB_LOGS_FILE" | |
else | |
echo "Fetching logs for failed RSpec job $JOB_ID" | |
curl -s --location --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ | |
"https://gitlab.com/api/v4/projects/$PROJECT_ID/jobs/$JOB_ID/trace" > "$JOB_LOGS_FILE" | |
fi | |
done | |
FAILING_SPECS=$(ruby -e "puts Dir.glob(\"$PIPELINE_CACHE_DIR/job_*.txt\").map{ |f| | |
File.read(f) | |
.split('Failed examples:')[1] | |
.split('Randomized with seed')[0] | |
.scan(/rspec ([^#]+)/) }.join(' ')") | |
echo "Running failed specs locally..." | |
set -x | |
./bin/rspec $FAILING_SPECS |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment