Skip to content

Commit b5b4c34

Browse files
ikalnytskyimalorrkiyanchuk
committed
Add 'postgres-version' input parameter
One of the foundational principles of this action was to use GitHub runners preinstalled PostgreSQL binaries. The rationale was simple: * Make sure the action is fast and no installation is required. * Make sure it's safe and doesn't reach out to external servers. * Make sure the action is easy to audit. Unfortunately, those foundational principles aren't working well anymore due to the following reasons: * Ubuntu 24.04 is shipped with PostgreSQL 16, while other runners ship PostgreSQL 14. It's not nice when different versions are used on different runners. * macOS 13 & 14 runners are no longer shipped with preinstalled PostgreSQL, which means we have to install the server. * Many FOSS users are attracted by using the most recent PostgreSQL, and not stuck with few years old release. This patch adds a new `postgres-version` input parameter that controls what major version of PostgreSQL to install. Please note, the parameter receives only major part of the version, e.g. "14'. It's impossible to request any minor release. Co-Authored-By: Roman Podoliaka <[email protected]> Co-Authored-By: Ruslan Kiyanchuk <[email protected]> Resolves: #14
1 parent 4f88640 commit b5b4c34

File tree

4 files changed

+89
-38
lines changed

4 files changed

+89
-38
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
pull_request:
77
branches: [ master ]
88
schedule:
9-
- cron: "0 8 * * *"
9+
- cron: "0 0 * * Fri"
1010

1111
defaults:
1212
run:
@@ -23,7 +23,7 @@ jobs:
2323
- ubuntu-24.04
2424
- macos-12
2525
- macos-13
26-
- macos-14 # M1 CPU
26+
- macos-14
2727
- windows-2019
2828
- windows-2022
2929
steps:
@@ -47,15 +47,24 @@ jobs:
4747
SERVICE_NAME: ${{ steps.postgres.outputs.service-name }}
4848
EXPECTED_CONNECTION_URI: postgresql://postgres:postgres@localhost:5432/postgres
4949
EXPECTED_SERVICE_NAME: postgres
50+
EXPECTED_SERVER_VERSION: "16"
5051

5152
parametrized:
5253
runs-on: ${{ matrix.os }}
5354
strategy:
5455
matrix:
5556
os:
56-
- ubuntu-latest
57-
- macos-latest
58-
- windows-latest
57+
- ubuntu-20.04
58+
- ubuntu-22.04
59+
- ubuntu-24.04
60+
- macos-12
61+
- macos-13
62+
- macos-14
63+
- windows-2019
64+
- windows-2022
65+
postgres-version:
66+
- "14"
67+
- "15"
5968
steps:
6069
- uses: actions/checkout@v4
6170

@@ -66,6 +75,7 @@ jobs:
6675
password: GrandMaster
6776
database: jedi_order
6877
port: 34837
78+
postgres-version: ${{ matrix.postgres-version }}
6979
id: postgres
7080

7181
- name: Run setup-python
@@ -82,3 +92,4 @@ jobs:
8292
SERVICE_NAME: ${{ steps.postgres.outputs.service-name }}
8393
EXPECTED_CONNECTION_URI: postgresql://yoda:GrandMaster@localhost:34837/jedi_order
8494
EXPECTED_SERVICE_NAME: yoda
95+
EXPECTED_SERVER_VERSION: ${{ matrix.postgres-version }}

README.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ key features:
99

1010
* Runs on Linux, macOS and Windows action runners.
1111
* Adds PostgreSQL [client applications][1] to `PATH`.
12-
* Uses PostgreSQL binaries baked into [GitHub Actions Runner Images][2].
13-
* Easy [to prove][3] that it DOES NOT contain malicious code.
12+
* PostgreSQL version can be parametrized.
13+
* Easy [to verify][2] that it DOES NOT contain malicious code.
14+
15+
By default PostgreSQL 15 is used.
1416

1517
[1]: https://www.postgresql.org/docs/current/reference-client.html
16-
[2]: https://github.com/actions/runner-images
17-
[3]: action.yml
18+
[2]: action.yml
1819

1920
## Usage
2021

@@ -33,12 +34,13 @@ key features:
3334
3435
#### Action Parameters
3536

