Skip to content

feature(example-app): set c2pie version for example app in .env file #186

feature(example-app): set c2pie version for example app in .env file

feature(example-app): set c2pie version for example app in .env file #186

Workflow file for this run

name: Linting and Testing
on:
push:
branches:
- '**'
paths-ignore:
- '**.md'
- 'docs/**'
tags-ignore:
- v**
workflow_call:
permissions:
contents: read
packages: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
ruff:
name: Linting and Formatting
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 'latest'
virtualenvs-create: true
virtualenvs-in-project: true
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-ruff-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --only dev
- name: Ruff version
run: poetry run ruff --version
- name: Check formatting
run: poetry run ruff format --check .
- name: Lint (GitHub Annotations)
run: poetry run ruff check --output-format=github .
run-unit-tests:
name: Run unit tests using matrix
needs: ruff
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
defaults:
run:
shell: bash
runs-on: ${{ matrix.os }}
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 'latest'
virtualenvs-create: true
virtualenvs-in-project: true
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-tests-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
run: poetry install --no-interaction
- name: Run unit tests with coverage
run: |
poetry run pytest \
--cov=c2pie \
-m "not e2e" \
--maxfail=1 \
-v
- name: Upload coverage artifact
if: (matrix.python-version == '3.12') && (matrix.os == 'ubuntu-latest')
uses: actions/upload-artifact@v4
with:
include-hidden-files: true
name: coverage-unit
path: .coverage
run-e2e-tests:
name: Run e2e tests
needs: ruff
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
defaults:
run:
shell: bash
runs-on: ${{ matrix.os }}
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 'latest'
virtualenvs-create: true
virtualenvs-in-project: true
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-tests-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
run: poetry install --no-interaction
- name: Install Rust toolchain and c2patool
uses: baptiste0928/cargo-install@v3
with:
crate: c2patool
- name: Verify if c2patool is installed
run: |
c2patool -V
- name: Run e2e tests with coverage
run: |
poetry run pytest tests/c2pa/e2e_test.py \
--cov=c2pie \
-v
env:
C2PIE_KEY_FILEPATH: ${{ vars.C2PIE_KEY_FILEPATH }}
C2PIE_CERT_FILEPATH: ${{ vars.C2PIE_CERT_FILEPATH }}
- name: Upload coverage artifact
if: (matrix.python-version == '3.12') && (matrix.os == 'ubuntu-latest')
uses: actions/upload-artifact@v4
with:
include-hidden-files: true
name: coverage-e2e
path: .coverage
combine-coverage:
name: Combine and upload coverage
needs: [run-unit-tests, run-e2e-tests]
if: always()
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install coverage
run: python -m pip install coverage[toml]
- name: Download unit coverage
uses: actions/download-artifact@v5
with:
name: coverage-unit
path: coverage-unit
continue-on-error: true
- name: Download e2e coverage
uses: actions/download-artifact@v5
with:
name: coverage-e2e
path: coverage-e2e
continue-on-error: true
- name: Check if artifacts exist
id: check
run: |
if [ -f ./coverage-e2e/.coverage ] && [ -f ./coverage-unit/.coverage ]; then
echo "ready=true" >> $GITHUB_OUTPUT
else
echo "ready=false" >> $GITHUB_OUTPUT
fi
- name: Fail if coverage missing
if: steps.check.outputs.ready != 'true'
run: |
echo "Coverage artifacts not found — skipping coverage report"
exit 1
- name: Combine coverage reports
run: |
coverage combine ./coverage-e2e/.coverage ./coverage-unit/.coverage
coverage xml -o coverage-combined.xml
coverage report --format=markdown >> $GITHUB_STEP_SUMMARY
coverage json -o coverage-combined.json
- name: Upload combined coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-combined
path: coverage-combined.json
update-coverage:
name: Update Coverage
runs-on: ubuntu-latest
needs: [combine-coverage]
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Download jq
run: |
sudo apt install jq
- name: Download combined coverage
uses: actions/download-artifact@v5
with:
name: coverage-combined
path: coverage-combined
# Find existing score and color by line matching in README and get calculated coverage from json file
- name: Find existing and calculated test coverage scores and existing color
run: |
echo "EXISTING_COVERAGE=$(grep -oP '(?<=coverage-)\d+' README.md | head -n1)" >> "$GITHUB_ENV"
echo "EXISTING_BADGE_COLOR=$(grep -oP '(?<=%25-)[^?]+' README.md | head -n1)" >> "$GITHUB_ENV"
echo "CALCULATED_COVERAGE=$(jq -r .totals.percent_covered_display coverage-combined/coverage-combined.json)" >> "$GITHUB_ENV"
- name: Check found coverage scores and color
run: |
echo $EXISTING_COVERAGE
echo $CALCULATED_COVERAGE
echo $EXISTING_BADGE_COLOR
# 0-60: red; 60-70: orange; 70-80: yellow; 80-90: yellowish green; 90-100: green
# set new color and then add its variable to workflow's environment
- name: Define new badge color
if: ${{ env.EXISTING_COVERAGE != env.CALCULATED_COVERAGE }}
run: |
python3 - <<'PY'
import os
new_coverage = int(os.getenv("CALCULATED_COVERAGE"))
if new_coverage < 60:
new_badge_color = "crimson"
elif 60 <= new_coverage < 70:
new_badge_color = "orange"
elif 70 <= new_coverage < 80:
new_badge_color = "yellow"
elif 80 <= new_coverage < 90:
new_badge_color = "olivedrab"
elif new_coverage >= 90:
new_badge_color = "forestgreen"
env_file = os.getenv('GITHUB_ENV')
with open(env_file, "a") as f:
f.write(f"NEW_BADGE_COLOR={new_badge_color}")
PY
# Find existing badge url in README assuming that it looks like we expect (must be perfect match)
# Replace it with calculated url, where score and color are new
- name: Replace badge URL in README
if: ${{ env.EXISTING_COVERAGE != env.CALCULATED_COVERAGE }}
run: |
export EXISTING_COVERAGE_BADGE_URL="https://img.shields.io/badge/coverage-$EXISTING_COVERAGE%25-$EXISTING_BADGE_COLOR?logo=codecov&logoColor=ff9d1c"
export CALCULATED_COVERAGE_BADGE_URL="https://img.shields.io/badge/coverage-$CALCULATED_COVERAGE%25-$NEW_BADGE_COLOR?logo=codecov&logoColor=ff9d1c"
echo $EXISTING_COVERAGE_BADGE_URL
echo $CALCULATED_COVERAGE_BADGE_URL
python3 - <<'PY'
import io, sys, os
old_badge_url = os.getenv("EXISTING_COVERAGE_BADGE_URL")
new_badge_url = os.getenv("CALCULATED_COVERAGE_BADGE_URL")
path = "README.md"
if not old_badge_url or not new_badge_url:
sys.exit("Either existing or calculated badge URL doesn't exist")
with io.open(path, "r", encoding="utf-8") as f:
content = f.read()
if old_badge_url in content:
content = content.replace(old_badge_url, new_badge_url)
with io.open(path, "w", encoding="utf-8") as f:
f.write(content)
print("Replaced coverage badge URL in README.md")
else:
print("Old URL not found in README.md, no replacement made")
PY
- name: Commit README changes
if: ${{ env.EXISTING_COVERAGE != env.CALCULATED_COVERAGE }}
run: |
git config --global user.name github-actions[bot]
git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
git add README.md
git commit -m "docs(readme): bring test coverage score up to date"
git push origin ${{ github.ref }}