105 lines
4.5 KiB
Python
105 lines
4.5 KiB
Python
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import io
|
|
import json
|
|
from pathlib import Path
|
|
import tarfile
|
|
import tempfile
|
|
import unittest
|
|
|
|
from scripts import deploy_contract
|
|
from scripts import delivery_gate
|
|
from scripts import fetch_hugo
|
|
from scripts import generic_package
|
|
|
|
|
|
DELIVERY = Path(__file__).resolve().parents[1]
|
|
REPO_ROOT = DELIVERY.parent
|
|
WORKFLOWS = REPO_ROOT / ".gitea/workflows"
|
|
REVISION = "a" * 40
|
|
|
|
|
|
class BlogSiteTests(unittest.TestCase):
|
|
def test_site_is_the_netcup_release_root_not_a_checkout(self):
|
|
site = deploy_contract.load_site(DELIVERY / "site.json")
|
|
self.assertEqual(site.target, "/srv/libretech-static/blog")
|
|
self.assertEqual(site.verify_url, "https://blog.static.librete.ch/.well-known/release.json")
|
|
url = generic_package.package_file_url(
|
|
deploy_contract.REGISTRY, "public", "blog-site", REVISION, generic_package.ARCHIVE_NAME,
|
|
)
|
|
request = deploy_contract.validate_request(
|
|
site=site,
|
|
revision=REVISION,
|
|
artifact_url=url,
|
|
artifact_digest="sha256:" + "b" * 64,
|
|
target=site.target,
|
|
verify_url=site.verify_url,
|
|
desired_commit="c" * 40,
|
|
desired_generation="1",
|
|
)
|
|
self.assertEqual(request["artifact_url"], url)
|
|
with self.assertRaisesRegex(deploy_contract.ContractError, "immutable project package"):
|
|
deploy_contract.validate_request(**{**request, "artifact_url": url.replace("public", "libretech")}, site=site)
|
|
|
|
def test_reviewed_gate_enables_publication_and_deployment(self):
|
|
config = DELIVERY / ".delivery/config.json"
|
|
for capability in delivery_gate.CAPABILITIES:
|
|
delivery_gate.check(config, capability)
|
|
|
|
def test_hugo_is_pinned_and_verified(self):
|
|
self.assertRegex(fetch_hugo.SHA256, r"^[0-9a-f]{64}$")
|
|
self.assertIn(f"/v{fetch_hugo.VERSION}/", fetch_hugo.URL)
|
|
with tempfile.TemporaryDirectory() as temp:
|
|
buffer = io.BytesIO()
|
|
with tarfile.open(fileobj=buffer, mode="w:gz") as tar:
|
|
info = tarfile.TarInfo("hugo")
|
|
info.size = 4
|
|
tar.addfile(info, io.BytesIO(b"\x7fELF"))
|
|
archive = buffer.getvalue()
|
|
binary = fetch_hugo.extract_hugo(archive, hashlib.sha256(archive).hexdigest(), Path(temp))
|
|
self.assertEqual(binary.read_bytes(), b"\x7fELF")
|
|
with self.assertRaisesRegex(fetch_hugo.FetchError, "digest mismatch"):
|
|
fetch_hugo.extract_hugo(archive, "0" * 64, Path(temp))
|
|
|
|
|
|
class BlogWorkflowTests(unittest.TestCase):
|
|
def read(self, name):
|
|
return (WORKFLOWS / name).read_text(encoding="utf-8")
|
|
|
|
def test_no_workflow_publishes_from_a_checkout(self):
|
|
for workflow in sorted(WORKFLOWS.glob("*.yml")):
|
|
text = workflow.read_text(encoding="utf-8")
|
|
with self.subTest(workflow=workflow.name):
|
|
for forbidden in ("rsync", "scp ", "publishDir", "/var/www"):
|
|
self.assertNotIn(forbidden, text)
|
|
|
|
def test_publication_is_gated_before_any_package_write(self):
|
|
workflow = self.read("publish-blog.yml")
|
|
_, _, publish = workflow.partition("\n publish:\n")
|
|
self.assertIn("vars.BLOG_PACKAGE_PUBLISH_ENABLED == 'true'", publish)
|
|
self.assertLess(publish.index("delivery_gate.py package_publish"), publish.index("generic_package.py"))
|
|
_, _, validate = workflow.partition("\n validate:\n")
|
|
self.assertNotIn("secrets.", validate.partition("\n publish:\n")[0])
|
|
|
|
def test_deployment_is_gated_ordered_and_site_scoped(self):
|
|
workflow = self.read("deploy-blog.yml")
|
|
self.assertIn("workflow_dispatch:", workflow)
|
|
self.assertNotIn("\n push:", workflow)
|
|
self.assertIn("vars.BLOG_STATIC_DEPLOY_ENABLED == 'true'", workflow)
|
|
self.assertNotIn("DONATELLA", workflow)
|
|
self.assertEqual(workflow.count("--site-config delivery/site.json"), 2)
|
|
for field in ("revision", "artifact_url", "artifact_digest", "target", "verify_url",
|
|
"desired_commit", "desired_generation"):
|
|
self.assertIn(f" {field}:\n", workflow)
|
|
self.assertIn("StrictHostKeyChecking yes", workflow)
|
|
self.assertIn("steps.receive.outputs.superseded == 'false'", workflow)
|
|
self.assertLess(
|
|
workflow.index("delivery_gate.py static_deploy"),
|
|
workflow.index("ssh static-release-target"),
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|