Files
tzst/.github/workflows/ci.yml
T
Workflow config file is invalid. Please check your config file: yaml: construct errors: line 168: mapping key "run" already defined at line 164
xixu-me 1dd3cde654 Enhance CI/CD workflow for versioned tags
Updated the CI/CD pipeline to support versioned tags for releases. Added new jobs for building binaries across multiple platforms and architectures, creating release assets, and uploading them to GitHub. Improved conditional logic for triggering workflows based on tags and streamlined badge updates.
2025-06-04 20:42:48 +08:00

333 lines
9.5 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-latest # 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 -m tzst
- name: Build binary for ARM64 on macOS (override previous build)
if: matrix.os == 'macos-latest' && matrix.arch == 'arm64'
run: |
python -m PyInstaller --onefile --name tzst --console --target-arch arm64 -m tzst
- name: Build binary for ARM64 on Windows (override previous build)
if: matrix.os == 'windows-latest' && matrix.arch == 'arm64'
run: |
python -m PyInstaller --onefile --name tzst --console --target-arch arm64 -m tzst
- 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
- name: Build binary for ARM64 on Linux (override previous build)
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 -m tzst
- 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 v${{ steps.version.outputs.version }}" \
--notes "## tzst v${{ steps.version.outputs.version }}
### Installation
#### Python Package
\`\`\`bash
pip install tzst==${{ steps.version.outputs.version }}
\`\`\`
#### Standalone Binaries
Download the appropriate binary for your platform from the assets below.
### Changes
See the [commit history](https://github.com/xixu-me/tzst/commits/${{ github.ref_name }}) for detailed changes."
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Release Assets
run: |
for file in tzst-v${{ steps.version.outputs.version }}-*.zip; do
if [ -f "$file" ]; then
echo "Uploading $file"
gh release upload ${{ github.ref_name }} "$file" --clobber
fi
done
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 }}"
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