Skip to content
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
70798c1
CNF: add base workflows
vvvieira Apr 3, 2025
a3028d6
CNF: use previous image
vvvieira Apr 3, 2025
7513fdd
CNF: added tar based image build
vvvieira Apr 3, 2025
f66bb33
CNF: pinned debian, changed pull request workflow
vvvieira Apr 3, 2025
9239269
CNF: fixed env var referencing
vvvieira Apr 3, 2025
dce269c
CNF: updated os for runners
vvvieira Apr 3, 2025
82ca4ba
CNF: update upload version
vvvieira Apr 3, 2025
1d63e6f
CNF: added dev multistage
vvvieira Apr 3, 2025
b3fe7b4
CNF: updated action versions
vvvieira Apr 3, 2025
3131f58
CNF: try new config
vvvieira Apr 4, 2025
c506e54
CNF: target dev stage
vvvieira Apr 4, 2025
1b5d16f
CNF: added coverage
vvvieira Apr 4, 2025
bd8352d
CNF: only include source files for coverage
vvvieira Apr 4, 2025
0b9b8bc
CNF: added source to the correct place
vvvieira Apr 4, 2025
cbd1229
CNF: add PR comment and update coverage report toml settings
vvvieira Apr 4, 2025
00b81ba
CNF: call with uv
vvvieira Apr 4, 2025
156c198
CNF: enable caching
vvvieira Apr 4, 2025
88ed897
CNF: optimize docker cache and remove uid change
vvvieira Apr 4, 2025
fd1ace3
CNF: removed upload to artifact storage
vvvieira Apr 4, 2025
b49a550
CNF: add sticky comment to avoid spam
vvvieira Apr 4, 2025
5c18b2a
CNF: add build check stage
vvvieira Apr 4, 2025
6376200
CNF: hi
vvvieira Apr 4, 2025
23292c2
Merge remote-tracking branch 'origin/main' into 2-publish-pypi-stage
vvvieira Apr 4, 2025
f65d3e8
CNF: try out 2 publishing stages
vvvieira Apr 4, 2025
22b8e8f
CNF: add publish to pypi automatically
vvvieira Apr 4, 2025
6b0b9dd
CNF: using existing pypa job for upload
vvvieira Apr 4, 2025
4f2b5f3
CNF: changed rules for test and main pypi
vvvieira Apr 4, 2025
771c021
Merge remote-tracking branch 'origin/main' into 2-publish-pypi-stage
vvvieira Apr 4, 2025
f333cfd
CNF: add verbose output
vvvieira Apr 4, 2025
fcc40e3
CNF: correct dev/main pypi push
vvvieira Apr 4, 2025
2db6585
CNF: always run the dev version
vvvieira Apr 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 113 additions & 30 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
name: CI - Run Unit Tests in Docker with Coverage
name: CI, Test, and Tag-Based Release with Dev TestPyPI

on:
push:
branches: [ main ]
branches:
- main # Trigger for pushes to main
tags:
- 'v*' # Trigger for pushes of tags like v1.0, v2.3.4

pull_request:
branches: [ main ]
branches: [ main ] # Trigger for PRs targeting main
types: [opened, synchronize, reopened]

jobs:
# --- Test Job (Remains the same) ---
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
Expand All @@ -21,22 +28,15 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile # Assuming Dockerfile is at the root
# Build the 'dev' target stage
file: ./Dockerfile
target: dev
# Tag the image locally so subsequent steps can use it
tags: my-test-image:latest
# IMPORTANT: Load the image into the local Docker daemon
load: true
# Enable layer caching using GitHub Actions cache
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Run tests with dFBA extra
run: |
# Runs coverage collection via 'uv run' using --with pytest-cov.
# Uses --parallel-mode for coverage data.
# Generates uniquely named JUnit report.
docker run --rm \
-v "$(pwd):/app" \
-w /app \
Expand All @@ -45,23 +45,15 @@ jobs:

- name: Run tests without dFBA extra
run: |
# Runs coverage collection via 'uv run' using --with pytest-cov.
# Uses --parallel-mode for coverage data.
# Generates uniquely named JUnit report.
docker run --rm \
-v "$(pwd):/app" \
-w /app \
my-test-image:latest \
uv run --with pytest --with pytest-cov coverage run --parallel-mode -m pytest ./tests/core --junitxml=test-report-core.xml

