Skip to content

cancel-in-flight -> cancel-in-progress #5

cancel-in-flight -> cancel-in-progress

cancel-in-flight -> cancel-in-progress #5

Workflow file for this run

name: Release Pipeline

Check failure on line 1 in .github/workflows/release.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/release.yml

Invalid workflow file

(Line: 140, Col: 9): Unexpected symbol: '#'. Located at position 181 within expression: 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') # Custom condition for test releases
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') # Custom condition for test releases
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 }}