Files
tzst/.github/workflows/ci.yml
T
xixu-me a15a497c52 Update PyPI badge and README formatting
Modified the PyPI version badge URL in the CI workflow and README to simplify the URL. Enhanced README with emojis for better visual appeal and added detailed installation instructions for standalone binaries.
2025-06-04 22:16:41 +08:00

357 lines
10 KiB
YAML

name: CI/CD
on:
push:
branches: [main, develop]
tags:
- "v*.*.*"
paths-ignore:
- "*.md"
- "LICENSE"
- "docs/**"
- ".gitignore"
pull_request:
branches: [main]
paths-ignore:
- "*.md"
- "LICENSE"
- "docs/**"
- ".gitignore"
release:
types: [published]
jobs:
test:
permissions:
contents: read
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .[dev]
- name: Lint with ruff
run: |
ruff check src tests
- name: Format check with ruff
run: |
ruff format --check src tests
- name: Run tests
run: |
pytest --cov=tzst --cov-branch --cov-report=xml
- name: Upload coverage to Codecov
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: xixu-me/tzst
build:
needs: test
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
- name: Build package
run: python -m build
- name: Check package
run: twine check dist/*
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
publish:
needs: build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
environment:
name: pypi
url: https://pypi.org/p/tzst
permissions:
id-token: write
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
build-binaries:
needs: test
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: read
strategy:
matrix:
include:
# Linux architectures
- os: ubuntu-latest
os_name: linux
arch: x86_64
python-version: "3.12"
- os: ubuntu-latest
os_name: linux
arch: aarch64
python-version: "3.12"
cross_compile: true
# Windows architectures
- os: windows-latest
os_name: windows
arch: amd64
python-version: "3.12"
- os: windows-latest
os_name: windows
arch: arm64
python-version: "3.12"
cross_compile: true # macOS architectures
- os: macos-13 # Intel-based runner
os_name: macos
arch: x86_64
python-version: "3.12"
- os: macos-14 # ARM-based runner (M1/M2)
os_name: macos
arch: arm64
python-version: "3.12"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Extract version from tag
id: version
shell: bash
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install pyinstaller
- name: Build binary
run: |
python -m PyInstaller --onefile --name tzst --console src/main.py
- name: Verify binary (Linux/macOS)
if: matrix.os != 'windows-latest'
run: |
if [ ! -f "dist/tzst" ]; then
echo "Binary build failed!"
exit 1
fi
- name: Verify binary (Windows)
if: matrix.os == 'windows-latest'
run: |
if (-not (Test-Path "dist/tzst.exe")) {
Write-Host "Binary build failed!"
exit 1
}
- name: Build binary for ARM64 on macOS
if: matrix.os == 'macos-14' && matrix.arch == 'arm64'
run: |
python -m PyInstaller --onefile --name tzst --console --target-arch arm64 src/main.py
- name: Build binary for ARM64 on Windows
if: matrix.os == 'windows-latest' && matrix.arch == 'arm64'
run: |
python -m PyInstaller --onefile --name tzst --console --target-arch arm64 src/main.py
- name: Setup cross-compilation for Linux ARM64
if: matrix.os == 'ubuntu-latest' && matrix.arch == 'aarch64'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
- name: Build binary for ARM64 on Linux
if: matrix.os == 'ubuntu-latest' && matrix.arch == 'aarch64'
env:
CC: aarch64-linux-gnu-gcc
run: |
python -m PyInstaller --onefile --name tzst --console --target-arch aarch64 src/main.py
- name: Prepare archive contents (Linux/macOS)
if: matrix.os != 'windows-latest'
run: |
mkdir -p archive
cp dist/tzst archive/
cp README.md archive/
cp LICENSE archive/
- name: Prepare archive contents (Windows)
if: matrix.os == 'windows-latest'
run: |
New-Item -ItemType Directory -Path archive -Force
Copy-Item dist/tzst.exe archive/
Copy-Item README.md archive/
Copy-Item LICENSE archive/
- name: Create zip archive (Linux/macOS)
if: matrix.os != 'windows-latest'
run: |
cd archive
zip -r ../tzst-v${{ steps.version.outputs.version }}-${{ matrix.os_name }}-${{ matrix.arch }}.zip .
- name: Create zip archive (Windows)
if: matrix.os == 'windows-latest'
run: |
cd archive
Compress-Archive -Path * -DestinationPath ../tzst-v${{ steps.version.outputs.version }}-${{ matrix.os_name }}-${{ matrix.arch }}.zip
- name: Upload binary artifacts
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.os_name }}-${{ matrix.arch }}
path: tzst-v${{ steps.version.outputs.version }}-${{ matrix.os_name }}-${{ matrix.arch }}.zip
create-release:
needs: [publish, build-binaries]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Extract version from tag
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Download all binary artifacts
uses: actions/download-artifact@v4
with:
pattern: binary-*
merge-multiple: true
- name: Create GitHub Release
run: |
gh release create ${{ github.ref_name }} \
--title "tzst ${{ steps.version.outputs.version }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Release Assets
run: |
echo "Available files:"
ls -la tzst-v${{ steps.version.outputs.version }}-*.zip 2>/dev/null || echo "No zip files found"
success=0
for file in tzst-v${{ steps.version.outputs.version }}-*.zip; do
if [ -f "$file" ]; then
echo "Uploading $file"
if gh release upload ${{ github.ref_name }} "$file" --clobber; then
echo "Successfully uploaded $file"
success=$((success + 1))
else
echo "Failed to upload $file"
fi
fi
done
if [ $success -eq 0 ]; then
echo "Warning: No files were successfully uploaded"
else
echo "Successfully uploaded $success file(s)"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
update_badges:
needs: [build, publish]
if: always() && needs.build.result == 'success' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Fetch PyPI version
id: pypi_version
run: |
pip install requests
python -c "
import requests, json, os
try:
data = requests.get('https://pypi.org/pypi/tzst/json').json()
version = data['info']['version']
print(f'PyPI version: {version}')
except Exception as e:
print(f'Error fetching version: {e}')
version = 'unknown'
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
f.write(f'version={version}\n')
"
- name: Update README badge
run: |
echo "Updating PyPI badge with version: ${{ steps.pypi_version.outputs.version }}"
# Update PyPI version badge in README.md
if [ -f "README.md" ]; then
# Replace PyPI version badge
sed -i 's|https://img.shields.io/pypi/v/tzst[^)]*|https://img.shields.io/pypi/v/tzst|g' README.md || true
# Update version in badge alt text if exists
sed -i 's|PyPI - Version[^]]*|PyPI - Version|g' README.md || true
fi
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
- name: Commit and push changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "Update badges [skip ci]"
file_pattern: README.md
branch: main