diff --git a/.mokogitea/workflows/deploy-mokogitea.yml b/.mokogitea/workflows/deploy-mokogitea.yml
index 188266406b..2a6fcfacd3 100644
--- a/.mokogitea/workflows/deploy-mokogitea.yml
+++ b/.mokogitea/workflows/deploy-mokogitea.yml
@@ -140,6 +140,78 @@ jobs:
exit 1
"
+ - name: Update updates.xml
+ if: success()
+ env:
+ GITEA_TOKEN: ${{ secrets.GA_TOKEN }}
+ TAG: ${{ steps.config.outputs.tag }}
+ INSTANCE_URL: ${{ steps.config.outputs.instance_url }}
+ DEPLOY_ENV: ${{ github.event.inputs.environment }}
+ run: |
+ # Only update updates.xml for production stable releases
+ if [ "$DEPLOY_ENV" != "production" ]; then
+ echo "Skipping updates.xml — dev deployments don't update stable channel"
+ exit 0
+ fi
+
+ # Extract moko version from tag (e.g. v1.26.1-moko.05.01.01 -> 05.01.01)
+ MOKO_VER=$(echo "$TAG" | sed -n 's/.*-moko\.\(.*\)/\1/p')
+ if [ -z "$MOKO_VER" ]; then
+ echo "Could not extract moko version from tag: $TAG"
+ exit 0
+ fi
+
+ RELEASE_URL="https://${REGISTRY}/MokoConsulting/MokoGitea/releases/tag/${TAG}"
+ DOCKER_IMG="${REGISTRY}/${IMAGE}:${TAG}"
+
+ python3 << PYEOF
+ import json, os, re, base64, urllib.request
+
+ token = os.environ["GITEA_TOKEN"]
+ registry = os.environ["REGISTRY"]
+ tag = os.environ["TAG"]
+ moko_ver = os.environ["MOKO_VER"]
+ release_url = os.environ["RELEASE_URL"]
+ docker_img = os.environ["DOCKER_IMG"]
+ api = f"https://{registry}/api/v1/repos/MokoConsulting/MokoGitea"
+
+ # Fetch current updates.xml
+ req = urllib.request.Request(f"{api}/contents/updates.xml?ref=main",
+ headers={"Authorization": f"token {token}"})
+ with urllib.request.urlopen(req) as resp:
+ data = json.loads(resp.read())
+ sha = data["sha"]
+ content = base64.b64decode(data["content"]).decode("utf-8")
+
+ # Update stable channel version, infourl, and docker tag
+ content = re.sub(
+ r"(stable[\s\S]*?)[^<]*()",
+ rf"\g<1>{moko_ver}\2", content)
+ content = re.sub(
+ r"(stable[\s\S]*?]*>)[^<]*()",
+ rf"\g<1>{release_url}\2", content)
+ content = re.sub(
+ r"(stable[\s\S]*?]*>)[^<]*()",
+ rf"\g<1>{docker_img}\2", content)
+
+ # Also update VERSION comment at top
+ content = re.sub(r"VERSION: [^\n]*", f"VERSION: {moko_ver}", content)
+
+ # Push updated file
+ encoded = base64.b64encode(content.encode()).decode()
+ payload = json.dumps({
+ "message": f"chore(ci): update updates.xml to {moko_ver}",
+ "content": encoded,
+ "sha": sha,
+ "branch": "main",
+ }).encode()
+ req = urllib.request.Request(f"{api}/contents/updates.xml",
+ data=payload, method="PUT",
+ headers={"Authorization": f"token {token}", "Content-Type": "application/json"})
+ with urllib.request.urlopen(req) as resp:
+ print(f"updates.xml updated to {moko_ver}")
+ PYEOF
+
- name: Disable maintenance mode
if: always()
env: