Skip to content

CI

CI #992

name: CI
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
schedule:
- cron: "23 4 * * 0"
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
DOCKER_BUILDKIT: 1
PIP_BREAK_SYSTEM_PACKAGES: 1
jobs:
changes:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
pgtagprefix: ${{ steps.check.outputs.pgtagprefix }}
buildpgdocker: ${{ steps.check.outputs.buildpg }}
pyrustdocker: ${{ steps.check.outputs.pytag }}
buildpyrustdocker: ${{ steps.check.outputs.buildpy }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
id: filter
with:
filters: |
pgstac:
- 'docker/pgstac/**'
pyrust:
- 'docker/pypgstac/**'
- id: check
run: |
buildpg=false;
ref=$(echo ${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}} | tr / _);
pgref=$ref;
[[ "${{ steps.filter.outputs.pgstac }}" == "true" ]] && buildpg=true || pgref=main;
if [[ "${{ github.event_name }}" == "schedule" || "${{ github.event_name }}" == "workflow_dispatch" ]]; then
buildpg=true;
pgref=main;
fi
echo "pgtagprefix=${{ env.REGISTRY }}/${GITHUB_REPOSITORY_OWNER}/pgstac-postgres:$pgref" >>$GITHUB_OUTPUT;
echo "buildpg=$buildpg" >>$GITHUB_OUTPUT;
buildpy=false;
pyref=$ref;
[[ "${{ steps.filter.outputs.pyrust }}" == "true" ]] && buildpy=true || pyref=main;
if [[ "${{ github.event_name }}" == "schedule" || "${{ github.event_name }}" == "workflow_dispatch" ]]; then
buildpy=true;
pyref=main;
fi
echo "pytag=${{ env.REGISTRY }}/${GITHUB_REPOSITORY_OWNER}/pgstac-pyrust:$pyref" >>$GITHUB_OUTPUT;
echo "buildpy=$buildpy" >>$GITHUB_OUTPUT;
# This builds a base postgres image that has everything installed to be able to run pgstac. This image does not have pgstac itself installed.
buildpg:
name: Build and push base postgres image
runs-on: ubuntu-latest
needs: [changes]
strategy:
matrix:
pg_major: [16, 17, 18]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Log in to the Container registry
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Base Postgres
if: ${{ needs.changes.outputs.buildpgdocker == 'true' }}
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
platforms: linux/amd64,linux/arm64
context: .
target: pgstacbase
file: docker/pgstac/Dockerfile
build-args: |
PG_MAJOR=${{ matrix.pg_major }}
tags: ${{ needs.changes.outputs.pgtagprefix }}-pg${{ matrix.pg_major }}
push: true
cache-from: type=gha
cache-to: type=gha, mode=max
buildpyrust:
name: Build and push base pyrust
runs-on: ubuntu-latest
needs: [changes]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Log in to the Container registry
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Base pyrust
if: ${{ needs.changes.outputs.buildpyrustdocker == 'true' }}
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
platforms: linux/amd64,linux/arm64
context: .
target: pyrustbase
file: docker/pypgstac/Dockerfile
tags: ${{ needs.changes.outputs.pyrustdocker }}
push: true
cache-from: type=gha
cache-to: type=gha, mode=max
test:
name: test
needs: [changes, buildpg, buildpyrust]
runs-on: ubuntu-latest
strategy:
matrix:
pg_major: [16, 17, 18]
flags:
- ""
- "--resolution lowest-direct"
container:
image: ${{ needs.changes.outputs.pyrustdocker }}
options: --user root
env:
PGPASSWORD: postgres
PGHOST: postgres
PGDATABASE: postgres
PGUSER: postgres
UV_CACHE_DIR: /tmp/.uv-cache
services:
postgres:
env:
POSTGRES_PASSWORD: postgres
image: ${{ needs.changes.outputs.pgtagprefix }}-pg${{ matrix.pg_major }}
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Ensure PostgreSQL client tools
run: |
set -euo pipefail
apt-get update
apt-get install -y --no-install-recommends gnupg ca-certificates curl
install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/keyrings/postgresql.gpg
. /etc/os-release
echo "deb [signed-by=/etc/apt/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt ${VERSION_CODENAME}-pgdg main" > /etc/apt/sources.list.d/pgdg.list
apt-get update
apt-get install -y --no-install-recommends "postgresql-client-${{ matrix.pg_major }}"
client_major="$(pg_dump --version | sed -E 's/.* ([0-9]+)\..*/\1/')"
server_major="$(psql -X -tA -h postgres -d postgres -c 'show server_version' | sed -E 's/^([0-9]+).*/\1/')"
if [[ "$client_major" != "${{ matrix.pg_major }}" ]]; then
echo "Expected pg_dump major ${{ matrix.pg_major }}, got ${client_major}" >&2
exit 1
fi
if [[ "$client_major" != "$server_major" ]]; then
echo "pg_dump major (${client_major}) does not match postgres major (${server_major})" >&2
exit 1
fi
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Build the pgstac wheel and install pgstac-migrate
working-directory: /__w/pgstac/pgstac
run: |
export UV_CACHE_DIR=/tmp/.uv-cache
export XDG_CACHE_HOME=/tmp/.cache
mkdir -p "$UV_CACHE_DIR" "$XDG_CACHE_HOME"
uv --cache-dir "$UV_CACHE_DIR" venv /tmp/ci-venv
# Build the Rust-backed pgstac extension wheel (the read API used by stac-fastapi-pgstac).
uv --cache-dir "$UV_CACHE_DIR" pip install --python /tmp/ci-venv/bin/python maturin
/tmp/ci-venv/bin/maturin build --release -m src/pgstac-rs/Cargo.toml --out /tmp/pgstac-wheels
uv --cache-dir "$UV_CACHE_DIR" pip install --python /tmp/ci-venv/bin/python /tmp/pgstac-wheels/*.whl
# Install pgstac-migrate (the migration CLI) plus its dev/test tooling for the container test runner.
uv --cache-dir "$UV_CACHE_DIR" pip install --python /tmp/ci-venv/bin/python ${{ matrix.flags }} ./src/pgstac-migrate
echo "/tmp/ci-venv/bin" >> "$GITHUB_PATH"
- name: Run tests
working-directory: /__w/pgstac/pgstac
run: scripts/container-scripts/test
# Compile/lint only — NOT tests. The Rust *tests* run via scripts/container-scripts/test (the single
# entrypoint, same as local) in the `test` matrix job, against every Postgres version. This job just
# feature-matrix compile-checks + doc-lints once (no database needed).
rust-crate:
name: Rust compile & docs
runs-on: ubuntu-latest
needs:
- changes
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Compile-check the feature matrix
run: |
set -euo pipefail
for feat in \
"--no-default-features" \
"--no-default-features --features pool" \
"--no-default-features --features export" \
"--features cli" \
"--all-features"; do
echo "::group::cargo check $feat"
cargo check $feat --all-targets --manifest-path src/pgstac-rs/Cargo.toml
echo "::endgroup::"
done
- name: Check docs (deny warnings)
env:
RUSTDOCFLAGS: -D warnings
run: cargo doc --all-features --no-deps --manifest-path src/pgstac-rs/Cargo.toml