Skip to content

Fixed issue with whitespaces #157

Fixed issue with whitespaces

Fixed issue with whitespaces #157

Workflow file for this run

name: Python Package CI
on:
push:
branches:
- main
tags:
# Trigger on any tag (matches 0.0.1, v0.0.1 etc.)
- 'v[0-9]+.[0-9]+.[0-9]+' # Matches vX.Y.Z
- '[0-9]+.[0-9]+.[0-9]+' # Matches X.Y.Z
pull_request:
branches:
- main
release:
types: [published] # Trigger if you create releases via GitHub UI based on tags
# Define permissions required for the workflow jobs
permissions:
contents: read # Needed for actions/checkout
packages: write # Needed for pushing Docker images to GHCR
jobs:
lint:
name: Lint (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false # Don't cancel other jobs if one lint version fails
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
# No fetch-depth needed for linting typically
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip' # Cache pip dependencies
- name: Install lint dependencies
run: |
python -m pip install --upgrade pip
# Install linters AND setuptools (might be needed by some implicitly)
pip install ruff flake8 pylint isort setuptools
# Install project dependencies if linters need to import them
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
# Optional: Install package if pylint needs deep import checks
# pip install .
- name: Analysing the code with pylint
run: |
# Adjust path if needed
pylint python_gpt_po/ || echo "Pylint found issues but continuing..." # Or remove || to fail on issues
- name: Check code style with flake8
run: |
# Adjust path if needed
flake8 python_gpt_po/
- name: Check import order with isort
run: |
isort --check-only --diff .
- name: Linting with Ruff
run: |
# Uses git ls-files to find only tracked python files
ruff check $(git ls-files '*.py')
test:
name: Test (Python ${{ matrix.python-version }})
needs: lint # Run tests only if linting passes
runs-on: ubuntu-latest
strategy:
fail-fast: false # Don't cancel other jobs if one test version fails
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Fetch depth and tags might be needed if tests rely on git history/version
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y gettext
- name: Install test dependencies
run: |
python -m pip install --upgrade pip
# Install runtime dependencies
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
# Install test runner (e.g., pytest) and any test-specific packages
pip install pytest pytest-cov
# Install the package itself in editable mode for testing
pip install -e .
- name: Run tests with pytest
run: |
pytest --cov=python_gpt_po --cov-report=xml --cov-report=term-missing
docker-test-build:
name: Docker Test Build (Python ${{ matrix.python-version }})
# Renamed job to be clearer it's for testing the build, not deploying
needs: test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed for git describe
fetch-tags: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers for Test Build
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache-test # Separate cache path for test builds
# Key includes python version and commit SHA for distinct caching per commit
key: ${{ runner.os }}-buildx-test-${{ matrix.python-version }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-test-${{ matrix.python-version }}-
- name: Get Version using git describe
# Use git describe for non-tag builds (main, PRs) and tags
id: get_version
run: |
git fetch --tags --force --prune --unshallow || echo "Fetching tags failed, proceeding..."
# Use git describe. Outputs exact tag (e.g., 0.1.0) or dev version (0.1.0-3-gddfce44)
GIT_DESCRIBE=$(git describe --tags --always --dirty 2>/dev/null || echo "0.0.0")
# Remove 'v' prefix if tags have it (adjust if your tags don't use 'v')
VERSION=${GIT_DESCRIBE#v}
echo "Using version for Docker build arg: $VERSION"
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
- name: Build Docker Image (Test) - Python ${{ matrix.python-version }}
uses: docker/build-push-action@v5
with:
context: .
# Load image into Docker daemon for local testing, don't push
load: true
tags: local/gpt-po-translator:py${{ matrix.python-version }}-test
build-args: |
PYTHON_VERSION=${{ matrix.python-version }}
VERSION=${{ steps.get_version.outputs.VERSION }}
cache-from: type=gha,scope=test-${{ matrix.python-version }}
cache-to: type=gha,mode=max,scope=test-${{ matrix.python-version }}
- name: Test Docker Image - Basic Commands
run: |
docker run --rm local/gpt-po-translator:py${{ matrix.python-version }}-test --version
docker run --rm local/gpt-po-translator:py${{ matrix.python-version }}-test --help
echo "✅ Basic command tests passed for Docker image (Python ${{ matrix.python-version }})"
- name: Test Docker Image - CLI Options Help
run: |
docker run --rm local/gpt-po-translator:py${{ matrix.python-version }}-test --provider openai --help
docker run --rm local/gpt-po-translator:py${{ matrix.python-version }}-test --provider anthropic --help
echo "✅ CLI provider help test passed for Docker image (Python ${{ matrix.python-version }})"
- name: Test Docker Image - Volume Mount Help
# This verifies the entrypoint script and basic arg parsing work with volumes
run: |
mkdir -p ./test-po-dir # Create a temporary directory on the runner
echo 'msgid "Test"\nmsgstr ""' > ./test-po-dir/sample.po
docker run --rm \
-v $(pwd)/test-po-dir:/app/po_files \
local/gpt-po-translator:py${{ matrix.python-version }}-test \
--folder /app/po_files --help
rm -rf ./test-po-dir # Clean up
echo "✅ Volume mount help test passed for Docker image (Python ${{ matrix.python-version }})"
deploy:
name: Deploy to PyPI and GHCR
needs: [test, docker-test-build] # Depends on successful tests and Docker builds
runs-on: ubuntu-latest
# Condition: Run only on pushing a tag matching the pattern
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
# Optional: Define environment for secrets or protection rules
environment: release
# Permissions: Add id-token write if using PyPI Trusted Publishing
permissions:
contents: read # For checkout
packages: write # For GHCR push
# id-token: write # Uncomment if using PyPI Trusted Publishing`
strategy:
fail-fast: true # If one deployment fails, stop others
matrix:
# Define ALL python versions for Docker images
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
# Designate ONE primary version for PyPI publish and Docker 'latest' tag
primary-py: ['3.11'] # Choose your primary Python version
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed for setuptools_scm
fetch-tags: true
# === PyPI Deployment (runs only once for the primary Python version) ===
- name: Set up Python for PyPI deploy
# Run ONLY for the designated primary version
if: matrix.python-version == matrix.primary-py
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.primary-py }}
- name: Install PyPI build dependencies
if: matrix.python-version == matrix.primary-py
run: python -m pip install --upgrade pip build twine
- name: Verify Git state before PyPI build
if: matrix.python-version == matrix.primary-py
run: |
echo "Current Git Ref: ${{ github.ref }}"
git status
git describe --tags --exact-match # Should match the tag exactly
- name: Build package for PyPI
# Uses setuptools_scm automatically via pyproject.toml build-system config
if: matrix.python-version == matrix.primary-py
run: python -m build
- name: Verify built package metadata for PyPI
if: matrix.python-version == matrix.primary-py
run: twine check dist/*
- name: Publish package to PyPI
if: matrix.python-version == matrix.primary-py
uses: pypa/gh-action-pypi-publish@release/v1
with:
# --- API Token Authentication ---
# Ensure PYPI_API_TOKEN is set in GitHub Secrets
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
# --- Or use Trusted Publishing (recommended) ---
# Requires 'id-token: write' permission at job level
# Requires configuration on PyPI website first
# trust-token: true
# === Docker Deployment (runs for EACH Python version in the matrix) ===
# No 'if' condition on these Docker steps, they run for all matrix versions
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers for Deploy
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache-deploy # Separate cache path for deploy builds
# Cache key includes python version and the specific tag ref being built
key: ${{ runner.os }}-deploy-buildx-${{ matrix.python-version }}-${{ github.ref }}
restore-keys: |
${{ runner.os }}-deploy-buildx-${{ matrix.python-version }}-
- name: Log in to GitHub Container Registry (GHCR)
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
# GITHUB_TOKEN is automatically available, no secret needed
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
# Use the Git tag from the event ref as the base version
# Assumes tags are like '0.1.0' or 'v0.1.0' - metadata-action handles 'v' prefix
tags: |
# Generate tags like: 0.1.0-py3.9, 0.1-py3.9, 0-py3.9
type=semver,pattern={{version}}-py${{ matrix.python-version }}
type=semver,pattern={{major}}.{{minor}}-py${{ matrix.python-version }}
type=semver,pattern={{major}}-py${{ matrix.python-version }}
# Add 'latest' tag ONLY for the primary python version build
type=raw,value=latest,enable=${{ matrix.python-version == matrix.primary-py }}
- name: Get Version from Tag for Build Arg
# Extract the clean tag name (e.g., 0.1.0) to pass as build arg
id: get_version_tag
run: |
# Get the tag name from the ref (e.g., refs/tags/0.1.0 -> 0.1.0)
GIT_TAG=${GITHUB_REF#refs/tags/}
# Remove 'v' prefix if present (adjust if your tags don't use 'v')
VERSION=${GIT_TAG#v}
echo "Using version for Docker build arg: $VERSION"
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
- name: Build and Push Docker Image to GHCR
uses: docker/build-push-action@v5
with:
context: .
push: true # Push the image to GHCR
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
PYTHON_VERSION=${{ matrix.python-version }}
VERSION=${{ steps.get_version_tag.outputs.VERSION }}
cache-from: type=gha,scope=deploy-${{ matrix.python-version }}
cache-to: type=gha,mode=max,scope=deploy-${{ matrix.python-version }}