diff --git a/.github/workflows/runJdbcComparator.yml b/.github/workflows/runJdbcComparator.yml index 3814af1f7..7cd953506 100644 --- a/.github/workflows/runJdbcComparator.yml +++ b/.github/workflows/runJdbcComparator.yml @@ -3,36 +3,46 @@ name: JDBC Driver Comparison on: schedule: - cron: '0 0 * * 1' # Run at 00:00 UTC on Monday (1) - workflow_dispatch: # Allow manual trigger + workflow_dispatch: + # Manual trigger from Actions UI. Defaults below scope the run to a fast + # initial-test config; blank a field out at dispatch time for broader + # coverage. The weekly cron is unaffected (inputs are empty for schedule + # events, so the script's "empty = all" semantics give full coverage). + inputs: + suites: + description: 'SUITES_RUN_ONLY (comma-separated; leave blank for full coverage matching cron)' + required: false + default: '' + metadata_methods: + description: 'METADATA_RUN_ONLY_METHODS (comma-separated; leave blank for all methods)' + required: false + default: '' + connection_config: + description: 'CONNECTION_CONFIG (comma-separated; leave blank for all configs)' + required: false + default: '' permissions: + id-token: write # for JFrog OIDC token exchange contents: read jobs: comparator: - runs-on: ubuntu-latest + # Public GitHub runners are blocked org-wide; use internal Databricks runners. + runs-on: + group: databricks-protected-runner-group + labels: linux-ubuntu-latest steps: - - name: Checkout main branch + - name: Checkout comparator-v2 (or PR branch for dispatch) + # Schedule events from main (if this workflow ever moves to main): always + # checkout comparator-v2, where the comparator framework + script live. + # Dispatch events: checkout the triggering ref so PR branches can validate + # workflow/script changes pre-merge. uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: - ref: main - fetch-depth: 0 - - - name: Configure Git - run: | - git config user.name "GitHub Actions" - git config user.email "actions@github.com" - - - name: Merge main into comparator-v2 - run: | - git checkout comparator-v2 - git merge main --allow-unrelated-histories --no-edit -X theirs || { - echo "Force merging by accepting all changes from main" - git checkout --theirs . - git add . - git commit --no-edit - } + ref: ${{ github.event_name == 'schedule' && 'comparator-v2' || github.ref }} + fetch-depth: 1 - name: Set up JDK 11 uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4 @@ -41,54 +51,153 @@ jobs: distribution: 'temurin' cache: maven - - name: Set up PAT - env: - DATABRICKS_COMPARATOR_TOKEN: ${{ secrets.DATABRICKS_COMPARATOR_TOKEN }} + - name: Get JFrog OIDC token + # Internal runners can't reach Maven Central directly; route mvn + # through Databricks Artifactory using a short-lived JFrog token + # obtained by exchanging the GitHub OIDC ID token. run: | - echo "DATABRICKS_COMPARATOR_TOKEN=${DATABRICKS_COMPARATOR_TOKEN}" >> $GITHUB_ENV + set -euo pipefail - - name: Run Tests - run: mvn -pl jdbc-core test -Dtest=JDBCDriverComparisonTest + # Get GitHub OIDC ID token + ID_TOKEN=$(curl -sLS \ + -H "User-Agent: actions/oidc-client" \ + -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ + "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=jfrog-github" | jq .value | tr -d '"') + echo "::add-mask::${ID_TOKEN}" - - name: Format Email Content + # Exchange for JFrog access token + ACCESS_TOKEN=$(curl -sLS -XPOST -H "Content-Type: application/json" \ + "https://databricks.jfrog.io/access/api/v1/oidc/token" \ + -d "{\"grant_type\": \"urn:ietf:params:oauth:grant-type:token-exchange\", \"subject_token_type\":\"urn:ietf:params:oauth:token-type:id_token\", \"subject_token\": \"${ID_TOKEN}\", \"provider_name\": \"github-actions\"}" | jq .access_token | tr -d '"') + echo "::add-mask::${ACCESS_TOKEN}" + + if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then + echo "FAIL: Could not extract JFrog access token" + exit 1 + fi + + echo "JFROG_ACCESS_TOKEN=${ACCESS_TOKEN}" >> "$GITHUB_ENV" + + echo "JFrog OIDC token obtained successfully" + + - name: Configure maven run: | - chmod +x bin/format-comparator-email.sh - ./bin/format-comparator-email.sh + set -euo pipefail + + mkdir -p ~/.m2 + cat > ~/.m2/settings.xml << EOF + + + + jfrog-central + * + https://databricks.jfrog.io/artifactory/db-maven/ + + + + + jfrog-central + gha-service-account + ${JFROG_ACCESS_TOKEN} + + + + EOF + + echo "Maven configured to use JFrog registry" + + - name: Run comparator + env: + DATABRICKS_COMPARATOR_TOKEN: ${{ secrets.DATABRICKS_COMPARATOR_TOKEN }} + COMPARATOR_HOST: ${{ vars.COMPARATOR_HOST }} + COMPARATOR_WAREHOUSE: ${{ vars.COMPARATOR_WAREHOUSE }} + PRO_WAREHOUSE_ID: ${{ vars.PRO_WAREHOUSE_ID }} + RUN_NAME: ci-weekly-${{ github.run_id }} + # Scoping knobs β€” workflow_dispatch.inputs populate these when + # manually triggered. For schedule events, inputs are empty, + # which the script treats as "run everything". + SUITES_RUN_ONLY: ${{ inputs.suites }} + METADATA_RUN_ONLY_METHODS: ${{ inputs.metadata_methods }} + CONNECTION_CONFIG: ${{ inputs.connection_config }} + run: bash src/test/java/com/databricks/jdbc/comparator/run-comparator.sh - - name: Check for Report and Differences - id: check_differences + - name: Locate generated files + id: outputs + if: always() run: | - REPORT=$(ls jdbc-comparison-report-*.txt 2>/dev/null | head -1) - if [ -n "$REPORT" ]; then - echo "report_file=$REPORT" >> $GITHUB_OUTPUT - if grep -q "No differences found" "$REPORT"; then - echo "has_differences=false" >> $GITHUB_OUTPUT - else - echo "has_differences=true" >> $GITHUB_OUTPUT - fi - else + shopt -s nullglob + report_files=(ci-weekly-*-report-*.txt) + csv_files=(ci-weekly-*-results-*.csv) + log_files=(ci-weekly-*-logs-*.txt) + + REPORT="${report_files[0]:-}" + CSV="${csv_files[0]:-}" + LOG="${log_files[0]:-}" + + if [ -z "$REPORT" ]; then echo "Report file not found" exit 1 fi - - name: Send Email - if: steps.check_differences.outputs.has_differences == 'true' + # Build comma-separated attachments list of files that actually exist + ATTACHMENTS="$REPORT" + [ -n "$CSV" ] && ATTACHMENTS="$ATTACHMENTS,$CSV" + [ -n "$LOG" ] && ATTACHMENTS="$ATTACHMENTS,$LOG" + + if grep -q "No differences found" "$REPORT"; then + HAS_DIFFS=false + else + HAS_DIFFS=true + fi + + { + echo "report_file=$REPORT" + echo "csv_file=$CSV" + echo "log_file=$LOG" + echo "attachments=$ATTACHMENTS" + echo "has_differences=$HAS_DIFFS" + } >> "$GITHUB_OUTPUT" + + - name: Send email + # Skip under `act` (local CI runner) β€” env.ACT is injected by act only. + if: ${{ env.ACT != 'true' && steps.outputs.outputs.has_differences == 'true' }} uses: dawidd6/action-send-mail@4226df7daafa6fc901a43789c49bf7ab309066e7 # v3 with: server_address: smtp.gmail.com server_port: 465 username: ${{ secrets.SMTP_USERNAME }} password: ${{ secrets.SMTP_PASSWORD }} - subject: JDBC Driver Comparison Results - 🚨Differences Found - html_body: file://jdbc-comparison-report.html + subject: "JDBC Driver Comparison Results β€” Differences Found (run ${{ github.run_id }})" to: ${{ secrets.EMAIL_RECIPIENTS }} from: JDBC Comparator Runner - content_type: text/html + body: | + Hi Team, + + The weekly Thrift-vs-SEA JDBC driver comparison detected differences. + + Run ID: ${{ github.run_id }} + Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + Triggered: ${{ github.event_name }} + + Attached: + - ${{ steps.outputs.outputs.report_file }} β€” diff report (TXT) + - ${{ steps.outputs.outputs.csv_file }} β€” per-test results (CSV) + - ${{ steps.outputs.outputs.log_file }} β€” full mvn log + + To exclude known/accepted diffs from future reports, add a filter + to FILTER_JSON in + src/test/java/com/databricks/jdbc/comparator/run-comparator.sh + (under "metadataSkipFilters") and include the reason. + + β€” JDBC Comparator Runner + attachments: ${{ steps.outputs.outputs.attachments }} - - name: Upload Report as Artifact + - name: Upload reports as artifact + if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: jdbc-comparison-report path: | - jdbc-comparison-report-*.txt - jdbc-comparison-report.html + ci-weekly-*-report-*.txt + ci-weekly-*-results-*.csv + ci-weekly-*-logs-*.txt diff --git a/src/test/java/com/databricks/jdbc/comparator/run-comparator.sh b/src/test/java/com/databricks/jdbc/comparator/run-comparator.sh index 6c9b33607..22672f7ae 100755 --- a/src/test/java/com/databricks/jdbc/comparator/run-comparator.sh +++ b/src/test/java/com/databricks/jdbc/comparator/run-comparator.sh @@ -5,23 +5,31 @@ # This script pulls the latest code, merges main into comparator-v2, # runs the comparator, and outputs logs + report. # -# Usage: -# 1. Update DATABRICKS_COMPARATOR_TOKEN below with your PAT -# 2. chmod +x run-comparator.sh -# 3. ./run-comparator.sh +# Usage (local): +# export DATABRICKS_COMPARATOR_TOKEN=dapi... +# export COMPARATOR_HOST=adb-xxx.azuredatabricks.net +# export COMPARATOR_WAREHOUSE= # legacy mode +# # OR set LEFT_*/RIGHT_* for generic two-endpoint mode (see below) +# chmod +x run-comparator.sh +# ./run-comparator.sh # -# Output: -# comparator-logs-.txt -# comparator-report-.txt +# Usage (CI): invoked by .github/workflows/runJdbcComparator.yml β€” env vars +# come from secrets (DATABRICKS_COMPARATOR_TOKEN) and repo Variables +# (COMPARATOR_HOST, COMPARATOR_WAREHOUSE, PRO_WAREHOUSE_ID). +# +# Output (in $PWD at script start): +# -logs-.txt (or comparator-logs-*.txt if RUN_NAME unset) +# -report-.txt +# -results-.csv # ============================================================================ # ============================================================================ -# CONFIGURATION β€” edit these values +# CONFIGURATION β€” override via env, or edit defaults below # ============================================================================ -# Workspace -COMPARATOR_HOST="adb-7405613695221181.1.azuredatabricks.net" -DATABRICKS_COMPARATOR_TOKEN="dapi..." # Replace with your token +# Workspace β€” REQUIRED, must be set in env (no defaults) +COMPARATOR_HOST="${COMPARATOR_HOST:-}" +DATABRICKS_COMPARATOR_TOKEN="${DATABRICKS_COMPARATOR_TOKEN:-}" # Comparison axis β€” choose ONE of: # @@ -44,22 +52,22 @@ DATABRICKS_COMPARATOR_TOKEN="dapi..." # Replace with your token # RIGHT_CLUSTER="1234567890:0413-104341-eajdv7uv" # RIGHT_TRANSPORT="thrift" # -COMPARATOR_WAREHOUSE="6feab30b476abfa4" # legacy mode default +COMPARATOR_WAREHOUSE="${COMPARATOR_WAREHOUSE:-}" # legacy mode -LEFT_WAREHOUSE="" -LEFT_CLUSTER="" -LEFT_HTTP_PATH="" -LEFT_TRANSPORT="" -LEFT_LABEL="" +LEFT_WAREHOUSE="${LEFT_WAREHOUSE:-}" +LEFT_CLUSTER="${LEFT_CLUSTER:-}" +LEFT_HTTP_PATH="${LEFT_HTTP_PATH:-}" +LEFT_TRANSPORT="${LEFT_TRANSPORT:-}" +LEFT_LABEL="${LEFT_LABEL:-}" -RIGHT_WAREHOUSE="" -RIGHT_CLUSTER="" -RIGHT_HTTP_PATH="" -RIGHT_TRANSPORT="" -RIGHT_LABEL="" +RIGHT_WAREHOUSE="${RIGHT_WAREHOUSE:-}" +RIGHT_CLUSTER="${RIGHT_CLUSTER:-}" +RIGHT_HTTP_PATH="${RIGHT_HTTP_PATH:-}" +RIGHT_TRANSPORT="${RIGHT_TRANSPORT:-}" +RIGHT_LABEL="${RIGHT_LABEL:-}" # Pro warehouse (leave empty to skip; runs the PRO_WAREHOUSE config against this third warehouse) -PRO_WAREHOUSE_ID="" +PRO_WAREHOUSE_ID="${PRO_WAREHOUSE_ID:-}" # Connection configs to run (comma-separated, empty = all) # @@ -78,33 +86,34 @@ PRO_WAREHOUSE_ID="" # VOLUME_OPERATIONS | VOLUME_OPERATIONS # PRO_WAREHOUSE | SELECT, COMPLEX_TYPES, GEOSPATIAL (requires PRO_WAREHOUSE_ID) # -CONNECTION_CONFIG="DEFAULT_PARAMS" +CONNECTION_CONFIG="${CONNECTION_CONFIG:-}" # Test suites to run (comma-separated, empty = all suites for the config) # Options: STATEMENT_SELECT, STATEMENT_SELECT_TRUNCATED, STATEMENT_DDL, STATEMENT_DML, # STATEMENT_OTHER, PREPARED_STATEMENT_TYPES, PREPARED_STATEMENT_METADATA, # COMPLEX_TYPES, GEOSPATIAL, NULL_HANDLING, VOLUME_OPERATIONS, DATABASE_METADATA -SUITES_RUN_ONLY="DATABASE_METADATA" +SUITES_RUN_ONLY="${SUITES_RUN_ONLY:-}" # DatabaseMetaData options # Available methods: getCatalogs, getSchemas, getTables, getColumns, # getPrimaryKeys, getImportedKeys, getExportedKeys, getCrossReference, getFunctions -METADATA_RUN_ONLY_METHODS="getCatalogs,getSchemas" # empty = all methods -METADATA_SKIP_METHODS="" # comma-separated methods to skip (e.g., getFunctions) -METADATA_SKIP_SCHEMAS="information_schema,global_temp" -METADATA_PARALLEL_THREADS="40" -SKIP_DIFF_PATTERNS="" # pipe-separated patterns to exclude from report (e.g., "DATA_TYPE mismatch: 0 (Integer) vs 12 (Integer)") +# Note: getFunctions β€” skip, not supported in Thrift native (always returns 0 rows) +METADATA_RUN_ONLY_METHODS="${METADATA_RUN_ONLY_METHODS:-}" # empty = all methods +METADATA_SKIP_METHODS="${METADATA_SKIP_METHODS:-getFunctions}" # not supported in Thrift native (always returns 0 rows) +METADATA_SKIP_SCHEMAS="${METADATA_SKIP_SCHEMAS:-information_schema}" +METADATA_PARALLEL_THREADS="${METADATA_PARALLEL_THREADS:-50}" +SKIP_DIFF_PATTERNS="${SKIP_DIFF_PATTERNS:-}" # geo and variant fixes merged β€” no filtering needed # Workspace setup (empty = skip, "recreate" = drop + create all test data) -WORKSPACE_SETUP="" +WORKSPACE_SETUP="${WORKSPACE_SETUP:-}" # Git repo -REPO_URL="https://github.com/databricks/databricks-jdbc.git" -MERGE_BRANCH="main" # branch to merge into comparator-v2 (e.g., main, feature-branch) -WORK_DIR="/tmp/jdbc-comparator-$$" +REPO_URL="${REPO_URL:-https://github.com/databricks/databricks-jdbc.git}" +MERGE_BRANCH="${MERGE_BRANCH:-main}" # branch to merge into comparator-v2 (e.g., main, feature-branch) +WORK_DIR="${WORK_DIR:-/tmp/jdbc-comparator-$$}" # Run name (used in log/report filenames for easy identification, empty = generic name) -RUN_NAME="" +RUN_NAME="${RUN_NAME:-}" # ============================================================================ # FILTER CONFIG β€” edit to skip known noisy argument combinations @@ -112,31 +121,106 @@ RUN_NAME="" FILTER_JSON='{ "metadataSkipFilters": { + "getSchemas": [ + {"catalog": "%", "reason": "Thrift treats % as catalog pattern, SEA does exact match (correct per JDBC spec)"}, + {"catalog": "compar%", "reason": "Thrift treats compar% as catalog pattern, SEA does exact match (correct per JDBC spec)"}, + {"catalog": "COMPARATOR-TESTS", "reason": "Thrift returns upper case value, SEA returns stored value (SEA behaviour is correct)"} + ], "getTables": [ - {"schemaPattern": ""}, - {"types": "[]"}, - {"catalog": "compar%", "schemaPattern": "nonexistent"} + {"catalog": "", "schemaPattern": "null", "tableNamePattern": "!"}, + {"catalog": "", "schemaPattern": "%", "tableNamePattern": "!"}, + {"catalog": "", "schemaPattern": "oss_jdbc_tests", "tableNamePattern": "!"}, + {"catalog": "", "schemaPattern": "oss%", "tableNamePattern": "!"}, + {"catalog": "", "schemaPattern": "!", "tableNamePattern": "null"}, + {"catalog": "", "schemaPattern": "!", "tableNamePattern": "%"}, + {"catalog": "", "schemaPattern": "!", "tableNamePattern": "test_result_set_types"}, + {"catalog": "", "schemaPattern": "!", "tableNamePattern": "test%"}, + {"catalog": "COMPARATOR-TESTS", "reason": "SEA resolves catalog case-insensitively (correct), Thrift does not"}, + {"catalog": "comparator\\_tests", "reason": "SEA unescapes underscore in catalog (correct), Thrift does not"} + ], + "getColumns": [ + {"catalog": "", "tableNamePattern": "null"}, + {"catalog": "", "tableNamePattern": "%"}, + {"catalog": "", "tableNamePattern": "test_result_set_types"}, + {"catalog": "", "tableNamePattern": "test%"}, + {"schemaPattern": "", "tableNamePattern": "null"}, + {"schemaPattern": "", "tableNamePattern": "%"}, + {"schemaPattern": "", "tableNamePattern": "test_result_set_types"}, + {"schemaPattern": "", "tableNamePattern": "test%"}, + {"catalog": "%"}, + {"catalog": "compar%"} ] } }' +# ---- Skip filter reasons ---- +# getSchemas: +# catalog=% β€” Thrift treats % as catalog pattern, SEA does exact match (correct per JDBC spec) +# catalog=compar% β€” Same as above +# catalog=comparator\_tests β€” SEA returns escaped catalog name in TABLE_CATALOG. PR open: #1365 +# +# getTables: +# catalog="" β€” Thrift throws when catalog is empty AND at least one of schema/table is a pattern +# AND neither schema nor table is empty "". SEA returns ResultSet. +# Pattern schemas (4): null, %, oss_jdbc_tests, oss% +# Pattern tables (4): null, %, test_result_set_types, test% +# 336 diffs total +# catalog=COMPARATOR-TESTS β€” SEA resolves case-insensitively and finds tables, Thrift doesn't. 168 diffs. +# SEA correct per JDBC spec. +# catalog=comparator\_tests β€” SEA unescapes the input catalog and finds tables, Thrift doesn't. 168 diffs. +# Same pattern as COMPARATOR-TESTS. +# +# getColumns: +# catalog="" or schemaPattern="" with pattern table β€” Thrift throws when either catalog or schema +# is empty "" AND table is a pattern (null, %, test_result_set_types, test%). +# SEA returns ResultSet. 468 metadata diffs total (180 empty catalog + 288 empty schema). +# catalog=% and compar% β€” Thrift treats as catalog pattern (returns all catalogs), SEA does exact match. +# Same as getSchemas. 686 extra row diffs. +# NOTE: GEOMETRY/GEOGRAPHY DATA_TYPE mismatch (0 vs 12) present across all catalogs β€” 3696 diffs. +# Driver-side bug: Thrift missing geospatial disable check in getThriftRows(). Not filtered. +# +# getPrimaryKeys: +# table=null or "" β€” Thrift throws for null/empty table. SEA returns ResultSet. 72 diffs. +# schema=null + non-null catalog β€” Thrift throws for null schema with any non-null catalog. 55 diffs. +# +# getImportedKeys: +# Same as getPrimaryKeys β€” table=null/empty (72 diffs) + schema=null with non-null catalog (40 diffs). 112 total. +# +# getExportedKeys: +# table=null β€” Thrift throws for null table. SEA returns ResultSet. 36 diffs. +# ---- End skip filter reasons ---- # ============================================================================ # DO NOT EDIT BELOW THIS LINE # ============================================================================ set -e -TIMESTAMP=$(date +%Y%m%d-%H%M%S) -if [ -n "${RUN_NAME}" ]; then - LOG_FILE="${RUN_NAME}-logs-${TIMESTAMP}.txt" - REPORT_FILE="${RUN_NAME}-report-${TIMESTAMP}.txt" -else - LOG_FILE="comparator-logs-${TIMESTAMP}.txt" - REPORT_FILE="comparator-report-${TIMESTAMP}.txt" + +# Validate required env +if [ -z "${DATABRICKS_COMPARATOR_TOKEN}" ]; then + echo "ERROR: DATABRICKS_COMPARATOR_TOKEN is not set." >&2 + echo " Local: export DATABRICKS_COMPARATOR_TOKEN=dapi..." >&2 + echo " CI: ensure the secret is wired in the workflow env block." >&2 + exit 1 fi +if [ -z "${COMPARATOR_HOST}" ]; then + echo "ERROR: COMPARATOR_HOST is not set." >&2 + exit 1 +fi +# Must specify legacy COMPARATOR_WAREHOUSE OR generic LEFT/RIGHT endpoint config +ANY_LEFT_RIGHT="${LEFT_WAREHOUSE}${LEFT_CLUSTER}${LEFT_HTTP_PATH}${RIGHT_WAREHOUSE}${RIGHT_CLUSTER}${RIGHT_HTTP_PATH}" +if [ -z "${COMPARATOR_WAREHOUSE}" ] && [ -z "${ANY_LEFT_RIGHT}" ]; then + echo "ERROR: Set COMPARATOR_WAREHOUSE (legacy) or LEFT_*/RIGHT_* (generic axis)." >&2 + exit 1 +fi + +TIMESTAMP=$(date +%Y%m%d-%H%M%S) +PREFIX="${RUN_NAME:-comparator}" +LOG_FILE="${PREFIX}-logs-${TIMESTAMP}.txt" +REPORT_FILE="${PREFIX}-report-${TIMESTAMP}.txt" +CSV_FILE_NAME="${PREFIX}-results-${TIMESTAMP}.csv" FILTER_FILE="${WORK_DIR}/metadata-filters.json" # Detect generic vs legacy axis and emit a one-line summary of each side. -ANY_LEFT_RIGHT="${LEFT_WAREHOUSE}${LEFT_CLUSTER}${LEFT_HTTP_PATH}${RIGHT_WAREHOUSE}${RIGHT_CLUSTER}${RIGHT_HTTP_PATH}" echo "=== JDBC Driver Comparator ===" echo "Timestamp: ${TIMESTAMP}" echo "Workspace: ${COMPARATOR_HOST}" @@ -147,7 +231,7 @@ else echo "Warehouse: ${COMPARATOR_WAREHOUSE} (legacy Thrift-vs-SEA mode)" fi echo "Config: ${CONNECTION_CONFIG:-all}" -echo "Output: ${LOG_FILE}, ${REPORT_FILE}" +echo "Output: ${LOG_FILE}, ${REPORT_FILE}, ${CSV_FILE_NAME}" echo "" # Capture current directory before cd @@ -158,6 +242,11 @@ echo "[1/5] Cloning repository..." git clone --branch comparator-v2 "${REPO_URL}" "${WORK_DIR}" cd "${WORK_DIR}" +# Local-only git identity for the merge commit below (CI runners have no global config). +# --local scope keeps this confined to the temp clone; caller's global config is untouched. +git config --local user.name "JDBC Comparator Runner" +git config --local user.email "actions@github.com" + echo "[2/5] Merging ${MERGE_BRANCH} into comparator-v2..." git fetch origin "${MERGE_BRANCH}" git merge "origin/${MERGE_BRANCH}" --no-commit --no-ff -X theirs @@ -249,7 +338,7 @@ fi # Copy CSV results CSV_FILE=$(ls ${WORK_DIR}/jdbc-core/jdbc-comparison-results-*.csv 2>/dev/null | head -1) if [ -n "${CSV_FILE}" ]; then - CSV_DEST="${ORIGINAL_DIR}/${RUN_NAME}-results-${TIMESTAMP}.csv" + CSV_DEST="${ORIGINAL_DIR}/${CSV_FILE_NAME}" cp "${CSV_FILE}" "${CSV_DEST}" CSV_LINES=$(wc -l < "${CSV_DEST}") echo "CSV: ${CSV_DEST} (${CSV_LINES} rows)" @@ -269,3 +358,6 @@ echo "" echo "=== Done ===" echo "Report: ${REPORT_FILE}" echo "Logs: ${LOG_FILE}" +echo "MVN exit: ${MVN_EXIT}" + +exit ${MVN_EXIT:-0}