Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
61dbcf8
docs(test): design spec for PostgreSQL protocol testing (SP-1 + SP-2)
renecannao Jul 8, 2026
69b3675
docs(test): revise PG testing spec per review feedback
renecannao Jul 8, 2026
23c18ac
docs(test): SP-1 implementation plan — PG TAP coverage gaps
renecannao Jul 8, 2026
1d045a2
docs(test): reposition SP-1 auth tasks around PR #5865
renecannao Jul 8, 2026
519e311
docs(test): SP-2 implementation plan — polyglot PG test foundation
renecannao Jul 8, 2026
debf333
docs(test): SP-2 — dbdeployer PG support confirmed, collapse spike to…
renecannao Jul 8, 2026
8885713
test(pgsql): auth-method matrix scaffold + cleartext case
renecannao Jul 8, 2026
1bb7144
test(pgsql): harden auth-matrix helper per review
renecannao Jul 8, 2026
0a421b5
test(pgsql): pg_lite_client MD5 frontend auth + matrix md5 case
renecannao Jul 8, 2026
8751dbf
test(pgsql): pg_lite_client SCRAM-SHA-256 frontend auth + matrix scra…
renecannao Jul 8, 2026
3a51d03
fix(pgsql): free SCRAM salt buffer leaked from read_server_first_mess…
renecannao Jul 8, 2026
86d4448
test(pgsql): data-type/binary-encoding matrix (text+binary, oid+value)
renecannao Jul 8, 2026
e90633a
fix(pgsql): make datatype-matrix binary assertions verify columnForma…
renecannao Jul 8, 2026
6db3321
test(pgsql): server-side cursors (DECLARE/FETCH/MOVE) + portal suspen…
renecannao Jul 8, 2026
07c2ff7
test(pgsql): mark portal-suspension assertion TODO (ProxySQL extended…
renecannao Jul 8, 2026
a005a86
test(pgsql): pool churn + session-state isolation across reuse
renecannao Jul 8, 2026
60e6ce0
test(pgsql): make session-isolation deterministically exercise backen…
renecannao Jul 8, 2026
8a5a6c6
test(pgsql): LISTEN 0A000 rejection + NOTIFY-as-query contract (libpq…
renecannao Jul 8, 2026
5cb2abc
test(pgsql): scope pool_churn cap/restore per-hostgroup + document SC…
renecannao Jul 8, 2026
f220a70
test(pgsql): cross-reference filed issues #5899/#5900 in test comments
renecannao Jul 8, 2026
f7e04e7
spike(pg-compat): capture exact dbdeployer PostgreSQL deploy command …
renecannao Jul 8, 2026
c4926e1
spike(pg-compat): fix doc gaps from review (deb ownership step, reser…
renecannao Jul 8, 2026
c8cc4e6
infra(pg-compat): dbdeployer PG17 primary+2-replica infra with pg_sta…
renecannao Jul 8, 2026
218e552
infra(pg-compat): parameterize Dockerfile PATH on PG_VERSION + review…
renecannao Jul 8, 2026
230fbea
infra(pg-compat): Toxiproxy sidecar with per-backend passthrough proxies
renecannao Jul 8, 2026
f738a40
config(pg-compat): automatic pgsql_replication_hostgroups via Toxiproxy
renecannao Jul 8, 2026
09336ac
config(pg-compat): fail proxy-post non-zero on SQL errors (ON_ERROR_S…
renecannao Jul 8, 2026
080f783
test(pg-compat): pytest harness skeleton + admin config primitive + s…
renecannao Jul 8, 2026
b4b811f
test(pg-compat): SQL-safe quoting in Admin.set_var/snapshot
renecannao Jul 8, 2026
96316bf
test(pg-compat): 6-target differential engine + cases + divergence se…
renecannao Jul 8, 2026
a3f91dd
fix(pg-compat): line-aware case parsing + empty-case guard + pipeline…
renecannao Jul 8, 2026
fb5ce59
test(pg-compat): pg_stat_statements routing oracle + write-pin self-c…
renecannao Jul 8, 2026
5e84354
test(pg-compat): shared behavior set + Python (psycopg3) driver adapter
renecannao Jul 8, 2026
1745a9d
test(pg-compat): xfail catalogue with xpass reporting (discovery phase)
renecannao Jul 8, 2026
a95fa02
ci(pg-compat): nightly + label-gated workflow (caller + staged reusab…
renecannao Jul 8, 2026
2085044
fix(pg-compat): native-var restore in differential engine + resource/…
renecannao Jul 8, 2026
9f819e6
docs(test): SP-3 implementation plan — driver matrix expansion
renecannao Jul 8, 2026
4bd0f37
test(pg-compat): multi-language runner image + behavior CLI scaffoldi…
renecannao Jul 8, 2026
feaab3a
fix(pg-compat): sentinel-based not-implemented dispatch + SHOW encodi…
renecannao Jul 8, 2026
e0cdcea
test(pg-compat): Go/pgx behavior program (full contract)
renecannao Jul 8, 2026
da7c6a1
test(pg-compat): Java/pgjdbc behavior program (full contract)
renecannao Jul 8, 2026
4cfeaba
test(pg-compat): Node/node-postgres behavior program (full contract)
renecannao Jul 8, 2026
5295364
test(pg-compat): Prisma behavior program (ORM tier, findings catalogued)
renecannao Jul 8, 2026
d167731
fix(pg-compat): pin client_encoding in Prisma URL (Task 5 review) + d…
renecannao Jul 8, 2026
45b34d0
docs(pg-compat): SP-3 driver matrix docs + spec sync (+ CI budget evi…
renecannao Jul 8, 2026
acd6f0b
docs(pg-compat): correct pgx Parse-once semantics in table + source c…
renecannao Jul 8, 2026
4db6cb4
docs(pg-compat): fix stale plan path in three driver headers (final r…
renecannao Jul 8, 2026
dde05c6
fix(tap): link libscram into all pg_lite_client consumers (CI build fix)
renecannao Jul 8, 2026
db359ee
Merge branch 'test/pgsql-protocol-testing-design' into test/pgsql-sp2…
renecannao Jul 8, 2026
8d2f338
Merge branch 'test/pgsql-sp2-polyglot-foundation' into test/pgsql-sp3…
renecannao Jul 8, 2026
f26787b
test(pg-compat): review follow-ups — Go cleanup parity, connect encod…
renecannao Jul 8, 2026
04cce6b
Merge remote-tracking branch 'origin/v3.0' into test/pgsql-protocol-t…
renecannao Jul 10, 2026
8859ee4
Merge branch 'test/pgsql-protocol-testing-design' into test/pgsql-sp2…
renecannao Jul 10, 2026
26fc586
Merge branch 'test/pgsql-sp2-polyglot-foundation' into test/pgsql-sp3…
renecannao Jul 10, 2026
0be6b4b
fix(pg-compat): compile Java behaviors with --release 17 (runtime com…
renecannao Jul 10, 2026
79438d0
Merge remote-tracking branch 'origin/v3.0' into test/pgsql-protocol-t…
renecannao Jul 10, 2026
c1fb385
Merge branch 'test/pgsql-protocol-testing-design' into test/pgsql-sp2…
renecannao Jul 10, 2026
ba207ea
Merge branch 'test/pgsql-sp2-polyglot-foundation' into test/pgsql-sp3…
renecannao Jul 10, 2026
a9e0a67
Merge PRs #5894, #5903, #5910 (PG protocol/compat test stack SP-1..SP…
renecannao Aug 10, 2026
f66297e
fix(test/pgsql): harden pg_lite_client auth parsing and the PG TAP as…
renecannao Aug 10, 2026
97128b1
fix(test/pg-compat): glob target filters, transaction cleanup, subpro…
renecannao Aug 10, 2026
38a13fb
fix(ci,infra): pin pgjdbc by digest, bound the admin wait, drop persi…
renecannao Aug 10, 2026
310e9c2
docs(plans): sync SP-1/SP-2 plans with the implemented contracts
renecannao Aug 10, 2026
8ef2264
fix(pg-compat): resolve SonarCloud security findings on new code
renecannao Aug 10, 2026
8de370b
fix(pg-compat): hash-lock the Python dependency tree
renecannao Aug 10, 2026
afac510
fix: address CodeRabbit, gitar-bot and codex review findings
renecannao Aug 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/CI-pg-compat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# PAIRED FILE -- caller half of the CI-pg-compat pair (lives on v3.0). The
# reusable half, .github/workflows/gh-actions-reusable/ci-pg-compat.yml, is
# staged in THIS repo for review but must be merged to the `GH-Actions`
# branch FIRST, at path `.github/workflows/ci-pg-compat.yml`, before (never
# after) this caller file merges to v3.0 -- see doc/GH-Actions/README.md
# "Merge order" (~line 816): `workflow_run`/`workflow_call` references are
# only resolved against files that already exist on the target branch, so a
# caller landing before its reusable exists on GH-Actions fails immediately
# with "Unable to resolve action". See doc/GH-Actions/README.md (~lines
# 42-170) for the full two-branch caller/reusable split rationale.
name: CI-pg-compat

on:
schedule:
- cron: '0 3 * * *'
pull_request:
types: [opened, synchronize, reopened, labeled]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref_name }}
cancel-in-progress: true

jobs:
pg-compat:
# Runs on: the nightly schedule, a manual dispatch, or a pull_request
# that carries the 'pg-compat' label (checked on every listed pull_request
# type, including 'labeled', so adding the label to an already-open PR
# triggers a run without needing a new commit). Unlike the TAP families,
# this does NOT chain off CI-trigger/CI-builds -- it builds ProxySQL
# inline in the reusable job, so it doesn't need CI-builds' cache to
# exist first (nightly/label runs have no guaranteed prior CI-builds run
# to restore from).
if: >-
github.event_name == 'schedule' ||
github.event_name == 'workflow_dispatch' ||
contains(github.event.pull_request.labels.*.name, 'pg-compat')
# write-all: reusable-workflow permissions are the intersection of
# caller + callee: the callee at ci-pg-compat.yml@GH-Actions also
# declares write-all (needed for actions/upload-artifact's write scope
# under the pull_request event, matching CI-3p-postgresql.yml's
# documented rationale).
permissions: write-all # NOSONAR githubactions:S8234 — see the note above; matches all other caller workflows
uses: sysown/proxysql/.github/workflows/ci-pg-compat.yml@GH-Actions # NOSONAR githubactions:S7637 — branch ref matches all other caller workflows
secrets: inherit # NOSONAR githubactions:S7635 — matches all other caller workflows
Comment on lines +43 to +45

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

caller='.github/workflows/CI-pg-compat.yml'
callee='.github/workflows/gh-actions-reusable/ci-pg-compat.yml'

# Inspect the caller and reusable workflow capability requirements.
rg -n -C 3 'permissions:|secrets:|uses:|upload-artifact|GITHUB_TOKEN|secrets\.' \
  "$caller" "$callee"

Repository: sysown/proxysql

Length of output: 3760


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow event/header lines =="
sed -n '1,55p' .github/workflows/CI-pg-compat.yml
echo

echo "== reusable workflow headers and relevant capability usage =="
sed -n '1,130p' .github/work S7637 — branch ref matches all other caller workflows.

Repository: sysown/proxysql

Length of output: 3222


🏁 Script executed:

#!/bin/bash
set -euo pipefail

caller='.github/workflows/CI-pg-compat.yml'
callee='.github/workflows/gh-actions-reusable/ci-pg-compat.yml'

echo "== caller top =="
sed -n '1,60p' "$caller"
echo

echo "== reusable top and permissions/secrets/token access =="
sed -n '1,160p' "$callee" | awk '
  /^  permissions:/ || /^    permissions:/ || /^permissions:/ || /^secrets:/ || /GITHUB_TOKEN|secrets\./ {print NR": "$0}
'

Repository: sysown/proxysql

Length of output: 2732


🌐 Web query:

GitHub Actions reusable workflows permissions inherit secrets inherit writable-GITHUB_TOKEN permission

💡 Result:

In GitHub Actions, you can manage secrets and GITHUB_TOKEN permissions for reusable workflows using specific configurations to ensure secure and efficient automation. Secrets To pass secrets from a caller workflow to a reusable workflow, you can use the secrets: inherit keyword [1][2]. When you use this keyword, all secrets defined at the repository or organization level in the caller's environment become available to the called workflow [3]. This simplifies the process compared to passing secrets individually [2]. Note that environment secrets cannot be passed via workflow_call; if you define an environment in a job within the reusable workflow, that environment's secrets will be used instead [4][5]. GITHUB_TOKEN Permissions Permissions for the GITHUB_TOKEN are governed by the following rules: 1. Default Permissions: If you do not explicitly define the permissions key in the caller job, the called reusable workflow will operate with the default GITHUB_TOKEN permissions [6][7]. 2. Downgrading Only: Permissions for the GITHUB_TOKEN passed from a caller workflow to a reusable workflow can only be downgraded, never elevated [6][7]. For example, if a chain of workflows exists (A > B > C), workflow B and C cannot have higher permissions than workflow A [7][8]. 3. Explicit Configuration: It is considered a best practice to explicitly define the permissions key at the workflow or job level in the calling workflow to ensure the reusable workflow has only the minimum access required [3][7][9]. Summary You do not need an explicit inherit keyword for permissions as you do for secrets; permissions are naturally constrained by the caller [6][7]. By using secrets: inherit and explicitly setting restrictive permissions in your caller job, you can effectively control the access level of your reusable workflows [10][3].

Citations:


Reduce the reusable workflow trust boundary.

This caller exposes write-all GitHub permissions and all caller secrets to sysown/proxysql/.github/workflows/ci-pg-compat.yml@GH-Actions, which is a mutable branch ref. If an update to that branch is accepted, it can run with these capabilities from the scheduled and manual dispatch paths. Pin the workflow to a reviewed full commit SHA, define only the required permissions, and pass only the named secrets the reusable job needs.

🧰 Tools
🪛 zizmor (1.29.0)

[error] 43-43: overly broad permissions (excessive-permissions): uses write-all permissions

(excessive-permissions)


[warning] 44-44: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow

(secrets-inherit)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/CI-pg-compat.yml around lines 43 - 45, Update the reusable
workflow invocation in the CI pg compatibility workflow: replace the mutable
GH-Actions ref with a reviewed full commit SHA, replace permissions: write-all
with only the required permission keys, and replace secrets: inherit with
explicit named secrets required by ci-pg-compat.yml. Preserve the scheduled and
manual dispatch behavior.

Source: Linters/SAST tools

with:
trigger: ${{ toJson(github) }}
165 changes: 165 additions & 0 deletions .github/workflows/gh-actions-reusable/ci-pg-compat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# STAGED FILE -- this is the reusable half of the CI-pg-compat pair.
# It is authored here (on v3.0, under gh-actions-reusable/) for review, but
# it does NOT run from here. It must be merged to the `GH-Actions` branch
# at path `.github/workflows/ci-pg-compat.yml` FIRST, before (or in the same
# merge window as, but not after) the caller `.github/workflows/CI-pg-compat.yml`
# lands on `v3.0` -- see doc/GH-Actions/README.md "Merge order" (~line 816):
# a caller referencing `ci-pg-compat.yml@GH-Actions` before that file exists
# on GH-Actions fails immediately with "Unable to resolve action". See the
# two-branch caller/reusable split explained in doc/GH-Actions/README.md
# (~lines 42-170): callers (`CI-*.yml`, uppercase) live on `v3.0`; reusables
# (`ci-*.yml`, lowercase) live on `GH-Actions`.
name: CI-pg-compat

on:
workflow_dispatch:
workflow_call:
inputs:
trigger:
type: string

# No env.SHA/trigger-JSON parsing here (unlike the workflow_run-triggered
# reusables, e.g. ci-legacy-g4.yml): those need it because their caller is
# invoked BY workflow_run, whose own github.sha is the default branch tip,
# not the real source commit -- the real sha only exists inside the passed
# `trigger` JSON. This caller triggers directly via pull_request/schedule/
# workflow_dispatch, so github.sha here (a workflow_call callee inherits the
# caller's context) already IS the right commit; `inputs.trigger` is kept
# only for parity with the sibling callers' `with: trigger: ...` shape and
# isn't parsed for a sha. checkout below uses actions/checkout@v4's default
# ref (the triggering ref), so no untrusted github.event.* field is ever
# substituted into a `ref:`.

jobs:
pg-compat:
runs-on: ubuntu-22.04
# Generous budget: a from-scratch `PROXYSQL31=1 make debug` (deps -> lib
# -> src) on a 2-core GH-hosted runner is the dominant cost here (there
# is no build-cache restore in this job, unlike the CI-builds-fed TAP
# families -- this suite runs inline, like the CI-3p-* family, since its
# schedule/label triggers have no guaranteed prior CI-builds run to
# restore a cache from).
timeout-minutes: 120
permissions: write-all
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# This job only builds and tests; it never pushes. Leaving the job's
# write-all token persisted in .git/config would expose it to every
# subsequent step, including the third-party driver images this suite
# builds and runs.
persist-credentials: false

# Inline build (CI-3p-* model, not the CI-trigger/CI-builds cache-chain
# model used by the TAP families): no ccache pattern exists elsewhere
# in this repo's workflows (checked both branches) to reuse, so this
# is a plain build for v1. PROXYSQL31=1 is required -- bare `make`
# would leave FFTO/TSDB symbols out and is not what any tier actually
# ships; debug is required because the isolated harness
# (start-proxysql-isolated.bash / ensure-infras.bash) issues
# debug-only admin commands.
- name: Build ProxySQL (debug, PROXYSQL31)
run: PROXYSQL31=1 make -j$(nproc) debug
Comment on lines +62 to +63

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Build the CI toolbelt image before starting infrastructure

On a fresh ubuntu-22.04 runner, this step produces only the ProxySQL binary, but the following ensure-infras.bash call reaches start-proxysql-isolated.bash, which runs both filesystem helpers and ProxySQL itself from the local-only tag proxysql-ci-base:latest. The repository's infra README says this image must be built locally, and the inspected ci-legacy-g4.yml workflow explicitly builds it before calling the same helper; without an equivalent build/tag step here, infrastructure startup fails before any pg-compat tests run.

Useful? React with 👍 / 👎.


# start-proxysql-isolated.bash runs ProxySQL (and its filesystem helpers)
# from the LOCAL-ONLY tag `proxysql-ci-base:latest`, which nothing on a
# fresh runner provides -- without this step infra startup dies before a
# single pg-compat test runs. Every sibling TAP workflow pulls the image
# from GHCR and retags it; this mirrors ci-legacy-g4.yml, retry loop
# included, because both the login and the pull have been observed to
# fail transiently with a client timeout.
- name: Log in to GHCR and pull CI base image
env:
GHCR_USER: ${{ github.actor }}
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set +e
attempt=0
max_attempts=5
while [ $attempt -lt $max_attempts ]; do
attempt=$((attempt + 1))
echo ">>> GHCR login+pull attempt ${attempt}/${max_attempts}"
if echo "$GHCR_TOKEN" | docker login ghcr.io \
-u "$GHCR_USER" --password-stdin \
&& docker pull ghcr.io/sysown/proxysql-ci-base:latest; then
echo ">>> GHCR login+pull OK on attempt ${attempt}"
docker tag ghcr.io/sysown/proxysql-ci-base:latest \
proxysql-ci-base:latest
exit 0
fi
if [ $attempt -lt $max_attempts ]; then
sleep_for=$((attempt * 10))
echo ">>> attempt ${attempt} failed; sleeping ${sleep_for}s"
sleep $sleep_for
fi
done
echo ">>> all ${max_attempts} GHCR attempts failed"
exit 1

# Stand up the pg-compat infra: dbdeployer PG17 primary+2-replica
# backend, Toxiproxy sidecar, and the ProxySQL container built above
# (ensure-infras.bash starts ProxySQL itself via
# start-proxysql-isolated.bash if it isn't already running -- see
# test/infra/control/ensure-infras.bash step 2). Never manage Docker
# by hand here; this script is the only supported entry point.
- name: Stand up infra (backends + Toxiproxy + ProxySQL)
env:
INFRA_ID: ci-${{ github.run_id }}
WORKSPACE: ${{ github.workspace }}
TAP_GROUP: pg-compat
run: test/infra/control/ensure-infras.bash

# Non-gating (discovery phase, spec sec 2.1): the suite's job right now
# is to build a failure inventory in xfail.toml, not to be all-green.
# `|| true` keeps this step (and therefore the job) from failing the
# workflow on real/uncatalogued divergences during discovery. Promote
# to gating by dropping `|| true` (and tightening xfail.toml) once the
# suite is green and stable -- see test/pg-compat/README.md.
#
# --junitxml path: run-pg-compat.bash's container runs with --rm, so a
# report written to the container's own filesystem (e.g. /tmp) would
# be destroyed on exit and never reach this runner -- traced and fixed
# in run-pg-compat.bash, which now bind-mounts a host directory
# (default "${WORKSPACE}/pg-compat-reports", override via
# PGCOMPAT_REPORT_DIR) to /pg-compat-reports inside the container.
# Writing the report there is what makes it visible to the upload
# step below.
- name: Run pg-compat suite (non-gating, discovery phase)
env:
INFRA_ID: ci-${{ github.run_id }}
WORKSPACE: ${{ github.workspace }}
run: test/pg-compat/run-pg-compat.bash --junitxml=/pg-compat-reports/pg-compat.xml -rxX || true

# The pg-compat container's default user is root, so the bind-mounted
# report directory is root-owned on the host afterwards; chown it back
# to the runner user before upload-artifact (which runs as the
# non-root runner account) tries to read it. Same pattern already
# used for docker-written logs in ci-3p-postgresql.yml.
- name: Fix report ownership
if: always()
run: sudo chown -R "$(id -u):$(id -g)" "${{ github.workspace }}/pg-compat-reports" || true

- name: Publish report
if: always()
uses: actions/upload-artifact@v4
with:
name: pg-compat-report
path: ${{ github.workspace }}/pg-compat-reports/pg-compat.xml
if-no-files-found: warn

# Teardown always runs, mirroring ci-legacy-g4.yml's cleanup step:
# stop the ProxySQL container first, then tear down the backend +
# Toxiproxy infra. destroy-infras.bash is test/infra/control's
# documented teardown entry point (paired with ensure-infras.bash).
- name: Cleanup
if: always()
env:
INFRA_ID: ci-${{ github.run_id }}
WORKSPACE: ${{ github.workspace }}
TAP_GROUP: pg-compat
run: |
set +e
docker logs "proxysql.${INFRA_ID}" 2>&1 | tail -50 || true
test/infra/control/stop-proxysql-isolated.bash
test/infra/control/destroy-infras.bash
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ test/tap/tests/parsersql_digest_test
test/tap/tests/setparser_parsersql_test
deps/protobuf/protobuf-*/

# pg-compat report output (run-pg-compat.bash's default host bind-mount
# target; see test/pg-compat/README.md "Report output")
/pg-compat-reports/

# Stray build artifact: run-tests-isolated.bash creates the real mysqlbinlog
# symlink at runtime under test-scripts/deps/; never commit this one (it was
# accidentally committed once with an absolute /home path).
Expand Down
Loading
Loading