Upgrade Case Study: PostgreSQL 16 to 17 in One Line, With Every Platform's Files Following
Setup files are written once and changed many times. Every upgrade of a runtime or a database has to reach every file that installs it: the dev container, the Copilot workflow, the Cursor environment, the server script. Miss one, and one agent works on a different version from everyone else, which shows up later as a bug nobody else can reproduce.
In the Alpha demo, the orders-api team moves from PostgreSQL 16 to 17. One line changes in preconfig.yaml. preconfig check lists every file that is now out of date, preconfig build rewrites them, and check is clean again.

The upgrade as recorded: one edit, ten findings, five files rewritten.
The Set-Up
| Upgrade | |
|---|---|
| The repository | orders-api, with the seven files build wrote for it in step 2 of the demo |
| The change | PostgreSQL 16 to 17 |
| The edit | sed -i 's/version: "16"/version: "17"/' preconfig.yaml |
| The commands | preconfig check, preconfig build, preconfig check |
What Happened
Step 1: the edit. One line of the spec:
services:
postgres:
- version: "16"
+ version: "17"
user: orders
Step 2: check. Before anything was rebuilt, check compared every file with what the new spec produces. It found ten errors across six files, of two kinds. X002 says a file differs from a fresh build. X003 says what that means: which version the file installs now.
.github/workflows/copilot-setup-steps.yml:26: error X003: copilot-setup-steps.yml installs PostgreSQL 16; preconfig.yaml asks for 17
.preconfig/setup.sh:51: error X003: setup.sh installs PostgreSQL 16; preconfig.yaml asks for 17
cloud-init.yaml:62: error X003: cloud-init.yaml installs PostgreSQL 16; preconfig.yaml asks for 17
.cursor/environment.json: error X003: environment.json installs PostgreSQL 16 (set in .preconfig/setup.sh, line 51); preconfig.yaml asks for 17
Each finding points at the line that says 16. Where a file gets its version from another file, as Cursor’s environment does through the setup script, check names that file and line. check --diff showed each change before it was made.
Step 3: build. build rewrote five files and left two alone:
unchanged .cursor/Dockerfile
unchanged .cursor/environment.json
wrote .devcontainer/compose.yaml
wrote .devcontainer/devcontainer.json
wrote .github/workflows/copilot-setup-steps.yml
wrote .preconfig/setup.sh
wrote cloud-init.yaml
Cursor’s two files didn’t change because they run the setup script, which carries the version. Step 4: check again: checked 6 files: 0 errors, 0 warnings.
What Changed in Each File
| File | Lines added / removed | The change |
|---|---|---|
| .devcontainer/compose.yaml | 1 / 1 | The service image: postgres:16 to postgres:17 |
| .devcontainer/devcontainer.json | 1 / 1 | The summary line at the top |
| copilot-setup-steps.yml | 1 / 1 | The service container: postgres:16 to postgres:17 |
| .preconfig/setup.sh | 13 / 9 | PostgreSQL 16 comes from Ubuntu itself. 17 comes from the PostgreSQL project’s own archive, so the script adds its signing key and source, then installs, checks and starts version 17 |
| cloud-init.yaml | 14 / 10 | The same script, as cloud-init carries it, and its summary line |
The setup script is where a hand edit would most likely go wrong. Moving from 16 to 17 on Ubuntu 24.04 is not a version number in one place: the package comes from somewhere else, and the cluster commands name the version. The engine knows which versions Ubuntu ships and writes the rest.
The Numbers
| Result | |
|---|---|
| Lines edited by hand | 1 |
| Findings before the build | 10 errors in 6 files |
| Files rewritten / unchanged | 5 / 2 |
| Lines changed across the files | 30 added, 22 removed |
| Findings after the build | 0 |
What the Alpha Revealed: Not Every Install Path Has Run
The rewritten files pass every schema and tool the Alpha checks them with. But PostgreSQL 17 comes from the PostgreSQL project’s archive, which the Alpha’s test machine couldn’t reach, so this setup hasn’t run on a clean machine yet. The same holds for Node.js, Go, Redis 8 and Python versions other than 3.12. The Alpha says so rather than count them as proven, and they are the first thing the Beta runs.
Next: Upgrades Proven Before They Merge
In the Beta, a GitHub Action runs check on every pull request that touches the setup, and verify when the spec changes, so an upgrade like this one is proven on a clean machine before it merges. The roadmap has the plan.
Try It Yourself
Open the live demo and press Play, or jump to step 6. Then, in the first panel under the replay, pick orders-api, change PostgreSQL to 17 or Python to 3.13, and watch the files change. For drift, pick “A workflow preconfig wrote” in the second panel, tick the box, and check it against your changed spec.