Upstream released v1.11.0 (e42ae7a, 2026-11-06): 42 commits, mostly
fixes, plus two WebUI features that add ~415 lines to explorer.html
(on-demand bucket size calculation, restore archived objects).
The series needed no content changes — the regenerated patches differ
from the v1.10.0 ones only in their `index <blob>..<blob>` lines, since
the de-brand edits sit above the regions upstream touched. Regenerating
them is still worthwhile: the v1.10.0 patches' pre-image blobs do not
exist in a v1.11.0 clone, so `git am --3way` could not use its 3-way
fallback and was silently applying them directly.
Verified before committing:
- round-trips from a clean clone to tree 8d509fe
- residual branding identical to the patched v1.10.0 tree (23
occurrences, same per-file spread, no regressions)
- all 5 light-mode Tailwind classes in the new explorer markup are
overridden in theme.css
- series touches only webui/; file count 1049 -> 1051
- goreleaser builds all 8 targets plus deb/rpm
- matrix accepts v1.11.0, refuses v1.10.0, PATCH_DIR still rebuilds
the archived series
v1.10.0 moves to patches/archive/ as *superseded*, not vulnerable: it is
the release carrying upstream's CVE-2026-111943 notice, and that fix
comes from the Go toolchain (>= 1.26.10 / 1.27.3) rather than from the
tag. The archive README and the top-level README now say so, instead of
implying every archived series predates a security fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
s3-gateway
Downstream build pipeline that produces de-branded versitygw releases — the upstream Versity S3 Gateway with Versity trademarks and logos removed from the admin web UI.
Same pattern as scoutfs-build: pull an upstream
release tag, apply our patch series scoped to that tag, build
with upstream's GoReleaser, and publish to Gitea Releases.
Artifact names are intentionally unchanged — the binary stays
versitygw and the deb/rpm packages stay versitygw, so builds are
drop-in compatible with existing configs, systemd units, and the
versitygw CLI. Only the embedded web UI is rebranded to "S3 Gateway".
upstream tag (vX.Y.Z) this repo
github.com/versity/versitygw patches/<tag>/*.patch
│ │
▼ ▼
ci/clone-source.sh ───► ci/apply-patches.sh ───► ci/build.sh ───► ci/publish-release.sh
(shallow clone tag) (git am --3way) (goreleaser) (Gitea release assets)
ci/support-matrix.yaml records which upstream versions have a curated
patch set and maps each to its patch directory.
Layout
s3-gateway/
├── ci/
│ ├── support-matrix.yaml # upstream tag -> patch directory (registry)
│ ├── clone-source.sh # shallow-clone upstream versitygw at a tag
│ ├── apply-patches.sh # git am --3way patches/<tag>/*.patch
│ ├── build.sh # goreleaser release (binaries + deb/rpm)
│ ├── publish-release.sh # upload dist/* to a Gitea release
│ └── run.sh # local end-to-end: clone + patch + build one tag
├── patches/
│ ├── v1.11.0/ # the supported series
│ │ ├── 0001-webui-debrand.patch
│ │ └── 0002-webui-dark-theme.patch
│ └── archive/ # superseded; kept, not built
│ ├── v1.10.0/
│ ├── v1.8.0/
│ ├── v1.7.0/
│ ├── v1.6.0/
│ └── v1.5.0/
├── .gitea/workflows/build.yml
└── docs/multi-version-pipeline.md
Build locally
Prerequisites: git, go, and goreleaser.
# Build one upstream tag end-to-end → artifacts in src/dist/
VGW_TAG=v1.11.0 bash ci/run.sh
# Fast offline build against a local upstream clone:
VGW_REPO_URL="/path/to/versitygw" VGW_TAG=v1.11.0 bash ci/run.sh
Or run the steps individually:
VGW_TAG=v1.11.0 bash ci/clone-source.sh # → src/
VGW_TAG=v1.11.0 bash ci/apply-patches.sh # git am the series onto src/
VGW_TAG=v1.11.0 bash ci/build.sh # goreleaser → src/dist/
src/ and src/dist/ are gitignored.
Patches
Patch sets live in patches/<dir>/ as git format-patch files and are
applied with git am --3way, in filename order. The directory for a
tag comes from the patches: field in ci/support-matrix.yaml
(defaults to the tag name).
That matrix is an allowlist: ci/apply-patches.sh refuses any tag
it does not list, so a stray tag push or a mistyped dispatch can't
publish a build of a superseded release.
Currently maintained:
| Upstream tag | Patch set | Contents |
|---|---|---|
v1.11.0 |
v1.11.0/ |
0001-webui-debrand.patch, 0002-webui-dark-theme.patch |
v1.11.0 is the only supported version. It supersedes v1.10.0
with 42 further upstream fixes, so the older series — v1.10.0,
v1.8.0, v1.7.0, v1.6.0 and v1.5.0 — are no longer built.
Their patches are kept under
patches/archive/ for reference and for a
deliberate rebuild; see that directory's README.
Note that protection against CVE-2026-111943 (the Go crypto/x509
eMudhra distrust, announced in upstream's v1.10.0 release notes)
comes from the Go toolchain these binaries are built with, not
from the upstream tag. Build with Go 1.26.10 / 1.27.3 or later.
What the de-brand patch does
- Sidebar/login logos → a plain "S3 Gateway" wordmark.
- Page titles: "VersityGW Dashboard" → "Dashboard" (Buckets, Users, Explorer and the v1.8.0 IAM pages too).
- Browser tab titles → "S3 Gateway – …".
- Removes the sidebar Resources section (external
github.com/versitylinks). - Replaces the Versity favicon with a neutral SVG; deletes the Versity logo PNGs.
- Removes the visible "© Versity Software Inc." footer from the login page.
Deliberately kept (license compliance): the per-file Apache-2.0
license headers — which carry the upstream copyright notice as an HTML
comment at the top of each file — and the NOTICE file. Upstream is
Apache-2.0; the de-brand strips the visible Versity trademarks (logos,
wordmarks, and the login footer) while preserving the copyright notice
in the source headers.
What the dark-theme patch does
0002-webui-dark-theme.patch re-skins the admin UI to match the
kanrisha web app — a near-black palette with indigo/blue accents —
without touching the page markup. It works entirely through the two
shared asset files plus bundled fonts:
tailwind-config.js— remaps the named color tokens (surface,charcoal,primary,accent) onto the dark palette and switches the sans/mono fonts to Inter / JetBrains Mono.theme.css— sets the dark body, restyles the bespoke components (sidebar active state, dropdowns, toggles, checkboxes, file rows, login) in indigo, and adds an override layer that flips the built-in Tailwind white/gray/status utilities the markup uses.fonts.css+assets/fonts/*.woff2— self-hosts Inter and JetBrains Mono (variable, latin + latin-ext) so the UI stays fully offline, matching the existing self-hosted Roboto.
The only markup change is the login page's light background gradient,
which becomes a solid dark surface. It is part of the supported
v1.11.0 series, and of every archived set except v1.5.0.
Adding / refreshing a version
When upstream cuts a new release you want a build of, you rebase the patch series onto it and add a patch directory. See docs/multi-version-pipeline.md for the full recipe. In short:
# Rebase the series onto the new tag, re-export into patches/vX.Y.Z/
git clone https://github.com/versity/versitygw && cd versitygw
git -c core.autocrlf=false checkout -b debrand vX.Y.Z
git am --3way /path/to/s3-gateway/patches/<prev>/*.patch # resolve any conflicts
git format-patch --binary vX.Y.Z..HEAD -o /path/to/s3-gateway/patches/vX.Y.Z/
Then add the tag to ci/support-matrix.yaml, commit, and build it (see
below).
CI
.gitea/workflows/build.yml builds one version per run and
publishes it to a Gitea release in this repo. It triggers two ways — no
scheduled/cron builds:
- By new tag — push a
vX.Y.Ztag to this repo; CI builds upstream versitygwvX.Y.Zwithpatches/vX.Y.Z/. - One-shot — run the build workflow manually (workflow_dispatch) and enter the upstream tag to build.
Either way the tag must appear in ci/support-matrix.yaml; if it does
not, the patch step fails the run rather than publishing an
un-de-branded or superseded build.
Configuration:
- Runner: any Linux runner (
runs-on: ubuntu-latest). The Go toolchain comes from thegolangcontainer, so the runner only needs Docker. - Secret:
TOKEN_GITEA— a Gitea PAT with write:repository (clones this repo + creates releases / uploads assets). - Variable (optional):
VGW_REPO_URLto override the upstream URL.
License
Apache-2.0, matching versitygw upstream. Upstream copyright and
NOTICE are retained in every build.