main
Drew Owens 0.10.5 source 1dc9df6 7d ago
#!/usr/bin/env python3
"""Verify the published page against this release — every mismatch is printed
and the exit code is non-zero (0.9.12, run as the last step of
`tools/release.sh --publish`). Read-only.

Usage: verify-wiki.py VERSION SHA256 SIZE ZIPNAME
"""
import hashlib, json, os, subprocess, sys, urllib.request

ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
SLUG, OWNER = "solidworks-bridge", "adom"
MAN = "adom-bridge-solidworks-manifest.json"
API = "https://wiki.adom.inc/api/v1/pages/%s" % SLUG


def get(url, raw=False):
    with urllib.request.urlopen(url, timeout=120) as r:
        b = r.read()
    return b if raw else json.loads(b)


def main():
    ver, sha, size, zipname = sys.argv[1], sys.argv[2], int(sys.argv[3]), sys.argv[4]
    bad = []

    def check(ok, claim, detail=""):
        print(("  OK    " if ok else "  FAIL  ") + claim + (" [%s]" % detail if detail else ""))
        if not ok:
            bad.append(claim)

    pub = get(API + "/files/" + MAN)
    local = json.load(open(os.path.join(ROOT, MAN)))
    check(pub.get("version") == ver and pub.get("sha256") == sha and pub.get("size") == size,
          "the published manifest names this release", json.dumps({k: pub.get(k) for k in ("version", "size", "sha256")}))
    check(pub == local, "the committed manifest is byte-for-byte the published one")
    blob = get("https://wiki.adom.inc/download/%s/%s/%s/%s" % (OWNER, SLUG, ver, zipname), raw=True)
    check(hashlib.sha256(blob).hexdigest() == sha and len(blob) == size, "the downloadable zip hashes to the manifest",
          "%d bytes" % len(blob))
    page = get(API)["page"]
    want = json.load(open(os.path.join(ROOT, "page.json")))
    pkg = json.load(open(os.path.join(ROOT, "package.json")))
    check(page.get("hero_path") == want["hero"]["path"], "the hero is linked", str(page.get("hero_path")))
    check(page.get("title") == want.get("title"), "the title", str(page.get("title")))
    check(page.get("brief") == want.get("brief"), "the brief")
    tags = page.get("tags")
    tags = json.loads(tags) if isinstance(tags, str) else tags
    check(sorted(tags or []) == sorted(pkg.get("tags", [])), "the tags", str(tags))
    check(page.get("version") == ver, "the page's package version", str(page.get("version")))
    # Three user skills: solidworks-bridge and the dependent solidworks-sign-in
    # and solidworks-memory.
    check(page.get("skill_count") == 3, "the package ships 3 skills", str(page.get("skill_count")))
    bv = get(API + "/files/BRIDGE_VERSION", raw=True).decode().strip()
    check(bv == ver, "the page's BRIDGE_VERSION", bv)
    want_title = os.environ.get("RELEASE_TITLE")
    if want_title:
        rel = subprocess.run(["adom-wiki", "release", "list", "%s/%s" % (OWNER, SLUG)], capture_output=True, text=True)
        try:
            rows = json.loads(rel.stdout).get("releases", [])
        except ValueError:
            rows = []
        got = next((r.get("title") for r in rows if r.get("version") == ver), None)
        check(got == want_title, "the release title (a pkg publish rewrites it)", str(got))
    head = subprocess.run(["git", "-C", ROOT, "rev-parse", "HEAD"], capture_output=True, text=True).stdout.strip()
    print("  page commit %s, local HEAD %s" % (page.get("last_commit_hash"), head))
    if bad:
        print("VERIFY FAILED — %d mismatch(es): %s" % (len(bad), "; ".join(bad)))
        return 1
    print("VERIFY PASSED — manifest, zip, hero, title, brief, tags, package version, BRIDGE_VERSION.")
    return 0


if __name__ == "__main__":
    sys.exit(main())