36-
| Key | Value | Default |
37-
|------------|------------------------------------------------------------------------------------------------------|-------------|
38-
| username | The username of the user to setup. | `postgres` |
39-
| password | The password of the user to setup. | `postgres` |
40-
| database | The database name to setup and grant permissions to created user. | `postgres` |
41-
| port | The server port to listen on. | `5432` |
37+
| Key | Value | Default |
38+
|------------------|------------------------------------------------------------------------------------|-------------|
39+
| username | The username of the user to setup. | `postgres` |
40+
| password | The password of the user to setup. | `postgres` |
41+
| database | The database name to setup and grant permissions to created user. | `postgres` |
42+
| port | The server port to listen on. | `5432` |
43+
| postgres-version | The PostgreSQL major version to install. Supported values: "14", "15", "16". | `16` |
4244

4345
#### Outputs
4446

@@ -58,19 +60,20 @@ key features:
5860

5961
```yaml
6062
steps:
61-
- uses: ikalnytskyi/action-setup-postgres@v6
63+
- uses: ikalnytskyi/action-setup-postgres@v6
6264
```
6365
6466
#### Advanced
6567
6668
```yaml
6769
steps:
68-
- uses: ikalnytskyi/action-setup-postgres@v6
70+
- uses: ikalnytskyi/action-setup-postgres@v6
6971
with:
7072
username: ci
7173
password: sw0rdfish
7274
database: test
7375
port: 34837
76+
postgres-version: "14"
7477
id: postgres
7578

7679
- run: pytest -vv tests/
@@ -88,7 +91,7 @@ steps:
8891
8992
```yaml
9093
steps:
91-
- uses: ikalnytskyi/action-setup-postgres@v6
94+
- uses: ikalnytskyi/action-setup-postgres@v6
9295

