diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index e67a4ec2..d5ec1d1f 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -59,7 +59,7 @@ jobs:
           - os: ubuntu-20.04
             rust-toolchain: stable
             type: debug
-          - os: macos-12
+          - os: macos-13
             rust-toolchain: stable
             type: debug
           - os: windows-2019
@@ -81,8 +81,8 @@ jobs:
       - uses: ./neqo/.github/actions/rust
         with:
           version: ${{ matrix.rust-toolchain }}
-          components: ${{ matrix.rust-toolchain == 'stable' && 'llvm-tools' || '' }} ${{ matrix.rust-toolchain == 'nightly' && 'rust-src' || '' }}
-          tools: ${{ matrix.rust-toolchain == 'stable' && 'cargo-llvm-cov, ' || '' }}
+          components: ${{ matrix.rust-toolchain == 'nightly' && 'llvm-tools' || '' }} ${{ matrix.rust-toolchain == 'nightly' && 'rust-src' || '' }}
+          tools: ${{ matrix.rust-toolchain == 'nightly' && 'cargo-llvm-cov, ' || '' }}
           token: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Check
@@ -101,8 +101,8 @@ jobs:
           if [ "$BUILD_TYPE" ]; then
             OPTIONS+=("$BUILD_TYPE")
           fi
-          if [ "${{ matrix.rust-toolchain }}" == "stable" ] && [ "${{ matrix.type }}" == "debug" ] && [ "${{endsWith(matrix.os, '-latest') && 'latest' || '' }}" == "latest" ]; then
-            cargo +${{ matrix.rust-toolchain }} llvm-cov test "${OPTIONS[@]}" --lcov --output-path lcov.info
+          if [ "${{ matrix.rust-toolchain }}" == "nightly" ] && [ "${{ matrix.type }}" == "debug" ] && [ "${{endsWith(matrix.os, '-latest') && 'latest' || '' }}" == "latest" ]; then
+            cargo +${{ matrix.rust-toolchain }} llvm-cov test --mcdc --include-ffi "${OPTIONS[@]}" --codecov --output-path codecov.json
           else
             if [ "${{ startsWith(matrix.os, 'windows') && 'windows' || '' }}" == "windows" ]; then
               # The codegen_windows_bindings test only succeeds when run via llvm-cov?!
@@ -120,7 +120,7 @@ jobs:
           verbose: true
         env:
           CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
-        if: matrix.type == 'debug' && matrix.rust-toolchain == 'stable' && endsWith(matrix.os, '-latest')
+        if: matrix.type == 'debug' && matrix.rust-toolchain == 'nightly' && endsWith(matrix.os, '-latest')
 
       - name: Run tests with sanitizers
         if: (matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest') && matrix.rust-toolchain == 'nightly'
@@ -268,13 +268,13 @@ jobs:
           prepare: |
             pkg install -y curl llvm
           run: |
-            sh rustup.sh --default-toolchain stable --component llvm-tools -y
+            sh rustup.sh --default-toolchain nightly --component llvm-tools -y
             . "$HOME/.cargo/env"
             export RUST_LOG=trace
             cargo install cargo-llvm-cov --locked
             cargo check --all-targets
             cargo clippy
-            cargo llvm-cov test --no-fail-fast --lcov --output-path lcov.info
+            cargo llvm-cov test --mcdc --include-ffi --no-fail-fast --codecov --output-path codecov.json
             cargo test --no-fail-fast --release
 
       - if: matrix.os == 'openbsd'
@@ -301,7 +301,7 @@ jobs:
             /usr/sbin/pkg_add pkgin
             pkgin -y install curl clang
           run: |
-            sh rustup.sh --default-toolchain stable --component llvm-tools -y
+            sh rustup.sh --default-toolchain nightly --component llvm-tools -y
             . "$HOME/.cargo/env"
             export LIBCLANG_PATH=/usr/pkg/lib
             export RUST_LOG=trace
@@ -311,7 +311,7 @@ jobs:
             cargo test --no-fail-fast
             # FIXME: error[E0463]: can't find crate for `profiler_builtins`,
             # so don't fail the workflow when that happens.
-            cargo llvm-cov test --no-fail-fast --lcov --output-path lcov.info || true
+            cargo llvm-cov test --mcdc --include-ffi --no-fail-fast --codecov --output-path codecov.json || true
             cargo test --no-fail-fast --release
 
       - if: matrix.os == 'solaris'
@@ -320,18 +320,18 @@ jobs:
           usesh: true
           envs: "CARGO_TERM_COLOR RUST_BACKTRACE GITHUB_ACTIONS"
           run: |
-            sh rustup.sh --default-toolchain stable --component llvm-tools -y
+            sh rustup.sh --default-toolchain nightly --component llvm-tools -y
             . "$HOME/.cargo/env"
             export RUST_LOG=trace
             cargo install cargo-llvm-cov --locked
             cargo check --all-targets
             cargo clippy
-            cargo llvm-cov test --no-fail-fast --lcov --output-path lcov.info
+            cargo llvm-cov test --mcdc --include-ffi --no-fail-fast --codecov --output-path codecov.json
             cargo test --no-fail-fast --release
 
       - uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
         with:
-          file: lcov.info
+          files: codecov.json
           fail_ci_if_error: false
           token: ${{ secrets.CODECOV_TOKEN }}
           verbose: true
