From 76310a8de8e343ddf299c42be4724cdf783c0470 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Mon, 11 May 2026 16:43:03 -0400 Subject: [PATCH] Enable inputs for setup-postgres --- .changeset/chatty-cups-exist.md | 5 ++ .github/workflows/setup-postgres-validate.yml | 55 ++++++++++++ actions/setup-postgres/README.md | 87 +++++++++++++++---- actions/setup-postgres/action.yml | 13 +++ 4 files changed, 142 insertions(+), 18 deletions(-) create mode 100644 .changeset/chatty-cups-exist.md create mode 100644 .github/workflows/setup-postgres-validate.yml diff --git a/.changeset/chatty-cups-exist.md b/.changeset/chatty-cups-exist.md new file mode 100644 index 000000000..1fc2f6382 --- /dev/null +++ b/.changeset/chatty-cups-exist.md @@ -0,0 +1,5 @@ +--- +"setup-postgres": minor +--- + +Add optional `postgres-options` input. When set, it replaces `POSTGRES_OPTIONS` for the `docker compose up` invocation so workflows can match a documented Postgres profile (for example Chainlink `tools/test` diagnose) without changing the baked-in default in `.env`. Empty value preserves previous behavior. diff --git a/.github/workflows/setup-postgres-validate.yml b/.github/workflows/setup-postgres-validate.yml new file mode 100644 index 000000000..3e2c7bf90 --- /dev/null +++ b/.github/workflows/setup-postgres-validate.yml @@ -0,0 +1,55 @@ +name: setup-postgres validate + +on: + pull_request: + paths: + - "actions/setup-postgres/**" + - ".github/workflows/setup-postgres-validate.yml" + push: + branches: + - main + paths: + - "actions/setup-postgres/**" + - ".github/workflows/setup-postgres-validate.yml" + +permissions: + contents: read + +jobs: + postgres-options: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - case: default + postgres-options: "" + want_shared_buffers: "2GB" + want_fsync: "on" + - case: override + postgres-options: '-c max_connections=50 -c shared_buffers=128MB -c fsync=off -c log_lock_waits=false' + want_shared_buffers: "128MB" + want_fsync: "off" + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Setup Postgres (${{ matrix.case }}) + uses: ./actions/setup-postgres + with: + postgres-options: ${{ matrix.postgres-options }} + + - name: Assert effective GUCs + shell: bash + working-directory: ${{ github.workspace }}/actions/setup-postgres + env: + WANT_SHARED_BUFFERS: ${{ matrix.want_shared_buffers }} + WANT_FSYNC: ${{ matrix.want_fsync }} + run: | + got_sb=$(docker exec cl_pg psql -U postgres -d chainlink_test -tAc "SHOW shared_buffers" | tr -d '[:space:]') + got_fsync=$(docker exec cl_pg psql -U postgres -d chainlink_test -tAc "SHOW fsync" | tr -d '[:space:]') + echo "shared_buffers=$got_sb (want $WANT_SHARED_BUFFERS)" + echo "fsync=$got_fsync (want $WANT_FSYNC)" + test "$got_sb" = "$WANT_SHARED_BUFFERS" + test "$got_fsync" = "$WANT_FSYNC" diff --git a/actions/setup-postgres/README.md b/actions/setup-postgres/README.md index c9ae88e94..d01715557 100644 --- a/actions/setup-postgres/README.md +++ b/actions/setup-postgres/README.md @@ -2,34 +2,85 @@ Sets up a basic postgres database for **testing** only. +## Inputs + +| Input | Default | Description | +| ------------------ | ------------------------- | ------------------------------------------------------------- | +| `image-tag` | `16-alpine` | Docker Hub `postgres` image tag. | +| `tmpfs` | `false` | Use tmpfs for Postgres data (see `docker-compose.tmpfs.yml`). | +| `print-logs` | _(unset)_ | When `true`, dump logs instead of starting the service. | +| `print-logs-path` | `${{ github.workspace }}` | Log output directory when `print-logs` is `true`. | +| `postgres-options` | `""` | See below. | + +### `postgres-options` + +- **Default (empty):** Compose uses `POSTGRES_OPTIONS` from this action’s `.env` + (same as releases before this input existed). +- **Non-empty:** That string **replaces** `POSTGRES_OPTIONS` for variable + interpolation in `docker compose up` only. Compose resolves + `${POSTGRES_OPTIONS}` in `command:` from the process environment first, so an + exported value overrides the `.env` file for the rendered command + ([variable interpolation](https://docs.docker.com/compose/how-tos/environment-variables/variable-interpolation/)). + +Exact default when the input is omitted (from `.env`): + +```text +-c max_connections=1000 -c shared_buffers=2GB -c log_lock_waits=true +``` + +Copy this into workflows or into Chainlink `tools/test` if you want CI and local +diagnose to share one profile. + +**YAML:** Prefer a single-quoted scalar so inner double quotes are literal: + +```yaml +with: + postgres-options: "-c max_connections=100 -c shared_buffers=256MB" +``` + +For long strings, use YAML block scalars; ensure the result is one `postgres` +argv string (same as you would pass after `postgres` on the shell). + +**Security:** Treat `postgres-options` as **trusted** workflow configuration +only (maintainer-controlled). Do not feed unsanitized fork PR data into it +without the usual `pull_request_target` / environment isolation precautions. + +### Parity with Chainlink diagnose + +Chainlink’s diagnose harness may start Postgres with a different `-c` bundle +than this action’s default. To align CI with diagnose, pass the **full** +intended flag string via `postgres-options` (replace semantics—no merge with +`.env`). Long term, keep **one** canonical string in maintainer docs (here +and/or Chainlink) and reference it from both GHA and `tools/test` so the +profiles do not drift. + ## Usage ### Setup Database -``` -... - - name: Setup Postgres - id: setup-postgres - uses: smartcontractkit/.github/actions/setup-postgres@ # -... - # use the database url later - env: - DB_URL: ${{ setups.setup-postgres.outputs.database-url }} +```yaml +- name: Setup Postgres + id: setup-postgres + uses: smartcontractkit/.github/actions/setup-postgres@ # + +- name: Example consumer + env: + DB_URL: ${{ steps.setup-postgres.outputs.database-url }} + run: echo "connect with $DB_URL" ``` ### Dump Logs -To be called after the database has been setup only! +To be called after the database has been setup only. Will output database logs to console, and to `postgres_logs.txt` at the provided directory (absolute path). -``` -... - - name: Print Postgres Logs - # sha must match previous call - uses: smartcontractkit/.github/actions/setup-postgres@ # - with: - print-logs: 'true' - print-logs-path: ${{ github.workspace }} +```yaml +- name: Print Postgres Logs + # sha must match previous call + uses: smartcontractkit/.github/actions/setup-postgres@ # + with: + print-logs: "true" + print-logs-path: ${{ github.workspace }} ``` diff --git a/actions/setup-postgres/action.yml b/actions/setup-postgres/action.yml index f3bf492ea..53731b943 100644 --- a/actions/setup-postgres/action.yml +++ b/actions/setup-postgres/action.yml @@ -26,6 +26,14 @@ inputs: default: "false" required: false + postgres-options: + description: | + When non-empty, replaces POSTGRES_OPTIONS for this compose run only (full + `postgres -c ...` flag string). When empty, uses POSTGRES_OPTIONS from the + action's .env (default CI profile). Must be trusted workflow input only. + default: "" + required: false + outputs: database-url: description: The URL to connect to the postgres database @@ -47,12 +55,17 @@ runs: env: IMAGE_TAG: ${{ inputs.image-tag }} USE_TMPFS: ${{ inputs.tmpfs }} + SETUP_POSTGRES_OPTIONS: ${{ inputs.postgres-options }} run: | if [ "${USE_TMPFS}" == "true" ]; then echo "Using tmpfs mount for postgres data directory" cp docker-compose.tmpfs.yml docker-compose.override.yml fi + if [ -n "${SETUP_POSTGRES_OPTIONS}" ]; then + export POSTGRES_OPTIONS="${SETUP_POSTGRES_OPTIONS}" + fi + docker compose up -d - name: Wait for postgres service to be healthy