diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index befeb171bce7c68bd7f3e93739e663c6d15a9b15..bccb3eda65be6ee2df025ba29827dad6fdd8846b 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -315,7 +315,7 @@ jobs:
           mkdir ./coverage-reports
           for shard in ${{ matrix.shards }};
           do
-            mv ./coverage/shard/$shard/coverage-final.json ./coverage-reports/$shard.json
+            mv ./coverage/shard/$shard/lcov.info ./coverage-reports/$shard.txt
           done
 
       - name: Save coverage artifacts
@@ -323,7 +323,7 @@ jobs:
         uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
         with:
           name: coverage-reports
-          path: ./coverage-reports/*.json
+          path: ./coverage-reports/*.txt
 
   codecov:
     needs: [setup, test]
diff --git a/jest.config.ts b/jest.config.ts
index 756ab4b807adbd058c319d098362ca773444dd21..0e9659d2b4abac1590864fff8a051f921f824f79 100644
--- a/jest.config.ts
+++ b/jest.config.ts
@@ -342,7 +342,9 @@ const config: JestConfig = {
   cacheDirectory: '.cache/jest',
   clearMocks: true,
   collectCoverage: true,
-  coverageReporters: ci ? ['json', 'text-summary'] : ['html', 'text-summary'],
+  coverageReporters: ci
+    ? ['lcovonly', 'text-summary']
+    : ['html', 'text-summary'],
   transform: {
     '\\.ts$': [
       'ts-jest',
@@ -567,7 +569,7 @@ if (process.env.SCHEDULE_TEST_SHARDS) {
    * Output will be consumed by `codecov` GitHub Action.
    */
   const testCoverageFiels = shardKeys
-    .map((shard) => `./coverage-reports/${shard}.json`)
+    .map((shard) => `./coverage-reports/${shard}.txt`)
     .join(',');
   // eslint-disable-next-line no-console
   console.log(`test-coverage-files=${testCoverageFiels}`);