Archived
CI: a pull request must not touch the :latest tag
Gating only the push was not enough. This runner builds on the host's Docker daemon — the same daemon the live container runs on — so `docker build -t …: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. That is not hypothetical. The PR builds for this branch deployed unmerged code to itsthevine.com several times this evening, and each time Watchtower's next pull of the older registry :latest reverted it, so the site flapped between the two. One of those deploys ran V4 against the production database, which is why the wedding-row correction had to be a new migration rather than an edit to V4. A PR now builds pr-<number>, which nothing watches; Trivy scans whatever was built; the push step is unchanged and still only runs off a PR. Nothing was lost — 40 products, 6 categories and 2 enquiries are all present, and the old image tolerates the newer schema (it warns that the schema is ahead of its migrations and carries on). The other five apps on the platform share this workflow and this daemon, so they have the same hole — including for Renovate's PRs, which build before they automerge. Not touched here; each needs the same three lines and its own green run.
This commit is contained in:
@@ -40,7 +40,26 @@ jobs:
|
|||||||
mvn -B -ntp -s .gitea/ci-settings.xml -DskipFrontend=true verify
|
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
|
# 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 was not enough; on 2026-07-26 the PR
|
||||||
|
# builds for this branch deployed unmerged code to itsthevine.com several times over, and each time
|
||||||
|
# Watchtower's next pull of the (older) registry :latest reverted it. One of those deploys ran a
|
||||||
|
# migration against the production database.
|
||||||
|
#
|
||||||
|
# So a PR builds pr-<number> instead, 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
|
- name: Build image
|
||||||
env:
|
env:
|
||||||
DOCKER_BUILDKIT: "1"
|
DOCKER_BUILDKIT: "1"
|
||||||
@@ -51,17 +70,18 @@ jobs:
|
|||||||
--secret id=maven_user,env=MAVEN_USER \
|
--secret id=maven_user,env=MAVEN_USER \
|
||||||
--secret id=maven_token,env=MAVEN_TOKEN \
|
--secret id=maven_token,env=MAVEN_TOKEN \
|
||||||
--build-arg GIT_SHA=${{ github.sha }} \
|
--build-arg GIT_SHA=${{ github.sha }} \
|
||||||
-t git.thebennett.net/thevine/itsthevine:latest -t git.thebennett.net/thevine/itsthevine:${{ github.sha }} .
|
-t "git.thebennett.net/thevine/itsthevine:$IMAGE_TAG" \
|
||||||
|
-t "git.thebennett.net/thevine/itsthevine:${{ github.sha }}" .
|
||||||
|
|
||||||
- name: Scan image (Trivy)
|
- name: Scan image (Trivy)
|
||||||
run: |
|
run: |
|
||||||
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
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 \
|
aquasec/trivy:latest image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --no-progress \
|
||||||
git.thebennett.net/thevine/itsthevine:latest || true
|
"git.thebennett.net/thevine/itsthevine:$IMAGE_TAG" || true
|
||||||
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
aquasec/trivy:latest image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed \
|
aquasec/trivy:latest image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed \
|
||||||
--pkg-types library --exit-code 1 --no-progress \
|
--pkg-types library --exit-code 1 --no-progress \
|
||||||
git.thebennett.net/thevine/itsthevine:latest
|
"git.thebennett.net/thevine/itsthevine:$IMAGE_TAG"
|
||||||
|
|
||||||
# Publish only on a real push to main (or manual dispatch) — never from a pull request.
|
# Publish only on a real push to main (or manual dispatch) — never from a pull request.
|
||||||
- name: Push image
|
- name: Push image
|
||||||
|
|||||||
Reference in New Issue
Block a user