From d7b4b9f50b9ee055d6f161c892782571144710ef Mon Sep 17 00:00:00 2001 From: Mark Merritt Date: Thu, 14 May 2026 20:40:54 -0700 Subject: [PATCH 1/4] add start-postgres composite action Installs postgres directly on the runner via apt-get and starts it on localhost:5432 with trust auth. Drop-in for `services: { postgres: ... }` on ARC runners (where the docker daemon isn't available). Inputs: version (default 16), database (optional createdb), password (optional, only if client code wants a literal). --- .github/actions/start-postgres/action.yaml | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/actions/start-postgres/action.yaml diff --git a/.github/actions/start-postgres/action.yaml b/.github/actions/start-postgres/action.yaml new file mode 100644 index 0000000..dc38b78 --- /dev/null +++ b/.github/actions/start-postgres/action.yaml @@ -0,0 +1,44 @@ +name: "start-postgres" +description: > + Install postgres directly on the runner (no docker daemon required) and + start it on localhost:5432 with trust auth. Designed for ARC runners + where GitHub Actions `services:` blocks don't work because there's no + docker daemon. Equivalent drop-in for `services: { postgres: { image: + postgres:N } }`. + +inputs: + version: + description: "postgres major version, e.g. 14, 15, 16, 17" + required: false + default: "16" + database: + description: "Optional database to createdb after starting" + required: false + default: "" + password: + description: > + Optional password for the postgres superuser. Only needed if your + client code expects a literal password value — server-side auth is + `trust` so the password is not validated on connect. + required: false + default: "" + +runs: + using: composite + steps: + - name: install + start postgres ${{ inputs.version }} + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y postgresql-${{ inputs.version }} + sudo -u postgres /usr/lib/postgresql/${{ inputs.version }}/bin/initdb \ + -D /tmp/pgdata --auth=trust + sudo -u postgres /usr/lib/postgresql/${{ inputs.version }}/bin/pg_ctl \ + -D /tmp/pgdata -l /tmp/pg.log -o "-p 5432" start + if [[ -n "${{ inputs.password }}" ]]; then + sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '${{ inputs.password }}'" + fi + if [[ -n "${{ inputs.database }}" ]]; then + sudo -u postgres createdb "${{ inputs.database }}" + fi + until pg_isready -h localhost -p 5432; do sleep 0.2; done From b6da93deceb4a2e4c718b1d1b7f39efbb2e0104e Mon Sep 17 00:00:00 2001 From: Mark Merritt Date: Mon, 1 Jun 2026 16:00:39 -0700 Subject: [PATCH 2/4] Harden start-postgres action --- .github/actions/start-postgres/action.yaml | 43 +++++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/.github/actions/start-postgres/action.yaml b/.github/actions/start-postgres/action.yaml index dc38b78..952bdea 100644 --- a/.github/actions/start-postgres/action.yaml +++ b/.github/actions/start-postgres/action.yaml @@ -28,17 +28,40 @@ runs: steps: - name: install + start postgres ${{ inputs.version }} shell: bash + env: + POSTGRES_VERSION: ${{ inputs.version }} + POSTGRES_DATABASE: ${{ inputs.database }} + POSTGRES_PASSWORD: ${{ inputs.password }} run: | + set -euo pipefail + + pg_bin="/usr/lib/postgresql/${POSTGRES_VERSION}/bin" + pg_data="$(mktemp -d /tmp/start-postgres.XXXXXX)" + pg_log="$(mktemp /tmp/start-postgres.XXXXXX.log)" + sudo apt-get update - sudo apt-get install -y postgresql-${{ inputs.version }} - sudo -u postgres /usr/lib/postgresql/${{ inputs.version }}/bin/initdb \ - -D /tmp/pgdata --auth=trust - sudo -u postgres /usr/lib/postgresql/${{ inputs.version }}/bin/pg_ctl \ - -D /tmp/pgdata -l /tmp/pg.log -o "-p 5432" start - if [[ -n "${{ inputs.password }}" ]]; then - sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '${{ inputs.password }}'" + sudo apt-get install -y "postgresql-${POSTGRES_VERSION}" + sudo -u postgres "$pg_bin/initdb" \ + -D "$pg_data" --auth=trust + sudo -u postgres "$pg_bin/pg_ctl" \ + -D "$pg_data" -l "$pg_log" -o "-p 5432" start + for _ in $(seq 1 150); do + if "$pg_bin/pg_isready" -h localhost -p 5432 >/dev/null 2>&1; then + break + fi + sleep 0.2 + done + if ! "$pg_bin/pg_isready" -h localhost -p 5432 >/dev/null 2>&1; then + echo "postgres failed to become ready; startup log:" >&2 + sed 's/^/ /' "$pg_log" >&2 + exit 1 + fi + if [[ -n "$POSTGRES_PASSWORD" ]]; then + sudo -u postgres "$pg_bin/psql" \ + --set=password="$POSTGRES_PASSWORD" \ + -v ON_ERROR_STOP=1 \ + -c "ALTER USER postgres WITH PASSWORD :'password'" fi - if [[ -n "${{ inputs.database }}" ]]; then - sudo -u postgres createdb "${{ inputs.database }}" + if [[ -n "$POSTGRES_DATABASE" ]]; then + sudo -u postgres "$pg_bin/createdb" -- "$POSTGRES_DATABASE" fi - until pg_isready -h localhost -p 5432; do sleep 0.2; done From f349699f4ae60d1a4c98dfc6d072870c54799ebb Mon Sep 17 00:00:00 2001 From: Mark Merritt Date: Mon, 1 Jun 2026 16:03:28 -0700 Subject: [PATCH 3/4] Fix postgres data directory ownership --- .github/actions/start-postgres/action.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/start-postgres/action.yaml b/.github/actions/start-postgres/action.yaml index 952bdea..67cc49c 100644 --- a/.github/actions/start-postgres/action.yaml +++ b/.github/actions/start-postgres/action.yaml @@ -37,7 +37,8 @@ runs: pg_bin="/usr/lib/postgresql/${POSTGRES_VERSION}/bin" pg_data="$(mktemp -d /tmp/start-postgres.XXXXXX)" - pg_log="$(mktemp /tmp/start-postgres.XXXXXX.log)" + sudo chown postgres:postgres "$pg_data" + pg_log="$pg_data/postgres.log" sudo apt-get update sudo apt-get install -y "postgresql-${POSTGRES_VERSION}" From 33f5d96543c1eed0e32c13b1bb3353f88255a8de Mon Sep 17 00:00:00 2001 From: Mark Merritt Date: Mon, 1 Jun 2026 16:04:13 -0700 Subject: [PATCH 4/4] Escape postgres password safely --- .github/actions/start-postgres/action.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/start-postgres/action.yaml b/.github/actions/start-postgres/action.yaml index 67cc49c..d615248 100644 --- a/.github/actions/start-postgres/action.yaml +++ b/.github/actions/start-postgres/action.yaml @@ -58,10 +58,10 @@ runs: exit 1 fi if [[ -n "$POSTGRES_PASSWORD" ]]; then + escaped_password=${POSTGRES_PASSWORD//\'/\'\'} sudo -u postgres "$pg_bin/psql" \ - --set=password="$POSTGRES_PASSWORD" \ -v ON_ERROR_STOP=1 \ - -c "ALTER USER postgres WITH PASSWORD :'password'" + -c "ALTER USER postgres WITH PASSWORD '$escaped_password'" fi if [[ -n "$POSTGRES_DATABASE" ]]; then sudo -u postgres "$pg_bin/createdb" -- "$POSTGRES_DATABASE"