blob: 003f7374b3e4cb09b419a89e76e210a080185edb [file] [log] [blame]
#!/usr/bin/env bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
set -e
set -o pipefail
if [ ${VERBOSE:-0} -gt 0 ]; then
set -x
fi
# Check that required dependencies are installed
check_dependencies() {
local missing_deps=0
local required_deps=("curl" "git" "gpg" "cc" "cargo" "cmake")
for dep in "${required_deps[@]}"; do
if ! command -v $dep &> /dev/null; then
echo "Error: $dep is not installed or not in PATH"
missing_deps=1
fi
done
# pkg-config doesn't work with the above check
if ! pkg-config --version &> /dev/null; then
echo "Error: pkg-config is not installed or not in PATH"
missing_deps=1
fi
# Check for either shasum or sha256sum/sha512sum
local has_sha_tools=0
if command -v shasum &> /dev/null; then
has_sha_tools=1
elif command -v sha256sum &> /dev/null && command -v sha512sum &> /dev/null; then
has_sha_tools=1
else
echo "Error: Neither shasum nor sha256sum/sha512sum are installed or in PATH"
missing_deps=1
fi
if [ $missing_deps -ne 0 ]; then
echo "Please install missing dependencies and try again"
exit 1
fi
}
# Check that required native dependencies are installed. For the purposes of this
# script we require geos, proj, absl_base, and openssl via pkg-config, even though
# technically absl_base and openssl are resolved via CMake for sedona-s2geography.
check_pkg_config_dependencies() {
local missing_deps=0
local required_deps=(geos proj openssl absl_base)
for dep in "${required_deps[@]}"; do
if ! pkg-config --modversion $dep &> /dev/null; then
echo "Error: $dep is not installed or not in PKG_CONFIG_PATH"
missing_deps=1
fi
done
local absl_version=$(pkg-config --modversion absl_base)
# Check if Abseil version is sufficient (need at least version 20230802)
if [ "$absl_version" -lt "20230802" ]; then
echo "Error: Abseil version $absl_version is too old, need at least 20230802"
echo "On Linux, this typically requires verification within a conda environment"
echo "or by installing Abseil via vcpkg and ensuring PKG_CONFIG_PATH and"
echo "CMAKE_TOOLCHAIN_FILE are updated appropriately."
missing_deps=1
fi
if [ $missing_deps -ne 0 ]; then
echo "Please install or update missing dependencies and try again"
echo "Using Homebrew: brew install geos proj openssl abseil"
echo "Using conda: conda install geos proj openssl libabseil"
exit 1
fi
}
case $# in
0) VERSION="HEAD"
SOURCE_KIND="local"
;;
1) VERSION="TARBALL"
SOURCE_KIND="local_tarball"
LOCAL_TARBALL="$(realpath $1)"
;;
2) VERSION="$1"
RC_NUMBER="$2"
SOURCE_KIND="tarball"
;;
*) echo "Usage:"
echo " Verify release candidate:"
echo " $0 X.Y.Z RC_NUMBER"
echo ""
echo " Run the source verification tasks on this sedona-db checkout:"
echo " $0"
exit 1
;;
esac
# Check dependencies early
check_dependencies
check_pkg_config_dependencies
# Note that these point to the current verify-release-candidate.sh directories
# which is different from the SEDONADB_SOURCE_DIR set in ensure_source_directory()
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
SEDONADB_DIR="$(cd "${SOURCE_DIR}/../.." && pwd)"
show_header() {
if [ -z "$GITHUB_ACTIONS" ]; then
echo ""
printf '=%.0s' $(seq ${#1}); printf '\n'
echo "${1}"
printf '=%.0s' $(seq ${#1}); printf '\n'
else
echo "::group::${1}"; printf '\n'
fi
}
show_info() {
echo "└ ${1}"
}
SEDONADB_DIST_URL='https://dist.apache.org/repos/dist/dev/sedona'
download_dist_file() {
curl \
--silent \
--show-error \
--fail \
--location \
--remote-name $SEDONADB_DIST_URL/$1
}
download_rc_file() {
download_dist_file apache-sedona-db-${VERSION}-rc${RC_NUMBER}/$1
}
import_gpg_keys() {
if [ "${GPGKEYS_ALREADY_IMPORTED:-0}" -gt 0 ]; then
return 0
fi
download_dist_file KEYS
if [ "${SEDONADB_ACCEPT_IMPORT_GPG_KEYS_ERROR:-0}" -gt 0 ]; then
gpg --import KEYS || true
else
gpg --import KEYS
fi
GPGKEYS_ALREADY_IMPORTED=1
}
if type shasum >/dev/null 2>&1; then
sha512_verify="shasum -a 512 -c"
else
sha512_verify="sha512sum -c"
fi
fetch_archive() {
import_gpg_keys
local dist_name=$1
download_rc_file ${dist_name}.tar.gz
download_rc_file ${dist_name}.tar.gz.asc
download_rc_file ${dist_name}.tar.gz.sha512
gpg --verify ${dist_name}.tar.gz.asc ${dist_name}.tar.gz
${sha512_verify} ${dist_name}.tar.gz.sha512
}
verify_dir_artifact_signatures() {
import_gpg_keys
# verify the signature and the checksums of each artifact
find $1 -name '*.asc' | while read sigfile; do
artifact=${sigfile/.asc/}
gpg --verify $sigfile $artifact || exit 1
# go into the directory because the checksum files contain only the
# basename of the artifact
pushd $(dirname $artifact)
base_artifact=$(basename $artifact)
if [ -f $base_artifact.sha512 ]; then
${sha512_verify} $base_artifact.sha512 || exit 1
fi
popd
done
}
setup_tempdir() {
cleanup() {
if [ "${TEST_SUCCESS}" = "yes" ]; then
rm -fr "${SEDONADB_TMPDIR}"
else
echo "Failed to verify release candidate. See ${SEDONADB_TMPDIR} for details."
fi
}
show_header "Creating temporary directory"
if [ -z "${SEDONADB_TMPDIR}" ]; then
# clean up automatically if SEDONADB_TMPDIR is not defined
SEDONADB_TMPDIR=$(mktemp -d -t "sedonadb-${VERSION}.XXXXXX")
trap cleanup EXIT
else
# don't clean up automatically
mkdir -p "${SEDONADB_TMPDIR}"
fi
echo "Working in sandbox ${SEDONADB_TMPDIR}"
}
test_rust() {
show_header "Build and test Rust libraries"
pushd "${SEDONADB_SOURCE_DIR}"
cargo test --workspace --exclude sedona-s2geography
popd
}
activate_or_create_venv() {
if [ ! -z "${SEDONADB_PYTHON_VENV}" ]; then
show_info "Activating virtual environment at ${SEDONADB_PYTHON_VENV}"
source "${SEDONADB_PYTHON_VENV}/bin/activate"
else
# Try python3 first, then try regular python (e.g., already in a venv)
if [ -z "${PYTHON_BIN}" ] && python3 --version >/dev/null; then
PYTHON_BIN=python3
elif [ -z "${PYTHON_BIN}" ]; then
PYTHON_BIN=python
fi
show_info "Creating temporary virtual environment using ${PYTHON_BIN}..."
"${PYTHON_BIN}" -m venv "${SEDONADB_TMPDIR}/venv"
source "${SEDONADB_TMPDIR}/venv/bin/activate"
python -m pip install --upgrade pip
fi
}
test_python() {
show_header "Build and test Python package"
activate_or_create_venv
pushd "${SEDONADB_SOURCE_DIR}/python"
show_info "Installing Python package"
rm -rf "${SEDONADB_TMPDIR}/python"
pip install "sedonadb/[test]" -v
show_info "Testing Python package"
python -m pytest -vv
popd
}
ensure_source_directory() {
show_header "Ensuring source directory"
dist_name="apache-sedona-db-${VERSION}"
if [ "${SOURCE_KIND}" = "local" ]; then
# Local repository
if [ -z "$SEDONADB_SOURCE_DIR" ]; then
export SEDONADB_SOURCE_DIR="${SEDONADB_DIR}"
fi
echo "Verifying local sedona-db checkout at ${SEDONADB_SOURCE_DIR}"
elif [ "${SOURCE_KIND}" = "local_tarball" ]; then
# Local tarball
pushd $SEDONADB_TMPDIR
tar xf "$LOCAL_TARBALL"
dist_name=$(ls)
export SEDONADB_SOURCE_DIR="${SEDONADB_TMPDIR}/${dist_name}"
# Ensure submodules are where tests expect them to be
pushd "$SEDONADB_SOURCE_DIR/submodules"
git clone https://github.com/apache/sedona-testing.git
git clone https://github.com/geoarrow/geoarrow-data.git
popd
popd
echo "Verifying local tarball at $LOCAL_TARBALL"
else
# Release tarball
echo "Verifying official SedonaDB release candidate ${VERSION}-rc${RC_NUMBER}"
export SEDONADB_SOURCE_DIR="${SEDONADB_TMPDIR}/${dist_name}"
if [ ! -d "${SEDONADB_SOURCE_DIR}" ]; then
pushd $SEDONADB_TMPDIR
fetch_archive ${dist_name}
tar xf ${dist_name}.tar.gz
# Ensure submodules are where tests expect them to be
pushd "${SEDONADB_SOURCE_DIR}/submodules"
git clone https://github.com/apache/sedona-testing.git
git clone https://github.com/geoarrow/geoarrow-data.git
popd
popd
fi
fi
}
test_source_distribution() {
pushd $SEDONADB_SOURCE_DIR
if [ ${TEST_RUST} -gt 0 ]; then
test_rust
fi
if [ ${TEST_PYTHON} -gt 0 ]; then
test_python
fi
popd
}
# By default test all functionalities.
# To deactivate one test, deactivate the test and all of its dependents
# To explicitly select one test, set TEST_DEFAULT=0 TEST_X=1
: ${TEST_DEFAULT:=1}
: ${TEST_SOURCE:=${TEST_DEFAULT}}
: ${TEST_RUST:=${TEST_SOURCE}}
: ${TEST_PYTHON:=${TEST_SOURCE}}
TEST_SUCCESS=no
setup_tempdir
ensure_source_directory
test_source_distribution
TEST_SUCCESS=yes
echo "Release candidate ${VERSION}-RC${RC_NUMBER} looks good!"
exit 0