diff --git a/.env.example b/.env.example index 2b72ef2c7c..0fcfc3b2a1 100644 --- a/.env.example +++ b/.env.example @@ -262,10 +262,7 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review # # starts Redis automatically; override for an external Redis. # GITTENSORY_IMAGE=ghcr.io/jsonbored/loopover-selfhost:latest # image used by scripts/deploy-selfhost-image.sh; # # pin production rollouts to a release tag such as :orb-v0.1.0 -# # or to an immutable @sha256 digest. #4770: the pre-rename -# # ghcr.io/jsonbored/gittensory-selfhost name is a deprecated -# # alias of the same image during the deprecation window (#4777) -# # -- an existing pin to it keeps working unmodified. +# # or to an immutable @sha256 digest. # GITHUB_CACHE_TTL_SECONDS=20 # Enables the Redis-backed GitHub GET-response cache when >0; set 0 # # to disable. NOT a per-entry TTL duration — each cached class # # resolves its own TTL below (GITHUB_BRANCH_PROTECTION_CACHE_TTL_SECONDS diff --git a/.github/workflows/orb-beta-release.yml b/.github/workflows/orb-beta-release.yml index 6537b463c0..11e5da97c9 100644 --- a/.github/workflows/orb-beta-release.yml +++ b/.github/workflows/orb-beta-release.yml @@ -1,6 +1,4 @@ -# Automated ORB (self-host container image, ghcr.io/jsonbored/loopover-selfhost -- #4770: the pre-rename -# ghcr.io/jsonbored/gittensory-selfhost name remains a deprecated alias of the same build during the -# deprecation window tracked by #4777) beta channel. +# Automated ORB (self-host container image, ghcr.io/jsonbored/loopover-selfhost) beta channel. # Daily (or on demand via workflow_dispatch), checks whether any image-relevant commit has landed # since the last orb-v tag (scripts/check-orb-release-due.mjs / scripts/orb-release-core.mjs) and, # if so, cuts the next `orb-vX.Y.Z-beta.N` tag and dispatches release-selfhost.yml to build + publish diff --git a/.github/workflows/orb-stable-release-pr.yml b/.github/workflows/orb-stable-release-pr.yml index 99a948d0f8..ab90a4301e 100644 --- a/.github/workflows/orb-stable-release-pr.yml +++ b/.github/workflows/orb-stable-release-pr.yml @@ -1,6 +1,4 @@ -# Automated ORB (self-host container image, ghcr.io/jsonbored/loopover-selfhost -- #4770: the pre-rename -# ghcr.io/jsonbored/gittensory-selfhost name remains a deprecated alias of the same build during the -# deprecation window tracked by #4777) STABLE-channel Release PR -- +# Automated ORB (self-host container image, ghcr.io/jsonbored/loopover-selfhost) STABLE-channel Release PR -- # the release-please-equivalent for ORB, whose cross-cutting image-relevant scoping (src/** shared with # UI/MCP-only subtrees it must exclude -- see orb-release-core.mjs's IMAGE_RELEVANT_PREFIXES/EXCLUDED_PREFIXES) # doesn't fit release-please's directory-component model the way packages/gittensory-mcp and diff --git a/.github/workflows/release-selfhost.yml b/.github/workflows/release-selfhost.yml index 2cb8eb44b5..ab86d925dd 100644 --- a/.github/workflows/release-selfhost.yml +++ b/.github/workflows/release-selfhost.yml @@ -5,10 +5,9 @@ # # Pull: docker pull ghcr.io//loopover-selfhost:orb-v0.1.0 # -# #4770: `ghcr.io//gittensory-selfhost` is a deprecated alias of the SAME image, published from this -# same build/push so both names resolve to the byte-identical digest -- see the "Image metadata" step below. -# Self-hosters pinned to the old name keep working unmodified during the deprecation window; do not remove -# that alias without the sign-off tracked by #4777. +# #4777: publishing under the pre-rename "gittensory-selfhost" name stopped -- see the "Image metadata" +# step below. Already-published tags/digests under that name are untouched and keep resolving forever +# (GHCR has no server-side alias); only new pushes moved to "loopover-selfhost" exclusively. # # Prerelease tags (#1937): orb-v0.1.0-rc.1 / orb-v0.1.0-beta.1 run the identical pipeline but never move # `latest` and are marked prerelease on the GitHub Release -- for beta-testing an image before it becomes @@ -222,21 +221,15 @@ jobs: echo "GTORBTAGS" } >> "$GITHUB_OUTPUT" - # #4770: publish under BOTH the new "loopover-selfhost" name (primary going forward, listed first) and - # the legacy "gittensory-selfhost" name (deprecated alias) from this SAME buildx build/push below -- - # docker/metadata-action applies the identical `tags:` set to every entry in a multi-line `images:` - # list, so both names resolve to the byte-identical multi-arch manifest with no second build and no - # extra registry round-trip. Self-hosters who pinned the old image reference in their own deployment - # config must keep working unmodified until the deprecation window closes. Removal of the alias is - # tracked by #4777 ("retire every deprecation shim") and requires an explicit, separately-announced - # window before it's dropped -- do not remove the second `images:` line without that sign-off. + # #4777: publishes only under the "loopover-selfhost" name now. The pre-rename "gittensory-selfhost" + # name is no longer pushed to; GHCR has no server-side alias, so its already-published exact-version + # and digest pins keep resolving forever regardless -- this only stops new tags from landing there. - name: Image metadata id: meta uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6 with: images: | ghcr.io/${{ github.repository_owner }}/loopover-selfhost - ghcr.io/${{ github.repository_owner }}/gittensory-selfhost tags: ${{ steps.tags.outputs.list }} labels: | org.opencontainers.image.title=gittensory-orb @@ -354,10 +347,6 @@ jobs: Multi-arch (linux/amd64 + linux/arm64). See https://loopover.ai/docs/maintainer-self-hosting for setup. Includes the Claude Code / Codex subscription CLIs by default; credentials stay runtime-only. Sentry release id baked into the image: \`${RELEASE_ID}\`. - - #4770: \`ghcr.io/${REPOSITORY_OWNER_LOWER}/gittensory-selfhost:${RELEASE_TAG}\` (the pre-rename name) - still resolves to this identical build/digest during the deprecation window -- no action needed if - you're already pinned to it. Track eventual removal via #4777. EOF )" # #1937: a prerelease tag never becomes the repo's "Latest release" and is visibly marked as such diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx index e7862a0b0e..6174571eed 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx @@ -982,9 +982,8 @@ SENTRY_ORG_SLUG= GITTENSORY_IMAGE=ghcr.io/jsonbored/loopover-selfhost@sha256:... ./scripts/deploy-selfhost-image.sh`} />

