diff --git a/.github/workflows/kcov.yml b/.github/workflows/kcov.yml new file mode 100644 index 000000000..ddd7993fb --- /dev/null +++ b/.github/workflows/kcov.yml @@ -0,0 +1,46 @@ +name: Code Coverage + +on: + pull_request: + types: [opened, synchronize] + +permissions: + pull-requests: write + +jobs: + coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: true + + - uses: goto-bus-stop/setup-zig@v2 + with: + version: master + + - run: zig version + - run: zig env + + - name: Build + run: zig build + + - name: Install kcov + run: | + sudo apt-get update + sudo apt-get install kcov + + - name: Run Tests with kcov + run: | + mkdir -p zig-out/kcov + zig build test -Dgenerate_coverage + + - uses: actions/checkout@master + - uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + directory: zig-out/kcov/kcov-merged + fail_ci_if_error: true + verbose: true + diff --git a/build.zig b/build.zig index b5eaca769..a9dc7ec9c 100644 --- a/build.zig +++ b/build.zig @@ -216,31 +216,46 @@ pub fn build(b: *std.build.Builder) !void { if (coverage) { const include_pattern = b.fmt("--include-pattern=/src", .{}); const exclude_pattern = b.fmt("--exclude-pattern=/src/stage2", .{}); - const args = &[_]std.build.RunStep.Arg{ - .{ .bytes = b.dupe("kcov") }, - .{ .bytes = b.dupe("--collect-only") }, - .{ .bytes = b.dupe(include_pattern) }, - .{ .bytes = b.dupe(exclude_pattern) }, - .{ .bytes = b.dupe(coverage_output_dir) }, - }; var tests_run = b.addRunArtifact(tests); var src_tests_run = b.addRunArtifact(src_tests); tests_run.has_side_effects = true; src_tests_run.has_side_effects = true; - tests_run.argv.insertSlice(0, args) catch @panic("OOM"); - src_tests_run.argv.insertSlice(0, args) catch @panic("OOM"); + tests_run.argv.insertSlice(0, &[_]std.build.RunStep.Arg{ + .{ .bytes = b.dupe("kcov") }, + .{ .bytes = b.dupe(include_pattern) }, + .{ .bytes = b.dupe(exclude_pattern) }, + .{ .bytes = b.pathJoin(&.{ coverage_output_dir, "test-tests" }) }, + }) catch @panic("OOM"); + + src_tests_run.argv.insertSlice(0, &[_]std.build.RunStep.Arg{ + .{ .bytes = b.dupe("kcov") }, + .{ .bytes = b.dupe(include_pattern) }, + .{ .bytes = b.dupe(exclude_pattern) }, + .{ .bytes = b.pathJoin(&.{ coverage_output_dir, "test-src" }) }, + }) catch @panic("OOM"); var merge_step = std.build.RunStep.create(b, "merge kcov"); merge_step.has_side_effects = true; + merge_step.addArgs(&.{ "kcov", "--merge", + }); + + if (b.env_map.get("COVERALLS_REPO_TOKEN")) |repo_token| { + std.log.info("Detected repo token; enabling automatic upload to Coveralls", .{}); + merge_step.addArg(std.mem.concat(b.allocator, u8, &[_][]const u8{ "--coveralls-id=", repo_token }) catch @panic("OOM")); + } + + merge_step.addArgs(&.{ coverage_output_dir, - b.pathJoin(&.{ coverage_output_dir, "test" }), + b.pathJoin(&.{ coverage_output_dir, "test-tests" }), + b.pathJoin(&.{ coverage_output_dir, "test-src" }), }); - merge_step.step.dependOn(&b.addRemoveDirTree(coverage_output_dir).step); + + // merge_step.step.dependOn(&b.addRemoveDirTree(coverage_output_dir).step); merge_step.step.dependOn(&tests_run.step); merge_step.step.dependOn(&src_tests_run.step); test_step.dependOn(&merge_step.step);