Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1170b93
Add .editorconfig
ivanovmg Aug 25, 2025
d423bd6
Add pyproject.toml
ivanovmg Aug 25, 2025
5576c55
Add Makefile
ivanovmg Aug 25, 2025
412eea0
Ignore venv*
ivanovmg Aug 25, 2025
22e4a7c
Add tests
ivanovmg Aug 25, 2025
964f28b
Add production code
ivanovmg Aug 25, 2025
4a6b42a
REF: extract clean_diff into separate module
ivanovmg Aug 25, 2025
f8611ec
REF: extract pretty_format_xml into separate module
ivanovmg Aug 25, 2025
c40b1f5
TYP: test function
ivanovmg Aug 25, 2025
66c1a72
Add types-defusedxml as a dev dependency for mypy
ivanovmg Aug 25, 2025
fb636c3
FIX: exclude lines in coverage
ivanovmg Aug 25, 2025
065bdf2
REF: extract indenting module
ivanovmg Aug 25, 2025
857d006
REF: move _canonical to formatting.py
ivanovmg Aug 25, 2025
a7b8f69
Export clean_diff explicitly
ivanovmg Aug 25, 2025
d7abb56
Split parameters one per line
ivanovmg Aug 25, 2025
b8061f4
Set minimal requirement on defusedxml>=0.6.0
ivanovmg Aug 25, 2025
3fb0331
REF: simplify indent
ivanovmg Aug 25, 2025
ab65738
TST: make tests on assertion error more strict
ivanovmg Aug 25, 2025
523b76b
Add copyright statement
ivanovmg Aug 25, 2025
b07d2f7
Add SPDX identifier in LICENSE
ivanovmg Aug 25, 2025
f97c547
TYP: add empty py.typed
ivanovmg Aug 25, 2025
61ba3ff
Add CHANGELOG
ivanovmg Aug 25, 2025
78dc35b
Make version 0.1.0rc1
ivanovmg Aug 25, 2025
b40fcbc
Add github actions
ivanovmg Aug 25, 2025
3f9a358
Validate package version and git tag version
ivanovmg Aug 25, 2025
e2ccb47
Fix version extraction from git tag name
ivanovmg Aug 25, 2025
7f156b3
FIX: git tag version parsing maybe
ivanovmg Aug 25, 2025
ae0caed
cancel-in-flight -> cancel-in-progress
ivanovmg Aug 25, 2025
759d03b
FIX: drop comment
ivanovmg Aug 25, 2025
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
23 changes: 23 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# .editorconfig
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.py]
indent_size = 4
max_line_length = 88

[*.{yml,yaml}]
indent_size = 2

[*.{md,toml,json}]
indent_size = 2

[Makefile]
indent_style = tab
235 changes: 235 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
name: Release Pipeline

on:
push:
tags:
- 'v*' # trigger on version tags
pull_request:
branches: [ master ]

# Allow only one concurrent deployment to avoid conflicts
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
validate-version:
name: Validate tag version
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
outputs:
tag_version: ${{ steps.tag-version.outputs.TAG_VERSION }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Extract package version
id: package-version
run: |
# Extract version from pyproject.toml
PACKAGE_VERSION=$(python -c "
import tomli
with open('pyproject.toml', 'rb') as f:
data = tomli.load(f)
print(data['project']['version'])
")
echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_OUTPUT

- name: Extract tag version
id: tag-version
run: |
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
echo "TAG_VERSION=$TAG_VERSION" >> $GITHUB_OUTPUT

- name: Validate versions match
run: |
PACKAGE_VERSION="${{ steps.package-version.outputs.PACKAGE_VERSION }}"
TAG_VERSION="${{ steps.tag-version.outputs.TAG_VERSION }}"

if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
echo "? CRITICAL: VERSION MISMATCH DETECTED!"
echo "::error::Git tag version does not match package version!"
echo "::error::Tag version: v$TAG_VERSION"
echo "::error::Package version: $PACKAGE_VERSION"
echo "::error::"
echo "::error::To fix this:"
echo "::error::1. Delete the wrong tag: git tag -d v$TAG_VERSION"
echo "::error::2. Delete remote tag: git push --delete origin v$TAG_VERSION"
echo "::error::3. Update pyproject.toml with correct version"
echo "::error::4. Create correct tag: git tag -a v$PACKAGE_VERSION -m 'Release v$PACKAGE_VERSION'"
echo "::error::5. Push correct tag: git push origin v$PACKAGE_VERSION"
exit 1
else
echo "? Versions match: v$TAG_VERSION"
fi

test:
name: Test on Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .[dev]

- name: Run tests with pytest
run: |
pytest -v --cov=xmlassert --cov-report=xml

build:
name: Build package
runs-on: ubuntu-latest
needs: test # Only build if tests pass
if: startsWith(github.ref, 'refs/tags/v')

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'

- name: Install build tools
run: |
python -m pip install --upgrade pip
pip install build twine

- name: Build package
run: python -m build

- name: Verify package
run: twine check dist/*

- name: Inspect built packages (optional)
run: |
echo "Built packages:"
ls -la dist/
echo "Wheel compatibility:"
for wheel in dist/*.whl; do
echo "$wheel:"
unzip -l "$wheel" | grep -E "(.py$|METADATA)" | head -5
done

- name: Upload build artifacts (tags only)
if: startsWith(github.ref, 'refs/tags/v')
uses: actions/upload-artifact@v3
with:
name: distribution-packages
path: dist/

test-pypi:
name: Publish to TestPyPI
runs-on: ubuntu-latest
needs: [validate-version, build]
if: |
startsWith(github.ref, 'refs/tags/v') &&
(contains(github.ref, 'alpha') ||
contains(github.ref, 'beta') ||
contains(github.ref, 'rc') ||
github.ref == 'refs/tags/v0.0.0-test')

steps:
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: distribution-packages

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'

- name: Install twine
run: pip install twine

- name: Publish to TestPyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
run: twine upload --repository-url https://test.pypi.org/legacy/ dist/*

- name: Verify TestPyPI installation
run: |
python -m pip install --index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
xmlassert==${{ needs.validate-version.outputs.tag_version }}

pypi:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: [validate-version, build]
if: |
startsWith(github.ref, 'refs/tags/v') &&
!contains(github.ref, 'alpha') &&
!contains(github.ref, 'beta') &&
!contains(github.ref, 'rc') &&
github.ref != 'refs/tags/v0.0.0-test'

steps:
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: distribution-packages

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install twine
run: pip install twine

- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: twine upload dist/*

- name: Verify PyPI installation
run: |
# Wait a moment for PyPI to update
sleep 30
pip install \
xmlassert==${{ needs.validate-version.outputs.tag_version }}

github-release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs: [test-pypi, pypi]
if: always() && startsWith(github.ref, 'refs/tags/v')

steps:
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: distribution-packages

- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
dist/*.whl
dist/*.tar.gz
generate_release_notes: true
body: |
Automated release for ${{ github.ref_name }}

See CHANGELOG.md for details.
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ celerybeat.pid
.venv
env/
venv/
venv*/
ENV/
env.bak/
venv.bak/
Expand Down Expand Up @@ -182,9 +183,9 @@ cython_debug/
.abstra/

# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/

Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# CHANGELOG

## v0.1.0 (2025-08-25)

**Initial Release**

- First release of `xmlassert`
- Includes `assert_xml_equal` function
2 changes: 2 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
MIT License

SPDX-License-Identifier: MIT

Copyright (c) 2025 Maxim Ivanov

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
Loading