- ghcr.io/jsonbored/gittensory-selfhost (the pre-rename name) remains a - deprecated alias of the identical image during the deprecation window — an existing pin to - it keeps resolving unmodified. + ghcr.io/jsonbored/gittensory-selfhost (the pre-rename name) is no longer + published to, but an existing pin to a specific tag or digest under it keeps resolving.

The pull always runs with --policy always, so re-running the script against an diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-quickstart.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-quickstart.tsx index 87df53eeb0..b0b3c4e409 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-quickstart.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-quickstart.tsx @@ -120,9 +120,8 @@ curl http://localhost:8787/ready`} GITTENSORY_IMAGE=ghcr.io/jsonbored/loopover-selfhost@sha256:... ./scripts/deploy-selfhost-image.sh`} />

- ghcr.io/jsonbored/gittensory-selfhost (the pre-rename name) remains available - as a deprecated alias of the identical image during the deprecation window — existing pins - keep working unmodified. + ghcr.io/jsonbored/gittensory-selfhost (the pre-rename name) is no longer + published to, but an existing pin to a specific tag or digest under it keeps resolving.

Contributors and anyone customizing the Dockerfile can still build locally —{" "} diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-release-checklist.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-release-checklist.tsx index a79e3c99e5..a57542f2db 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-release-checklist.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-release-checklist.tsx @@ -233,7 +233,7 @@ git push origin orb-v0.1.0`} scripts/deploy-selfhost-prebuilt.sh, run{" "} scripts/deploy-selfhost-image.sh - ghcr.io/<owner>/gittensory-selfhost:orb-v0.1.0 + ghcr.io/<owner>/loopover-selfhost:orb-v0.1.0 . @@ -570,8 +570,8 @@ docker rm -f gt-qdrant && docker network rm gt-rag-smoke`}

