-
Notifications
You must be signed in to change notification settings - Fork 1
202 lines (197 loc) · 9.26 KB
/
Copy pathci.yml
File metadata and controls
202 lines (197 loc) · 9.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
name: CI
on:
push:
branches: [main, "claude/**"]
pull_request:
# Cancel superseded runs on the same ref.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: Lint & type-check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up uv
uses: astral-sh/setup-uv@v7
with:
python-version: "3.14"
enable-cache: true
- run: uv sync --frozen
- name: ruff (lint)
run: uv run ruff check .
- name: ruff (format)
run: uv run ruff format --check .
- name: mypy
run: uv run mypy src/mcpg
security:
name: Security audit (SAST & Dependencies)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up uv
uses: astral-sh/setup-uv@v7
with:
python-version: "3.14"
enable-cache: true
- run: uv sync --frozen
# pip-audit consults the PyPI advisory DB + OSV.dev for known
# CVEs in resolved dependencies. ``--strict`` upgrades warnings
# to failures so a vulnerable transitive dep blocks merge. We
# audit the uv-resolved requirements (runtime deps only, project
# excluded — the editable install of mcpg itself isn't on PyPI).
- name: Dependency audit (pip-audit)
run: |
uv export --no-dev --no-emit-project --format requirements-txt > /tmp/mcpg-reqs.txt
uv run pip-audit --strict --disable-pip -r /tmp/mcpg-reqs.txt
- name: Bandit static analysis (SAST)
run: uv run bandit -r src/mcpg --skip B101,B608,B110 -ll
test:
name: Tests (PG ${{ matrix.postgres }})
runs-on: ubuntu-latest
# PG 19 is beta. We track it as an experimental matrix entry —
# failures are reported but don't fail the job. Promoted to
# required once PG 19 reaches GA (issue #120, Phase 3).
continue-on-error: ${{ matrix.experimental == true }}
strategy:
fail-fast: false
matrix:
postgres: ["14", "15", "16", "17", "18"]
include:
- postgres: "19"
experimental: true
# WarehousePG (Greenplum-derived MPP) characterisation lane.
# Pinned to woblerr/warehousepg:7.4.1-WHPG — see
# .github/ci-postgres-warehousepg.Dockerfile (single source of
# truth for the upstream image tag) and roadmap row 15.8.
# `continue-on-error: true` stays on: it's a single community
# image with no fallback, and a single-node Greenplum-family
# cluster is inherently slower/heavier to bring up in CI than a
# plain postgres container.
- postgres: "warehousepg-latest"
experimental: true
steps:
- uses: actions/checkout@v7
# The ubuntu-latest runner ships an older PostgreSQL client by
# default; `pg_dump` refuses to dump from a newer server (PG 17 /
# 18 in this matrix). Install the matching client tools from the
# pgdg apt repo so `pg_dump` matches the matrix server version
# exactly. Required by the Phase-24 subprocess integration tests
# (mcpg.shell + dump_database); harmless for the older versions.
- name: Install PostgreSQL ${{ matrix.postgres }} client tools
# WarehousePG is wire-compatible with libpq, so the default
# runner-shipped psql works. We don't try to install a custom
# `postgresql-client-warehousepg` package — it doesn't exist on
# pgdg and the existing client is what mcpg.shell expects.
if: matrix.postgres != 'warehousepg-latest'
run: |
sudo apt-get install -y wget gnupg lsb-release ca-certificates
wget --quiet -O- https://www.postgresql.org/media/keys/ACCC4CF8.asc \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
| sudo tee /etc/apt/sources.list.d/pgdg.list
sudo apt-get update
# PG 19 client packages are published under `postgresql-client-19`
# by the pgdg repo as soon as the server enters beta — but during
# the beta window the package can be temporarily absent from the
# noble suite (observed mid-Beta-1, 2026-06-22). Probe apt-cache
# for the literal "Unable to locate package" failure mode before
# installing so the step distinguishes "package not yet published"
# (downgraded to a workflow ::warning::) from genuine apt errors
# (network / mirror outage — kept fatal so we don't silently mask
# real infra problems; sourcery feedback on PR #152). The matrix
# entry is already `continue-on-error: true` for the
# `Tests (PG 19)` job; this just stops the step-level webhook
# noise. See roadmap 14.1 in docs/feature-shortlist.md.
set +e
pkg="postgresql-client-${{ matrix.postgres }}"
apt_cache_out=$(apt-cache show "$pkg" 2>&1)
apt_cache_rc=$?
set -e
if [ "$apt_cache_rc" -eq 0 ]; then
sudo apt-get install -y "$pkg"
elif printf '%s' "$apt_cache_out" | grep -q "Unable to locate package\|No packages found"; then
echo "::warning::$pkg not yet in apt cache — skipping. Tests that shell out to pg_dump will be limited to what the runner's default client provides."
else
echo "::error::apt-cache show $pkg failed with an unexpected error (likely a transient network / mirror issue, not a package-availability one):"
printf '%s\n' "$apt_cache_out" >&2
exit "$apt_cache_rc"
fi
# A custom image (pgvector + PostGIS) so the integration suite can test
# vector and geospatial features against a real database. It is built
# and run as a step because GitHub `services:` cannot build images.
- name: Start PostgreSQL (pgvector + PostGIS)
run: |
# Docker Hub intermittently times out resolving the
# pgvector base-image manifest (observed across the matrix:
# "Head https://registry-1.docker.io/...: i/o timeout"). That
# is transient infra, not a code failure, so retry the build
# with exponential backoff before giving up.
# PG 19 (beta) needs a separate Dockerfile — pgvector doesn't
# publish a `pg19` image tag yet, so we build pgvector from source
# against `postgres:19beta1`. Drop this branch once pgvector ships
# a PG 19 image (issue #120 Phase 3, on GA).
DOCKERFILE=".github/ci-postgres.Dockerfile"
if [ "${{ matrix.postgres }}" = "19" ]; then
DOCKERFILE=".github/ci-postgres-pg19.Dockerfile"
elif [ "${{ matrix.postgres }}" = "warehousepg-latest" ]; then
# WarehousePG (Greenplum-derived MPP) lane — see roadmap 15.8
# and .github/ci-postgres-warehousepg.Dockerfile. The matrix
# entry is `continue-on-error: true` so an upstream image
# outage doesn't block the main suite.
DOCKERFILE=".github/ci-postgres-warehousepg.Dockerfile"
fi
build_db() {
docker build -f "$DOCKERFILE" \
--build-arg PG_MAJOR=${{ matrix.postgres }} -t mcpg-ci-db .
}
attempt=1
max_attempts=4
until build_db; do
if [ "$attempt" -ge "$max_attempts" ]; then
echo "docker build failed after $attempt attempts" >&2
exit 1
fi
backoff=$((2 ** attempt))
echo "docker build attempt $attempt failed; retrying in ${backoff}s..." >&2
sleep "$backoff"
attempt=$((attempt + 1))
done
# -e POSTGRES_* is inert for the WarehousePG lane — that image's
# entrypoint reads GREENPLUM_*-prefixed vars instead (baked into
# ci-postgres-warehousepg.Dockerfile), so its superuser is
# `gpadmin`, not `postgres`. Harmless to still pass these; every
# other matrix entry needs them.
docker run -d --name mcpg-db -p 5432:5432 \
-e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=mcpg_test mcpg-ci-db
if [ "${{ matrix.postgres }}" = "warehousepg-latest" ]; then
DB_USER=gpadmin
# A single-node Greenplum-family coordinator+segment cluster
# takes much longer to initialize than a plain postgres
# container, so this lane gets a longer, coarser poll.
max_attempts=90
sleep_secs=4
else
DB_USER=postgres
max_attempts=30
sleep_secs=2
fi
echo "DB_USER=$DB_USER" >> "$GITHUB_ENV"
for _ in $(seq 1 "$max_attempts"); do
docker exec mcpg-db pg_isready -U "$DB_USER" && break
sleep "$sleep_secs"
done
- name: Set up uv
uses: astral-sh/setup-uv@v7
with:
python-version: "3.14"
enable-cache: true
- run: uv sync --frozen
# Runs unit, vendored-kernel, and integration suites with the coverage
# gate (fail_under = 90, authored code only) against each PG version.
- name: pytest
env:
MCPG_TEST_DATABASE_URL: postgresql://${{ env.DB_USER }}:postgres@localhost:5432/mcpg_test
run: uv run pytest -q --cov