Skip to content

[WIP] replace new compiler driver by calling compiler-cli using subprocess #10142

[WIP] replace new compiler driver by calling compiler-cli using subprocess

[WIP] replace new compiler driver by calling compiler-cli using subprocess #10142

name: Check Catalyst Build
on:
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review
push:
branches: [ main ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
determine_runner:
if: github.event.pull_request.draft == false
name: Determine runner type to use
uses: ./.github/workflows/determine-workflow-runner.yml
with:
default_runner: ubuntu-22.04
constants:
name: "Set build matrix"
uses: ./.github/workflows/constants.yaml
needs: [determine_runner]
with:
multiple_compilers: ${{ github.trigger == 'push' && github.ref_name == 'main' }}
runs_on: ${{ needs.determine_runner.outputs.runner_group }}
runtime:
name: Catalyst-Runtime Build
needs: [constants, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
strategy:
matrix:
compiler: ${{ fromJson(needs.constants.outputs.compilers) }}
steps:
- name: Checkout Catalyst repo
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y -q install ninja-build make cmake clang libomp-dev
- name: Build Catalyst-Runtime
run: |
COMPILER_LAUNCHER="" \
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
RT_BUILD_DIR="$(pwd)/runtime-build" \
ENABLE_ASAN=OFF \
make runtime
COMPILER_LAUNCHER="" \
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
RT_BUILD_DIR="$(pwd)/runtime-build" \
OQC_BUILD_DIR="$(pwd)/oqc-build" \
make oqc
- name: Upload Catalyst-Runtime Artifact
uses: actions/upload-artifact@v4
with:
name: runtime-build-${{ matrix.compiler }}
path: |
runtime-build/lib/*.so
runtime-build/lib/backend/*.toml
retention-days: 1
- name: Upload OQC-Runtime Artifact
uses: actions/upload-artifact@v4
with:
name: oqc-build-${{ matrix.compiler }}
path: |
oqc-build/*.so
oqc-build/*.toml
retention-days: 1
llvm:
name: LLVM Build
needs: [constants, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
strategy:
matrix:
compiler: ${{ fromJson(needs.constants.outputs.compilers) }}
steps:
- name: Checkout Catalyst repo
uses: actions/checkout@v4
# Both the LLVM source and build folder are required for further dialect builds.
# Caching is significantly faster than git cloning since LLVM is such a large repository.
- name: Cache LLVM Source
id: cache-llvm-source
uses: actions/cache@v4
with:
path: mlir/llvm-project
key: llvm-${{ needs.constants.outputs.llvm_version }}-default-source
enableCrossOsArchive: true
- name: Clone LLVM Submodule
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: llvm/llvm-project
ref: ${{ needs.constants.outputs.llvm_version }}
path: mlir/llvm-project
- name: Cache LLVM Build
id: cache-llvm-build
uses: actions/cache@v4
with:
path: llvm-build
key: ${{ runner.os }}-llvm-${{ needs.constants.outputs.llvm_version }}-default-build-${{ matrix.compiler }}
- name: Install Deps
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
run: |
sudo apt-get update
sudo apt-get install -y python3 python3-pip cmake ninja-build clang lld
python3 --version | grep ${{ needs.constants.outputs.primary_python_version }}
python3 -m pip install numpy pybind11
- name: Build LLVM
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
# Note: Disable instrumentation for the mlir runtime support library,
# as user programs aren't instrumented.
run: |
# echo 'target_compile_options(mlir_c_runner_utils PRIVATE "-fno-sanitize=all")' \
# >> mlir/llvm-project/mlir/lib/ExecutionEngine/CMakeLists.txt
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
LLVM_BUILD_DIR="$(pwd)/llvm-build" \
COMPILER_LAUNCHER="" \
make llvm
mhlo:
name: MHLO Dialect Build
needs: [constants, llvm, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
strategy:
matrix:
compiler: ${{ fromJson(needs.constants.outputs.compilers) }}
steps:
- name: Checkout Catalyst repo
uses: actions/checkout@v4
- name: Cache MHLO Source
id: cache-mhlo-source
uses: actions/cache@v4
with:
path: mlir/mlir-hlo
key: mhlo-${{ needs.constants.outputs.mhlo_version }}-default-source
enableCrossOsArchive: true
- name: Clone MHLO Submodule
if: steps.cache-mhlo-source.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: tensorflow/mlir-hlo
ref: ${{ needs.constants.outputs.mhlo_version }}
path: mlir/mlir-hlo
- name: Cache MHLO Build
id: cache-mhlo
uses: actions/cache@v4
with:
path: mhlo-build
key: ${{ runner.os }}-mhlo-${{ needs.constants.outputs.mhlo_version }}-default-build-${{ matrix.compiler }}
- name: Get Cached LLVM Source
id: cache-llvm-source
if: steps.cache-mhlo.outputs.cache-hit != 'true'
uses: actions/cache@v4
with:
path: mlir/llvm-project
key: llvm-${{ needs.constants.outputs.llvm_version }}-default-source
enableCrossOsArchive: true
fail-on-cache-miss: true
- name: Get Cached LLVM Build
id: cache-llvm-build
if: steps.cache-mhlo.outputs.cache-hit != 'true'
uses: actions/cache@v4
with:
path: llvm-build
key: ${{ runner.os }}-llvm-${{ needs.constants.outputs.llvm_version }}-default-build-${{ matrix.compiler }}
fail-on-cache-miss: true
- name: Install Deps
if: steps.cache-mhlo.outputs.cache-hit != 'true'
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build clang lld
- name: Build MHLO Dialect
if: steps.cache-mhlo.outputs.cache-hit != 'true'
run: |
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
LLVM_BUILD_DIR="$(pwd)/llvm-build" \
MHLO_BUILD_DIR="$(pwd)/mhlo-build" \
COMPILER_LAUNCHER="" \
make mhlo
enzyme:
name: Enzyme Build
needs: [constants, llvm, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
strategy:
matrix:
compiler: ${{ fromJson(needs.constants.outputs.compilers) }}
steps:
- name: Checkout Catalyst repo
uses: actions/checkout@v4
- name: Cache Enzyme Source
id: cache-enzyme-source
uses: actions/cache@v4
with:
path: mlir/Enzyme
key: enzyme-${{ needs.constants.outputs.enzyme_version }}-default-source
enableCrossOsArchive: true
- name: Clone Enzyme Submodule
if: steps.cache-enzyme-build.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: EnzymeAD/Enzyme
ref: ${{ needs.constants.outputs.enzyme_version }}
path: mlir/Enzyme
- name: Cache Enzyme Build
id: cache-enzyme-build
uses: actions/cache@v4
with:
path: enzyme-build
key: ${{ runner.os }}-enzyme-${{ needs.constants.outputs.llvm_version }}-${{ needs.constants.outputs.enzyme_version }}-default-build-${{ matrix.compiler }}
- name: Get Cached LLVM Source
id: cache-llvm-source
if: steps.cache-enzyme-build.outputs.cache-hit != 'true'
uses: actions/cache@v4
with:
path: mlir/llvm-project
key: llvm-${{ needs.constants.outputs.llvm_version }}-default-source
enableCrossOsArchive: true
fail-on-cache-miss: true
- name: Get Cached LLVM Build
id: cache-llvm-build
if: steps.cache-enzyme-build.outputs.cache-hit != 'true'
uses: actions/cache@v4
with:
path: llvm-build
key: ${{ runner.os }}-llvm-${{ needs.constants.outputs.llvm_version }}-default-build-${{ matrix.compiler }}
fail-on-cache-miss: true
- name: Install Deps
if: steps.cache-enzyme-build.outputs.cache-hit != 'true'
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build clang lld
- name: Build Enzyme
if: steps.cache-enzyme-build.outputs.cache-hit != 'true'
run: |
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
LLVM_BUILD_DIR="$(pwd)/llvm-build" \
ENZYME_BUILD_DIR="$(pwd)/enzyme-build" \
COMPILER_LAUNCHER="" \
make enzyme
quantum:
name: Quantum Dialects Build
needs: [constants, llvm, mhlo, enzyme, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
strategy:
matrix:
compiler: ${{ fromJson(needs.constants.outputs.compilers) }}
steps:
- name: Checkout Catalyst repo
uses: actions/checkout@v4
- name: Install Deps
run: |
sudo apt-get update
sudo apt-get install -y python3 python3-pip cmake ninja-build ccache clang lld
python3 --version | grep ${{ needs.constants.outputs.primary_python_version }}
python3 -m pip install numpy pybind11
- name: Get Cached LLVM Source
id: cache-llvm-source
uses: actions/cache/restore@v4
with:
path: mlir/llvm-project
key: llvm-${{ needs.constants.outputs.llvm_version }}-default-source
enableCrossOsArchive: true
fail-on-cache-miss: true
- name: Get Cached LLVM Build
id: cache-llvm-build
uses: actions/cache/restore@v4
with:
path: llvm-build
key: ${{ runner.os }}-llvm-${{ needs.constants.outputs.llvm_version }}-default-build-${{ matrix.compiler }}
fail-on-cache-miss: true
- name: Get Cached MHLO Source
id: cache-mhlo-source
uses: actions/cache/restore@v4
with:
path: mlir/mlir-hlo
key: mhlo-${{ needs.constants.outputs.mhlo_version }}-default-source
enableCrossOsArchive: true
fail-on-cache-miss: true
- name: Get Cached MHLO Build
id: cache-mhlo
uses: actions/cache/restore@v4
with:
path: mhlo-build
key: ${{ runner.os }}-mhlo-${{ needs.constants.outputs.mhlo_version }}-default-build-${{ matrix.compiler }}
fail-on-cache-miss: true
- name: Get Cached Enzyme Source
id: cache-enzyme-source
uses: actions/cache/restore@v4
with:
path: mlir/Enzyme
key: enzyme-${{ needs.constants.outputs.enzyme_version }}-default-source
enableCrossOsArchive: true
fail-on-cache-miss: true
- name: Get Cached Enzyme Build
id: cache-enzyme-build
uses: actions/cache/restore@v4
with:
path: enzyme-build
key: ${{ runner.os }}-enzyme-${{ needs.constants.outputs.llvm_version }}-${{ needs.constants.outputs.enzyme_version }}-default-build-${{ matrix.compiler }}
fail-on-cache-miss: true
- name: Restore CCache on feature branches
id: restore-ccache
if: ${{ github.ref != 'refs/heads/main' }}
uses: actions/cache/restore@v4
with:
path: .ccache
key: ${{ runner.os }}-ccache-${{ github.run_id }}
restore-keys: ${{ runner.os }}-ccache-
- name: Build MLIR Dialects
run: |
CCACHE_DIR="$(pwd)/.ccache" \
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
LLVM_BUILD_DIR="$(pwd)/llvm-build" \
MHLO_BUILD_DIR="$(pwd)/mhlo-build" \
ENZYME_BUILD_DIR="$(pwd)/enzyme-build" \
DIALECTS_BUILD_DIR="$(pwd)/quantum-build" \
make dialects
- name: Upload Quantum Build Artifact
uses: actions/upload-artifact@v4
with:
name: quantum-build-${{ matrix.compiler }}
path: |
quantum-build/bin
quantum-build/python_packages/*
retention-days: 1
- name: Cache CCache on main branch
id: save-ccache
if: ${{ github.ref == 'refs/heads/main' }}
uses: actions/cache/save@v4
with:
path: .ccache
key: ${{ runner.os }}-ccache-${{ github.run_id }}
frontend-tests:
name: Frontend Tests
needs: [constants, llvm, runtime, quantum, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
strategy:
matrix:
compiler: ${{ fromJson(needs.constants.outputs.compilers) }}
steps:
- name: Checkout Catalyst repo
uses: actions/checkout@v4
- name: Install Deps
run: |
sudo apt-get update
sudo apt-get install -y python3 python3-pip libomp-dev libasan6 make
python3 --version | grep ${{ needs.constants.outputs.primary_python_version }}
python3 -m pip install -r requirements.txt
# cuda-quantum is added manually here.
# It can't be in requirements.txt as that will break
# macOS requirements.txt
python3 -m pip install cuda-quantum==0.6.0
python3 -m pip install oqc-qcaas-client
make frontend
- name: Get Cached LLVM Build
id: cache-llvm-build
uses: actions/cache@v4
with:
path: llvm-build
key: ${{ runner.os }}-llvm-${{ needs.constants.outputs.llvm_version }}-default-build-${{ matrix.compiler }}
fail-on-cache-miss: true
- name: Download Quantum Build Artifact
uses: actions/download-artifact@v4
with:
name: quantum-build-${{ matrix.compiler }}
path: quantum-build
- name: Download Catalyst-Runtime Artifact
uses: actions/download-artifact@v4
with:
name: runtime-build-${{ matrix.compiler }}
path: runtime-build/lib
- name: Add Frontend Dependencies to PATH
run: |
echo "$(pwd)/llvm-build/bin" >> $GITHUB_PATH
echo "PYTHONPATH=$PYTHONPATH:$(pwd)/quantum-build/python_packages/quantum" >> $GITHUB_ENV
echo "RUNTIME_LIB_DIR=$(pwd)/runtime-build/lib" >> $GITHUB_ENV
echo "MLIR_LIB_DIR=$(pwd)/llvm-build/lib" >> $GITHUB_ENV
- name: Run Python Lit Tests
run: |
llvm-lit -sv frontend/test/lit -j$(nproc)
- name: Run Python Pytest Tests
run: |
COVERAGE_REPORT="xml:coverage.xml -p no:warnings" \
make coverage-frontend
mv coverage.xml coverage-${{ github.job }}.xml
- name: Upload to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
- name: Check Catalyst Demos
run: | # Do not run demos in parallel, seems to cause package issues with numpy.
MDD_BENCHMARK_PRECISION=1 \
python3 -m pytest demos --nbmake
frontend-tests-lightning-kokkos:
name: Frontend Tests (backend="lightning.kokkos")
needs: [constants, llvm, runtime, quantum, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
strategy:
matrix:
compiler: ${{ fromJson(needs.constants.outputs.compilers) }}
steps:
- name: Checkout Catalyst repo
uses: actions/checkout@v4
- name: Install lightning.kokkos used in Python tests
run: |
pip install PennyLane-Lightning-Kokkos==0.39.0 --extra-index-url https://test.pypi.org/simple
- name: Install Deps
run: |
sudo apt-get update
sudo apt-get install -y python3 python3-pip libomp-dev libasan6 make
python3 --version | grep ${{ needs.constants.outputs.primary_python_version }}
python3 -m pip install -r requirements.txt
make frontend
- name: Get Cached LLVM Build
id: cache-llvm-build
uses: actions/cache@v4
with:
path: llvm-build
key: ${{ runner.os }}-llvm-${{ needs.constants.outputs.llvm_version }}-default-build-${{ matrix.compiler }}
fail-on-cache-miss: true
- name: Download Quantum Build Artifact
uses: actions/download-artifact@v4
with:
name: quantum-build-${{ matrix.compiler }}
path: quantum-build
- name: Download Catalyst-Runtime Artifact
uses: actions/download-artifact@v4
with:
name: runtime-build-${{ matrix.compiler }}
path: runtime-build/lib
- name: Add Frontend Dependencies to PATH
run: |
echo "PYTHONPATH=$PYTHONPATH:$(pwd)/quantum-build/python_packages/quantum" >> $GITHUB_ENV
echo "RUNTIME_LIB_DIR=$(pwd)/runtime-build/lib" >> $GITHUB_ENV
echo "MLIR_LIB_DIR=$(pwd)/llvm-build/lib" >> $GITHUB_ENV
- name: Run Python Pytest Tests (backend=lightning.kokkos)
run: |
make pytest TEST_BACKEND="lightning.kokkos"
frontend-tests-openqasm-device:
name: Frontend Tests (backend="openqasm3")
needs: [constants, llvm, runtime, quantum, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
strategy:
matrix:
compiler: ${{ fromJson(needs.constants.outputs.compilers) }}
steps:
- name: Checkout Catalyst repo
uses: actions/checkout@v4
- name: Install device dependencies (OpenQasm device)
run: |
pip install amazon-braket-pennylane-plugin
echo "AWS_DEFAULT_REGION=us-east-1" >> $GITHUB_ENV
- name: Install Deps
run: |
sudo apt-get update
sudo apt-get install -y python3 python3-pip libomp-dev libasan6 make
python3 --version | grep ${{ needs.constants.outputs.primary_python_version }}
python3 -m pip install -r requirements.txt
make frontend
- name: Get Cached LLVM Build
id: cache-llvm-build
uses: actions/cache@v4
with:
path: llvm-build
key: ${{ runner.os }}-llvm-${{ needs.constants.outputs.llvm_version }}-default-build-${{ matrix.compiler }}
fail-on-cache-miss: true
- name: Download Quantum Build Artifact
uses: actions/download-artifact@v4
with:
name: quantum-build-${{ matrix.compiler }}
path: quantum-build
- name: Download Catalyst-Runtime Artifact
uses: actions/download-artifact@v4
with:
name: runtime-build-${{ matrix.compiler }}
path: runtime-build/lib
- name: Add Frontend Dependencies to PATH
run: |
echo "PYTHONPATH=$PYTHONPATH:$(pwd)/quantum-build/python_packages/quantum" >> $GITHUB_ENV
echo "RUNTIME_LIB_DIR=$(pwd)/runtime-build/lib" >> $GITHUB_ENV
echo "MLIR_LIB_DIR=$(pwd)/llvm-build/lib" >> $GITHUB_ENV
- name: Run Python Pytest Tests
run: |
make pytest TEST_BRAKET=LOCAL
runtime-device-tests:
name: Runtime Tests (Linux)
needs: [constants, runtime, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
strategy:
fail-fast: false
matrix:
backend: ${{ fromJson(needs.constants.outputs.rt_backends) }}
compiler: ${{ fromJson(needs.constants.outputs.compilers) }}
steps:
# - name: Collect Workflow Telemetry
# uses: catchpoint/workflow-telemetry-action@v2
- name: Checkout the repo
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y -q install cmake ninja-build libomp-dev lcov libasan6
- name: Install additional dependencies (OpenQasm device)
if: ${{ matrix.backend == 'openqasm' }}
run: |
pip install numpy amazon-braket-sdk
echo "AWS_DEFAULT_REGION=us-east-1" >> $GITHUB_ENV
- name: Download Catalyst-Runtime Artifact
uses: actions/download-artifact@v4
with:
name: runtime-build-${{ matrix.compiler }}
path: runtime-build/lib
- name: Build Runtime test suite for OQC device
if: ${{ matrix.backend == 'oqc' }}
run: |
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
RT_BUILD_DIR="$(pwd)/runtime-build" \
make test-oqc
- name: Build Runtime test suite for Lightning simulator
if: ${{ matrix.backend == 'lightning' }}
run: |
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
COMPILER_LAUNCHER="" \
ENABLE_OPENQASM=OFF \
ENABLE_ASAN=ON \
make test-runtime
- name: Build Runtime test suite with both Lightning and Lightning-Kokkos simulators
if: ${{ matrix.backend == 'lightning-kokkos' }}
run: |
# ASAN fails w/ leaks, odr-violation, and double-free from Kokkos_Profiling.cpp
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
COMPILER_LAUNCHER="" \
ENABLE_OPENQASM=OFF \
ENABLE_ASAN=OFF \
make test-runtime
- name: Build Runtime test suite for OpenQasm device
if: ${{ matrix.backend == 'openqasm' }}
run: |
# Asan prevents dlopen from working?
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
COMPILER_LAUNCHER="" \
ENABLE_ASAN=OFF \
make test-runtime
- name: Build examples
if: ${{ matrix.backend == 'lightning' }}
run: |
C_COMPILER=$(which ${{ needs.constants.outputs[format('c_compiler.{0}', matrix.compiler)] }}) \
CXX_COMPILER=$(which ${{ needs.constants.outputs[format('cxx_compiler.{0}', matrix.compiler)] }}) \
COMPILER_LAUNCHER="" \
make examples-runtime
runtime-code-cov:
name: Runtime Code Coverage (Linux)
needs: [constants, determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
steps:
- name: Checkout the repo
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y -q install cmake ninja-build libomp-dev lcov
- name: Build Runtime test suite for Lightning simulator
run: |
C_COMPILER=$(which gcc) \
CXX_COMPILER=$(which g++) \
COMPILER_LAUNCHER="" \
make coverage-runtime
mv runtime/build/coverage.info coverage-${{ github.job }}.info
- name: Upload to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}