This audit is Dockerfile-derived, not a runtime scan. If a future dependency bump adds a @@ -635,7 +635,7 @@ docker images ghcr.io/jsonbored/gittensory-selfhost:orb-v0.1.0 --format '{{.Size code={`Gittensory Orb container image: \`\`\`bash -docker pull ghcr.io/jsonbored/gittensory-selfhost:orb-v0.1.0 +docker pull ghcr.io/jsonbored/loopover-selfhost:orb-v0.1.0 \`\`\` Multi-arch (linux/amd64 + linux/arm64). See https://gittensory.aethereal.dev/docs/maintainer-self-hosting for setup. diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-releases.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-releases.tsx index 3fd61a3ca3..7ed8fd6eb0 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-releases.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-releases.tsx @@ -56,10 +56,10 @@ function SelfHostingReleases() { docker pull ghcr.io/jsonbored/loopover-selfhost:latest`} /> - ghcr.io/jsonbored/loopover-selfhost is the current name. The pre-rename{" "} - ghcr.io/jsonbored/gittensory-selfhost remains available as a deprecated alias - of the byte-identical image during the deprecation window — existing pins keep working - unmodified. + ghcr.io/jsonbored/loopover-selfhost is the only name new releases publish + under. The pre-rename ghcr.io/jsonbored/gittensory-selfhost is no longer + published to, but an existing pin to a specific tag or digest under that name keeps + resolving — pull it and switch to the new name at your convenience.

Prerelease (beta/rc) images

