Skip to content

Update regression workflow 28 #218

Update regression workflow 28

Update regression workflow 28 #218

Workflow file for this run

name: Regression testing
on:
push:
branches: [ "OPENGPDB_STABLE", "OPENGPDB_6_27_STABLE", "MDB_6_25_STABLE_YEZZEY" ]
pull_request:
branches: [ "OPENGPDB_STABLE", "OPENGPDB_6_27_STABLE", "MDB_6_25_STABLE_YEZZEY" ]
jobs:
## ======================================================================
## Job: prepare-test-matrix
## ======================================================================
prepare-test-matrix:
runs-on: ubuntu-latest
outputs:
test-matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- id: set-matrix
run: |
echo "=== Matrix Preparation Diagnostics ==="
echo "Event type: ${{ github.event_name }}"
echo "Test selection input: '${{ github.event.inputs.test_selection }}'"
stat -fc %T /sys/fs/cgroup/
# Define defaults
DEFAULT_NUM_PRIMARY_MIRROR_PAIRS=3
DEFAULT_ENABLE_CGROUPS=false
DEFAULT_ENABLE_CORE_CHECK=true
DEFAULT_PG_SETTINGS_OPTIMIZER=""
DEFAULT_RUNS_ON="ubuntu-latest"
# Define base test configurations
ALL_TESTS='{
"include": [
{"test":"ic-good-opt-off",
"make_configs":["src/test/regress:installcheck-good"],
"pg_settings":{"optimizer":"off"}
},
{"test":"ic-good-opt-on",
"make_configs":["src/test/regress:installcheck-good"],
"pg_settings":{"optimizer":"on"}
},
{"test":"ic-expandshrink",
"make_configs":["src/test/isolation2:installcheck-expandshrink"]
},
{"test":"ic-resgroup",
"make_configs":["src/test/isolation2:installcheck-resgroup"],
"enable_cgroups":true,
"runs_on":"ubuntu-20.04"
},
{"test":"ic-contrib",
"make_configs":["contrib/amcheck:installcheck",
"contrib/auto_explain:installcheck",
"contrib/citext:installcheck",
"contrib/btree_gin:installcheck",
"contrib/btree_gist:installcheck",
"contrib/citext:installcheck",
"contrib/cube:installcheck",
"contrib/dblink:installcheck",
"contrib/dict_in:installcheck",
"contrib/dict_xsyn:installcheck",
"contrib/earthdistance:installcheck",
"contrib/extprotocol:installcheck",
"contrib/file_fdw:installcheck",
"contrib/formatter_fixedwidth:installcheck",
"contrib/fuzzystrmatch:installcheck",
"contrib/hstore:installcheck",
"contrib/indexscan:installcheck"]
},
{"test":"ic-gpcontrib",
"make_configs":["gpcontrib/gp_array_agg:installcheck",
"gpcontrib/gp_debug_numsegments:installcheck",
"gpcontrib/gp_distribution_policy:installcheck",
"gpcontrib/gp_error_handling:installcheck",
"gpcontrib/gp_inject_fault:installcheck",
"gpcontrib/gp_internal_tools:installcheck",
"gpcontrib/gp_legacy_string_agg:installcheck",
"gpcontrib/gp_percentile_agg:installcheck",
"gpcontrib/gp_sparse_vector:installcheck",
"gpcontrib/gp_subtransaction_overflow:installcheck",
"gpcontrib/gpcloud:installcheck",
"gpcontrib/gpmapreduce:installcheck",
"gpcontrib/orafce:installcheck",
"gpcontrib/pgaudit:installcheck"]
},
{"test":"ic-parallel-retrieve-cursor",
"make_configs":["src/test/isolation2:installcheck-parallel-retrieve-cursor"]
},
{"test":"ic-mirrorless",
"make_configs":["src/test/isolation2:installcheck-mirrorless"]
}
]
}'
# Function to apply defaults
apply_defaults() {
echo "$1" | jq --arg npm "$DEFAULT_NUM_PRIMARY_MIRROR_PAIRS" \
--argjson ec "$DEFAULT_ENABLE_CGROUPS" \
--argjson ecc "$DEFAULT_ENABLE_CORE_CHECK" \
--arg opt "$DEFAULT_PG_SETTINGS_OPTIMIZER" \
--arg ro "$DEFAULT_RUNS_ON" \
'def get_defaults:
{
num_primary_mirror_pairs: ($npm|tonumber),
enable_cgroups: $ec,
runs_on: $ro,
enable_core_check: $ecc,
pg_settings: {
optimizer: $opt
}
};
get_defaults * .'
}
# Extract all valid test names from ALL_TESTS
VALID_TESTS=$(echo "$ALL_TESTS" | jq -r '.include[].test')
# Parse input test selection
IFS=',' read -ra SELECTED_TESTS <<< "${{ github.event.inputs.test_selection }}"
# Default to all tests if selection is empty or 'all'
if [[ "${SELECTED_TESTS[*]}" == "all" || -z "${SELECTED_TESTS[*]}" ]]; then
mapfile -t SELECTED_TESTS <<< "$VALID_TESTS"
fi
# Validate and filter selected tests
INVALID_TESTS=()
FILTERED_TESTS=()
for TEST in "${SELECTED_TESTS[@]}"; do
TEST=$(echo "$TEST" | tr -d '[:space:]') # Trim whitespace
if echo "$VALID_TESTS" | grep -qw "$TEST"; then
FILTERED_TESTS+=("$TEST")
else
INVALID_TESTS+=("$TEST")
fi
done
# Handle invalid tests
if [[ ${#INVALID_TESTS[@]} -gt 0 ]]; then
echo "::error::Invalid test(s) selected: ${INVALID_TESTS[*]}"
echo "Valid tests are: $(echo "$VALID_TESTS" | tr '\n' ', ')"
exit 1
fi
# Build result JSON with defaults applied
RESULT='{"include":['
FIRST=true
for TEST in "${FILTERED_TESTS[@]}"; do
CONFIG=$(jq -c --arg test "$TEST" '.include[] | select(.test == $test)' <<< "$ALL_TESTS")
FILTERED_WITH_DEFAULTS=$(apply_defaults "$CONFIG")
if [[ "$FIRST" == true ]]; then
FIRST=false
else
RESULT="${RESULT},"
fi
RESULT="${RESULT}${FILTERED_WITH_DEFAULTS}"
done
RESULT="${RESULT}]}"
# Output the matrix for GitHub Actions
echo "Final matrix configuration:"
echo "$RESULT" | jq .
# Fix: Use block redirection
{
echo "matrix<<EOF"
echo "$RESULT"
echo "EOF"
} >> "$GITHUB_OUTPUT"
echo "=== Matrix Preparation Complete ==="
## ======================================================================
## Job: build
## ======================================================================
build:
env:
JOB_TYPE: build
runs-on: ubuntu-latest
timeout-minutes: 120
outputs:
build_timestamp: ${{ steps.set_timestamp.outputs.timestamp }}
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./docker/test/Dockerfile
tags: test_test:1234
outputs: type=docker,dest=/tmp/myimage.tar
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: myimage
path: /tmp/myimage.tar
## ======================================================================
## Job: test
## ======================================================================
test:
name: ${{ matrix.test }}
needs: [build, prepare-test-matrix]
runs-on: ${{ matrix.runs_on }}
timeout-minutes: 120
# actionlint-allow matrix[*].pg_settings
strategy:
fail-fast: false # Continue with other tests if one fails
matrix: ${{ fromJson(needs.prepare-test-matrix.outputs.test-matrix) }}
steps:
- name: Check disk space
run: df . -h
- name: Free disk space
run: |
sudo docker rmi $(docker image ls -aq) >/dev/null 2>&1 || true
sudo rm -rf \
/usr/share/dotnet /usr/local/lib/android /opt/ghc \
/usr/local/share/powershell /usr/share/swift /usr/local/.ghcup \
/usr/lib/jvm || true
echo "some directories deleted"
sudo apt install aptitude -y >/dev/null 2>&1
sudo aptitude purge aria2 ansible azure-cli shellcheck rpm xorriso zsync \
esl-erlang firefox gfortran-8 gfortran-9 google-chrome-stable \
google-cloud-sdk imagemagick \
libmagickcore-dev libmagickwand-dev libmagic-dev ant ant-optional kubectl \
mercurial apt-transport-https mono-complete libmysqlclient \
unixodbc-dev yarn chrpath libssl-dev libxft-dev \
libfreetype6 libfreetype6-dev libfontconfig1 libfontconfig1-dev \
snmp pollinate libpq-dev postgresql-client powershell ruby-full \
sphinxsearch subversion mongodb-org azure-cli microsoft-edge-stable \
-y -f >/dev/null 2>&1
sudo aptitude purge google-cloud-sdk -f -y >/dev/null 2>&1
sudo aptitude purge microsoft-edge-stable -f -y >/dev/null 2>&1 || true
sudo apt purge microsoft-edge-stable -f -y >/dev/null 2>&1 || true
sudo aptitude purge '~n ^mysql' -f -y >/dev/null 2>&1
sudo aptitude purge '~n ^php' -f -y >/dev/null 2>&1
sudo aptitude purge '~n ^dotnet' -f -y >/dev/null 2>&1
sudo apt-get autoremove -y >/dev/null 2>&1
sudo apt-get autoclean -y >/dev/null 2>&1
echo "some packages purged"
- name: Check disk space
run: df . -h
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: myimage
path: /tmp
- name: Load Docker image
run: |
docker image ls -a
docker load --input /tmp/myimage.tar
docker image ls -a
- name: "Run Tests: ${{ matrix.test }}"
run: |
set -o pipefail
# Initialize test status
overall_status=0
# Create logs directory structure
mkdir -p build-logs/details
# Create results directory structure
mkdir -p build-results
# Set PostgreSQL options if defined
PG_OPTS=""
if [[ "${{ matrix.pg_settings.optimizer != '' }}" == "true" ]]; then
PG_OPTS="$PG_OPTS -c optimizer=${{ matrix.pg_settings.optimizer }}"
fi
# Set regroup options if defined
TEST_CGROUP=""
if [ "${{ matrix.enable_cgroups }}" = "true" ]; then
TEST_CGROUP="true"
stat -fc %T /sys/fs/cgroup/
docker info | grep Cgroup
stat -f /sys/fs/cgroup/unified
stat -f /sys/fs/cgroup
fi
# Read configs into array
IFS=' ' read -r -a configs <<< "${{ join(matrix.make_configs, ' ') }}"
echo "=== Starting test execution for ${{ matrix.test }} ==="
echo "Number of configurations to execute: ${#configs[@]}"
echo ""
# Execute each config separately
for ((i=0; i<${#configs[@]}; i++)); do
config="${configs[$i]}"
IFS=':' read -r dir target <<< "$config"
echo "=== Executing configuration $((i+1))/${#configs[@]} ==="
echo "Make command: make -C $dir $target"
echo "Environment:"
echo "- PGOPTIONS: ${PG_OPTS}"
config_log="build-logs/details/make-${{ matrix.test }}-config$i.log"
df . -h
if ! docker run \
-e TEST_DIR="${dir}" \
-e TEST_TARGET="${target}" \
-e PGOPTIONS="${PG_OPTS}" \
-e TEST_CGROUP="${TEST_CGROUP}" \
--privileged \
--cgroupns=private \
--name test_test_container test_test:1234 \
2>&1 | tee "$config_log"; then
echo "::warning::Test execution failed for configuration $((i+1)): make -C $dir $target"
overall_status=1
fi
df . -h
RESULTS_PATH="build-results/results-${{ matrix.test }}-${dir}"
mkdir -p $RESULTS_PATH
docker cp test_test_container:/home/gpadmin $RESULTS_PATH
docker rm test_test_container
done
echo "=== Test execution completed ==="
echo "Log files:"
ls -l build-logs/details/
# Store number of configurations for parsing step
echo "NUM_CONFIGS=${#configs[@]}" >> "$GITHUB_ENV"
# Report overall status
if [ $overall_status -eq 0 ]; then
echo "All test executions completed successfully"
else
echo "::warning::Some test executions failed, check individual logs for details"
fi
exit $overall_status
- name: Check and Display Diffs
if: always()
run: |
# Search for regression.diffs recursively
found_files=$(find . -type f -path "*/regression.diffs")
if [[ "x$found_files" != "x" ]]; then
for found_file in $found_files
do
echo "-----------------------------------------------------"
echo "Found regression.diffs at: $found_file"
echo "-----------------------------------------------------"
cat "$found_file"
done
else
echo "No regression.diffs file found in the hierarchy."
fi
- name: Upload test logs
if: always()
uses: actions/upload-artifact@v4
with:
name: test-logs-${{ matrix.test }}-${{ needs.build.outputs.build_timestamp }}
path: |
build-logs/
- name: Upload test results files
uses: actions/upload-artifact@v4
with:
name: results-${{ matrix.test }}-${{ needs.build.outputs.build_timestamp }}
path: |
**/regression.out
**/regression.diffs
**/results/
- name: Upload test regression logs
if: failure() || cancelled()
uses: actions/upload-artifact@v4
with:
name: regression-logs-${{ matrix.test }}-${{ needs.build.outputs.build_timestamp }}
path: |
**/regression.out
**/regression.diffs
**/*.diffs
**/results/
## ======================================================================
## Job: report
## ======================================================================
report:
name: Generate GPDB Build Report
needs: [build, prepare-test-matrix, test]
if: always()
runs-on: ubuntu-latest
steps:
- name: Generate Final Report
run: |
{
echo "# Apache Cloudberry Build Pipeline Report"
echo "## Job Status"
echo "- Build Job: ${{ needs.build.result }}"
echo "- Test Job: ${{ needs.test.result }}"
echo "- Completion Time: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
if [[ "${{ needs.build.result }}" == "success" && "${{ needs.test.result }}" == "success" ]]; then
echo "✅ Pipeline completed successfully"
else
echo "⚠️ Pipeline completed with failures"
if [[ "${{ needs.build.result }}" != "success" ]]; then
echo "### Build Job Failure"
echo "Check build logs for details"
fi
if [[ "${{ needs.test.result }}" != "success" ]]; then
echo "### Test Job Failure"
echo "Check test logs and regression files for details"
fi
fi
} >> "$GITHUB_STEP_SUMMARY"
- name: Notify on failure
if: |
(needs.build.result != 'success' || needs.test.result != 'success')
run: |
echo "::error::Build/Test pipeline failed! Check job summaries and logs for details"
echo "Timestamp: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
echo "Build Result: ${{ needs.build.result }}"
echo "Test Result: ${{ needs.test.result }}"