# --- The step below only runs if BOTH test steps above succeeded ---

- name: Combine and Report Coverage
if: success()
run: |
# Runs combine, report, and html generation in a single container
# Saves the console summary to /app/coverage_summary.txt within the container
# which maps to coverage_summary.txt on the runner host via the volume mount.
docker run --rm \
-v "$(pwd):/app" \
-w /app \
Expand All @@ -74,30 +66,121 @@ jobs:
echo "Generating HTML coverage report..." && \
uv run --with pytest --with pytest-cov coverage html -d htmlcov \
'
# Also echo the summary to the main job log for easy viewing there
echo "--- Coverage Summary ---"
cat coverage_summary.txt
echo "------------------------"

- name: Format Coverage Comment Body
# Prepare the content for the comment in a file
# Only run on successful PR builds
if: success() && github.event_name == 'pull_request'
run: |
echo '### :test_tube: Coverage Report' > coverage_comment.md
echo '' >> coverage_comment.md
echo '```text' >> coverage_comment.md
cat coverage_summary.txt >> coverage_comment.md
echo '' >> coverage_comment.md # Ensure newline before closing fence
echo '' >> coverage_comment.md
echo '```' >> coverage_comment.md
# Optional: Add a hidden HTML comment marker for extra safety/identification
# echo "<!-- coverage-report-marker -->" >> coverage_comment.md


- name: Post or Update Coverage Comment
# Use the sticky comment action
# Only run on successful PR builds
if: success() && github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@v2
with:
# Tell the action to read the comment body from the file we just created
path: coverage_comment.md

# --- Job: Publish DEV version to TestPyPI (Runs ONLY on tag pushes) ---
publish-testpypi:
name: Publish Dev Version to TestPyPI
needs: test
# Run ONLY when a tag is pushed, AFTER tests pass
if: success()
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/pypi
permissions:
id-token: write

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install build dependencies
run: python -m pip install build twine

# --- Add step to generate dev suffix ---
- name: Generate development version suffix
id: version_suffix
# Using timestamp for uniqueness on TestPyPI for potentially repeated tag tests
run: echo "suffix=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT

# --- Add step to update version ---
- name: Update version in pyproject.toml for TestPyPI
run: |
# Add .dev<timestamp> suffix to the version line
# This assumes version = "X.Y.Z" format in pyproject.toml
VERSION_SUFFIX="${{ steps.version_suffix.outputs.suffix }}"
# Use temp file for sed compatibility
sed -i.bak "s/^\(version\s*=\s*\"\)\([^\"]*\)\"/\1\2.dev${VERSION_SUFFIX}\"/" pyproject.toml
rm pyproject.toml.bak # Remove backup
echo "Updated pyproject.toml with dev version suffix for TestPyPI build:"
grep "^version" pyproject.toml

- name: Build package with dev version
run: |
echo "Building package for tag ${{ github.ref_name }} with dev suffix..."
python -m build

- name: Publish package distributions to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
# skip-existing: true # Recommended for dev builds

# --- Job: Publish CLEAN version to PyPI (Runs ONLY on tag pushes, after TestPyPI) ---
publish-pypi:
name: Publish Clean Version to PyPI
needs: publish-testpypi # Depends on the TestPyPI dev publish job
# Run ONLY when a tag is pushed, AFTER TestPyPI publish succeeds
if: success() && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/pypi
permissions:
id-token: write

steps:
# --- Checkout code AGAIN to get the original version ---
- name: Checkout ORIGINAL code for tag
uses: actions/checkout@v4
with:
# Make sure we're checking out the code corresponding to the tag
# This ensures we get the pyproject.toml WITHOUT the .dev suffix
ref: ${{ github.ref }}
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install build dependencies
run: python -m pip install build twine

- name: Build package with CLEAN version
run: |
echo "Building package for tag ${{ github.ref_name }} for PyPI release (using original version)..."
grep "^version" pyproject.toml
# Builds the package using the version defined in the tagged commit's source
# because we checked out the original code again.
python -m build

- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
# Defaults to PyPI, uses trusted publishing via OIDC
Loading