Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/actions/zpretty/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Set up zpretty
description: >
Install zpretty so a workflow can run it (for example `zpretty --check`).

inputs:
spec:
description: >
pip requirement specifier for zpretty: a release such as
"zpretty==4.0.2", a VCS URL, or "." to install the checked-out source.
required: false
default: zpretty
python-version:
description: Python version to set up.
required: false
default: "3.x"

runs:
using: composite
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version }}

- name: Install zpretty
shell: bash
run: python -m pip install "${{ inputs.spec }}"

- name: Report zpretty version
shell: bash
run: zpretty --version
22 changes: 22 additions & 0 deletions .github/workflows/zpretty-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: zpretty action

on: [push, pull_request]

permissions:
contents: read

jobs:
self-test:
name: Set up zpretty from source and run it
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Set up zpretty from this checkout
uses: ./.github/actions/zpretty
with:
spec: .

- name: Smoke-test the installed zpretty
shell: bash
run: zpretty --check zpretty/tests/original/sample_xml.xml
4 changes: 4 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
@ale-rt
- Fix possible issue with whitespaces lost around comments in XML documents.
@ale-rt
- Add a reusable GitHub Action and GitLab CI/CD component to set up
`zpretty` in CI pipelines.
(#232)
@gronke


## 4.0.2 (2026-06-09)
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
global-exclude *.pyc __pycache__ pyvenv.cfg
graft zpretty
graft zpretty/tests/include-excludes/.git
recursive-include gitlab *.yml
include *.cfg *.txt *.md *.in LICENSE Makefile .pre-commit-config.yaml .pre-commit-hooks.yaml tox.ini pyproject.toml
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,49 @@ To do so, add the following to your `.pre-commit-config.yaml`:
- id: zpretty
```

# Continuous integration

The examples below pin `4.0.3`, the first release that ships the action
and the template. Pinning a release keeps the formatting behavior stable
across repeated CI runs; any other git reference (a newer tag, a commit
SHA, or `master` to follow the development version) works as well.

## GitHub Actions

This repository ships a composite action that installs `zpretty` so a
workflow can run it:

```yaml
# Check out the repository whose files zpretty should check
- uses: actions/checkout@v6
- uses: collective/zpretty/.github/actions/zpretty@4.0.3
- run: zpretty --check path/to/file.xml
```

The action takes two optional inputs: `spec`, a pip requirement specifier
(a release such as `zpretty==4.0.2`, a VCS URL, or `.` to install the

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see the reason of checking out a zpretty and then using a spec different from .

checked-out source; defaults to `zpretty`), and `python-version`
(defaults to `3.x`).

## GitLab CI/CD

For GitLab there is a reusable CI/CD configuration. Include it and extend
the `.zpretty` job it defines:

```yaml
include:
- remote: "https://raw.githubusercontent.com/collective/zpretty/4.0.3/gitlab/zpretty.gitlab-ci.yml"

zpretty:
extends: .zpretty
script:
- zpretty --check path/to/file.xml
```

Set the `ZPRETTY_SPEC` variable (default `zpretty`) to change the pip
specifier and `ZPRETTY_PYTHON_VERSION` (default `3`) to pick the Python
image tag.

# VSCode extension

There is a VSCode extension that uses `zpretty`:
Expand Down
15 changes: 15 additions & 0 deletions gitlab/zpretty.gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Reusable zpretty setup for GitLab CI. Usage:
# include:
# - remote: "https://raw.githubusercontent.com/collective/zpretty/<ref>/gitlab/zpretty.gitlab-ci.yml"
# zpretty:
# extends: .zpretty
# variables: { ZPRETTY_SPEC: "zpretty==4.0.2" } # optional
# script: [zpretty --check path/to/file.xml]
.zpretty:
image: "python:$ZPRETTY_PYTHON_VERSION"
variables:
ZPRETTY_PYTHON_VERSION: "3"
ZPRETTY_SPEC: zpretty
before_script:
- python -m pip install "$ZPRETTY_SPEC"
- zpretty --version
30 changes: 30 additions & 0 deletions zpretty/tests/test_readme.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from zpretty.tests.mock import MockCLIRunner

import argparse
import re


class TestReadme(TestCase):
Expand Down Expand Up @@ -36,3 +37,32 @@ def test_readme(self):
observed = self.extract_usage_from_readme()
expected = self.extract_usage_from_parser()
self.assertListEqual(observed, expected)

def extract_pinned_versions_from_readme(self):
"""Extract the versions pinned in the CI examples"""
readme_path = files("zpretty").parent / "README.md"
readme = readme_path.read_text()
github = re.search(r"collective/zpretty/\.github/actions/zpretty@(\S+)", readme)
gitlab = re.search(
r"collective/zpretty/([^/\s]+)/gitlab/zpretty\.gitlab-ci\.yml", readme
)
return github.group(1), gitlab.group(1)

def extract_versions_from_history(self):
"""Return the topmost and the latest released version from HISTORY.md"""
history_path = files("zpretty").parent / "HISTORY.md"
entries = re.findall(
r"^## (\d\S*) \(([^)]+)\)", history_path.read_text(), re.MULTILINE
)
released = [version for version, date in entries if date != "unreleased"]
return entries[0][0], released[0]

def test_ci_examples_pin_a_current_release(self):
"""Both CI examples must pin the same version, and it must be the
latest released or the upcoming one, so the README cannot silently
fall a release behind.
"""
github, gitlab = self.extract_pinned_versions_from_readme()
self.assertEqual(github, gitlab)
topmost, latest_released = self.extract_versions_from_history()
self.assertIn(github, (topmost, latest_released))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test is a pain to keep it running and not very comprehensive.
As you can see in the README you still have a mixture of 4.0.2 and 4.0.3.