Skip to content

feat(installer): ship a Windows setup with PostgreSQL 17 - #20

Draft
mrcsin wants to merge 28 commits into
site-loopback-and-restartfrom
windows-installer
Draft

mrcsin wants to merge 28 commits into
site-loopback-and-restartfrom
windows-installer

Conversation

@mrcsin

@mrcsin mrcsin commented Oct 19, 2026

Copy link
Copy Markdown
Member

Commissioning a machine today takes three manual steps: install PostgreSQL with winget, run semibase site, restart the service. A suite installer cannot chain that.

SemiBase-Setup.exe (Inno Setup) does it in one run. It carries the EDB PostgreSQL 17 installer, pinned by SHA256, installs it when the machine has no PostgreSQL, uses a registered 17 when there is one, refuses every other engine state, then runs semibase site --restart-service. Exit code 0 means provisioned. Passwords reach semibase through the environment, never a command line.

Plan: docs/plans/20261019-windows-installer.md. Stacked on #19.

Verification: in progress, task by task. The installer CI job runs the setup silently on windows-latest, one case per state the plan lists.

mrcsin added 28 commits October 19, 2026 17:20
SemiBase-Setup.exe needs a script before it can provision anything.
This one carries semibase.exe into {app}, the EDB installer stored
uncompressed for [Code] to extract, and the C:\DISTR log folder.

PrepareToInstall refuses a missing superuser password, a password that
is not printable ASCII, and a superuser password with " or a trailing
\, so a refusal exits 7 before a file is copied. Setup's parser drops
every " from its command line, measured here, so a password parameter
that does not appear verbatim in GetCmdTail is refused as well.
A windows-latest job builds semibase.exe, fetches the cached EDB
payload, compiles the setup and runs it with no superuser password:
it must exit 7, install nothing and leave postgresql-x64-17 Disabled.
Until now a usable 17 or a clean machine made Setup copy semibase.exe
and exit 0 with nothing provisioned. PrepareToInstall now does the work
before a file is copied, so exit 0 means provisioned.

On a clean machine it runs the EDB installer with an option file under
{tmp}, deleted as soon as EDB returns, and reads the install back from
the registry like any registered 17. It then sets the service to
Automatic, starts it, waits up to 60 s for the port, and runs
semibase site with the passwords in Setup's environment and its output
in C:\DISTR\Logs\SemiBase\site-*.log. A non-zero EDB or site exit, or
a port that stays closed, is a refusal naming the log.

ExtractTemporaryFile matches the DestName of a [Files] entry, measured
with a scratch setup and recorded in installer.md.
Acceptance case 2: Setup with SEMIBASE_SUPER_PASSWORD=root and a writer
token in its environment must exit 0, leave postgresql-x64-17 Automatic
and let semiplot read semiplot_tags with password semiplot.
An interactive Setup had no way to take the superuser and scada_writer
passwords: it refused every run that came without a parameter or a
SEMIBASE_* variable. A password page now holds both, prefilled from the
same resolution, and PrepareToInstall reads its passwords from the page
in every mode, so the checks keep one input. Next on the page refuses an
empty superuser field, an unprintable or EDB-breaking password, and an
empty writer field when no PostgreSQL is registered; PrepareToInstall
still enforces each rule. Under /SILENT Setup simulates Next on the page,
so the page check returns True there and silent runs refuse exactly as
before.
The setup replaces the bare Windows binary as the commissioning path,
and Inno Setup needs a Windows runner while the image needs Linux. The
one release job becomes build, installer and release: the Windows
binary only feeds the setup, and the release page carries the Linux
binary and SemiBase-Setup.exe. "Latest" is still decided once in the
build job, and the image is still built and smoke-run before the
release and pushed after it.
The setup replaced winget, the bare Windows binary and the manual
restart, but every doc still described them. deployment.md now gives
the silent command line with Start-Process -Wait, the parameters, the
SEMIBASE_* fallbacks, exit codes 0 and 7, the setup and site logs, the
three state tables in operator terms, and the recovery section every
engine refusal points to, including the manual semibase.exe run.
README, CLAUDE.md, the architecture index, provisioning.md and
overview.md follow the three-job release and the two release assets;
installer.md gains what the setup does.
Every refusal came before the [Files] copy and the release no longer
attaches the Windows binary, so a machine where Setup never succeeded
had no semibase.exe for the manual recovery, and an offline site could
not get one. Every run now copies the carried binary to
C:\DISTR\Tools\SemiBase before any check.

The EDB password rules (ASCII, ", trailing \) refused a registered 17
whose password reaches semibase byte for byte; they now hold on the
fresh-install row only, which also refuses a leading - and leading or
trailing spaces nobody measured. An unquoted space in a password
parameter no longer passes as its first half. SEMIBASE_WRITER_PASSWORD
is always set, so a cleared field does not let the caller's value reset
scada_writer. The port probe dials localhost like semibase and tells a
failed probe from a closed port; registry values cmd.exe would change
are refused; an exception reaches the setup log; the dead [Dirs] entry
and the one-read Fresh field are gone. The payload has a fixed name, so
the pin lives in the fetch script, and Inno Setup is pinned to the
measured 6.7.3 in one composite action.

CI now runs every reachable engine row, the remaining password rules,
the variable channel on the fresh install with a watch on the option
file, a superuser-only re-run, a writer password change under full
statement logging, and a wrong registered port.
The release installer job compiled SemiBase-Setup.exe and attached it
without ever running it. It now runs the shipped setup once with no
password, requires the refusal, and requires the semibase.exe the
setup copied out to print the tag. The build steps come from the
shared build-setup action, so release and CI compile the same way.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant