From 33b0fd652e338666894f0213f633a6a943762f8f Mon Sep 17 00:00:00 2001 From: Justin Paul Date: Fri, 22 May 2026 09:34:26 -0400 Subject: [PATCH] ci: derive image name + package linking from repo, add link step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both workflows had a static IMAGE env (/-docs-mcp) and a static --package arg in the GC step. Switch both to Gitea Actions context variables so a clone of the template into any repo name works on the first CI run without find/replace: IMAGE: ${{ github.repository_owner }}/${{ github.event.repository.name }} --owner ${{ github.repository_owner }} --package ${{ github.event.repository.name }} Also add the "Link container package to this repo" step that was missing from the template (and which, naively copy-pasted from the reference build, would have linked everything back to docs-mcp- template). The new step derives owner + package + link-target all from the running repo's context. The github.* namespace is Gitea Actions' inherited GitHub-Actions context — values come from the Gitea server, not github.com. Same mechanism the reference build's $GITHUB_SHA tag-builder uses. CLAUDE.md updated to note that image and package naming are repo-derived; only registry endpoints and the Ollama URL need per-clone editing. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitea/workflows/image-only.yml | 34 ++++++++++++++++++++++++++++---- .gitea/workflows/refresh.yml | 35 +++++++++++++++++++++++++++++---- CLAUDE.md | 17 ++++++++++++++++ 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/image-only.yml b/.gitea/workflows/image-only.yml index 83b9b5f..2085c7d 100644 --- a/.gitea/workflows/image-only.yml +++ b/.gitea/workflows/image-only.yml @@ -16,7 +16,11 @@ on: env: REGISTRY_PUSH: : REGISTRY_PULL: - IMAGE: /-docs-mcp + # Image name derives from the actual repo at runtime, so a clone + # doesn't need to find/replace anything. e.g. justin/my-product-docs. + # github.* context is Gitea Actions' inherited GitHub-Actions namespace + # — values come from the Gitea server, not github.com. + IMAGE: ${{ github.repository_owner }}/${{ github.event.repository.name }} OLLAMA_URL: http://:11434 EMBED_MODEL: nomic-embed-text PRODUCT_NAME: @@ -63,7 +67,7 @@ jobs: run: python -m rag.index --rebuild - name: Log in to registry (LAN endpoint) - run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${REGISTRY_PUSH}" -u --password-stdin + run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${REGISTRY_PUSH}" -u "${{ github.repository_owner }}" --password-stdin - name: Build & push image run: | @@ -78,12 +82,34 @@ jobs: docker push "${REGISTRY_PUSH}/${IMAGE}:${SHA_TAG}" docker push "${REGISTRY_PUSH}/${IMAGE}:${DATE_TAG}" + - name: Link container package to this repo + # Gitea container packages are owned by a USER, not a repo — + # they don't auto-appear under the repo's Packages tab. + # This API call creates the association. One-time-effective: + # re-running returns 400 once linked, which we swallow. + # Endpoint requires Gitea 1.21+. + env: + GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + run: | + OWNER="${{ github.repository_owner }}" + PKG="${{ github.event.repository.name }}" + BODY=$(mktemp) + CODE=$(curl -sS -o "$BODY" -w "%{http_code}" -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "https://${REGISTRY_PULL}/api/v1/packages/${OWNER}/container/${PKG}/-/link/${PKG}") + echo "link http=$CODE body=$(cat "$BODY")" + case "$CODE" in + 201) echo "linked package to ${OWNER}/${PKG}" ;; + 400) echo "already linked (re-link returns 400) — ok" ;; + *) echo "unexpected status $CODE"; exit 1 ;; + esac + - name: Prune old container versions env: GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | python scripts/registry_gc.py \ - --owner \ - --package -docs-mcp \ + --owner "${{ github.repository_owner }}" \ + --package "${{ github.event.repository.name }}" \ --keep-days 90 \ --keep-latest 5 diff --git a/.gitea/workflows/refresh.yml b/.gitea/workflows/refresh.yml index ad10efe..ee24d97 100644 --- a/.gitea/workflows/refresh.yml +++ b/.gitea/workflows/refresh.yml @@ -24,7 +24,11 @@ env: # for pulls (response bodies aren't capped). REGISTRY_PUSH: : REGISTRY_PULL: - IMAGE: /-docs-mcp + # Image name derives from the actual repo at runtime, so a clone + # doesn't need to find/replace anything. e.g. justin/my-product-docs. + # github.* context is Gitea Actions' inherited GitHub-Actions namespace + # — values come from the Gitea server, not github.com. + IMAGE: ${{ github.repository_owner }}/${{ github.event.repository.name }} # Embedder. One URL per GPU; the indexer round-robins. OLLAMA_URL: http://:11434 @@ -126,7 +130,7 @@ jobs: # ---- Build & push image ------------------------------------ - name: Log in to registry (LAN endpoint) if: steps.commit.outputs.changed == 'true' || inputs.force_build == true - run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${REGISTRY_PUSH}" -u --password-stdin + run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${REGISTRY_PUSH}" -u "${{ github.repository_owner }}" --password-stdin - name: Build & push image if: steps.commit.outputs.changed == 'true' || inputs.force_build == true @@ -145,6 +149,29 @@ jobs: docker push "${REGISTRY_PUSH}/${IMAGE}:${SHA_TAG}" docker push "${REGISTRY_PUSH}/${IMAGE}:${DATE_TAG}" + - name: Link container package to this repo + # Gitea container packages are owned by a USER, not a repo — + # they don't auto-appear under the repo's Packages tab. + # This API call creates the association. One-time-effective: + # re-running returns 400 once linked, which we swallow. + # Endpoint requires Gitea 1.21+. + if: steps.commit.outputs.changed == 'true' || inputs.force_build == true + env: + GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + run: | + OWNER="${{ github.repository_owner }}" + PKG="${{ github.event.repository.name }}" + BODY=$(mktemp) + CODE=$(curl -sS -o "$BODY" -w "%{http_code}" -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "https://${REGISTRY_PULL}/api/v1/packages/${OWNER}/container/${PKG}/-/link/${PKG}") + echo "link http=$CODE body=$(cat "$BODY")" + case "$CODE" in + 201) echo "linked package to ${OWNER}/${PKG}" ;; + 400) echo "already linked (re-link returns 400) — ok" ;; + *) echo "unexpected status $CODE"; exit 1 ;; + esac + # ---- Registry GC ------------------------------------------- - name: Prune old container versions if: steps.commit.outputs.changed == 'true' || inputs.force_build == true @@ -152,7 +179,7 @@ jobs: GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | python scripts/registry_gc.py \ - --owner \ - --package -docs-mcp \ + --owner "${{ github.repository_owner }}" \ + --package "${{ github.event.repository.name }}" \ --keep-days 90 \ --keep-latest 5 diff --git a/CLAUDE.md b/CLAUDE.md index 4d4da98..30a8b46 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -157,6 +157,23 @@ throughout. Set it on first build. References show up in: Use lowercase, underscores not hyphens, since it ends up in tool identifiers that the LLM reads. +### Image name and package linking are repo-name-derived + +You do NOT need to edit the IMAGE env or the `--package` arg in the +workflows. Both derive from the repo at runtime via +`${{ github.repository_owner }}` and +`${{ github.event.repository.name }}`. So a clone into a repo named +`my-product-docs` automatically pushes the container as +`/my-product-docs:latest` and links the package to its own +repo. (`github.*` is Gitea Actions' inherited GitHub-Actions +namespace — the values come from the Gitea server, no github.com +involvement.) + +The only workflow placeholders you still have to replace per clone +are the registry endpoints (`REGISTRY_PUSH`, `REGISTRY_PULL`) and +the Ollama URL, because those depend on the deployment environment, +not the repo identity. + ## Common commands ```bash