FROM rust:1.96.0-bookworm@sha256:5e2214abe154fe26e39f64488952e5c991eeed1d6d6da7cc8381ae83927f0cfc ARG PGRX_VERSION=0.19.1 ARG SFW_VERSION=1.13.1 ARG TARGETARCH SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN rm -f /etc/apt/apt.conf.d/docker-clean \ && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' \ > /etc/apt/apt.conf.d/keep-cache RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update \ && apt-get install -y --no-install-recommends \ ca-certificates \ curl \ gnupg \ lsb-release \ && curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \ | gpg --dearmor -o /usr/share/keyrings/postgresql.gpg \ && echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \ > /etc/apt/sources.list.d/pgdg.list \ && apt-get update \ && apt-get install -y --no-install-recommends \ clang \ libclang-dev \ pkg-config \ postgresql-client-common \ postgresql-common \ valgrind \ postgresql-14 postgresql-server-dev-14 \ postgresql-15 postgresql-server-dev-15 \ postgresql-16 postgresql-server-dev-16 \ postgresql-17 postgresql-server-dev-17 \ postgresql-18 postgresql-server-dev-18 \ && rm -rf /var/lib/apt/lists/* RUN --mount=type=cache,target=/var/cache/pggraph-sfw \ case "${TARGETARCH}" in \ arm64) \ sfw_asset="sfw-free-linux-arm64"; \ sfw_sha256="f87bbbca2192fca9740f9bdb115e7cfaa22e957a8f5234d5f97fce1383aa1d66" \ ;; \ amd64) \ sfw_asset="sfw-free-linux-x86_64"; \ sfw_sha256="4dc46b626a7c5b81c0b54e1984ee53be5a628dbfb2f55ab14e9b04c8a134db6a" \ ;; \ *) \ echo "unsupported Docker architecture for sfw: ${TARGETARCH}" >&2; \ exit 2 \ ;; \ esac \ && sfw_path="/var/cache/pggraph-sfw/${sfw_asset}-${SFW_VERSION}" \ && if ! echo "${sfw_sha256} ${sfw_path}" \ | sha256sum --check --strict >/dev/null 2>&1; then \ download_sfw() { \ curl --http1.1 --fail --silent --show-error --location \ --connect-timeout 30 --max-time 300 \ --speed-limit 1024 --speed-time 30 \ --retry 5 --retry-all-errors --retry-delay 2 \ "$@" \ "https://github.com/SocketDev/sfw-free/releases/download/v${SFW_VERSION}/${sfw_asset}" \ -o "${sfw_path}"; \ }; \ if ! download_sfw --continue-at -; then \ rm -f "${sfw_path}"; \ download_sfw; \ fi; \ fi \ && echo "${sfw_sha256} ${sfw_path}" | sha256sum --check --strict \ && install -m 0755 "${sfw_path}" /usr/local/bin/sfw ENV CARGO_NET_RETRY=5 \ CARGO_HTTP_TIMEOUT=300 \ CARGO_HTTP_MULTIPLEXING=false RUN --mount=type=cache,target=/usr/local/cargo/registry \ --mount=type=cache,target=/tmp/cargo-pgrx-target \ export CARGO_TARGET_DIR=/tmp/cargo-pgrx-target; \ installed=0; \ for attempt in 1 2 3; do \ sfw cargo install cargo-pgrx --version "${PGRX_VERSION}" --locked || true; \ if command -v cargo-pgrx >/dev/null 2>&1 \ && cargo pgrx --version 2>/dev/null | grep -Fq "${PGRX_VERSION}"; then \ installed=1; \ break; \ fi; \ rm -f /usr/local/cargo/bin/cargo-pgrx; \ sleep "$((attempt * 2))"; \ done; \ if [[ "$installed" != "1" ]]; then \ echo "sfw did not install verified cargo-pgrx ${PGRX_VERSION}" >&2; \ exit 1; \ fi RUN groupadd --gid 1000 pggraph \ && useradd --uid 1000 --gid 1000 --create-home --shell /bin/bash pggraph \ && for pg in 14 15 16 17 18; do \ chown -R pggraph:pggraph "/usr/lib/postgresql/${pg}/lib" "/usr/share/postgresql/${pg}/extension"; \ done ENV CARGO_HOME=/home/pggraph/.cargo ENV RUSTUP_HOME=/home/pggraph/.rustup ENV USER=pggraph ENV LOGNAME=pggraph ENV PATH=/usr/local/cargo/bin:/home/pggraph/.cargo/bin:${PATH} WORKDIR /src/graph COPY --chown=pggraph:pggraph graph/rust-toolchain.toml /src/graph/rust-toolchain.toml USER pggraph RUN rustup show active-toolchain RUN set -euo pipefail; \ for pg in 14 15 16 17 18; do \ echo "==> cargo pgrx init pg${pg}"; \ cargo pgrx init "--pg${pg}=/usr/lib/postgresql/${pg}/bin/pg_config"; \ done USER root COPY --chown=pggraph:pggraph graph/ /src/graph/ COPY --chown=pggraph:pggraph release/ /src/release/ COPY --chown=pggraph:pggraph scripts/ /src/scripts/ USER pggraph ARG PG_VERSIONS="14 15 16 17 18" ARG RUN_RUST_TESTS=1 ARG RUN_PGRX_SQL=1 ARG RUN_GQL_WRITE_MATRIX=1 ARG RUN_POSTGRES_SANITIZER=0 ARG RUN_DURABLE_PROJECTION_MATRIX=0 ARG RUN_PACKAGE_INSTALL_MATRIX=0 ARG RUN_CRASH_MATRIX=0 ARG RUN_RUNTIME_RESOURCES=0 ARG RUN_PG_UPGRADE_MATRIX=0 ARG PROFILE_TIMEOUT_SECONDS=600 # Linux test executables retain PostgreSQL backend references from the extension # crate even though unit-test code must not call them directly. The symbols # resolve when the packaged shared object is loaded by each PostgreSQL server; # allow that same late binding while linking the harness. RUN --mount=type=cache,target=/home/pggraph/.cargo/registry,uid=1000,gid=1000 \ --mount=type=cache,target=/src/graph/target,uid=1000,gid=1000 \ set -euo pipefail; \ export RUSTFLAGS="${RUSTFLAGS:-} -C link-arg=-Wl,--unresolved-symbols=ignore-all"; \ for pg in ${PG_VERSIONS}; do \ feature="pg${pg}"; \ if [[ "${RUN_RUST_TESTS}" == "1" ]]; then \ echo "==> cargo test --release --features ${feature} development"; \ cargo test --release --no-default-features --features "${feature} development"; \ fi; \ if [[ "${RUN_PGRX_SQL}" == "1" ]]; then \ echo "==> cargo pgrx test --features development ${feature} (serial shared cluster)"; \ RUST_TEST_THREADS=1 cargo pgrx test --features development "${feature}"; \ fi; \ done RUN --mount=type=cache,target=/home/pggraph/.cargo/registry,uid=1000,gid=1000 \ --mount=type=cache,target=/src/graph/target,uid=1000,gid=1000 \ if [[ "${RUN_GQL_WRITE_MATRIX}" == "1" ]]; then \ PG_VERSIONS="${PG_VERSIONS}" ./tests/heavy/run_gql_write_matrix.sh; \ fi RUN --mount=type=cache,target=/home/pggraph/.cargo/registry,uid=1000,gid=1000 \ --mount=type=cache,target=/src/graph/target,uid=1000,gid=1000 \ if [[ "${RUN_POSTGRES_SANITIZER}" == "1" ]]; then \ PG_VERSION_FEATURE=pg17 ./tests/heavy/run_postgres_process_sanitizer.sh; \ fi RUN --mount=type=cache,target=/home/pggraph/.cargo/registry,uid=1000,gid=1000 \ --mount=type=cache,target=/src/graph/target,uid=1000,gid=1000 \ if [[ "${RUN_DURABLE_PROJECTION_MATRIX}" == "1" ]]; then \ PG_VERSIONS="${PG_VERSIONS}" \ PROFILE_TIMEOUT_SECONDS="${PROFILE_TIMEOUT_SECONDS}" \ ./tests/heavy/run_durable_projection_matrix.sh; \ fi RUN --mount=type=cache,target=/home/pggraph/.cargo/registry,uid=1000,gid=1000 \ --mount=type=cache,target=/src/graph/target,uid=1000,gid=1000 \ if [[ "${RUN_PACKAGE_INSTALL_MATRIX}" == "1" ]]; then \ PG_VERSIONS="${PG_VERSIONS}" ./tests/heavy/package_install_matrix.sh; \ fi RUN --mount=type=cache,target=/home/pggraph/.cargo/registry,uid=1000,gid=1000 \ --mount=type=cache,target=/src/graph/target,uid=1000,gid=1000 \ if [[ "${RUN_CRASH_MATRIX}" == "1" ]]; then \ PG_VERSIONS="${PG_VERSIONS}" ./tests/heavy/run_crash_matrix.sh; \ fi RUN --mount=type=cache,target=/home/pggraph/.cargo/registry,uid=1000,gid=1000 \ --mount=type=cache,target=/src/graph/target,uid=1000,gid=1000 \ if [[ "${RUN_RUNTIME_RESOURCES}" == "1" ]]; then \ PG_CONFIG=/usr/lib/postgresql/17/bin/pg_config \ PG_VERSION_FEATURE=pg17 \ DBNAME=pggraph_runtime_resources_linux \ MAX_RSS_MB=1024 \ MAX_PSS_MB=1024 \ /src/scripts/with_disposable_postgres.sh \ ./tests/heavy/measure_runtime_resources.sh; \ fi RUN --mount=type=cache,target=/home/pggraph/.cargo/registry,uid=1000,gid=1000 \ --mount=type=cache,target=/src/graph/target,uid=1000,gid=1000 \ if [[ "${RUN_PG_UPGRADE_MATRIX}" == "1" ]]; then \ ./tests/heavy/run_pg_upgrade_matrix.sh; \ fi