Skip to content

Commit bdd4eb0

Browse files
author
bram
committed
Fixed
1 parent f5bdd96 commit bdd4eb0

File tree

1 file changed

+144
-115
lines changed

1 file changed

+144
-115
lines changed

.github/workflows/ci-cd.yml

Lines changed: 144 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
# .github/workflows/ci-cd.yml
2-
31
name: Python Package CI
42

53
on:
64
push:
75
branches:
86
- main
97
tags:
10-
# Trigger on any tag (matches 0.0.1 style)
118
- '*'
129
pull_request:
1310
branches:
1411
- main
1512
release:
16-
types: [published] # If you create releases via GitHub UI based on tags
13+
types: [published]
1714

1815
permissions:
19-
contents: read # Needed for checkout
20-
packages: write # Needed for GitHub Packages (Docker registry)
16+
contents: read
17+
packages: write
2118

2219
jobs:
2320
lint:
@@ -26,8 +23,7 @@ jobs:
2623
matrix:
2724
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
2825
steps:
29-
- name: Checkout
30-
uses: actions/checkout@v4
26+
- uses: actions/checkout@v4
3127
with:
3228
fetch-depth: 0 # Fetch all history for proper versioning
3329
fetch-tags: true # Explicitly fetch all tags
@@ -36,11 +32,10 @@ jobs:
3632
with:
3733
python-version: ${{ matrix.python-version }}
3834
cache: 'pip'
39-
- name: Install lint dependencies
35+
- name: Install dependencies
4036
run: |
4137
python -m pip install --upgrade pip
4238
pip install ruff flake8 pylint isort setuptools
43-
# Install runtime deps if linters need them (e.g., pylint requires imports)
4439
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
4540
- name: Analysing the code with pylint
4641
run: |
@@ -62,8 +57,7 @@ jobs:
6257
matrix:
6358
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
6459
steps:
65-
- name: Checkout
66-
uses: actions/checkout@v4
60+
- uses: actions/checkout@v4
6761
with:
6862
fetch-depth: 0 # Fetch all history for proper versioning
6963
fetch-tags: true # Explicitly fetch all tags
@@ -72,20 +66,17 @@ jobs:
7266
with:
7367
python-version: ${{ matrix.python-version }}
7468
cache: 'pip'
75-
- name: Install test dependencies
69+
- name: Install dependencies
7670
run: |
7771
python -m pip install --upgrade pip
78-
# Install runtime dependencies AND test dependencies (like pytest)
7972
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
8073
pip install pytest
81-
# Install the package itself in editable mode for testing
8274
pip install -e .
8375
- name: Run tests
8476
run: |
8577
python -m pytest
8678
8779
docker:
88-
# Builds Docker images for testing, does not push
8980
needs: test
9081
runs-on: ubuntu-latest
9182
strategy:
@@ -95,177 +86,215 @@ jobs:
9586
- name: Checkout
9687
uses: actions/checkout@v4
9788
with:
98-
fetch-depth: 0 # Needed for git describe
99-
fetch-tags: true
89+
fetch-depth: 0 # Fetch all history for proper versioning
90+
fetch-tags: true # Explicitly fetch all tags
10091

