Commit Graph
13 Commits
Author SHA1 Message Date
jcoffey-dev 00f00d6d75 ci: copy each release image to GHCR as a replica
ci / fork-checks (pull_request) Skipped
ci / build (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 6m27s
The Gitea registry stays authoritative; GHCR becomes a copy of it, the way
the GitHub repository is a copy of the Gitea one. After the tag build has
pushed the release image to the registry, a new ghcr job copies it to
ghcr.io under the same version tag and :latest with `imagetools create` --
a copy, not a rebuild, so the digest on GHCR is the digest on the registry.

Anything still pulling the old ghcr.io name, including the TrueNAS app
submission, keeps receiving releases. The job uses the run's own token and is
left out of the status reported to Gitea, so a GHCR problem cannot fail a
release.
2026-09-30 09:27:55 -07:00
jcoffey-dev 68d3ad795e Merge pull request 'ci: copy each release to GitHub after the tag build' (#131) from ci/github-release-copy into main
ci / fork-checks (push) Skipped
ci / build (push) Skipped
github/ci (branch) GitHub Actions
ci / github (push) Successful in 50m7s
2026-09-30 13:59:22 +00:00
jcoffey-dev e69df1ae8d ci: copy each release to GitHub after the tag build
ci / fork-checks (pull_request) Skipped
ci / build (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 6m47s
The mirror carries tags to GitHub but not releases, so the replica's
Releases page -- and anyone watching the repository there -- stopped at the
last release made on GitHub. After the tag build has published, a new
github-release job copies the tag's Gitea release to a GitHub release: the
same notes, with PR and issue numbers rewritten to Gitea links, the same
files, and a line pointing back to the Gitea release.

It uses the run's own token and is left out of the status reported to
Gitea, so it cannot fail a release. With no Gitea release for the tag it
does nothing.
2026-09-30 06:52:24 -07:00
jcoffey-dev 031d028ba4 ci: drop the build cache from tag image builds
ci / fork-checks (pull_request) Skipped
ci / build (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 7m28s
GitHub scopes a run's Actions cache to its ref, so the cache a tag build
wrote could only ever be read by that same tag: the next release built cold
anyway. Each release also parked several GB of Rust layers in the
repository's 10 GB cache, enough to evict main's cargo cache and slow
everyday builds too. The image builds now run without a cache.
2026-09-30 06:44:41 -07:00
jcoffey-dev 4ba1896eb1 ci: a cancelled GitHub run no longer reports failure to Gitea
ci / fork-checks (pull_request) Skipped
ci / build (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 6m5s
The mirror can push one commit twice in quick succession. GitHub then
starts two runs and cancels the older, and that run's report job posted
"failure" for the commit. Gitea's github job, seeing the newest status,
failed the check while the surviving run was still building and later
passed.

A cancelled run now posts nothing and leaves the result to the run that
superseded it. A real failure still reports failure.
2026-09-30 00:26:48 -07:00
jcoffey-dev 3450c31345 Build on the GitHub mirror when BUILD_ON=github
ci / build (pull_request) Successful in 7m46s
ci / github (pull_request) Skipped
ci / fork-checks (pull_request) Successful in 2m4s
Gitea stays where the project lives and push-mirrors every branch and tag
to GitHub. With the Actions variable BUILD_ON set to 'github' on both
forges, the GitHub copy does the building and reports back to Gitea as a
commit status; unset, nothing changes and Gitea builds as before.

.github/workflows/ci.yml replaces the GitHub-era files. Branch pushes run
what Gitea's ci.yml checks (fork checks, dev build, test targets, the
release profile on main). v* tags run what publish.yml does, with the same
two guards: the image per architecture on native runners side by side,
the multi-arch index and :latest, the Gitea Release if the tag has none,
and the host-install binaries taken out of the image. A final job posts
"github/ci (branch)" or "github/ci (tag)" to the commit on Gitea.

On Gitea, the heavy jobs skip under BUILD_ON=github and a `github` job
waits for that status and passes or fails with it, so pull requests and
merges still look at a Gitea run. The weekly release, the upstream watch
and the announcement stay on Gitea.

Removed: cleanup.yml and publish.yml (GHCR), release.yml (a second weekly
schedule), and dependabot.yml, whose pull request branches every mirror
sync would delete.
2026-09-29 23:06:52 -07:00
jcoffey-dev bc2ae32207 The weekly release lands its bump through a pull request
main is protected as of today -- no force-push, no deletion, and a pull
request with a green build to merge -- and GITHUB_TOKEN is not a bypass
actor. `git push origin HEAD:main` in the cut job would have been refused
from Monday, on a scheduled run nobody watches.

GitHub would not take the obvious fix. Adding the Actions integration as a
bypass actor is rejected ("must be part of the ruleset source or owner
organization") because the organization has no app installations. The
other two routes -- an organization-level ruleset, a deploy key with write
access -- both amount to handing the release a credential that outranks
the rule, which is a worse thing to own than a slower Monday.

So the bump lands the way every other change does. It commits to
release/v<version>, opens a pull request, waits for the build the ruleset
requires, merges, and tags what came out. The waiting is not merely the
rule being satisfied: a release cut from a tree that does not compile is
the failure this whole arrangement exists to prevent, and until now
nothing checked.

Three details that would each have produced a wrong tag. The sha comes
from GitHub's merge commit, not the tip that was pushed, because a rebase
merge rewrites it. The pull request is tracked by number, not by branch,
because the branch is deleted on merge and a deleted branch no longer
resolves to its pull request. And a failed or slow build leaves the pull
request open and cuts nothing, rather than tagging whatever main happened
to hold.

Quiet weeks are unaffected: the tag still names the bump commit, so
`previous..HEAD` is still zero when nothing else has landed.

The cost is a Monday run that now takes as long as a full build -- about
25 minutes at the moment, most of it saving the cache.
2026-09-20 16:53:29 -07:00
jcoffey-dev f95f10809a Release weekly, and publish an image
The fork had CI and nothing after it. v2026.9.20 was tagged and released
by hand, and there has never been an image: running INBUXA meant
building the tree yourself, or using install.sh to do it for you.

This adds the three workflows ihasmail already runs -- weekly release,
publish, prune.

Monday 10:07 UTC, and nothing on a quiet week. Last of the three, so
INBUXA Admin and the webmail release ahead of the server they talk to,
and staggered so 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's
lives in the brand_version! macro, deliberately apart from Cargo.toml so
upstream's bumps merge without conflicts -- 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 macro cannot promise.

Both the bump and the read are scoped to the macro body and fail if they
do not match exactly once. branding.rs holds other string literals, and
a bump that silently edited one of those, or an image tagged from one,
would be worse than a run that stops.

The existing Dockerfile needs nothing: it cross-compiles from
BUILDPLATFORM and takes no arguments beyond TARGETPLATFORM, so each
architecture builds on its own native runner as ihasmail's does, without
docker-bake.hcl. `docker build --check` is clean.

Two things to expect from the first run. GHCR creates a package private
the first time even in a public repository, and no workflow can change
that, so the first image will refuse an anonymous pull until its
visibility is set by hand. And a full Rust build of this tree is long;
the per-platform GitHub Actions cache is what keeps the second one from
being just as long, and it is worth watching that it stays inside the
cache limit.
2026-09-20 15:42:25 -07:00
dependabot[bot] b39694f03b Bump Swatinem/rust-cache in the actions group
Bumps the actions group with 1 update: [Swatinem/rust-cache](https://github.com/swatinem/rust-cache).


Updates `Swatinem/rust-cache` from 49a0bdc70d2e1b713ca9e2869b211fcce03d3c1c to 6323deb102c322ba6fcbdcafc7e3dddab59af2b6
- [Release notes](https://github.com/swatinem/rust-cache/releases)
- [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md)
- [Commits](https://github.com/swatinem/rust-cache/compare/49a0bdc70d2e1b713ca9e2869b211fcce03d3c1c...6323deb102c322ba6fcbdcafc7e3dddab59af2b6)

---
updated-dependencies:
- dependency-name: Swatinem/rust-cache
  dependency-version: 6323deb102c322ba6fcbdcafc7e3dddab59af2b6
  dependency-type: direct:production
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-09-20 14:22:45 -07:00
jcoffey-dev a63839f6b0 The repository's own .github, now that it is public
SPEC 2.2a says INBUXA writes its own when the repository is first published,
and it is. Until now the public repository carried Stalwart's: a security
policy telling people to report vulnerabilities to Stalwart Labs, and a
contributing guide whose policy is that pull requests from anyone not on
upstream's vouched list are closed automatically. Neither is this project's,
and both were being offered to anyone who looked.

So: a security policy that says where to send a report, and what happens if
it turns out to be upstream's bug rather than ours; a contributing guide that
says what a fork of someone else's code needs from a contributor, including
the clean-room question, since the record has to stay true; the Contributor
Covenant; and a sponsor link. Upstream's two security documents move to
.github-upstream/ beside its workflows -- kept, not used, not presented as
ours.

CI builds the server and compiles every test target, and deliberately runs
no suite. The unit tests only build with the integration crate in the graph,
and the integration suites want a STORE, fixed ports and a container apiece,
so running them here would mean a tick that skipped everything or a cross
that means "the runner has no Redis". The workflow says as much, so nobody
has to rediscover it.

Also ignores /artifact: two hand-built binaries, ~190 MB, one `git add -A`
away from a public repository.
2026-09-20 00:00:05 -07:00
jcoffey-dev d3f0b36dd2 Packaging: the binary and package are inbuxa, INBUXA_* settings with STALWART_* fallback
- crates/main: package and [[bin]] renamed to inbuxa; homepage inbuxa.org;
  license AGPL-3.0-only (upstream is dual; the fork takes the AGPL).
- types::branding::env_var reads INBUXA_<name>, falling back to
  STALWART_<name> with a warning, for all nine server settings.
  STALWART_APP_ and STALWART_SPAM_* storage keys are unchanged.
- New-install default paths /var/lib/inbuxa and /var/log/inbuxa.
- Dockerfiles, systemd unit, launchd plist and AppArmor profile renamed.
- Upstream's .github moved to .github-upstream so none of it runs.
- install.sh stubbed: upstream's would install Stalwart.
- Two missed brand strings: the SMTP Received header and the utils user agent.
2026-09-18 11:09:22 -07:00
jcoffey-dev 083474f67a Re-import upstream v0.16.22, stripped (strip tool update)
The strip tool now also removes enterprise from build scripts' --features
lists (Dockerfiles, CI), so the container and release builds work.

Upstream commit: 474dd0229cb20cf513036619781ed97bd8073c3f
Enterprise-only files removed or emptied: 63
Enterprise-only snippets removed: 117 in 50 files
Dangling module declarations removed: 5
Edits turning enterprise off: 25 (11 in build scripts)
Verification: clean
2026-09-18 10:52:56 -07:00
jcoffey-dev 7dae9b29fd Import upstream v0.16.22, stripped
Upstream commit: 474dd0229cb20cf513036619781ed97bd8073c3f
Enterprise-only files removed or emptied: 63
Enterprise-only snippets removed: 117 in 50 files
Dangling module declarations removed: 5
Cargo edits turning enterprise off: 14
Verification: clean
Enterprise feature gates left for rebuilt features: 19 in 18 files

Produced by tools/fork/strip.py. The full report is in docs/fork/strip-reports/ on main.
2026-09-18 10:21:56 -07:00