├── action.yml ├── .github └── workflows │ ├── service.yml │ └── build.yml ├── LICENSE.txt ├── README.md ├── keys └── ACCC4CF8.asc └── index.js /action.yml: -------------------------------------------------------------------------------- 1 | name: Setup Postgres 2 | inputs: 3 | postgres-version: 4 | description: The Postgres version to download (if necessary) and use 5 | config: 6 | description: Set config 7 | database: 8 | description: Database to create 9 | user: 10 | description: User to create 11 | dev-files: 12 | description: Install development files 13 | runs: 14 | using: node24 15 | main: index.js 16 | -------------------------------------------------------------------------------- /.github/workflows/service.yml: -------------------------------------------------------------------------------- 1 | name: service 2 | on: workflow_dispatch 3 | jobs: 4 | service: 5 | runs-on: ubuntu-latest 6 | services: 7 | postgres: 8 | image: postgres 9 | env: 10 | POSTGRES_HOST_AUTH_METHOD: trust 11 | options: >- 12 | --health-cmd pg_isready 13 | --health-interval 10s 14 | --health-timeout 5s 15 | --health-retries 5 16 | ports: 17 | - 5432:5432 18 | steps: 19 | - run: psql -h localhost -U postgres -d postgres -c 'SHOW server_version' 20 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020-2025 Andrew Kane 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: [push, pull_request] 3 | jobs: 4 | build: 5 | runs-on: ${{ matrix.os }} 6 | strategy: 7 | fail-fast: false 8 | matrix: 9 | os: [ubuntu-24.04, ubuntu-24.04-arm, ubuntu-22.04, ubuntu-22.04-arm, macos-26, macos-15, macos-15-intel, macos-14] 10 | postgres-version: [18, 17, 16, 15, 14, 13] 11 | include: 12 | - os: windows-2025 13 | postgres-version: 17 14 | - os: windows-2022 15 | postgres-version: 14 16 | steps: 17 | - uses: actions/checkout@v5 18 | - uses: ./. 19 | with: 20 | postgres-version: ${{ matrix.postgres-version }} 21 | config: | 22 | shared_preload_libraries = 'pg_stat_statements' 23 | database: testdb 24 | user: ${{ matrix.postgres-version == 14 && 'testuser' || '' }} 25 | dev-files: ${{ matrix.postgres-version == 13 }} 26 | - run: createdb testdb2 ${{ matrix.postgres-version == 14 && '-U testuser' || '' }} 27 | - run: psql -d testdb -c 'SHOW server_version' ${{ matrix.postgres-version == 14 && '-U testuser' || '' }} 28 | - run: psql -d testdb -h localhost -c 'SELECT current_user' ${{ matrix.postgres-version == 14 && '-U testuser' || '' }} 29 | - run: psql --version 30 | - run: pg_config 31 | - if: ${{ matrix.postgres-version == 13 }} 32 | run: test -f $(pg_config --includedir-server)/postgres.h 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # setup-postgres 2 | 3 | The missing action for Postgres :tada: 4 | 5 | - Faster (with the default version) and simpler than containers 6 | - Works on Linux, Mac, and Windows 7 | - Supports different versions 8 | 9 | [![Build Status](https://github.com/ankane/setup-postgres/actions/workflows/build.yml/badge.svg)](https://github.com/ankane/setup-postgres/actions) 10 | 11 | ## Getting Started 12 | 13 | Add it as a step to your workflow 14 | 15 | ```yml 16 | - uses: ankane/setup-postgres@v1 17 | ``` 18 | 19 | The default credentials are: 20 | 21 | - user: `runner` (the OS user) on Linux and Mac, `postgres` on Windows 22 | - password: none 23 | - host: `localhost` or socket 24 | - port: `5432` 25 | 26 | ## Versions 27 | 28 | Specify a version 29 | 30 | ```yml 31 | - uses: ankane/setup-postgres@v1 32 | with: 33 | postgres-version: 18 34 | ``` 35 | 36 | Currently supports 37 | 38 | Version | `18` | `17` | `16` | `15` | `14` | `13` 39 | --- | --- | --- | --- | --- | --- | --- 40 | `ubuntu-24.04` | ✓ | ✓ | default | ✓ | ✓ | ✓ 41 | `ubuntu-24.04-arm` | ✓ | ✓ | default | ✓ | ✓ | ✓ 42 | `ubuntu-22.04` | ✓ | ✓ | ✓ | ✓ | default | ✓ 43 | `ubuntu-22.04-arm` | ✓ | ✓ | ✓ | ✓ | default | ✓ 44 | `macos-26` | ✓ | default | ✓ | ✓ | ✓ | ✓ 45 | `macos-15` | ✓ | default | ✓ | ✓ | ✓ | ✓ 46 | `macos-15-intel` | ✓ | default | ✓ | ✓ | ✓ | ✓ 47 | `macos-14` | ✓ | default | ✓ | ✓ | ✓ | ✓ 48 | `windows-2025` | | default | | | | | 49 | `windows-2022` | | | | | default | | 50 | 51 | Test against multiple versions 52 | 53 | ```yml 54 | strategy: 55 | matrix: 56 | postgres-version: [18, 17, 16, 15, 14] 57 | steps: 58 | - uses: ankane/setup-postgres@v1 59 | with: 60 | postgres-version: ${{ matrix.postgres-version }} 61 | ``` 62 | 63 | ## Options 64 | 65 | Create a database 66 | 67 | ```yml 68 | - uses: ankane/setup-postgres@v1 69 | with: 70 | database: testdb 71 | ``` 72 | 73 | Specify a user 74 | 75 | ```yml 76 | - uses: ankane/setup-postgres@v1 77 | with: 78 | user: testuser 79 | ``` 80 | 81 | Set `postgresql.conf` config 82 | 83 | ```yml 84 | - uses: ankane/setup-postgres@v1 85 | with: 86 | config: | 87 | shared_preload_libraries = 'pg_stat_statements' 88 | ``` 89 | 90 | Install development files (for building extensions) 91 | 92 | ```yml 93 | - uses: ankane/setup-postgres@v1 94 | with: 95 | dev-files: true 96 | ``` 97 | 98 | ## Extra Steps 99 | 100 | Run queries 101 | 102 | ```yml 103 | - run: psql -d testdb -c 'SHOW server_version' 104 | ``` 105 | 106 | ## Related Actions 107 | 108 | - [setup-mysql](https://github.com/ankane/setup-mysql) 109 | - [setup-mariadb](https://github.com/ankane/setup-mariadb) 110 | - [setup-mongodb](https://github.com/ankane/setup-mongodb) 111 | - [setup-elasticsearch](https://github.com/ankane/setup-elasticsearch) 112 | - [setup-opensearch](https://github.com/ankane/setup-opensearch) 113 | - [setup-sqlserver](https://github.com/ankane/setup-sqlserver) 114 | 115 | ## Contributing 116 | 117 | Everyone is encouraged to help improve this project. Here are a few ways you can help: 118 | 119 | - [Report bugs](https://github.com/ankane/setup-postgres/issues) 120 | - Fix bugs and [submit pull requests](https://github.com/ankane/setup-postgres/pulls) 121 | - Write, clarify, or fix documentation 122 | - Suggest or add new features 123 | -------------------------------------------------------------------------------- /keys/ACCC4CF8.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | 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 76 | =DA1T 77 | -----END PGP PUBLIC KEY BLOCK----- 78 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const os = require('os'); 3 | const path = require('path'); 4 | const spawnSync = require('child_process').spawnSync; 5 | 6 | function run() { 7 | const args = Array.from(arguments); 8 | console.log(args.map(v => v.toString().includes(' ') ? `"${v}"` : v).join(' ')); 9 | const command = args.shift(); 10 | let env = Object.assign({}, process.env); 11 | env.HOMEBREW_NO_AUTO_UPDATE = '1'; 12 | env.HOMEBREW_NO_INSTALL_CLEANUP = '1'; 13 | // spawn is safer and more lightweight than exec 14 | const ret = spawnSync(command, args, {stdio: 'inherit', env: env}); 15 | if (ret.status !== 0) { 16 | throw ret.error; 17 | } 18 | } 19 | 20 | function addToPath(newPath) { 21 | fs.appendFileSync(process.env.GITHUB_PATH, `${newPath}\n`); 22 | } 23 | 24 | function isMac() { 25 | return process.platform == 'darwin'; 26 | } 27 | 28 | function isWindows() { 29 | return process.platform == 'win32'; 30 | } 31 | 32 | function isArm() { 33 | return process.arch == 'arm64'; 34 | } 35 | 36 | // TODO read each line and replace existing value if needed 37 | function setConfig(dir) { 38 | const config = process.env['INPUT_CONFIG']; 39 | if (config) { 40 | const file = path.join(dir, 'postgresql.conf'); 41 | 42 | if (isMac() || isWindows()) { 43 | fs.appendFileSync(file, config); 44 | } else { 45 | spawnSync(`sudo`, [`tee`, `-a`, file], {input: config}); 46 | } 47 | } 48 | } 49 | 50 | function updateHba(dir, user) { 51 | const contents = ` 52 | # TYPE DATABASE USER ADDRESS METHOD 53 | local all ${user} trust 54 | local all postgres peer 55 | local all all peer 56 | host all ${user} 127.0.0.1/32 trust 57 | host all ${user} ::1/128 trust 58 | host all all 127.0.0.1/32 md5 59 | host all all ::1/128 md5 60 | `; 61 | const file = path.join(dir, 'pg_hba.conf'); 62 | 63 | if (isMac() || isWindows()) { 64 | fs.writeFileSync(file, contents); 65 | } else { 66 | spawnSync(`sudo`, [`tee`, file], {input: contents}); 67 | } 68 | } 69 | 70 | function formulaPresent(formula) { 71 | const tapPrefix = process.arch == 'arm64' ? '/opt/homebrew' : '/usr/local/Homebrew'; 72 | const tap = `${tapPrefix}/Library/Taps/homebrew/homebrew-core`; 73 | return fs.existsSync(`${tap}/Formula/${formula[0]}/${formula}.rb`) || fs.existsSync(`${tap}/Aliases/${formula}`); 74 | } 75 | 76 | function getDefaultVersion() { 77 | if (isMac() || process.env['ImageOS'] == 'win25') { 78 | return 17; 79 | } else if (process.env['ImageOS'] == 'ubuntu24') { 80 | return 16; 81 | } else { 82 | return 14; 83 | } 84 | } 85 | 86 | const defaultVersion = getDefaultVersion(); 87 | const postgresVersion = parseFloat(process.env['INPUT_POSTGRES-VERSION'] || defaultVersion); 88 | if (![19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9.6].includes(postgresVersion)) { 89 | throw `Postgres version not supported: ${postgresVersion}`; 90 | } 91 | 92 | const database = process.env['INPUT_DATABASE']; 93 | const defaultUser = isWindows() ? 'postgres' : os.userInfo().username; 94 | const user = process.env['INPUT_USER'] || defaultUser; 95 | if (!/^[a-z0-9_-]+$/i.test(user)) { 96 | throw `Unsupported user: ${user}`; 97 | } 98 | const userExists = isMac() ? user == defaultUser : user == 'postgres'; 99 | 100 | let bin; 101 | let cmdPrefix = []; 102 | 103 | if (isMac()) { 104 | const prefix = isArm() ? '/opt/homebrew' : '/usr/local'; 105 | 106 | bin = `${prefix}/opt/postgresql@${postgresVersion}/bin`; 107 | 108 | if (!fs.existsSync(bin)) { 109 | if (fs.existsSync(`${prefix}/opt/postgresql@14`)) { 110 | // remove previous version 111 | run(`brew`, `unlink`, `postgresql@14`); 112 | } 113 | 114 | if (!formulaPresent(`postgresql@${postgresVersion}`)) { 115 | run(`brew`, `update`, `--quiet`); 116 | } 117 | 118 | // install new version 119 | run(`brew`, `install`, `--quiet`, `postgresql@${postgresVersion}`); 120 | } 121 | 122 | // update config 123 | const dataDir = `${prefix}/var/postgresql@${postgresVersion}`; 124 | setConfig(dataDir); 125 | updateHba(dataDir, user); 126 | 127 | // start 128 | run(`${bin}/pg_ctl`, `-w`, `-D`, dataDir, `start`); 129 | } else if (isWindows()) { 130 | if (isArm()) { 131 | throw `Windows ARM not supported`; 132 | } 133 | 134 | const supportedVersion = process.env['ImageOS'] == 'win25' ? 17 : 14; 135 | if (postgresVersion != supportedVersion) { 136 | throw `Postgres version not supported on Windows: ${postgresVersion}`; 137 | } 138 | 139 | // update config 140 | const dataDir = process.env.PGDATA; 141 | setConfig(dataDir); 142 | updateHba(dataDir, user); 143 | 144 | // start 145 | run(`sc`, `config`, `postgresql-x64-${supportedVersion}`, `start=auto`); 146 | run(`net`, `start`, `postgresql-x64-${supportedVersion}`); 147 | 148 | bin = process.env.PGBIN; 149 | } else { 150 | // removed in https://github.com/actions/virtual-environments/pull/3091 151 | if (!fs.existsSync('/etc/apt/sources.list.d/pgdg.list')) { 152 | // beta versions require extra component 153 | // development snapshots require this and -snapshot after pgdg 154 | // https://wiki.postgresql.org/wiki/Apt/FAQ 155 | const suffix = postgresVersion >= 19 ? ` ${postgresVersion}` : ''; 156 | const snapshot = postgresVersion >= 19 ? `-snapshot` : ''; 157 | run(`sudo`, `install`, `-d`, `/usr/share/postgresql-common/pgdg`); 158 | run(`sudo`, `cp`, path.join(__dirname, `keys`, `ACCC4CF8.asc`), `/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc`); 159 | const codename = spawnSync(`lsb_release`, [`-cs`], {encoding: 'utf-8'}).stdout.trim(); 160 | const pgdgList = `deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt ${codename}-pgdg${snapshot} main${suffix}\n`; 161 | spawnSync(`sudo`, [`tee`, `/etc/apt/sources.list.d/pgdg.list`], {input: pgdgList}); 162 | } 163 | 164 | if (postgresVersion != defaultVersion || isArm()) { 165 | // remove previous cluster so port 5432 is used 166 | if (!isArm()) { 167 | run(`sudo`, `pg_dropcluster`, defaultVersion, `main`); 168 | 169 | if (postgresVersion < defaultVersion) { 170 | run(`sudo`, `apt-get`, `-qq`, `-o`, `Dpkg::Use-Pty=0`, `remove`, `postgresql-${defaultVersion}`); 171 | } 172 | } 173 | 174 | // install new version 175 | run(`sudo`, `apt-get`, `-qq`, `update`, `-o`, `Dir::Etc::sourcelist=sources.list.d/pgdg.list`, `-o`, `Dir::Etc::sourceparts=-`, `-o`, `APT::Get::List-Cleanup=0`); 176 | run(`sudo`, `apt-get`, `-qq`, `-o`, `Dpkg::Use-Pty=0`, `install`, `postgresql-${postgresVersion}`); 177 | } 178 | 179 | const devFiles = process.env['INPUT_DEV-FILES']; 180 | // maybe support other truthy values in future 181 | if (devFiles == 'true') { 182 | run(`sudo`, `apt-get`, `-qq`, `update`); 183 | run(`sudo`, `apt-get`, `-qq`, `-o`, `Dpkg::Use-Pty=0`, `install`, `postgresql-server-dev-${postgresVersion}`); 184 | } 185 | 186 | // update config 187 | const dataDir = `/etc/postgresql/${postgresVersion}/main`; 188 | setConfig(dataDir); 189 | updateHba(dataDir, user); 190 | 191 | // start 192 | const startCmd = isArm() ? `restart` : `start`; 193 | run(`sudo`, `systemctl`, startCmd, `postgresql@${postgresVersion}-main`); 194 | 195 | bin = `/usr/lib/postgresql/${postgresVersion}/bin`; 196 | cmdPrefix = [`sudo`, `-iu`, `postgres`]; 197 | } 198 | 199 | if (!userExists) { 200 | run(...cmdPrefix, path.join(bin, 'createuser'), `-s`, user); 201 | } 202 | 203 | if (database) { 204 | run(path.join(bin, 'createdb'), '-U', user, database); 205 | } 206 | 207 | addToPath(bin); 208 | --------------------------------------------------------------------------------