Skip to content

Commit 8702b7b

Browse files
committed
Release 0.5.0: integrate pg_maker build and development workflows
1 parent 570e28a commit 8702b7b

34 files changed

Lines changed: 2218 additions & 25 deletions

‎.github/workflows/publish.yml‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
with:
2626
python-version: "3.12"
2727
- name: Install all component, test, and build dependencies
28-
run: python -m pip install --editable '.[dev]'
28+
run: python -m pip install --editable '.[dev,maker]'
2929
- name: Verify tag matches package version
3030
shell: bash
3131
run: |
@@ -54,6 +54,11 @@ jobs:
5454
for command in pg-configurator pg-converter pg-diag pg-perf-bench pg-stand pg-workload; do
5555
"${RUNNER_TEMP}/pg-play-wheel-smoke/bin/${command}" --version
5656
done
57+
for wheel in dist/*.whl; do
58+
"${RUNNER_TEMP}/pg-play-wheel-smoke/bin/python" -m pip install "${wheel}[maker]"
59+
done
60+
"${RUNNER_TEMP}/pg-play-wheel-smoke/bin/pg-play" capabilities --component pg_maker
61+
"${RUNNER_TEMP}/pg-play-wheel-smoke/bin/pg-play" maker dev-open --help
5762
- name: Upload distributions for publishing
5863
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
5964
with:

‎.github/workflows/tests.yml‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
--editable .ci-components/pg_perf_bench \
6161
--editable .ci-components/pg_stand \
6262
--editable .ci-components/pg_workload \
63-
--editable '.[dev]'
63+
--editable '.[dev,maker]'
6464
- run: ruff check --exclude .ci-components .
6565
- run: ruff format --check --exclude .ci-components .
6666
- run: python -m pytest -q
@@ -120,3 +120,8 @@ jobs:
120120
for command in pg-configurator pg-converter pg-diag pg-perf-bench pg-stand pg-workload; do
121121
"${RUNNER_TEMP}/pg-play-wheel-smoke/bin/${command}" --version
122122
done
123+
for wheel in dist/*.whl; do
124+
"${RUNNER_TEMP}/pg-play-wheel-smoke/bin/python" -m pip install "${wheel}[maker]"
125+
done
126+
"${RUNNER_TEMP}/pg-play-wheel-smoke/bin/pg-play" capabilities --component pg_maker
127+
"${RUNNER_TEMP}/pg-play-wheel-smoke/bin/pg-play" maker dev-open --help

‎CHANGELOG.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Changelog
2+
3+
## 0.5.0 — 2026-10-18
4+
5+
- Add the optional `pg-play[maker]` integration with pg-maker 0.1.0 or newer.
6+
- Expose configuration validation, environment preparation, input resolution,
7+
reviewed build plans, durable operations, artifact inspection and export through
8+
CLI, Python and MCP.
9+
- Add Git development sessions, patch series management, selected component
10+
rebuilds, rebuild explanations, container debugging and iteration retention.
11+
- Bind maker-built packages and immutable runtime images to pg_stand experiments,
12+
preserving build provenance, cancellation and recovery behavior.
13+
- Package the runtime entrypoint, component recipe examples and integration guide.
14+
- Check the optional maker dependency and its CLI contract during release validation.
15+
16+
Database build tests remain opt-in. An unverified maker build retains that status
17+
when exported or used to create a runtime image.

‎MANIFEST.in‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
# Repository-only scenarios for generating the website's demonstration reports.
22
prune labs
3+
include CHANGELOG.md
4+
recursive-include docs *.md
5+
recursive-include examples/maker *.yaml

‎README.md‎

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ is `pg-play-mcp`. The import package and GitHub repository are named `pg_play`.
2020
- Plans and runs reviewed `pg_converter` packets against an exact alias set
2121
through a detached, auditable, sequential workflow.
2222
- Installs every component while preserving their independent use.
23+
- Optionally builds PostgreSQL through pg_maker, records package/image provenance,
24+
and runs the resulting immutable image in pg_stand. See
25+
[the maker workflow and interface contract](docs/pg_maker-integration.md).
2326

2427
The independently installable components are:
2528

@@ -69,7 +72,7 @@ The control layers are deliberately separate:
6972
agent skills workflow and interpretation rules
7073
|
7174
v
72-
pg-play-mcp thirty-one typed, high-level operations
75+
pg-play-mcp typed, high-level operations
7376
|
7477
v
7578
pg_play core validation, planning, state, comparison
@@ -79,14 +82,17 @@ component adapters argv arrays + strict JSON envelopes
7982
|
8083
+---- pg_configurator
8184
+---- pg_converter
85+
+---- pg_maker (optional)
8286
+---- pg_stand
8387
+---- pg_workload
8488
+---- pg_diag
8589
`---- pg_perf_bench
8690
```
8791

88-
MCP does not expose arbitrary shell, SQL, Docker, or raw component-command
89-
tools. Each component remains pleasant to use directly: orchestration flags
92+
MCP exposes typed workflow operations. The optional `maker_dev_exec` tool runs
93+
an argument vector inside a private copy of a pg_maker build container; it does
94+
not provide a host shell or a database SQL console. Each component remains
95+
pleasant to use directly: orchestration flags
9096
are hidden from its primary help and its normal human output is unchanged.
9197

9298
## Installation
@@ -105,6 +111,17 @@ Newer compatible versions are allowed; the major-version bounds are declared in
105111
python -m pip install --upgrade --upgrade-strategy eager pg-play
106112
```
107113

114+
To include PostgreSQL builds, documentation and Git development sessions, install
115+
the optional maker component:
116+
117+
```bash
118+
python -m pip install --upgrade --upgrade-strategy eager 'pg-play[maker]'
119+
pg-play capabilities --component pg_maker
120+
```
121+
122+
This adds `pg-maker>=0.1.0,<1`. See the [maker integration guide](docs/pg_maker-integration.md)
123+
for CLI, Python and MCP operations and [the changelog](CHANGELOG.md) for release notes.
124+
108125
The components remain available through their own commands:
109126

110127
```bash
@@ -614,7 +631,7 @@ parameters and the expected result.
614631
python3 -m venv .venv
615632
.venv/bin/pip install -e ../pg_stand -e ../pg_workload -e ../pg_diag \
616633
-e ../pg_configurator -e ../pg_converter -e ../pg_perf_bench
617-
.venv/bin/pip install -e '.[dev]'
634+
.venv/bin/pip install -e '.[dev,maker]'
618635
.venv/bin/ruff check .
619636
.venv/bin/ruff format --check .
620637
.venv/bin/pytest
@@ -623,7 +640,8 @@ python3 -m venv .venv
623640
For coordinated releases, publish the component distributions before tagging
624641
`pg_play`: first `pg_configurator`, `pg_converter`, `pg_diag`, `pg_stand`, and
625642
`pg_workload`, then `pg_perf_bench` (which depends on `pg_diag`), and finally
626-
`pg_play`.
643+
`pg_play`. Publish a required `pg_maker` update before `pg_play` when changing the
644+
optional maker integration.
627645
Ordinary branch CI checks out the component sources so a coordinated source
628646
change can be tested before those versions reach PyPI. Tagged publish jobs use
629647
the package index deliberately and therefore enforce this release order.

‎docs/pg_maker-integration.md‎

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# pg_maker and pg_play
2+
3+
Install the optional integration from PyPI:
4+
5+
```bash
6+
python -m pip install --upgrade 'pg-play[maker]'
7+
pg-play capabilities --component pg_maker
8+
```
9+
10+
For local pg_maker development, install its checkout into the same environment:
11+
12+
```bash
13+
pg_play/.venv/bin/python -m pip install -e ./pg_maker
14+
```
15+
16+
## Adapter contract
17+
18+
`PgPlayService.maker_*` and the corresponding MCP tools invoke the separate
19+
`pg-maker` CLI with argument vectors. pg_maker owns its build workers, Git trees,
20+
patch series and caches. Preparation, resolution, build and runtime creation return
21+
after starting a durable worker. Use `maker_status` and `maker_events` to observe
22+
it, and `maker_cancel` to cancel it, including after a client disconnect.
23+
24+
Preparation and resolution accept `config_dir`, `features`, `build_mode`,
25+
`with_doc` and `doc_languages` in Python and MCP. CLI options are
26+
`--config-dir`, `--feature`, `--build-mode`, `--with-doc`/`--without-doc`
27+
and `--doc-language`.
28+
29+
Development operations are `maker_dev_open`, `maker_dev_status`,
30+
`maker_dev_patch`, `maker_dev_explain`, `maker_dev_build`, `maker_dev_exec`,
31+
`maker_dev_pin` and `maker_dev_prune`. The CLI uses matching hyphenated names:
32+
33+
```bash
34+
pg-play maker dev-open ./work --from-run /path/to/operations/RUN
35+
pg-play maker dev-patch ./work commit --scope component:pg-wait-sampling --id fix-build
36+
pg-play maker dev-explain ./work --component pg-wait-sampling
37+
pg-play maker dev-build ./work --component pg-wait-sampling
38+
pg-play maker dev-exec ./work --component pg-wait-sampling -- make -n
39+
pg-play maker dev-prune ./work --keep-last 2 --out ./cleanup.json
40+
pg-play maker dev-prune ./work --keep-last 2 --apply ./cleanup.json
41+
```
42+
43+
Build and debug commands return an operation directory immediately. Observe or
44+
cancel them through the regular maker operation methods. A new development
45+
iteration freezes a new lock; `resume` retains the previous inputs and plan.
46+
Debug commands run inside a private container copy of an iteration's workspace.
47+
Pruning preserves the current and pinned iterations and requires an unchanged
48+
cleanup plan. It does not run a global Docker prune.
49+
50+
`maker_plan(lock, input_store?, goal="package", run_db_tests=False)` returns
51+
`pg_play/maker-plan-v1`: copies of the BuildLock and BuildPlan, parameters and an
52+
overall `plan_hash`. `maker_start(plan, plan_hash, operations, operation_id,
53+
cache_store?)` checks that hash, stores the reviewed inputs under
54+
`.pg-play-plans/OPERATION/`, passes the original maker plan hash and returns
55+
`operation_directory`. Reusing an operation ID with a different plan is rejected.
56+
Resume uses the maker build plan hash, or the input hash for preparation/resolution.
57+
The wrapper plan hash and the maker plan hash are distinct.
58+
59+
`maker_artifacts` lists verified artifact references, manifests, verification records
60+
and reports. `maker_export` copies a finished operation to a new directory.
61+
Ordinary run cleanup is available through pg_maker's CLI/Python API; development
62+
sessions have the separate `maker_dev_prune` operation.
63+
64+
The CLI exposes `pg-play maker validate|prepare|resolve|plan|start|status|events|
65+
cancel|resume|artifacts|export|runtime-plan|runtime-start`. After preparation and
66+
resolution:
67+
68+
```bash
69+
pg-play maker plan build.lock.json --goal package > reviewed-maker.json
70+
pg-play maker start reviewed-maker.json --plan-hash SHA256_FROM_REVIEWED_PLAN \
71+
--operations ./maker-operations --operation-id candidate
72+
pg-play maker status ./maker-operations/candidate
73+
pg-play maker artifacts ./maker-operations/candidate
74+
```
75+
76+
## Runtime image for pg_stand
77+
78+
The initial profile targets Debian 13 / x86_64 with server, client and libpq DEBs
79+
under a custom `/opt/...` prefix. `maker_runtime_plan(artifacts, base_image,
80+
output)` records hashes of packages, the local runtime repository and entrypoint
81+
files. `base_image` must be a prepared local Debian 13 image identified by
82+
`sha256:...`, containing Python 3, gosu, openssh-server, PgBouncer, iproute2,
83+
procps, lshw, sysstat, passwd, util-linux, locales and certificates. Match PgBouncer
84+
to the installed pg_stand profile. A custom platform recipe can add these packages
85+
to `environments.test.packages`; use the resulting image ID from `maker_prepare`.
86+
87+
Runtime construction is offline and does not run initdb or start PostgreSQL. It
88+
checks libraries with ldd. The package payload must contain pg_stat_statements,
89+
pg_buffercache, pg_wait_sampling, pg_stat_kcache and auto_explain under the same
90+
prefix. Create a separate stand feature with these diagnostic components. PGXS
91+
uses maker's internal headers and pg_config; headers and PGXS are excluded from
92+
the delivered packages. Extensions for a different PostgreSQL prefix do not
93+
satisfy this contract.
94+
95+
Pinned starting recipes are in [examples/maker](../examples/maker). Copy the five
96+
component recipes into the maker project's `components/` directory and
97+
`my-feature-stand.yaml` into `config/features/`, then select the feature in
98+
`build.yaml`. Previous local validation compiled the recipes against PostgreSQL
99+
18.1 and checked InstallTree/DEB packaging and offline runtime construction with
100+
`goal=package`, without documentation or database tests. Control and SQL files
101+
were included. pg_stat_statements uses its native check target because upstream
102+
does not support installcheck. CREATE EXTENSION and native database suites remain
103+
separate acceptance checks.
104+
105+
The profile reuses the installed pg_stand entrypoint and PgBouncer helper, hashing
106+
their contents. Updates require a new plan. The custom bootstrap uses maker's
107+
binaries, the postgres account, PGDATA/POSTGRES_* and pg_stand's WAL/log mounts.
108+
Configuration stays in PGDATA. The Unix socket directory is fixed at
109+
`/var/run/postgresql`; do not override it in stand parameters.
110+
111+
The result records the immutable image ID, build/runtime plan hashes, artifact
112+
manifest hash, prefix, version and original qualification. Creating an image does
113+
not raise its qualification. Publishing or exporting that local Docker image is a
114+
separate operation.
115+
116+
## Maker phase in an experiment
117+
118+
Add an optional section to the experiment manifest:
119+
120+
```yaml
121+
spec:
122+
maker:
123+
plan: reviewed-maker.json
124+
plan_hash: sha256:... # pg_play/maker-plan-v1 hash
125+
variant: my-feature-stand.debian13-x64.candidate
126+
runtime_base_image: sha256:... # prepared image with pg_stand utilities
127+
timeout_seconds: 7200
128+
```
129+
130+
Execution order is maker build, package verification, runtime image, pg_stand, then
131+
the existing benchmark/workload/diagnostic phases. Planning uses an image reference
132+
derived from the reviewed inputs. Execution checks the original configuration,
133+
substitutes the produced immutable image ID and records the resulting stand plan
134+
in `RUN/maker/stand-plan.json`. Other settings retain their reviewed values and
135+
`pull_policy=never`. The new image ID changes the desired-state hash. The original
136+
stand YAML is not overwritten.
137+
138+
`RUN/maker/active.json` is written before launching a worker so cancellation can
139+
find it after coordinator loss. Resume reuses successful operations and explicitly
140+
resumes failed ones after checking the maker plan hash. A timeout cancels the
141+
current maker operation. `RUN/maker/provenance.json` and `state.maker` retain
142+
qualification, database-test status and the plan, package and image hashes.
143+
A successful build with `db_tests=skipped` remains `unverified`.
144+
145+
For baseline/candidate comparisons without long database suites, create two
146+
features with the same diagnostic components, one with the ChangeSet and one
147+
without it. Use separate manifests and stand project/storage paths, run the
148+
experiments sequentially and release each active stand through teardown. Compare
149+
their reports with the existing report comparison commands. Maker's built-in
150+
baseline branch is included only when database tests are enabled.
151+
152+
Full database/workload execution is a separate acceptance step. Unit/contract
153+
tests and runtime image construction do not establish all topology/SQL behavior.
154+
155+
## Source-editing workflow
156+
157+
1. Resolve freezes a source snapshot in InputStore. `maker_changes_workspace`
158+
creates a separate editable `source/` tree. Supply `lock` and `feature` to
159+
include common and preceding ChangeSets; `until=CHANGE_ID/OPERATION_ID` selects
160+
the point before that operation. Without a lock, the base is raw upstream.
161+
2. Edit that copy, use `maker_changes_export` to create a ChangeSet and diff, and
162+
check its structure/files with `maker_changes_validate`. ABI, data and WAL
163+
compatibility remain unknown until separately established.
164+
3. Add the ChangeSet to a feature, resolve again and review the new plan hash.
165+
Build, run the experiment and compare it with the baseline.
166+
4. Documentation goals are `doc-source`, `translations`, `translated-docs` and
167+
`docs`. Translation bundles are checked for source identity and completeness;
168+
model credentials and calls remain outside maker.
169+
5. Export results before cleanup. Database build tests require an explicit
170+
`run_db_tests` selection; a quick successful build does not qualify a DB release.

‎examples/maker/auto-explain.yaml‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
api_version: pg_maker/component/v1
2+
kind: ComponentRecipe
3+
metadata:
4+
id: auto-explain
5+
revision: 1
6+
spec:
7+
type: contrib
8+
source_directory: contrib/auto_explain
9+
compatible_postgresql: ==18.1
10+
requires: []
11+
conflicts: []
12+
build_dependencies: []
13+
runtime_dependencies: []
14+
make_targets:
15+
- all
16+
test_targets:
17+
- installcheck
18+
install_targets:
19+
- install
20+
required_tests: []
21+
runtime_files:
22+
- lib/postgresql/auto_explain.so
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
api_version: pg_maker/feature/v1
2+
kind: FeatureProfile
3+
metadata:
4+
id: my-feature-stand
5+
revision: 1
6+
spec:
7+
description: PostgreSQL with pg_stand diagnostic components
8+
numeric_id: null
9+
changes: []
10+
components:
11+
- ../../components/pg-stat-statements.yaml
12+
- ../../components/pg-buffercache.yaml
13+
- ../../components/auto-explain.yaml
14+
- ../../components/pg-wait-sampling.yaml
15+
- ../../components/pg-stat-kcache.yaml
16+
build_options: {}
17+
documentation:
18+
rules: []
19+
required_tests: []

‎examples/maker/pg-buffercache.yaml‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
api_version: pg_maker/component/v1
2+
kind: ComponentRecipe
3+
metadata:
4+
id: pg-buffercache
5+
revision: 1
6+
spec:
7+
type: contrib
8+
source_directory: contrib/pg_buffercache
9+
compatible_postgresql: ==18.1
10+
requires: []
11+
conflicts: []
12+
build_dependencies: []
13+
runtime_dependencies: []
14+
make_targets:
15+
- all
16+
test_targets:
17+
- installcheck
18+
install_targets:
19+
- install
20+
required_tests: []
21+
sql_extension: pg_buffercache
22+
shared_library: pg_buffercache
23+
runtime_files:
24+
- lib/postgresql/pg_buffercache.so
25+
- share/postgresql/extension/pg_buffercache.control
26+
- share/postgresql/extension/pg_buffercache--*.sql

0 commit comments

Comments
 (0)