Skip to content

Commit

Permalink
coverage: add coverage CI action
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperAuguste committed Nov 21, 2023
1 parent 6b05cb6 commit b852779
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 11 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/kcov-json-to-summary.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# script for us in kcov.yml action

SUMMARY=$(cat zig-out/kcov/kcov-merged/coverage.json)

PERCENT_COVERED=$(echo $SUMMARY | jq .percent_covered -cr)
COVERED_LINES=$(echo $SUMMARY | jq .covered_lines -cr)
TOTAL_LINES=$(echo $SUMMARY | jq .total_lines -cr)

echo -e "## Code Coverage Report\n"
echo -e "### $PERCENT_COVERED% covered ($COVERED_LINES / $TOTAL_LINES lines)\n"

echo -e "<details open><summary>Per-file coverage details</summary><br>\n"

FILES=$(echo $SUMMARY | jq '.files | sort_by(.percent_covered | tonumber) | .[]' -cr)

echo "| File | Coverage | |"
echo "| ---- | -------- | - |"

for FILE in $FILES; do
FILENAME="$(echo $FILE | jq '.file' -cr)"
FILENAME=${FILENAME#*zls/}
FILE_PERCENT_COVERED=$(echo $FILE | jq '.percent_covered' -cr)
FILE_COVERED_LINES=$(echo $FILE | jq '.covered_lines' -cr)
FILE_TOTAL_LINES=$(echo $FILE | jq '.total_lines' -cr)

FILE_STATUS=$(
if [ $(echo $FILE_PERCENT_COVERED'<25' | bc -l) -eq 1 ];
then
echo ""
elif [ $(echo $FILE_PERCENT_COVERED'<75' | bc -l) -eq 1 ];
then
echo "⚠️"
else
echo ""
fi
)

echo "| \`$FILENAME\` | $FILE_PERCENT_COVERED% ($FILE_COVERED_LINES / $FILE_TOTAL_LINES lines) | $FILE_STATUS |"
done

echo "</details>"
70 changes: 70 additions & 0 deletions .github/workflows/kcov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
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: Build kcov
# run: |
# sudo apt-get update
# sudo apt-get install binutils-dev libssl-dev libcurl4-openssl-dev zlib1g-dev libdw-dev libiberty-dev
# git clone https://github.com/SimonKagstrom/kcov
# cd kcov
# mkdir build
# cd build
# sudo cmake ..
# sudo make
# sudo make install

- name: Install kcov
run: |
sudo apt-get update
sudo apt-get install kcov
- name: Run Tests with kcov
id: kcov
env: # Or as an environment variable
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
run: |
mkdir -p zig-out/kcov
zig build test -Dgenerate_coverage
tree zig-out/kcov
.github/workflows/kcov-json-to-summary.sh > zig-out/summary.md
cat zig-out/summary.md > $GITHUB_STEP_SUMMARY
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "report<<$EOF" >> "$GITHUB_OUTPUT"
cat zig-out/summary.md >> "$GITHUB_OUTPUT"
echo "$EOF" >> "$GITHUB_OUTPUT"
- name: Publish coverage status
uses: thollander/actions-comment-pull-request@v2
with:
message: |
${{ steps.kcov.outputs.report }}
comment_tag: coverage
37 changes: 26 additions & 11 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit b852779

Please sign in to comment.