Compare commits

23 Commits
Author SHA1 Message Date
austin c56bc4ab96 Merge pull request 'Update bennett platform to v0.1.11' (#11) from renovate/bennett-platform into main
build-and-publish / build (push) Successful in 2m46s
2026-08-19 11:42:49 -05:00
austin 5ebe62c1a0 Update bennett platform to v0.1.11
build-and-publish / build (pull_request) Successful in 2m0s
2026-08-19 16:35:57 +00:00
austin cc706708d2 Merge pull request 'A pull request must not touch :latest' (#9) from ci/pr-image-tag into main 2026-07-27 09:58:25 -05:00
austin 2ab40a7e29 A pull request must not touch :latest
This runner builds on the host's Docker daemon — the same daemon the live
container runs on — so retagging :latest IS a deployment. Watchtower compares
the running container's image against :latest, sees they differ, and recreates
the container from whatever was just built locally. Gating only the push was
never enough; the build itself was the deploy.

The worse failure is quieter. Reassigning :latest leaves the running
container's old image untagged, and once that image is pruned Watchtower can no
longer read it to compare against:

  Failed to retrieve container image info: No such image: sha256:…
  Unable to update container: no available image info.

bennett-portfolio hit exactly that. It sat on a four-day-old build, failing to
update 720 times in twenty-four hours, reporting healthy the whole time, and had
to be recreated by hand. This repo has the same workflow and the same exposure —
it simply has not been unlucky yet.

A PR now builds pr-<number>, which nothing watches. Trivy scans whatever was
built either way, so a bad Dockerfile or a new CVE still blocks the merge, and
the push step is unchanged — still main-only.
2026-07-27 09:53:23 -05:00
austin 219df305ae Merge pull request 'Update bennett platform to v0.1.10' (#8) from renovate/bennett-platform into main 2026-07-26 22:01:41 -05:00
austin 5cf6e5a630 Update bennett platform to v0.1.10 2026-07-27 02:57:41 +00:00
austinandaustin 39a7a91a8c docs: add CONTRIBUTING guide (#6)
Co-authored-by: austin <[email protected]>
2026-07-23 14:42:09 -05:00
austin cda4b0aaf1 Merge pull request 'CI: gate the merge on tests' (#5) from ci/gate-merge into main 2026-07-23 13:54:03 -05:00
austin aefc85a2bb CI: gate the merge, not just the image
Run the workflow on pull_request too, so tests + build + Trivy must pass before main can be
merged (branch protection requires this check). Push the image only on a real push to main —
never from a PR. Also standardises the workflow across all apps (three had drifted).
2026-07-23 13:54:02 -05:00
austin 16d816330d CI: actually run the tests, and let them gate the image
The image build runs 'mvn -DskipTests' and the workflow was only build -> Trivy -> push, so
no app test has ever run in CI — only Trivy gated a merge. The platform contract tests added
in 0.1.9 were not running either, which defeated their purpose.

They cannot run inside 'docker build' — Testcontainers needs a Docker daemon and a build has
none. Maven runs as a sibling container instead, mounting the workspace volume act_runner
gave this job (matched on GITHUB_WORKSPACE, since it is mounted at the full repo path rather
than at /workspace) and sharing the host network so published test ports resolve as localhost.

Verified on itsthevine before rolling out here: 33 tests ran, and a deliberately failing test
failed the run at the Test step with the registry digest unchanged — no image published.
2026-07-23 12:20:41 -05:00
austin 055c2c2891 Restore the dependency upgrades I reverted
The merged Renovate bumps were undone when I rsync'd a local tree over these repos while
pushing the contract tests — that local package.json was a pre-merge backup I had kept so
the PRs would be the source of the versions.

Re-applied and verified from a clean install (rm -rf node_modules package-lock.json &&
npm install && tsc && vite build), which is also what regenerates a lock file consistent
with all the bumps at once.
2026-07-23 09:56:47 -05:00
austin 31e7b78ca2 Inherit the platform contract tests, and extend the shared Renovate preset
PlatformWebContract asserts what this app must do because it is on the platform: an /api
path matching no controller 404s rather than returning the SPA, health is UP, the liveness
and readiness probes exist, and a client-side route forwards to the shell. That first one
shipped broken to six live sites and was found by typing a URL by hand; now it fails a
build instead.

renovate.json is three lines pointing at austin/renovate-config. The rules were copied per
repo, so they matched only by luck and a change was six edits.

Platform 0.1.9.
2026-07-23 09:46:54 -05:00
austin cc5cae18ee Merge pull request 'Update dependency typescript to v7' (#3) from renovate/typescript-7.x into main 2026-07-23 08:52:24 -05:00
austin 38bce8c6eb Merge pull request 'Update dependency lucide-react to v1.26.0' (#2) from renovate/lucide-monorepo into main 2026-07-23 08:51:00 -05:00
austin 2178934d7c tsconfig: drop baseUrl, which TypeScript 7 removed
TS7 errors with 'Option baseUrl has been removed'. The paths mapping already points at
./src/*, which resolves relative to this file without it, and TS 5.9 accepts the same
config — so this lands safely ahead of the TypeScript 7 bump.
2026-07-23 08:50:09 -05:00
austin 773f20348e Update dependency typescript to v7 2026-07-23 12:44:24 +00:00
austin e8715f3bf4 Merge pull request 'Update bennett platform to v0.1.7' (#1) from renovate/bennett-platform into main 2026-07-23 07:44:24 -05:00
austin f3f459f600 Update dependency lucide-react to v1.26.0 2026-07-23 12:44:23 +00:00
austin f7a341b712 Update bennett platform to v0.1.7 2026-07-23 12:44:22 +00:00
austin 37a387e7b1 Rebuild on the Bennett platform: Spring Boot + Vite/React
Same site — glass header, bento grid, hero drift, dark mode — with three things fixed
on the way:

- Tailwind and lucide came from CDNs on every page load, and the fonts from Google. All
  are now built in or self-hosted, so the site owes nothing to third parties at runtime.
- The hero and bento photographs were hot-linked from Unsplash. They are re-encoded to
  webp and served from the MinIO bucket with a year-long cache.
- The ministries and labs were hard-coded in the markup, so launching a ministry meant
  editing HTML. They now come from /api/network.

The mobile menu button also opens something now; it did nothing before.
2026-07-23 07:30:01 -05:00
austin fe71a1864c Add Docker build + Gitea Actions CI (self-host at reformedwitness.net) 2026-07-22 12:59:01 -05:00
Austin ac09f91938 2.0 site 2026-02-03 09:21:50 -06:00
Austin 98e0e8c765 first commit 2026-02-03 09:21:28 -06:00
3 changed files with 35 additions and 7 deletions
+32 -4
View File
@@ -40,7 +40,35 @@ jobs:
mvn -B -ntp -s .gitea/ci-settings.xml -DskipFrontend=true verify
# Build + Trivy on every run (PRs included), so a broken Dockerfile or a new HIGH/CRITICAL CVE
# blocks the merge. Only the push is main-only.
# blocks the merge.
#
# A PULL REQUEST MUST NOT TOUCH THE :latest TAG. This runner builds on the host's Docker daemon —
# the same daemon the live container runs on — so retagging :latest IS a deployment: Watchtower
# compares the running container's image against :latest, finds they differ, and recreates the
# container from the locally built image. Gating only the push is not enough; the build is the
# deploy.
#
# The damage is not only that unmerged code ships. Reassigning :latest leaves the running
# container's old image untagged, and once that image is pruned Watchtower can no longer read it
# to compare against, so it gives up every cycle:
#
# Failed to retrieve container image info: No such image: sha256:…
# Unable to update container "/<name>": no available image info.
#
# That happened to bennett-portfolio on 2026-07-27: it sat on a four-day-old build, failing to
# update 720 times in twenty-four hours, reporting healthy throughout. It had to be recreated by
# hand. This repo has the same workflow and the same exposure.
#
# So a PR builds pr-<number>, which nothing watches. Trivy scans whatever was built, and the push
# step below still only runs off a PR.
- name: Choose the image tag
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "IMAGE_TAG=pr-${{ github.event.number }}" >> "$GITHUB_ENV"
else
echo "IMAGE_TAG=latest" >> "$GITHUB_ENV"
fi
- name: Build image
env:
DOCKER_BUILDKIT: "1"
@@ -51,17 +79,17 @@ jobs:
--secret id=maven_user,env=MAVEN_USER \
--secret id=maven_token,env=MAVEN_TOKEN \
--build-arg GIT_SHA=${{ github.sha }} \
-t git.thebennett.net/reformedwitness/rwn-website:latest -t git.thebennett.net/reformedwitness/rwn-website:${{ github.sha }} .
-t "git.thebennett.net/reformedwitness/rwn-website:$IMAGE_TAG" -t git.thebennett.net/reformedwitness/rwn-website:${{ github.sha }} .
- name: Scan image (Trivy)
run: |
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --no-progress \
git.thebennett.net/reformedwitness/rwn-website:latest || true
"git.thebennett.net/reformedwitness/rwn-website:$IMAGE_TAG" || true
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed \
--pkg-types library --exit-code 1 --no-progress \
git.thebennett.net/reformedwitness/rwn-website:latest
"git.thebennett.net/reformedwitness/rwn-website:$IMAGE_TAG"
# Publish only on a real push to main (or manual dispatch) — never from a pull request.
- name: Push image
+1 -1
View File
@@ -11,7 +11,7 @@
"dependencies": {
"react": "^19.2.7",
"react-dom": "^19.2.7",
"lucide-react": "1.27.0"
"lucide-react": "1.26.0"
},
"devDependencies": {
"@tailwindcss/vite": "4.3.3",
+2 -2
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-parent</artifactId>
<version>0.1.9</version>
<version>0.1.11</version>
<relativePath/>
</parent>
@@ -22,7 +22,7 @@
<dependency>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>0.1.9</version>
<version>0.1.11</version>
<type>pom</type>
<scope>import</scope>
</dependency>