From c2dfc607a1b9b805fac7cec5333e3f919e094494 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 17 Jul 2026 14:09:34 +0200 Subject: [PATCH] =?UTF-8?q?HT-14:=20PDF-l=C3=A9p=C3=A9s=20elt=C3=A1vol?= =?UTF-8?q?=C3=ADtva=20=E2=80=94=20csak=20HTML=20render?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Az ÁSZF saját 3.2. pontja "megismerhető, megjeleníthető és letölthető" szöveget kér — ezt egy önálló (külső CSS/JS-függőség nélküli) HTML oldal is teljesíti (böngészőből menthető/nyomtatható), külön PDF-render nélkül. Ez NEM ugyanaz, mint a HRF-33/34 ajánlat-szerződés PDF-je — az egy ténylegesen elfogadott, hash-elt clickwrap-példány, más indokkal; azt nem érinti ez a változás. Egyszerűsödött CI-környezet: WeasyPrint + natív libek (pango/cairo) törölve, csak pandoc + python3 kell. A manifest "pdf" mezője megszűnt. A rendereletHTML immár kicsi (nincs PDF), ezért a teljes dist/ kimenet visszacommitolódik "manifest/" néven (nem csak a JSON) — a fogyasztók ugyanazzal a git clone-nal a HTML-t is megkapják, nem csak a metaadatot. --- .gitea/workflows/legal-manifest.yml | 54 +++++++++-------------------- scripts/build-manifest.py | 32 ++++++++--------- 2 files changed, 32 insertions(+), 54 deletions(-) diff --git a/.gitea/workflows/legal-manifest.yml b/.gitea/workflows/legal-manifest.yml index 86e6e11..f824c84 100644 --- a/.gitea/workflows/legal-manifest.yml +++ b/.gitea/workflows/legal-manifest.yml @@ -1,9 +1,9 @@ name: Build legal manifest -# HT-14: renders every project's legal markdown to HTML+PDF and produces +# HT-14: renders every project's legal markdown to HTML and produces # dist/legal-manifest.json — the single canonical source HT-15's consumer backends import, # so no one hashes/versions independently. See scripts/build-manifest.py for the actual -# logic; this workflow just provides the environment it needs. +# logic (and why there's no PDF step); this workflow just provides the environment it needs. on: push: @@ -24,50 +24,30 @@ jobs: fetch-depth: 0 # The CI environment: a plain ubuntu-latest job container (act_runner default image), - # with pandoc (markdown -> HTML, per HT-14) and WeasyPrint (HTML -> PDF, same - # approach already proven deterministic for ResidentFirst's HRF-34 offer contracts) - # installed as an explicit step — not baked into a custom runner image, so the - # environment stays visible and reproducible directly from this file. - - name: Install pandoc + WeasyPrint - run: | - apt-get update -qq - apt-get install -y --no-install-recommends \ - pandoc python3 python3-pip python3-venv \ - libpango-1.0-0 libpangoft2-1.0-0 fonts-dejavu-core - python3 -m venv /tmp/venv - /tmp/venv/bin/pip install --quiet weasyprint==69.0 - echo "/tmp/venv/bin" >> "$GITHUB_PATH" + # with pandoc (markdown -> HTML, per HT-14) installed as an explicit step — not baked + # into a custom runner image, so the environment stays visible and reproducible + # directly from this file. + - name: Install pandoc + run: apt-get update -qq && apt-get install -y --no-install-recommends pandoc python3 - name: Build manifest run: python3 scripts/build-manifest.py - # v4 uses a newer artifact-storage protocol this Gitea version doesn't implement yet - # ("GHESNotSupportedError", confirmed empirically) — v3 uses the older, supported one. - # Convenience only (manual inspection via the Actions UI) — HT-15 consumers should NOT - # depend on this: the repo-level list-artifacts API returned empty even after a - # successful v3 upload (a Gitea REST API gap, not a real absence — the run's own job - # log confirms the upload step succeeded). The commit-back step below is the real, - # dependable distribution path. - - name: Upload manifest + rendered artifacts (convenience only, see note above) - uses: actions/upload-artifact@v3 - with: - name: legal-manifest - path: dist/ - - # The dependable distribution path for HT-15: just the small JSON manifest (not the - # bulkier rendered HTML/PDF, to avoid repo bloat over time) committed back to the repo - # consumers already git-clone for the markdown sources — no Gitea Actions artifact API - # involved at all. - - name: Commit manifest back to repo + # The rendered HTML is now small (no PDF, see build-manifest.py) — committing the + # whole dist/ output back to the repo consumers already git-clone for the markdown + # sources is cheap and avoids the Gitea Actions artifact API entirely (its repo-level + # list-artifacts endpoint returned empty even after a confirmed-successful upload in + # an earlier version of this workflow — a REST API gap, not worth depending on). + - name: Commit manifest + rendered HTML back to repo run: | - mkdir -p manifest - cp dist/legal-manifest.json manifest/legal-manifest.json + rm -rf manifest + cp -r dist manifest git config user.name "H2W Legal CI" git config user.email "ci@h2w.hu" - git add manifest/legal-manifest.json + git add manifest if git diff --cached --quiet; then echo "Manifest változatlan — nincs mit commitolni." else - git commit -m "CI: legal-manifest.json frissítve [skip ci]" + git commit -m "CI: legal-manifest.json + renderelt HTML frissítve [skip ci]" git push origin HEAD:main fi diff --git a/scripts/build-manifest.py b/scripts/build-manifest.py index 39da408..055a2d4 100644 --- a/scripts/build-manifest.py +++ b/scripts/build-manifest.py @@ -1,14 +1,23 @@ #!/usr/bin/env python3 """Builds dist/legal-manifest.json (HT-14): renders each project's markdown legal documents -to HTML+PDF and computes a content_hash, producing the single canonical manifest every -consumer backend imports at deploy time (HT-15) instead of hashing independently. +to HTML and computes a content_hash, producing the single canonical manifest every consumer +backend imports at deploy time (HT-15) instead of hashing independently. + +HTML only, no PDF: the ÁSZF's own 3.2. clause requires the text to be "megismerhető, +megjeleníthető és letölthető" (accessible, viewable, downloadable) before acceptance — a +self-contained HTML page (no external CSS/JS) satisfies that on its own (savable/printable +from the browser) without a separate render step. Unlike HRF-33/34's offer-contract PDF — +that one is a *formally accepted, hashed instance* via clickwrap, a genuinely different +requirement — nothing here is "accepted" as a fixed artifact, so there's no reason to add a +second render toolchain (pandoc's PDF path needs a LaTeX/wkhtmltopdf/WeasyPrint engine) just +to reproduce what the browser already does with an HTML page opened in a new tab. content_hash source (interim, per the HT-3 "Design döntés" comment): the source markdown's git blob hash (`git hash-object`), NOT the rendered artifact's hash yet — that requires a -proven byte-for-byte-deterministic render, which this pandoc+WeasyPrint combination hasn't -been tested for (ResidentFirst's HRF-34 proved a *different* render pipeline deterministic, -not this one). Switching later doesn't invalidate old receipts, since a receipt is bound to -document_version, not content_hash alone. +proven byte-for-byte-deterministic render, which hasn't been tested for the pandoc HTML step +(ResidentFirst's HRF-34 proved a *different* pipeline deterministic, not this one). Switching +later doesn't invalidate old receipts, since a receipt is bound to document_version, not +content_hash alone. effective_from source: parsed from each document's own "Hatálybalépés napja: " line — the one human-controlled field carrying the legally relevant date. A document whose date is @@ -78,14 +87,6 @@ def render_html(markdown_path: Path, html_path: Path) -> None: ) -def render_pdf(html_path: Path, pdf_path: Path) -> None: - from weasyprint import HTML - - # full_fonts=True: WeasyPrint's default font subsetting is not byte-for-byte - # deterministic (confirmed empirically while building HRF-34) — full embedding is. - HTML(filename=str(html_path)).write_pdf(str(pdf_path), full_fonts=True) - - def build_manifest_for_project(project_dir: Path) -> dict: manifest = {} for md_path in sorted(project_dir.glob("*.md")): @@ -95,17 +96,14 @@ def build_manifest_for_project(project_dir: Path) -> dict: out_dir = OUTPUT_DIR / project_dir.name out_dir.mkdir(parents=True, exist_ok=True) html_path = out_dir / f"{doc_type}.html" - pdf_path = out_dir / f"{doc_type}.pdf" render_html(md_path, html_path) - render_pdf(html_path, pdf_path) manifest[doc_type] = { "version": last_commit_hash(md_path), "effective_from": parse_effective_from(markdown), "content_hash": git_blob_hash(md_path), "html": f"{project_dir.name}/{doc_type}.html", - "pdf": f"{project_dir.name}/{doc_type}.pdf", } return manifest