10192
- name: Set up Docker Buildx
10293
uses: docker/setup-buildx-action@v3
103-
104-
- name: Cache Docker layers for Test Build
94+
95+
- name: Cache Docker layers
10596
uses: actions/cache@v4
10697
with:
107-
path: /tmp/.buildx-cache-test # Separate cache path
108-
key: ${{ runner.os }}-buildx-test-${{ matrix.python-version }}-${{ github.sha }}
98+
path: /tmp/.buildx-cache
99+
key: ${{ runner.os }}-buildx-${{ github.sha }}
109100
restore-keys: |
110-
${{ runner.os }}-buildx-test-${{ matrix.python-version }}-
101+
${{ runner.os }}-buildx-
111102
112-
- name: Get Version for Docker Build Args (Handles 0.0.1 style tags)
103+
- name: Get Version for Docker Build
113104
id: get_version
114105
run: |
115-
# Ensure we have tags fetched completely
116-
git fetch --tags --force --prune --unshallow || echo "Fetching tags failed, proceeding..."
117-
# Use git describe. Outputs exact tag (0.0.1) or dev version (0.0.1-3-gddfce44)
118-
GIT_DESCRIBE=$(git describe --tags --always --dirty 2>/dev/null || echo "0.0.0")
119-
# No 'v' prefix removal needed if tags are like '0.0.1'
120-
VERSION=$GIT_DESCRIBE
121-
echo "Using version for Docker build arg: $VERSION"
106+
# Ensure we have tags
107+
git fetch --tags --force
108+
109+
# For tagged builds, use the exact tag without v prefix for PACKAGE_VERSION
110+
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
111+
TAG=${GITHUB_REF#refs/tags/}
112+
VERSION="${TAG#v}"
113+
echo "Using tag version: $VERSION"
114+
else
115+
# Use git version without v prefix
116+
VERSION=$(git describe --tags --always 2>/dev/null | sed 's/^v//' || echo "0.1.0")
117+
echo "Using git version: $VERSION"
118+
fi
119+
120+
# Output for GitHub Actions
122121
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
123122
124123
- name: Build Docker Image - Python ${{ matrix.python-version }}
125124
uses: docker/build-push-action@v5
126125
with:
127126
context: .
128-
load: true # Load image for local testing steps below
129-
# Use a distinct tag for the test build image
130-
tags: gpt-po-translator:py${{ matrix.python-version }}-test
127+
load: true
128+
tags: gpt-po-translator:py${{ matrix.python-version }}
131129
build-args: |
132130
PYTHON_VERSION=${{ matrix.python-version }}
133131
VERSION=${{ steps.get_version.outputs.VERSION }}
134-
# Use distinct cache scope for test build
135-
cache-from: type=gha,scope=test-${{ matrix.python-version }}
136-
cache-to: type=gha,mode=max,scope=test-${{ matrix.python-version }}
132+
cache-from: type=gha
133+
cache-to: type=gha,mode=max
137134

138135
- name: Test Docker Image - Help Text
139136
run: |
140-
# Use the -test tag for running tests
141-
docker run gpt-po-translator:py${{ matrix.python-version }}-test --version
142-
docker run gpt-po-translator:py${{ matrix.python-version }}-test --help
137+
# Run Docker image to verify it works
138+
docker run gpt-po-translator:py${{ matrix.python-version }} --version
139+
140+
# Check help output (should exit with 0)
141+
docker run gpt-po-translator:py${{ matrix.python-version }} --help
142+
143143
echo "✅ Basic Docker image tests passed for Python ${{ matrix.python-version }}"
144144
145145
- name: Test Docker Image - CLI Options
146146
run: |
147-
# Use the -test tag
148-
docker run gpt-po-translator:py${{ matrix.python-version }}-test --provider openai --help
149-
docker run gpt-po-translator:py${{ matrix.python-version }}-test --provider anthropic --help
147+
# Test with --help flag for different providers (doesn't require API key)
148+
docker run gpt-po-translator:py${{ matrix.python-version }} --provider openai --help
149+
docker run gpt-po-translator:py${{ matrix.python-version }} --provider anthropic --help
150+
150151
echo "✅ CLI option test passed for Python ${{ matrix.python-version }}"
151-
152+
152153
- name: Test Docker Image with Sample PO file
153154
run: |
154-
# Create test directory and dummy PO file
155+
# Create test directory with sample PO file
155156
mkdir -p test-po-files
156-
echo 'msgid "Hello"\nmsgstr ""' > test-po-files/test-sample.po
157-
# cp .github/workflows/test-sample.po test-po-files/ # Or use your existing file
158-
159-
# Use the -test tag
157+
cp .github/workflows/test-sample.po test-po-files/
158+
159+
# Check if the tool can access the mounted files (without API operations)
160+
# Just verify help works with the folder mounted
160161
docker run \
161162
-v $(pwd)/test-po-files:/test \
162-
gpt-po-translator:py${{ matrix.python-version }}-test \
163+
gpt-po-translator:py${{ matrix.python-version }} \
163164
--folder /test --help
165+
164166
echo "✅ Docker volume mount test passed for Python ${{ matrix.python-version }}"
165167
166-
167168
deploy:
168-
needs: [test, docker] # Depends on successful tests and docker test-builds
169+
needs: [test, docker]
169170
runs-on: ubuntu-latest
170-
# Trigger deployment only on tag pushes (any tag format)
171171
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
172-
# environment: release # Uncomment if using GitHub environments for secrets/protection
173-
174-
permissions:
175-
contents: read # Needed for checkout
176-
packages: write # Needed for GitHub Packages (Docker registry)
177-
172+
environment: release
178173
strategy:
179174
matrix:
180175
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
181-
# Flag to indicate the primary version for single-run steps like PyPI deploy
182-
is_primary_py: [ ${{ matrix.python-version == '3.11' }} ] # Choose your primary Python version
183-
184176
steps:
185-
- name: Checkout
186-
uses: actions/checkout@v4
177+
- uses: actions/checkout@v4
187178
with:
188-
fetch-depth: 0 # Crucial for setuptools_scm
189-
fetch-tags: true
190-
191-
# === PyPI Deployment (runs only once for the primary Python version) ===
192-
- name: Set up Python for PyPI deploy
193-
if: matrix.is_primary_py
179+
fetch-depth: 0 # Fetch all history for proper versioning
180+
fetch-tags: true # Explicitly fetch all tags
181+
182+
# PyPI deployment (only for Python 3.x representative)
183+
- name: Set up Python
184+
if: matrix.python-version == '3.11'
194185
uses: actions/setup-python@v5
195186
with:
196-
python-version: ${{ matrix.python-version }} # Use the designated primary version
197-
198-
- name: Install build tool for PyPI
199-
if: matrix.is_primary_py
200-
run: python -m pip install --upgrade pip build
201-
202-
- name: Build PyPI package
203-
if: matrix.is_primary_py
204-
run: python -m build
205-
# setuptools_scm automatically determines version from git tag
206-
207-
- name: Publish package to PyPI
208-
if: matrix.is_primary_py
209-
uses: pypa/gh-action-pypi-publish@release/v1
187+
python-version: '3.x'
188+
189+
- name: Set Package Version for PyPI
190+
if: matrix.python-version == '3.11'
191+
run: |
192+
# Get tag name without 'refs/tags/' prefix
193+
TAG=${GITHUB_REF#refs/tags/}
194+
# Remove 'v' prefix if present
195+
VERSION="${TAG#v}"
196+
# Set as environment variable
197+
echo "PACKAGE_VERSION=$VERSION" >> $GITHUB_ENV
198+
echo "Using version $VERSION for PyPI package"
199+
200+
- name: Install dependencies
201+
if: matrix.python-version == '3.11'
202+
run: |
203+
python -m pip install --upgrade pip
204+
pip install -r requirements.txt
205+
pip install build
206+
207+
- name: Build package
208+
if: matrix.python-version == '3.11'
209+
run: |
210+
# Remove old build artifacts if any exist
211+
rm -rf dist build *.egg-info
212+
213+
# Explicitly set the version for the build tool
214+
if [ -n "$PACKAGE_VERSION" ]; then
215+
echo "Building package with version: $PACKAGE_VERSION"
216+
else
217+
echo "WARNING: PACKAGE_VERSION not set! Using git-based version."
218+
fi
219+
220+
# Build wheel and sdist with isolated environment
221+
python -m build
222+
223+
# Verify the wheel metadata
224+
pip install twine
225+
twine check dist/*
226+
227+
- name: Publish package
228+
if: matrix.python-version == '3.11'
229+
uses: pypa/[email protected]
210230
with:
211231
user: __token__
212-
password: ${{ secrets.PYPI_API_TOKEN }} # Ensure this secret is set in repo settings
213-
214-
# === Docker Deployment (runs for each Python version in the matrix) ===
232+
password: ${{ secrets.PYPI_API_TOKEN }}
233+
234+
# Docker deployment for all Python versions
215235
- name: Set up Docker Buildx
216236
uses: docker/setup-buildx-action@v3
217-
218-
- name: Cache Docker layers for Deploy
237+
238+
- name: Cache Docker layers
219239
uses: actions/cache@v4
220240
with:
221-
path: /tmp/.buildx-cache-deploy # Use separate cache path for deploy
222-
key: ${{ runner.os }}-deploy-buildx-${{ matrix.python-version }}-${{ github.ref }} # Use git ref for tag builds
241+
path: /tmp/.buildx-cache
242+
key: ${{ runner.os }}-buildx-${{ github.sha }}
223243
restore-keys: |
224-
${{ runner.os }}-deploy-buildx-${{ matrix.python-version }}-
225-
244+
${{ runner.os }}-buildx-
245+
226246
- name: Login to GitHub Container Registry
227247
uses: docker/login-action@v3
228248
with:
229249
registry: ghcr.io
230250
username: ${{ github.actor }}
231-
password: ${{ secrets.GITHUB_TOKEN }} # Built-in token
251+
password: ${{ secrets.GITHUB_TOKEN }}
232252

233-
- name: Extract metadata (tags, labels) for Docker (Handles 0.0.1 style tags)
253+
- name: Extract metadata for Docker
234254
id: meta
235255
uses: docker/metadata-action@v5
236256
with:
237-
images: ghcr.io/${{ github.repository }} # Correct variable for owner/repo
238-
# Generate tags based on the Git tag (e.g., 0.0.1 from refs/tags/0.0.1)
257+
images: |
258+
ghcr.io/${{ github.repository }}
239259
tags: |
260+
type=ref,event=branch,suffix=-py${{ matrix.python-version }}
240261
type=semver,pattern={{version}}-py${{ matrix.python-version }}
241262
type=semver,pattern={{major}}.{{minor}}-py${{ matrix.python-version }}
242263
type=semver,pattern={{major}}-py${{ matrix.python-version }}
243-
type=raw,value=latest-py${{ matrix.python-version }}
244-
type=raw,value=latest,enable=${{ matrix.is_primary_py }}
245-
# Also tag with the exact version number (e.g., 0.0.1-py3.11)
246-
type=match,pattern=(\d+\.\d+\.\d+.*),group=1,suffix=-py${{ matrix.python-version }}
264+
type=sha,format=short,suffix=-py${{ matrix.python-version }}
265+
flavor: |
266+
latest=${{ matrix.python-version == '3.11' }}
247267
248-
- name: Get Version for Docker Build Args (Handles 0.0.1 style tags)
249-
id: get_version_docker # Use different id from test job step
268+
- name: Get Version for Docker Build
269+
id: get_version
250270
run: |
251-
git fetch --tags --force --prune --unshallow || echo "Fetching tags failed, proceeding..."
252-
# Use git describe. Outputs exact tag (0.0.1) or dev version (0.0.1-3-gddfce44)
253-
GIT_DESCRIBE=$(git describe --tags --always --dirty 2>/dev/null || echo "0.0.0")
254-
# No 'v' prefix removal needed if tags are like '0.0.1'
255-
VERSION=$GIT_DESCRIBE
256-
echo "Using version for Docker build arg: $VERSION"
271+
# Ensure we have tags
272+
git fetch --tags --force
273+
274+
# For tagged builds, use the exact tag
275+
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
276+
TAG=${GITHUB_REF#refs/tags/}
277+
# Remove v prefix if present for Docker build arg
278+
VERSION="${TAG#v}"
279+
echo "Using tag version: $VERSION"
280+
else
281+
# Use git version without v prefix
282+
VERSION=$(git describe --tags --always 2>/dev/null | sed 's/^v//' || echo "0.1.0")
283+
echo "Using git version: $VERSION"
284+
fi
285+
286+
# Output for GitHub Actions
257287
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
258-
288+
259289
- name: Build and Push Docker Image
260290
uses: docker/build-push-action@v5
261291
with:
262292
context: .
263-
push: true # Push the image to GHCR
293+
push: true
264294
tags: ${{ steps.meta.outputs.tags }}
265295
labels: ${{ steps.meta.outputs.labels }}
266296
build-args: |
267297
PYTHON_VERSION=${{ matrix.python-version }}
268-
VERSION=${{ steps.get_version_docker.outputs.VERSION }} # Use correct step id
269-
# The comment that likely caused the error was here - now removed
270-
cache-from: type=gha,scope=deploy-${{ matrix.python-version }}
271-
cache-to: type=gha,mode=max,scope=deploy-${{ matrix.python-version }}
298+
VERSION=${{ steps.get_version.outputs.VERSION }}
299+
cache-from: type=gha
300+
cache-to: type=gha,mode=max

0 commit comments

Comments
 (0)