9396
- run: |
9497
createuser myuser
@@ -110,7 +113,7 @@ steps:
110113
111114
```yaml
112115
steps:
113-
- uses: ikalnytskyi/action-setup-postgres@v6
116+
- uses: ikalnytskyi/action-setup-postgres@v6
114117
```
115118
116119
```python

action.yml

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ inputs:
2121
description: The server port to listen on.
2222
default: "5432"
2323
required: false
24+
postgres-version:
25+
description: The PostgreSQL major version to install. Either "14", "15", or "16".
26+
default: "16"
27+
required: false
2428
outputs:
2529
connection-uri:
2630
description: The connection URI to connect to PostgreSQL.
@@ -31,38 +35,63 @@ outputs:
3135
runs:
3236
using: composite
3337
steps:
34-
- name: Prerequisites
38+
- name: Install PostgreSQL
3539
run: |
40+
if [[ ! "${{ inputs.postgres-version }}" =~ ^(14|15|16)$ ]]; then
41+
echo "::error::postgres-version must be one of: 14, 15, 16."
42+
exit 1
43+
fi
44+
3645
if [ "$RUNNER_OS" == "Linux" ]; then
37-
echo "$(pg_config --bindir)" >> $GITHUB_PATH
38-
elif [ "$RUNNER_OS" == "Windows" ]; then
39-
echo "$PGBIN" >> $GITHUB_PATH
40-
echo "PQ_LIB_DIR=$PGROOT\lib" >> $GITHUB_ENV
46+
APT_ENTRY="deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main"
47+
APT_KEY="https://www.postgresql.org/media/keys/ACCC4CF8.asc"
48+
49+
echo "$APT_ENTRY" | sudo tee /etc/apt/sources.list.d/pgdg.list
50+
wget --quiet -O - "$APT_KEY" | sudo apt-key add -
51+
sudo apt-get update
52+
sudo apt-get -y install postgresql-${{ inputs.postgres-version }}
53+
54+
PG_BINDIR=$("/usr/lib/postgresql/${{ inputs.postgres-version }}/bin/pg_config" --bindir)
55+
echo "$PG_BINDIR" >> $GITHUB_PATH
4156
57+
elif [ "$RUNNER_OS" == "Windows" ]; then
4258
# The Windows runner has some PostgreSQL environment variables set
4359
# that may confuse users since they may be irrelevant to the
44-
# PostgreSQL server we're using.
60+
# PostgreSQL server we're using. Since GitHub actions does not
61+
# support unsetting environment variables, the best we can do is to
62+
# clear their values in order to indicate they must not be used.
4563
for name in "PGROOT" "PGDATA" "PGBIN" "PGUSER" "PGPASSWORD"; do
4664
echo "$name=" >> $GITHUB_ENV
4765
done
66+
67+
choco install postgresql${{ inputs.postgres-version }} \
68+
--params "/Password:${{ inputs.password }}" \
69+
--ia "--enable-components server,commandlinetools --extract-only 1" \
70+
--no-progress
71+
72+
PG_BINDIR=$("$PROGRAMFILES/PostgreSQL/${{ inputs.postgres-version }}/bin/pg_config.exe" --bindir)
73+
PG_LIBDIR=$("$PROGRAMFILES/PostgreSQL/${{ inputs.postgres-version }}/bin/pg_config.exe" --libdir)
74+
75+
echo "$PG_BINDIR" >> $GITHUB_PATH
76+
echo "PQ_LIB_DIR=$PG_LIBDIR" >> $GITHUB_ENV
77+
4878
elif [ "$RUNNER_OS" == "macOS" ]; then
49-
case "$(sw_vers -productVersion)" in
50-
13.*|14.*)
51-
# Unfortunately, the macOS 13 runner image doesn't come w/
52-
# pre-installed PostgreSQL server.
53-
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
54-
export HOMEBREW_NO_INSTALL_CLEANUP=1
55-
export HOMEBREW_NO_INSTALL_UPGRADE=1
56-
brew install --skip-post-install postgresql@14
57-
;;
58-
esac
79+
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
80+
export HOMEBREW_NO_INSTALL_CLEANUP=1
81+
export HOMEBREW_NO_INSTALL_UPGRADE=1
82+
brew install --skip-post-install postgresql@${{ inputs.postgres-version }}
83+
84+
# Link PostgreSQL binaries from /usr/local/bin in order to make them
85+
# available globally. The overwrite option is required since some
86+
# GitHub runners come with preinstalled PostgreSQL binaries.
87+
brew link --overwrite postgresql@${{ inputs.postgres-version }}
5988
fi
6089
shell: bash
6190

6291
- name: Setup and start PostgreSQL
6392
run: |
64-
export PGDATA="$RUNNER_TEMP/pgdata"
65-
export PWFILE="$RUNNER_TEMP/pwfile"
93+
PGDATA="$RUNNER_TEMP/pgdata"
94+
PWFILE="$RUNNER_TEMP/pwfile"
6695
6796
DEFAULT_ENCODING="UTF-8"
6897
DEFAULT_LOCALE="en_US.$DEFAULT_ENCODING"
@@ -91,6 +120,7 @@ runs:
91120
#
92121
# [1] https://www.postgresql.org/docs/15/reference-client.html
93122
initdb \
123+
--pgdata="$PGDATA" \
94124
--username="${{ inputs.username }}" \
95125
--pwfile="$PWFILE" \
96126
--auth="scram-sha-256" \
@@ -102,7 +132,7 @@ runs:
102132
# directory we have no permissions to (owned by system postgres user).
103133
echo "unix_socket_directories = ''" >> "$PGDATA/postgresql.conf"
104134
echo "port = ${{ inputs.port }}" >> "$PGDATA/postgresql.conf"
105-
pg_ctl start
135+
pg_ctl start --pgdata="$PGDATA"
106136
107137
# Save required connection parameters for created superuser to the
108138
# connection service file [1]. This allows using these connection

test_action.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ def test_environment_variables(is_windows: bool):
140140
assert pg_environ == pg_environ_exp
141141

142142

143+
def test_server_version(connection: psycopg.Connection):
144+
"""Test that PostgreSQL's version is expected."""
145+
146+
server_version = connection.execute("SHOW SERVER_VERSION").fetchone()[0]
147+
assert server_version.split(".")[0] == os.getenv("EXPECTED_SERVER_VERSION")
148+
149+
143150
def test_user_permissions(connection: psycopg.Connection):
144151
"""Test that a user has super/createdb permissions."""
145152

0 commit comments

Comments
 (0)