Files
mkdocs-wiki/scripts/promote_wiki.py

68 lines
2.6 KiB
Python

"""Promote a successful Wiki image build to the Portainer placement matrix."""
import base64
import json
import os
import re
import urllib.error
import urllib.request
API = "https://gitea.rwcloud.ch/api/v1"
TARGET = "/repos/homelab/portainer-hosted/contents/hosts/deployments.yaml"
def update_matrix(content, image):
if not re.fullmatch(r"gitea\.rwcloud\.ch/homelab/wiki:sha-[0-9a-f]{40}@sha256:[0-9a-f]{64}", image):
raise ValueError("Invalid immutable Wiki image reference")
section = re.search(r"(?m)^wiki:\n(?:[ \t].*\n|\n)*", content)
if section is None:
raise ValueError("Wiki stack missing from placement matrix")
updated, count = re.subn(r"(?m)^( WIKI_IMAGE: ).+$", lambda m: m[1] + image, section.group())
if count != 1:
raise ValueError("Expected exactly one WIKI_IMAGE")
return content[:section.start()] + updated + content[section.end():]
def request(method, path, token, payload=None):
req = urllib.request.Request(
API + path, method=method,
data=json.dumps(payload).encode() if payload is not None else None,
headers={"Authorization": "token " + token, "Content-Type": "application/json"},
)
with urllib.request.urlopen(req, timeout=60) as response:
return json.load(response)
def main():
token = os.environ["GITEA_DEPLOY_TOKEN"]
source = os.environ["GITHUB_SHA"]
image = os.environ["WIKI_IMAGE"]
for attempt in range(3):
# A slower, older build must never replace a newer main revision.
latest = request("GET", "/repos/rewa81/mkdocs-wiki/branches/main", token)
if latest["commit"]["id"] != source:
print("Newer main revision exists; skipping obsolete build promotion.")
return
current = request("GET", TARGET + "?ref=main", token)
content = base64.b64decode(current["content"]).decode()
updated = update_matrix(content, image)
if updated == content:
print("Wiki image already selected; no deployment commit needed.")
return
try:
result = request("PUT", TARGET, token, {
"branch": "main", "sha": current["sha"],
"content": base64.b64encode(updated.encode()).decode(),
"message": f"deploy(wiki): mkdocs-wiki main {source}",
})
except urllib.error.HTTPError as exc:
if exc.code == 409 and attempt < 2:
continue
raise
print("Wiki deployment requested by commit " + result["commit"]["sha"])
return
raise RuntimeError("Placement matrix changed concurrently; promotion failed")
if __name__ == "__main__":
main()