Commit Graph
4 Commits
Author SHA1 Message Date
jcoffey a157fed8f2 Release weekly, and publish an image (#5)
INBUXA Admin had CI and nothing after it: twelve tags inherited from
upstream's numbering, no GitHub releases at all, and no image. Deploying
it meant building the tree yourself.

This adds the three workflows ihasmail already runs -- weekly release,
publish, prune -- and the Dockerfile they need.

Monday 09:37 UTC, and nothing on a quiet week. Staggered twenty minutes
behind ihasmail-inbuxa's and twenty ahead of the server's, so three
releases do not compete for runners and a bad Monday names one
repository rather than three.

The version is the difference from ihasmail. ihasmail derives its
version from the commit it builds, so its release only reads. INBUXA
Admin keeps its version in inbuxa-version.json, so the release writes
it: the bump is committed to main and the tag names that commit. The
tree a tag points at therefore reports the version the tag claims, which
a tag placed beside an unbumped file cannot promise. The bump is written
with a JSON parser rather than sed, because a version substituted into
JSON as a string is one stray quote from a file nothing can read.

The image is nginx serving the built files and nothing else -- the
interface talks to the mail server from the browser, never from the
container. It is built from source in the image rather than copied from
dist/, so an image always matches the commit it claims.

One image serves any installation: API_BASE_URL writes the
`<meta name="api-base-url">` tag that README already documents as the
deploy-time way to point the interface at its server. Set nothing and
the container still starts, for a build that was given
VITE_API_BASE_URL instead.

Two things the smoke test found rather than review. Unprivileged nginx
runs as uid 101, so the copied files are chowned to it or the tag can
never be written. And the directory stays root's, so the entrypoint
writes back through the existing file instead of `sed -i`, which
replaces the file and needs to create a temp file in the directory.

Verified by running it: the tag lands, a deep route falls back to
index.html, hashed assets come back immutable while index.html is
no-cache, it runs as uid 101, and it starts with no API_BASE_URL set.
2026-09-20 16:12:20 -07:00
jcoffey 4720470a3d The source offer is a link to this fork, not a tarball beside the app (#7)
INBUXA Admin built its own source into every deployment: the whole tree
packed as source.tar.gz next to the app, with an identity string shown
beside the link and in the version tooltip. The top bar menu and the
source link offered that download.

It answered the AGPL precisely -- the source of *this* build, uncommitted
work and all -- but it paid for that by carrying the tree into every
deployment, to a repository that is public and already has it. The
version shown beside the link already names the build, so the link and
the version together say what the archive said.

This is the same change already made to ihasmail-inbuxa, for the same
reason, and it leaves the two forks answering the offer the same way.

It is also what lets INBUXA Admin be built in an Alpine image: the
plugin shelled out to `tar --transform`, which BusyBox tar does not
have, so `npm run build` failed there and nowhere else.

Removed with it: source-archive.ts, the Vite plugin call, __SOURCE_ID__
and sourceDownloadUrl(). The build no longer shells out to git or tar,
and nothing is written next to the app.

The two strings that named the archive change with it: the link now
reads "Source code (<version>), AGPL-3.0" rather than naming a tree id,
and the version tooltip drops the id it appended.
2026-09-20 16:10:27 -07:00
jcoffey fa42a74697 Take the lint error out of main (#6)
`npm run lint` fails on main, and has since CI was added, so every pull
request opened against it starts red for a reason that has nothing to do
with the change in it. Two unrelated PRs came back with the same failure,
which is how it was found.

    vite.config.ts
      1:1  error  Do not use a triple slash reference for vitest/config,
                  use `import` style instead

The reference was doing one job: putting the `test` key in scope for
defineConfig. Importing defineConfig from vitest/config rather than vite
does the same job in the style the rule asks for, and the file already
imported configDefaults from there on the next line.
2026-09-20 16:08:17 -07:00
jcoffey 93a76098cc Update README to remove development status
Removed status indication from README.
2026-09-19 23:46:37 -07:00