diff --git a/.circleci/config.yml b/.circleci/config.yml index 1c894eba..bb54486f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -201,9 +201,18 @@ jobs: update-currency-versions: executor: name: base - ruby_version: "4.0" + ruby_version: "3.4" steps: - checkout + - run: + name: Install jq and curl + command: | + apt-get update + apt-get install -y jq curl + - run: + name: Wait for all workflow test suites and retries to finish + command: | + ./.circleci/wait_for_workflows.sh - run: name: Update RubyGems and Bundler command: | @@ -214,9 +223,9 @@ jobs: name: Capture installed gem versions and test with latest versions command: | #!/usr/bin/env bash - set -e mkdir -p bundle-list mkdir -p test-results + mkdir -p _junit run_bundle_list_and_test() { local label="$1" @@ -224,16 +233,19 @@ jobs: echo "=== Processing $label from $gemfile ===" # Install dependencies - BUNDLE_GEMFILE="$gemfile" bundle check 2>/dev/null \ - || BUNDLE_GEMFILE="$gemfile" bundle install --quiet + if ! (BUNDLE_GEMFILE="$gemfile" bundle check 2>/dev/null || BUNDLE_GEMFILE="$gemfile" bundle install --quiet); then + echo " ✗ bundle install failed for $label" + echo "FAIL" > "test-results/${label}_status.txt" + return 0 + fi # Capture installed versions - BUNDLE_GEMFILE="$gemfile" bundle list > "bundle-list/installed_${label}.txt" - echo " Captured $(grep -c '^\s\+\*' bundle-list/installed_${label}.txt) gems" + BUNDLE_GEMFILE="$gemfile" bundle list > "bundle-list/installed_${label}.txt" || true + echo " Captured $(grep -c '^\s\+\*' "bundle-list/installed_${label}.txt" 2>/dev/null || echo 0) gems" - # Run tests to verify the versions work + # Run tests with APPRAISAL_INITIALIZED=1 so Rakefile runs only this gem's tests echo " Running tests for $label..." - if BUNDLE_GEMFILE="$gemfile" bundle exec rake test 2>&1 | tee "test-results/${label}_test.log"; then + if APPRAISAL_INITIALIZED="1" BUNDLE_GEMFILE="$gemfile" bundle exec rake test 2>&1 | tee "test-results/${label}_test.log"; then echo "PASS" > "test-results/${label}_status.txt" echo " ✓ Tests passed for $label" else @@ -260,6 +272,27 @@ jobs: run_bundle_list_and_test "graphql" "./gemfiles/graphql_20.gemfile" run_bundle_list_and_test "roda" "./gemfiles/roda_30.gemfile" run_bundle_list_and_test "net-http" "./gemfiles/net_http_01.gemfile" + + # Assemble test-status.json in bundle-list directory + JSON="{" + FIRST=1 + for STATUS_FILE in test-results/*_status.txt; do + [ -f "$STATUS_FILE" ] || continue + LABEL=$(basename "$STATUS_FILE" _status.txt) + STATUS=$(cat "$STATUS_FILE" | tr -d '[:space:]') + if [ "$STATUS" = "FAIL" ]; then + [ $FIRST -eq 0 ] && JSON="${JSON}," + JSON="${JSON} \"${LABEL}\": \"fail\"" + FIRST=0 + fi + done + JSON="${JSON} }" + echo "$JSON" > bundle-list/test-status.json + + echo "=== test-status.json ===" + cat bundle-list/test-status.json + echo "" + ls -la bundle-list/ - store_artifacts: path: bundle-list - store_artifacts: @@ -355,11 +388,11 @@ workflows: only: - master requires: - - lint - - test_core-ruby-base-3.2 - - test_core-ruby-base-3.3 - - test_core-ruby-base-3.4 - - test_core-ruby-base-4.0 + - lint: terminal + - test_core-ruby-base-3.2: terminal + - test_core-ruby-base-3.3: terminal + - test_core-ruby-base-3.4: terminal + - test_core-ruby-base-4.0: terminal libraries_ruby_32_33: max_auto_reruns: 2 jobs: diff --git a/.circleci/wait_for_workflows.sh b/.circleci/wait_for_workflows.sh new file mode 100755 index 00000000..2799ab53 --- /dev/null +++ b/.circleci/wait_for_workflows.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -e + +if [[ -z "${CIRCLE_TOKEN:-}" ]]; then + echo "WARNING: CIRCLE_TOKEN is not set. Skipping waiting for sibling workflows." + exit 0 +fi + +PROJECT_SLUG='https://circleci.com/api/v2/project/gh/instana/ruby-sensor' +PIPELINE_SLUG='https://circleci.com/api/v2/pipeline' +WORKFLOW_SLUG='https://circleci.com/api/v2/workflow' + +echo "=== Getting Pipeline ID for build #${CIRCLE_BUILD_NUM} ===" +PIPELINE_ID=$(curl -s \ + -H "Circle-Token: ${CIRCLE_TOKEN}" \ + "${PROJECT_SLUG}/job/${CIRCLE_BUILD_NUM}" \ + | jq -rj '.pipeline.id // empty') + +if [[ -z "${PIPELINE_ID}" ]]; then + echo "WARNING: Could not retrieve PIPELINE_ID from job info. Proceeding." + exit 0 +fi + +echo "Pipeline ID: ${PIPELINE_ID}" + +echo "=== Querying workflows for pipeline ===" +WORKFLOW_INFO=$(curl -sf \ + -H "Circle-Token: ${CIRCLE_TOKEN}" \ + "${PIPELINE_SLUG}/${PIPELINE_ID}/workflow" \ + | jq -r '.items[] | select(.name != "core" and .name != "report_coverage" and .name != "publish") | "\(.id)\t\(.name)"') + +echo "Discovered test workflows to wait for:" +echo "${WORKFLOW_INFO}" +echo "" + +# Loop and wait until every sibling workflow reaches a terminal state +while IFS=$'\t' read -r workflow_id workflow_name; do + [[ -z "${workflow_id}" ]] && continue + + echo "Waiting for workflow '${workflow_name}' (${workflow_id}) to complete..." + MAX_ATTEMPTS=120 # up to 30 mins (120 * 15s) + ATTEMPT=0 + while [[ ${ATTEMPT} -lt ${MAX_ATTEMPTS} ]]; do + STATUS=$(curl -s \ + -H "Circle-Token: ${CIRCLE_TOKEN}" \ + "${WORKFLOW_SLUG}/${workflow_id}" \ + | jq -r '.status // "unknown"') + + if [[ "${STATUS}" != "running" && "${STATUS}" != "on_hold" && "${STATUS}" != "unknown" ]]; then + echo " ✓ Workflow '${workflow_name}' finished with status: ${STATUS}" + break + fi + + echo " ... '${workflow_name}' is currently: ${STATUS} (waiting 15s, attempt $((ATTEMPT+1))/${MAX_ATTEMPTS})" + sleep 15 + ATTEMPT=$((ATTEMPT + 1)) + done +done <<< "${WORKFLOW_INFO}" + +echo "" +echo "=== All sibling test workflows have finished (including auto-retries) ==="