Skip to content

Bump codecov/codecov-action from 5 to 6 #138

Bump codecov/codecov-action from 5 to 6

Bump codecov/codecov-action from 5 to 6 #138

Workflow file for this run

name: CI
# NOTE: The lab validation job in this workflow is kept in sync with
# reusable-lab-validation.yml. Changes to lab validation logic should be
# applied to both files to maintain consistency.
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
workflow_call:
inputs:
batfish_ref:
description: "Git ref for Batfish version to test"
required: false
default: "master"
type: string
batfish_docker:
description: "Docker image for Batfish (e.g., batfish/batfish:2024.12.20.1234)"
required: false
type: string
pybatfish_ref:
description: "Git ref for Pybatfish version to test"
required: false
default: "master"
type: string
pybatfish_version:
description: "PyPI version for Pybatfish (e.g., 2025.7.7.2423)"
required: false
type: string
pybatfish_pypi_repo:
description: "PyPI repository (test or prod)"
required: false
default: "prod"
type: string
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python 3.10
uses: actions/setup-python@v6
with:
python-version: "3.10"
cache: "pip"
cache-dependency-path: ".pre-commit-config.yaml"
- name: Run pre-commit hooks
uses: pre-commit/action@v3.0.1
test:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v6
- name: Set up Python 3.10
uses: actions/setup-python@v6
with:
python-version: "3.10"
cache: "pip"
cache-dependency-path: "requirements*.txt"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
pip install -e .
- name: Run tests with coverage
run: |
pytest tests/ -v --tb=short --cov=lab_validation --cov-report=xml --cov-report=term-missing
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v6
with:
files: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
use_oidc: true
- name: Test package build
run: |
python -m build
pip install dist/*.whl
python -c "import lab_validation; print('Package imports successfully')"
# First job to discover available labs
discover-labs:
runs-on: ubuntu-latest
outputs:
labs: ${{ steps.discover.outputs.labs }}
steps:
- name: Checkout lab-validation
uses: actions/checkout@v6
- name: Discover available labs
id: discover
run: |
# Find all directories in snapshots/ and create JSON array
labs=$(ls -1 snapshots/ | jq -R -s -c 'split("\n")[:-1]')
echo "labs=$labs" >> $GITHUB_OUTPUT
echo "Discovered labs: $labs"
# Build Batfish JAR once and cache it (only if not using Docker)
build-batfish:
runs-on: ubuntu-latest
if: inputs.batfish_docker == ''
steps:
- name: Checkout Batfish
uses: actions/checkout@v6
with:
repository: batfish/batfish
path: batfish
ref: ${{ inputs.batfish_ref || 'master' }}
- name: Set up Java 17
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "17"
- name: Cache Bazel
uses: actions/cache@v5
with:
path: ~/.cache/bazel
key: ${{ runner.os }}-bazel-17-${{ hashFiles('batfish/.bazelversion', 'batfish/WORKSPACE', 'batfish/maven_install.json') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-bazel-17-${{ hashFiles('batfish/.bazelversion', 'batfish/WORKSPACE', 'batfish/maven_install.json') }}-
- name: Build Batfish JAR and questions
working-directory: batfish
run: |
bazel build //projects/allinone:allinone_main_deploy.jar
cp bazel-bin/projects/allinone/allinone_main_deploy.jar allinone.jar
# Create questions archive following pybatfish pattern
tar -czf questions.tgz questions/
- name: Upload Batfish artifacts
uses: actions/upload-artifact@v7
with:
name: batfish-artifacts
path: |
batfish/allinone.jar
batfish/questions.tgz
retention-days: 1
# Matrix job to run each lab in parallel
lab-integration-test:
runs-on: ubuntu-latest
timeout-minutes: 20
needs: [discover-labs, build-batfish]
if: always() # Run even if build-batfish was skipped (for Docker mode)
strategy:
matrix:
lab: ${{ fromJson(needs.discover-labs.outputs.labs) }}
fail-fast: false # Don't cancel other jobs if one fails
steps:
- name: Checkout lab-validation
uses: actions/checkout@v6
with:
path: lab-validation
- name: Set up Python 3.10
uses: actions/setup-python@v6
with:
python-version: "3.10"
cache: "pip"
cache-dependency-path: "requirements*.txt"
- name: Set up Java 17
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "17"
- name: Download Batfish artifacts
if: inputs.batfish_docker == ''
uses: actions/download-artifact@v8
with:
name: batfish-artifacts
path: .
- name: Install lab-validation dependencies
working-directory: lab-validation
run: |
python -m pip install --upgrade pip
# Install base dependencies from requirements.txt
pip install -r requirements.txt
# Install Pybatfish based on input parameters (may override version from requirements.txt)
if [ "${{ inputs.pybatfish_version }}" != "" ]; then
if [ "${{ inputs.pybatfish_pypi_repo }}" = "test" ]; then
# Retry installation from test.pypi.org to handle propagation delays
for attempt in 1 2 3 4 5; do
if pip install -i https://test.pypi.org/simple --extra-index-url https://pypi.org/simple pybatfish==${{ inputs.pybatfish_version }}; then
break
else
echo "Attempt $attempt failed, waiting 30 seconds before retry..."
if [ $attempt -lt 5 ]; then
sleep 30
else
echo "Failed to install pybatfish after 5 attempts"
exit 1
fi
fi
done
else
pip install pybatfish==${{ inputs.pybatfish_version }}
fi
else
# Default: install from git ref (override requirements.txt version)
PYBF_REF="${{ inputs.pybatfish_ref || 'master' }}"
pip install git+https://github.com/batfish/pybatfish.git@${PYBF_REF}
fi
pip install -r requirements-dev.txt
pip install -e .
- name: Start Batfish service (Docker)
if: inputs.batfish_docker != ''
run: |
# Start Batfish using Docker container
docker run -d --name batfish \
-p 9996:9996 \
${{ inputs.batfish_docker }}
# Wait for service to start
sleep 15
- name: Start Batfish service (JAR)
if: inputs.batfish_docker == ''
run: |
# Extract questions archive and start from JAR
tar -xzf questions.tgz
# Start Batfish using simple allinone mode (like pybatfish CI)
coordinator_args=(\
-templatedirs=questions \
-periodassignworkms=5 \
)
allinone_args=(\
-runclient=false \
-coordinatorargs="$(echo -n "${coordinator_args[@]}")" \
)
java -cp allinone.jar org.batfish.allinone.Main "${allinone_args[@]}" > batfish.log 2>&1 &
# Wait for service to start
sleep 10
- name: Run lab integration test - ${{ matrix.lab }}
working-directory: lab-validation
run: |
python -m pytest lab_tests/test_labs.py -v --tb=short --labname=${{ matrix.lab }}
- name: Show Batfish logs on failure
if: failure()
run: |
echo "=== Batfish logs ==="
if [ "${{ inputs.batfish_docker }}" != "" ]; then
# Save docker logs to batfish.log for consistency, then display
docker logs batfish > batfish.log 2>&1 || echo "No Docker container logs found"
tail -100 batfish.log || echo "No batfish log found"
else
tail -100 batfish.log || echo "No batfish log found"
fi
# Summary job for required status checks
all-labs-passed:
runs-on: ubuntu-latest
needs: [lab-integration-test]
if: always() # Run even if some lab tests failed
steps:
- name: Check all lab tests passed
run: |
if [ "${{ needs.lab-integration-test.result }}" != "success" ]; then
echo "❌ Some lab integration tests failed"
exit 1
else
echo "✅ All lab integration tests passed"
fi