-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathindex.js
184 lines (150 loc) · 5.7 KB
/
index.js
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
const execSync = require('child_process').execSync;
const fs = require('fs');
const path = require('path');
const spawnSync = require('child_process').spawnSync;
function run(command) {
console.log(command);
let env = Object.assign({}, process.env);
env.HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK = '1';
execSync(command, {stdio: 'inherit', env: env});
}
function runSafe() {
const args = Array.from(arguments);
console.log(args.join(' '));
const command = args.shift();
// spawn is safer and more lightweight than exec
const ret = spawnSync(command, args, {stdio: 'inherit'});
if (ret.status !== 0) {
throw ret.error;
}
}
function addToPath(newPath) {
fs.appendFileSync(process.env.GITHUB_PATH, `${newPath}\n`);
}
function isMac() {
return process.platform == 'darwin';
}
function isWindows() {
return process.platform == 'win32';
}
function isArm() {
return process.arch == 'arm64';
}
// TODO read each line and replace existing value if needed
function setConfig(dir) {
const config = process.env['INPUT_CONFIG'];
if (config) {
const file = path.join(dir, 'postgresql.conf');
if (isMac() || isWindows()) {
fs.appendFileSync(file, config);
} else {
const tmpfile = '/tmp/postgresql.conf';
fs.writeFileSync(tmpfile, config);
execSync(`cat ${tmpfile} | sudo tee -a ${file}`);
}
}
}
function updateHba(dir) {
const contents = `
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
local all all peer
host all $USER 127.0.0.1/32 trust
host all $USER ::1/128 trust
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
`
execSync(`echo "${contents}" | sudo tee ${dir}/pg_hba.conf`);
}
function formulaPresent(formula) {
const tapPrefix = process.arch == 'arm64' ? '/opt/homebrew' : '/usr/local/Homebrew';
const tap = `${tapPrefix}/Library/Taps/homebrew/homebrew-core`;
return fs.existsSync(`${tap}/Formula/${formula[0]}/${formula}.rb`) || fs.existsSync(`${tap}/Aliases/${formula}`);
}
function getDefaultVersion() {
if (isMac() || process.env['ImageOS'] == 'win25') {
return 17;
} else if (process.env['ImageOS'] == 'ubuntu24') {
return 16;
} else {
return 14;
}
}
const defaultVersion = getDefaultVersion();
const postgresVersion = parseFloat(process.env['INPUT_POSTGRES-VERSION'] || defaultVersion);
if (![18, 17, 16, 15, 14, 13, 12, 11, 10, 9.6].includes(postgresVersion)) {
throw `Postgres version not supported: ${postgresVersion}`;
}
const database = process.env['INPUT_DATABASE'];
let bin;
if (isMac()) {
const prefix = isArm() ? '/opt/homebrew' : '/usr/local';
bin = `${prefix}/opt/postgresql@${postgresVersion}/bin`;
let dataDir = `${prefix}/var/postgresql@${postgresVersion}`;
if (!fs.existsSync(bin)) {
if (fs.existsSync(`${prefix}/opt/postgresql@14`)) {
// remove previous version
run(`brew unlink postgresql@14`);
}
if (!formulaPresent(`postgresql@${postgresVersion}`)) {
run(`brew update`);
}
// install new version
run(`brew install postgresql@${postgresVersion}`);
}
setConfig(dataDir);
// start
run(`${bin}/pg_ctl -w -D ${dataDir} start`);
} else if (isWindows()) {
const supportedVersion = process.env['ImageOS'] == 'win25' ? 17 : 14;
if (postgresVersion != supportedVersion) {
throw `Postgres version not supported on Windows: ${postgresVersion}`;
}
setConfig(process.env.PGDATA);
// start
run(`sc config postgresql-x64-${supportedVersion} start=auto`);
run(`net start postgresql-x64-${supportedVersion}`);
bin = process.env.PGBIN;
} else {
// removed in https://github.com/actions/virtual-environments/pull/3091
if (!fs.existsSync('/etc/apt/sources.list.d/pgdg.list')) {
// beta versions require extra component
// development snapshots require this and -snapshot after pgdg
// https://wiki.postgresql.org/wiki/Apt/FAQ
const suffix = postgresVersion >= 18 ? ` ${postgresVersion}` : "";
const snapshot = postgresVersion >= 18 ? `-snapshot` : "";
run(`curl -s https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null`)
run(`echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg${snapshot} main${suffix}" | sudo tee /etc/apt/sources.list.d/pgdg.list`);
}
if (postgresVersion != defaultVersion || isArm()) {
// remove previous cluster so port 5432 is used
if (!isArm()) {
run(`sudo pg_dropcluster ${defaultVersion} main`);
if (postgresVersion < defaultVersion) {
run(`sudo apt-get remove postgresql-${defaultVersion}`);
}
}
// install new version
run(`sudo apt-get update -o Dir::Etc::sourcelist="sources.list.d/pgdg.list" -o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0"`);
run(`sudo apt-get install postgresql-${postgresVersion}`);
}
const devFiles = process.env['INPUT_DEV-FILES'];
// maybe support other truthy values in future
if (devFiles == 'true') {
run(`sudo apt-get update`);
run(`sudo apt-get install postgresql-server-dev-${postgresVersion}`);
}
const dataDir = `/etc/postgresql/${postgresVersion}/main`;
setConfig(dataDir);
updateHba(dataDir);
// start
const startCmd = isArm() ? `restart` : `start`;
run(`sudo systemctl ${startCmd} postgresql@${postgresVersion}-main`);
// add user
run(`sudo -iu postgres createuser -s $USER`);
bin = `/usr/lib/postgresql/${postgresVersion}/bin`;
}
if (database) {
runSafe(path.join(bin, "createdb"), database);
}
addToPath(bin);