forked from cycle-five/action-setup-postgres
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaction.yml
154 lines (140 loc) · 6.46 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
name: Cycle Five Fork - Setup PostgreSQL for Linux/macOS/Windows
author: Ihor Kalnytskyi
description: Setup a preinstalled PostgreSQL server.
branding:
icon: database
color: purple
inputs:
username:
description: The username of the user to setup.
default: postgres
required: false
password:
description: The password of the user to setup.
default: postgres
required: false
database:
description: The database name to setup and grant permissions to created user.
default: postgres
required: false
port:
description: The server port to listen on.
default: "5432"
required: false
postgres-version:
description: The PostgreSQL version (major) to install. E.g. "13" or "14".
default: "15"
required: false
outputs:
connection-uri:
description: The connection URI to connect to PostgreSQL.
value: ${{ steps.set-outputs.outputs.connection-uri }}
service-name:
description: The service name with connection parameters.
value: ${{ steps.set-outputs.outputs.service-name }}
runs:
using: composite
steps:
- name: Install PostgreSQL
run: |
if [ "$RUNNER_OS" == "Linux" ]; then
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
| sudo tee /etc/apt/sources.list.d/pgdg.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get -y install postgresql-${{ inputs.postgres-version }}
# Add PostgreSQL binaries to PATH, so they become globally available.
/usr/lib/postgresql/${{ inputs.postgres-version }}/bin/pg_config --bindir >> $GITHUB_PATH
elif [ "$RUNNER_OS" == "macOS" ]; then
brew install postgresql@${{ inputs.postgres-version }}
# Link PostgreSQL binaries to /usr/local/bin so they become globally
# available. The overwrite option is required because they might be a
# preinstalled linked bottle.
brew link --overwrite postgresql@${{ inputs.postgres-version }}
elif [ "$RUNNER_OS" == "Windows" ]; then
# FIXME: Aargh! For reasons unknown the '--servicename' option is
# ignored when installing a PostgreSQL version that is already
# preinstalled on GitHub runners. In order to bypass the issue I'm
# using default naming convention (i.e. with arch in the name).
choco install postgresql${{ inputs.postgres-version }} \
--ia "--servicename postgresql-${{ runner.arch }}-${{ inputs.postgres-version }}"
# Stop PostgreSQL that has been auto started after installation. This
# action prepares new configuration and brings its own instance, and
# we need a network port to be free.
net stop postgresql-${{ runner.arch }}-${{ inputs.postgres-version }}
# Add PostgreSQL binaries to PATH, so they become globally available
# and set path to LIBPQ to link against. On Windows it comes together
# with PostgreSQL distribution.
export PGROOT="$PROGRAMFILES/PostgreSQL/${{ inputs.postgres-version }}"
"$PGROOT"/bin/pg_config.exe --bindir >> $GITHUB_PATH
echo "PQ_LIB_DIR=$("$PGROOT"/bin/pg_config.exe --libdir)" >> $GITHUB_ENV
fi
shell: bash
- name: Setup and start PostgreSQL
run: |
export PGDATA="$RUNNER_TEMP/pgdata"
export PWFILE="$RUNNER_TEMP/pwfile"
# Unfortunately 'initdb' could only receive a password via file on disk
# or prompt to enter on. Prompting is not an option since we're running
# in non-interactive mode.
echo '${{ inputs.password }}' > $PWFILE
# There are couple of reasons why we need to create a new PostgreSQL
# database cluster. First and foremost, we have to create a superuser
# with provided credentials. Second, we want the PostgreSQL client
# applications [1] to be available for execution without
# run-from-another-user dances. Third, we want to make sure that
# settings are the same between operating systems and aren't changed by
# package vendors.
#
# [1] https://www.postgresql.org/docs/15/reference-client.html
initdb \
--username="${{ inputs.username }}" \
--pwfile="$PWFILE" \
--auth="scram-sha-256" \
--encoding="UTF-8" \
--locale="en_US.UTF-8"
# Do not create unix sockets since they are created by default in the
# directory we have no permissions to (owned by system postgres user).
echo "unix_socket_directories = ''" >> "$PGDATA/postgresql.conf"
echo "port = ${{ inputs.port }}" >> "$PGDATA/postgresql.conf"
pg_ctl start
# Save required connection parameters for created superuser to the
# connection service file [1]. This allows using these connection
# parameters by setting 'PGSERVICE' environment variable or by
# requesting them via connection string.
#
# HOST is required for Linux/macOS because these OS-es default to unix
# sockets but we turned them off.
#
# PORT, USER, PASSWORD and DBNAME are required because they could be
# parametrized via action input parameters.
#
# [1] https://www.postgresql.org/docs/15/libpq-pgservice.html
cat <<EOF > "$PGDATA/pg_service.conf"
[${{ inputs.username }}]
host=localhost
port=${{ inputs.port }}
user=${{ inputs.username }}
password=${{ inputs.password }}
dbname=${{ inputs.database }}
EOF
shell: bash
- name: Setup PostgreSQL database
run: |
# The 'postgres' database is a pre-created database meant for use by
# users, utilities and third party applications. There's no way to
# parametrize the name, so all we can do is to avoid creating a
# database if provided name is 'postgres'.
if [ "${{ inputs.database }}" != "postgres" ]; then
createdb -O "${{ inputs.username }}" "${{ inputs.database }}"
fi
env:
PGSERVICE: ${{ inputs.username }}
shell: bash
- name: Set action outputs
run: |
CONNECTION_URI="postgresql://${{ inputs.username }}:${{ inputs.password }}@localhost:${{ inputs.port }}/${{ inputs.database }}"
echo "connection-uri=$CONNECTION_URI" >> $GITHUB_OUTPUT
echo "service-name=${{ inputs.username }}" >> $GITHUB_OUTPUT
shell: bash
id: set-outputs