diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 6cefe5bc9d..920882517b 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -422,7 +422,7 @@ jobs: container: image: 369495373322.dkr.ecr.eu-central-1.amazonaws.com/rust:pinned options: --init - needs: [ regress-tests, benchmarks ] + needs: [ regress-tests, coverage-report, benchmarks ] if: ${{ !cancelled() }} steps: @@ -449,12 +449,18 @@ jobs: reportJsonUrl: "${{ steps.create-allure-report.outputs.report-json-url }}", } + const coverage = { + coverageUrl: "${{ needs.coverage-report.outputs.coverage-html }}", + summaryJsonUrl: "${{ needs.coverage-report.outputs.coverage-json }}", + } + const script = require("./scripts/comment-test-report.js") await script({ github, context, fetch, report, + coverage, }) coverage-report: @@ -467,24 +473,15 @@ jobs: fail-fast: false matrix: build_type: [ debug ] + outputs: + coverage-html: ${{ steps.upload-coverage-report-new.outputs.report-url }} + coverage-json: ${{ steps.upload-coverage-report-new.outputs.summary-json }} steps: - name: Checkout uses: actions/checkout@v3 with: submodules: true - fetch-depth: 1 - -# Disabled for now -# - name: Restore cargo deps cache -# id: cache_cargo -# uses: actions/cache@v3 -# with: -# path: | -# ~/.cargo/registry/ -# !~/.cargo/registry/src -# ~/.cargo/git/ -# target/ -# key: v1-${{ runner.os }}-${{ matrix.build_type }}-cargo-${{ hashFiles('rust-toolchain.toml') }}-${{ hashFiles('Cargo.lock') }} + fetch-depth: 0 - name: Get Neon artifact uses: ./.github/actions/download @@ -527,13 +524,45 @@ jobs: REPORT_URL=https://${BUCKET}.s3.amazonaws.com/code-coverage/${COMMIT_SHA}/index.html echo "report-url=${REPORT_URL}" >> $GITHUB_OUTPUT + - name: Build coverage report NEW + id: upload-coverage-report-new + env: + BUCKET: neon-github-public-dev + COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + run: | + BASELINE="$(git merge-base HEAD origin/main)" + CURRENT="${COMMIT_SHA}" + + cp /tmp/coverage/report/lcov.info ./${CURRENT}.info + + GENHTML_ARGS="--ignore-errors path,unmapped,empty --synthesize-missing --demangle-cpp rustfilt --output-directory lcov-html ${CURRENT}.info" + + # Use differential coverage if the baseline coverage exists. + # It can be missing if the coverage repoer wasn't uploaded yet or tests has failed on BASELINE commit. + if aws s3 cp --only-show-errors s3://${BUCKET}/code-coverage/${BASELINE}/lcov.info ./${BASELINE}.info; then + git diff ${BASELINE} ${CURRENT} -- '*.rs' > baseline-current.diff + + GENHTML_ARGS="--baseline-file ${BASELINE}.info --diff-file baseline-current.diff ${GENHTML_ARGS}" + fi + + genhtml ${GENHTML_ARGS} + + aws s3 cp --only-show-errors --recursive ./lcov-html/ s3://${BUCKET}/code-coverage/${COMMIT_SHA}/lcov + + REPORT_URL=https://${BUCKET}.s3.amazonaws.com/code-coverage/${COMMIT_SHA}/lcov/index.html + echo "report-url=${REPORT_URL}" >> $GITHUB_OUTPUT + + REPORT_URL=https://${BUCKET}.s3.amazonaws.com/code-coverage/${COMMIT_SHA}/lcov/summary.json + echo "summary-json=${REPORT_URL}" >> $GITHUB_OUTPUT + - uses: actions/github-script@v6 env: REPORT_URL: ${{ steps.upload-coverage-report.outputs.report-url }} + REPORT_URL_NEW: ${{ steps.upload-coverage-report-new.outputs.report-url }} COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }} with: script: | - const { REPORT_URL, COMMIT_SHA } = process.env + const { REPORT_URL, REPORT_URL_NEW, COMMIT_SHA } = process.env await github.rest.repos.createCommitStatus({ owner: context.repo.owner, @@ -544,6 +573,15 @@ jobs: context: 'Code coverage report', }) + await github.rest.repos.createCommitStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + sha: `${COMMIT_SHA}`, + state: 'success', + target_url: `${REPORT_URL_NEW}`, + context: 'Code coverage report NEW', + }) + trigger-e2e-tests: runs-on: [ self-hosted, gen3, small ] container: diff --git a/scripts/comment-test-report.js b/scripts/comment-test-report.js index 1410b8a0ca..f62d923dc4 100755 --- a/scripts/comment-test-report.js +++ b/scripts/comment-test-report.js @@ -18,6 +18,10 @@ // reportUrl: "...", // reportJsonUrl: "...", // }, +// coverage: { +// coverageUrl: "...", +// summaryJsonUrl: "...", +// } // }) // @@ -183,7 +187,24 @@ const reportSummary = async (params) => { return summary } -module.exports = async ({ github, context, fetch, report }) => { +const parseCoverageSummary = async ({ summaryJsonUrl, coverageUrl, fetch }) => { + let summary = `### Code coverage [full report](${coverageUrl})\n` + + const coverage = await (await fetch(summaryJsonUrl)).json() + for (const covType of Object.keys(coverage).sort()) { + if (!coverage.hasOwnProperty(covType)) { + continue + } + + summary += `- \`${covType}s\`: \`${coverage[covType]["_summary"]}\`\n` + } + + summary += `\n___\n` + + return summary +} + +module.exports = async ({ github, context, fetch, report, coverage }) => { // Marker to find the comment in the subsequent runs const startMarker = `` // If we run the script in the PR or in the branch (main/release/...) @@ -204,7 +225,6 @@ module.exports = async ({ github, context, fetch, report }) => { } const {reportUrl, reportJsonUrl} = report - if (reportUrl && reportJsonUrl) { try { const parsed = await parseReportJson({ reportJsonUrl, fetch }) @@ -223,6 +243,22 @@ module.exports = async ({ github, context, fetch, report }) => { } else { commentBody += `#### No tests were run or test report is not available\n` } + + const { coverageUrl, summaryJsonUrl } = coverage + if (coverageUrl && summaryJsonUrl) { + try { + commentBody += await parseCoverageSummary({ summaryJsonUrl, coverageUrl, fetch }) + } catch (error) { + commentBody += `### [full report](${coverageUrl})\n___\n` + commentBody += `#### Failed to create a coverage summary for the test run: \n` + commentBody += "```\n" + commentBody += `${error.stack}\n` + commentBody += "```\n" + } + } else { + commentBody += `#### Test coverage report is not avaibale\n` + } + commentBody += autoupdateNotice let createCommentFn, listCommentsFn, updateCommentFn, issueNumberOrSha