diff --git a/orb-manifest.json b/orb-manifest.json index 862db6df11..8d2ce1c419 100644 --- a/orb-manifest.json +++ b/orb-manifest.json @@ -1,4 +1,4 @@ { "version": "1.0.0", - "description": "Source of truth for the self-hostable gittensory-orb container image's target release version (ghcr.io/jsonbored/loopover-selfhost -- #4770: ghcr.io/jsonbored/gittensory-selfhost is a deprecated alias of the same build/digest during the deprecation window tracked by #4777). Bumped by a maintainer when a feat/fix/breaking change since the last stable orb-v tag warrants moving to a new target version -- scripts/orb-release-core.mjs and .github/workflows/orb-beta-release.yml read this file to decide what version the next automated beta snapshot targets. Promoting a beta to a stable orb-vX.Y.Z release is still a manual `git tag` -- this manifest only drives the automated beta channel." + "description": "Source of truth for the self-hostable gittensory-orb container image's target release version (ghcr.io/jsonbored/loopover-selfhost). Bumped by a maintainer when a feat/fix/breaking change since the last stable orb-v tag warrants moving to a new target version -- scripts/orb-release-core.mjs and .github/workflows/orb-beta-release.yml read this file to decide what version the next automated beta snapshot targets. Promoting a beta to a stable orb-vX.Y.Z release is still a manual `git tag` -- this manifest only drives the automated beta channel." } diff --git a/scripts/deploy-selfhost-image.sh b/scripts/deploy-selfhost-image.sh index 4e1972d4da..6214eb63cf 100755 --- a/scripts/deploy-selfhost-image.sh +++ b/scripts/deploy-selfhost-image.sh @@ -10,11 +10,6 @@ # ./scripts/deploy-selfhost-image.sh ghcr.io/jsonbored/loopover-selfhost:orb-v0.1.0 # GITTENSORY_IMAGE=ghcr.io/jsonbored/loopover-selfhost@sha256:... ./scripts/deploy-selfhost-image.sh # -# #4770: ghcr.io/jsonbored/gittensory-selfhost (the pre-rename name) is a deprecated alias of the SAME -# build/digest during the deprecation window -- an existing GITTENSORY_IMAGE override or CLI argument -# pinned to that old name keeps resolving unmodified; only DEFAULT_IMAGE below moves to the new name. -# Removal of the alias is tracked by #4777. -# # The image itself carries official release metadata. Set SENTRY_RELEASE only for custom images whose # source maps were uploaded under that exact id. set -euo pipefail diff --git a/scripts/orb-release-core.mjs b/scripts/orb-release-core.mjs index a5c45ca7aa..b0effed457 100644 --- a/scripts/orb-release-core.mjs +++ b/scripts/orb-release-core.mjs @@ -1,6 +1,4 @@ -// Pure logic for the ORB (self-host container image, ghcr.io/jsonbored/loopover-selfhost -- #4770: the -// pre-rename ghcr.io/jsonbored/gittensory-selfhost name remains a deprecated alias of the same build -// during the deprecation window tracked by #4777) automated beta +// Pure logic for the ORB (self-host container image, ghcr.io/jsonbored/loopover-selfhost) automated beta // channel. Deliberately independent of scripts/mcp-release-core.mjs (no shared imports/state) even though the // shape mirrors it closely -- ORB and the MCP package are versioned, tagged, and published on separate // schedules by separate automation, and keeping them decoupled means neither can accidentally regress the diff --git a/test/unit/release-selfhost-notes.test.ts b/test/unit/release-selfhost-notes.test.ts index cb451c2989..06150f3659 100644 --- a/test/unit/release-selfhost-notes.test.ts +++ b/test/unit/release-selfhost-notes.test.ts @@ -138,10 +138,7 @@ describe('release-selfhost.yml "GitHub Release" step changelog generation', () = const r = harness.run(); expect(r.status).toBe(0); expect(r.notesPassed).toContain("docker pull ghcr.io/jsonbored/loopover-selfhost:orb-v0.2.0"); - // #4770: the notes must also tell an operator that the pre-rename image name still resolves to - // this identical build during the deprecation window, and point at #4777 for eventual removal. - expect(r.notesPassed).toContain("ghcr.io/jsonbored/gittensory-selfhost:orb-v0.2.0"); - expect(r.notesPassed).toContain("#4777"); + expect(r.notesPassed).not.toContain("gittensory-selfhost"); expect(r.notesPassed).toContain("## What's Changed"); expect(r.notesPassed).toContain("feat: something"); // The tag being released must never be diffed against itself. diff --git a/test/unit/selfhost-image-deploy.test.ts b/test/unit/selfhost-image-deploy.test.ts index 15061b797e..8e04e5e813 100644 --- a/test/unit/selfhost-image-deploy.test.ts +++ b/test/unit/selfhost-image-deploy.test.ts @@ -13,9 +13,10 @@ import { describe, expect, it } from "vitest"; const scriptPath = resolve("scripts/deploy-selfhost-image.sh"); const defaultImage = "ghcr.io/jsonbored/loopover-selfhost:latest"; -// #4770: the pre-rename name is a deprecated alias of the identical image during the deprecation -// window -- an operator who pinned it explicitly (CLI arg, env var, or .env value) must keep -// resolving to that exact string unmodified, even though DEFAULT_IMAGE above now points at the new name. +// #4777: publishing under the pre-rename name has stopped, but GHCR has no server-side alias, so its +// already-published tags/digests keep resolving forever -- an operator who pinned it explicitly (CLI +// arg, env var, or .env value) must keep resolving to that exact string unmodified, even though +// DEFAULT_IMAGE above now points at the new name. const legacyPinnedImage = "ghcr.io/jsonbored/gittensory-selfhost:orb-v0.1.0"; interface RunOptions { @@ -167,10 +168,11 @@ describe("self-host image deploy script", () => { } }); - // REGRESSION (#4770): DEFAULT_IMAGE moved to the new "loopover-selfhost" name, but a self-hoster who + // REGRESSION (#4777): DEFAULT_IMAGE moved to the new "loopover-selfhost" name, but a self-hoster who // explicitly pinned the pre-rename "gittensory-selfhost" image (as a CLI argument, GITTENSORY_IMAGE env - // var, or .env value) must keep resolving to that exact string, unmodified -- the deprecation alias is - // guaranteed by the release workflow's dual-tag push, not by rewriting an operator's existing pin here. + // var, or .env value) must keep resolving to that exact string, unmodified -- GHCR keeps already-published + // tags/digests resolving forever with no server-side alias needed, and this script must not rewrite an + // operator's existing pin either way. it("passes an explicit pre-rename image reference through unchanged despite the new default", () => { const { harness, result } = runHarness({ args: [legacyPinnedImage] }); try { diff --git a/test/unit/selfhost-sentry-release.test.ts b/test/unit/selfhost-sentry-release.test.ts index b295bf1ae0..ff520ca48d 100644 --- a/test/unit/selfhost-sentry-release.test.ts +++ b/test/unit/selfhost-sentry-release.test.ts @@ -42,18 +42,12 @@ describe("self-host Sentry release wiring", () => { expect(releaseWorkflow).toContain( "docker pull ghcr.io/${REPOSITORY_OWNER_LOWER}/loopover-selfhost:${RELEASE_TAG}", ); - // #4770: the release notes must also point out that the pre-rename image name still resolves to - // the identical build during the deprecation window (tracked for eventual removal by #4777). - expect(releaseWorkflow).toContain( - "ghcr.io/${REPOSITORY_OWNER_LOWER}/gittensory-selfhost:${RELEASE_TAG}", - ); - expect(releaseWorkflow).toContain("#4777"); - // The "Image metadata" step must push BOTH names from the same buildx build so the two tags share - // a byte-identical digest -- no second build, no drift between them. + // #4777: the "Image metadata" step must only push the renamed image now -- publishing under the + // pre-rename "gittensory-selfhost" name has stopped. expect(releaseWorkflow).toContain( "ghcr.io/${{ github.repository_owner }}/loopover-selfhost", ); - expect(releaseWorkflow).toContain( + expect(releaseWorkflow).not.toContain( "ghcr.io/${{ github.repository_owner }}/gittensory-selfhost", ); expect(releaseWorkflow).not.toContain('"selfhost-v*"');