Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/chatty-cups-exist.md
Original file line number Diff line number Diff line change
@@ -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.
55 changes: 55 additions & 0 deletions .github/workflows/setup-postgres-validate.yml
Original file line number Diff line number Diff line change
@@ -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"
87 changes: 69 additions & 18 deletions actions/setup-postgres/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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@<sha> # <version>
...
# 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@<sha> # <version>

- 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@<sha> # <version>
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@<sha> # <version>
with:
print-logs: "true"
print-logs-path: ${{ github.workspace }}
```
13 changes: 13 additions & 0 deletions actions/setup-postgres/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Loading