Skip to content

Commit 6bb2488

Browse files
ikalnytskyimalorrkiyanchuk
committed
Add 'postgres-version' input parameter
One of the foundational principles of this action was to use 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 it's auditable and everyone can verify it contains no malicious code. It's quite common, however, for applications to follow upstream PostgreSQL releases and switch to them as soon as possible. This applications look to install the latest stable version instead. 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 6bb2488

File tree

4 files changed

+79
-18
lines changed

4 files changed

+79
-18
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ 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 }}
@@ -56,6 +57,10 @@ jobs:
5657
- ubuntu-latest
5758
- macos-latest
5859
- windows-latest
60+
postgres-version:
61+
- "13"
62+
- "14"
63+
- "15"
5964
steps:
6065
- uses: actions/checkout@v4
6166

@@ -66,6 +71,7 @@ jobs:
6671
password: GrandMaster
6772
database: jedi_order
6873
port: 34837
74+
postgres-version: ${{ matrix.postgres-version }}
6975
id: postgres
7076

7177
- name: Run setup-python
@@ -82,3 +88,4 @@ jobs:
8288
SERVICE_NAME: ${{ steps.postgres.outputs.service-name }}
8389
EXPECTED_CONNECTION_URI: postgresql://yoda:GrandMaster@localhost:34837/jedi_order
8490
EXPECTED_SERVICE_NAME: yoda
91+
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+
* Supports PostgreSQL version parametrization.
13+
* Easy [to prove][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 versions: "13", "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: "13"
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: 48 additions & 4 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. One of "13", "14", "15", and "16".
26+
default: "16"
27+
required: false
2428
outputs:
2529
connection-uri:
2630
description: The connection URI to connect to PostgreSQL.
@@ -31,10 +35,25 @@ outputs:
3135
runs:
3236
using: composite
3337
steps:
34-
- name: Prerequisites
38+
- name: Cache PostgreSQL installation packages
39+
uses: actions/cache@v3
40+
with:
41+
key: ${{ runner.os }}-postgres-${{ inputs.postgres-version }}
42+
path: |
43+
/var/cache/apt/archives
44+
C:\Users\<username>\AppData\Local\Temp\chocolatey
45+
46+
- name: Install PostgreSQL
3547
run: |
3648
if [ "$RUNNER_OS" == "Linux" ]; then
37-
echo "$(pg_config --bindir)" >> $GITHUB_PATH
49+
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
50+
| sudo tee /etc/apt/sources.list.d/pgdg.list
51+
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
52+
sudo apt-get update
53+
sudo apt-get -y install postgresql-${{ inputs.postgres-version }}
54+
55+
# Add PostgreSQL binaries to PATH, so they become globally available.
56+
/usr/lib/postgresql/${{ inputs.postgres-version }}/bin/pg_config --bindir >> $GITHUB_PATH
3857
elif [ "$RUNNER_OS" == "Windows" ]; then
3958
echo "$PGBIN" >> $GITHUB_PATH
4059
echo "PQ_LIB_DIR=$PGROOT\lib" >> $GITHUB_ENV
@@ -45,6 +64,25 @@ runs:
4564
for name in "PGROOT" "PGDATA" "PGBIN" "PGUSER" "PGPASSWORD"; do
4665
echo "$name=" >> $GITHUB_ENV
4766
done
67+
68+
# FIXME: Aargh! For reasons unknown the '--servicename' option is
69+
# ignored when installing a PostgreSQL version that is already
70+
# preinstalled on GitHub runners. In order to bypass the issue I'm
71+
# using default naming convention to overwrite the service name.
72+
choco install postgresql${{ inputs.postgres-version }} \
73+
--ia "--servicename postgresql-${{ runner.arch }}-${{ inputs.postgres-version }}"
74+
75+
# Stop PostgreSQL that has been auto started after installation. This
76+
# action prepares new configuration and brings its own instance, and
77+
# we need a network port to be free.
78+
net stop postgresql-${{ runner.arch }}-${{ inputs.postgres-version }}
79+
80+
# Add PostgreSQL binaries to PATH, so they become globally available
81+
# and set path to LIBPQ to link against. On Windows it comes together
82+
# with PostgreSQL distribution.
83+
export PGROOT="$PROGRAMFILES/PostgreSQL/${{ inputs.postgres-version }}"
84+
"$PGROOT"/bin/pg_config.exe --bindir >> $GITHUB_PATH
85+
echo "PQ_LIB_DIR=$("$PGROOT"/bin/pg_config.exe --libdir)" >> $GITHUB_ENV
4886
elif [ "$RUNNER_OS" == "macOS" ]; then
4987
case "$(sw_vers -productVersion)" in
5088
13.*|14.*)
@@ -56,6 +94,13 @@ runs:
5694
brew install --skip-post-install postgresql@14
5795
;;
5896
esac
97+
98+
brew install postgresql@${{ inputs.postgres-version }}
99+
100+
# Link PostgreSQL binaries to /usr/local/bin so they become globally
101+
# available. The overwrite option is required because they might be a
102+
# preinstalled linked bottle.
103+
brew link --overwrite postgresql@${{ inputs.postgres-version }}
59104
fi
60105
shell: bash
61106

@@ -95,8 +140,7 @@ runs:
95140
--pwfile="$PWFILE" \
96141
--auth="scram-sha-256" \
97142
--encoding="$DEFAULT_ENCODING" \
98-
--locale="$DEFAULT_LOCALE" \
99-
--no-instructions
143+
--locale="$DEFAULT_LOCALE"
100144
101145
# Do not create unix sockets since they are created by default in the
102146
# directory we have no permissions to (owned by system postgres user).

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)