Skip to content

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 13 Sep 21:19
· 10 commits to main since this release

v0.2.0 (2026-09-13)

This release is published under the MIT License.

Bug Fixes

  • License date (2f1e9b4)

  • ci: Build dists with python -m build inside the release action (b0963ea)

pipx is not available in the semantic-release action container (exit 127); python -m build drives the poetry-core backend directly through PEP 517.

  • ci: Pin upload-to-gh-release to an existing tag (c268493)

  • ci: Use the semantic-release version action, not publish-action (cf65e6c)

publish-action only uploads distributions to an existing release; the version action (semantic-release version) computes the bump, stamps the version, builds, tags, pushes and creates the GitHub release.

  • tests: Replace bare conftest imports in the screenshot suite (0567270)

The full single-process pytest run (the CI image entrypoint) collects tests/import/smoke/conftest.py as the top-level 'conftest' module first, so 'from conftest import ARTIFACTS_DIR' in screenshot tests resolved to the wrong module and broke collection. The path constants now live in _pipeline.py; imports are explicit. Full suite in one process: 1003 passed, 18 skipped.

Chores

  • Move .dockerignore back to the repository root (e07d310)

Prefer the classic context-root ignore file over the BuildKit-only per-Dockerfile variant; works with any builder.

  • Relocate .dockerignore to docker/Dockerfile.dockerignore (9b31721)

BuildKit resolves the ignore file next to the Dockerfile itself (.dockerignore), keeping the repository root clean. All build paths (local Docker 28, GitHub Actions buildx) are BuildKit-based.

  • Ruff-fix screenshot test imports (dfe8928)

  • Slim the Dockerfile and move it to docker/ (0a56357)

  • drop libreoffice-impress/-calc and make from the system layer (only
    core/writer/math are exercised by the rendering pipeline; the full
    pixel-diff screenshot gate re-verified rendering parity)

  • apt retry loop trimmed to 3 attempts; pandoc check simplified

  • test stage now chains from deps (one poetry install instead of two)

  • Dockerfile relocated to docker/Dockerfile; Makefile and CI workflows
    pass -f/--file accordingly

Continuous Integration

  • Draft GitHub Actions workflows (1c02f44)

  • ci.yml: full suite (unit + integration + screenshot) inside the test
    image, MinIO sidecar for S3 integration tests

  • publish.yml: on semver tag — GHCR runtime image + PyPI sdist/wheel
    via trusted publishing; immutable tags only, no floating latest

  • Enforce conventional commits (caf3a66)

Local commit-msg hook (.githooks, enabled by make install / make hooks) rejects non-conventional messages before the commit lands; CI re-checks every PR commit with the same script. Merge and revert commits are exempt. Required by semantic-release: the bump level is computed from commit types.

  • publish: Fail when tag does not match pyproject version (b063909)

Documentation

  • Add AGENTS.md and an installable agent skill (bca5ef7)

  • AGENTS.md: short contributor rules — repo map, commands, contract-first
    syntax changes, screenshot-gate policy, brevity principle

  • skills/markdown-gost/: SKILL.md (CLI reference + syntax cheat sheet,
    Anthropic skill format; installable via npx skills add or copying into
    a harness skills directory) with syntax.md bundled

  • unit test keeps skills/markdown-gost/syntax.md identical to
    docs/syntax.md; test image copies skills/

  • English README, syntax reference and architecture overview (9090918)

  • Merge syntax manifest and example corpus into single syntax.md (d944540)

One normative file instead of three: docs/syntax.md now carries the syntax contract (principles, attribute grammar, container roles, error rules, change protocol — translated from the Russian manifest) and the executable example corpus. The unit suite parses every fenced markdown block in the file (test_full_corpus), so documented constructs are proven to parse and a construct without a live example is not covered.

  • docs/example.md and docs/syntax-manifest.md removed

  • reference docstrings updated to point at docs/syntax.md

  • the old English reference described the pre-migration syntax
    (%table, @cite:, ---content); the merged file documents the
    attribute-based syntax shipped since the manifest migration

  • Reference the upcoming 0.2.0 image tag in the docker example (b0410a1)

  • Single syntax source of truth in skills/markdown-gost/syntax.md (06acbf0)

docs/syntax.md removed; the skill copy is now the only file. The corpus test, docstrings and doc links point at skills/markdown-gost/syntax.md; the docs-sync unit test is obsolete and deleted.

  • Trim README to links and commands (33d9f9a)

  • Validate import-syntax-mapping against the actual postprocessors (d399f1c)

The document described the pre-migration syntax and stale behavior. Fixed against code: captions fold into ': Caption' (not %table/%listing), unnumbered headings emit {.unnumbered} for a fixed H1 title set, underline keeps the canonical [text]{.underline} form, monospace set gained DejaVu Sans Mono, image ids are sha256[:32] with content dedup, broken media links become placeholders, semantic_docx prestep (style rename + math-table unfold) and PDF textbox recovery documented, dead ADR link removed, template names updated.

  • skill: Drop stale docs/syntax.md reference (6425e6d)

Features

  • Agent skill (2fe75af)

  • Single multi-stage Docker image (CLI runtime + test stage) (e5fd4fc)

base (python 3.13, LibreOffice, pinned pandoc, unoserver, fonts) -> deps -> test (dev deps + playwright, default CI target via --target) -> runtime (CLI entrypoint, non-root uid 10001, default build target). Entrypoint starts unoserver on loopback before exec'ing the CLI so 'convert --format pdf' works out of the box.

  • ci: Automated semantic releases on push to main (20d1f6d)

python-semantic-release evaluates conventional commits on every push to main: feat -> minor, fix/perf -> patch, breaking changes (the "!" marker or footer) -> major

(major_on_zero). On release: version stamped into pyproject.toml and version, v-tag + GitHub release created, sdist/wheel published to PyPI via trusted publishing, runtime image pushed to GHCR with the same tag. Release commits carry [skip ci]. Test-image GHA cache scope shared between CI and publish gates. Tag-triggered publishing and the tag/version guard step are obsolete and removed.

  • templates: Rename titlepage-mirea to titlepage-university, add logo param (9dc02b8)

The bundled title page is a generic Russian university form and must not be tied to a particular institution.

  • registry id: titlepage-university (module titlepage_university); the titlepage-* namespace stays free for institution-specific variants - new logo template param: local path or http(s) URL of the emblem image (~2.5 cm wide). A broken explicit reference raises; an absent logo renders no emblem. Preview layout gains logo_url - tests: logo render (local file), no-logo, broken-reference cases; corpus/manifest/preview fixtures moved to the new name - screenshot cases 14/14a/15g use the new template name; rendering is unchanged, baselines verified (75 passed) - known follow-up for the platform switch (Stage B): frontend template picker, titlepage block helper and default session markdown still reference the old name

Refactoring

  • Drop the bundled S3 storage backend from the library (c6da268)

Object stores are an integrating-service concern, not a library one: the engine keeps the Storage protocol and the built-in FilesystemStorage, and services inject their own Storage implementations via the existing dependency-injection seams (convert/preview/import all accept a storage argument).

  • storage/s3.py and the STORAGE_BACKEND=s3 branch removed; get_storage()
    is filesystem-only and points to injection for anything else
  • [s3] extra and boto3 dev dependency dropped
  • S3 unit/integration tests moved out (hosted by the consuming service)
  • docs and CI no longer reference object storage or the EasyGOST
    platform; downstream integration details stay private

Detailed Changes: v0.1.0...v0.2.0