[build] Check documentation coverage on CI

Add a CI target that checks documentation coverage and reports back to
github. While at it, change the output of doxy-coverage to a json file
so it is easy to consume.
This commit is contained in:
Ander Conselvan de Oliveira
2019-03-04 15:13:31 +02:00
parent 3c4d41559a
commit 7bac0c7cba
4 changed files with 108 additions and 9 deletions

View File

@@ -39,6 +39,7 @@ workflows:
- linux-gcc49-debug:
name: linux-gcc4.9-debug
- linux-gcc5-debug-coverage
- linux-doxygen
- ios-debug
- ios-release-template:
name: ios-release
@@ -864,6 +865,31 @@ jobs:
chmod +x codecov
./codecov -c
# ------------------------------------------------------------------------------
linux-doxygen:
docker:
- image: mbgl/linux-gcc-5:54f59e3ac5
resource_class: large
working_directory: /src
environment:
LIBSYSCONFCPUS: 2
JOBS: 2
BUILDTYPE: Debug
WITH_EGL: 1
WITH_COVERAGE: 1
steps:
- install-dependencies
- run:
name: Install doxygen
command: apt update && apt install -y doxygen
- build-linux
- save-dependencies
- run:
name: Check documentation coverage
command: |
platform/linux/ninja -C "build/linux-$(uname -m)/Debug" doxygen_coverage
scripts/publish_doxygen_coverage.js "build/linux-$(uname -m)/Debug/doxygen-coverage.json"
# ------------------------------------------------------------------------------
ios-debug:
macos:

View File

@@ -11,7 +11,7 @@ if(DOXYGEN_FOUND)
)
add_custom_target(doxygen_coverage
COMMAND ${CMAKE_SOURCE_DIR}/scripts/doxy-coverage.py --noerror "${CMAKE_BINARY_DIR}/docs/xml"
COMMAND ${CMAKE_SOURCE_DIR}/scripts/doxy-coverage.py --quiet --noerror --json="${CMAKE_BINARY_DIR}/doxygen-coverage.json" "${CMAKE_BINARY_DIR}/docs/xml"
COMMENT "Checking documentation coverage"
DEPENDS generate_xml_doxygen
)

View File

@@ -158,18 +158,25 @@ def report (files, exclude_dirs):
total_yes += doc_yes
total_no += doc_no
print ('%3d%% - %s - (%d of %d)'%(doc_per, f, doc_yes, (doc_yes + doc_no)))
if not ns.quiet:
print ('%3d%% - %s - (%d of %d)'%(doc_per, f, doc_yes, (doc_yes + doc_no)))
defs_sorted = defs.keys()
defs_sorted.sort()
for d in defs_sorted:
if not defs[d]:
print ("\t", d)
defs_sorted = defs.keys()
defs_sorted.sort()
for d in defs_sorted:
if not defs[d]:
print ("\t", d)
total_all = total_yes + total_no
total_per = total_yes * 100 / total_all
print()
print("%d%% API documentation coverage" %(total_per))
if not ns.quiet:
print()
print("%d%% API documentation coverage (%d out of %d)" %(total_per, total_yes, total_all))
if ns.json:
with open(ns.json, "w") as f:
f.write('{"documented": %d, "total": %d}\n' % (total_yes, total_all))
return (ns.threshold - total_per, 0)[total_per > ns.threshold]
@@ -179,6 +186,8 @@ def main():
parser.add_argument ("dir", action="store", help="Path to Doxygen's XML doc directory")
parser.add_argument ("--noerror", action="store_true", help="Do not return error code after execution")
parser.add_argument ("--threshold", action="store", help="Min acceptable coverage percentage (Default: %s)"%(ACCEPTABLE_COVERAGE), default=ACCEPTABLE_COVERAGE, type=int)
parser.add_argument ("--quiet", action="store_true", help="Don't output report to standard output")
parser.add_argument ("--json", action="store", help="Output json coverage report to specified json file")
parser.add_argument("--excludedirs", nargs='+', help="List of directories to be excluded from coverage analysis", type=str, default=[])

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env node
const jwt = require('jsonwebtoken');
const github = require('@octokit/rest')();
const fs = require('fs');
const SIZE_CHECK_APP_ID = 14028;
const SIZE_CHECK_APP_INSTALLATION_ID = 229425;
var coverage;
try {
coverage = JSON.parse(fs.readFileSync(process.argv[2]));
if (typeof coverage.documented !== 'number' || typeof coverage.total !== 'number' ||
coverage.documented > coverage.total) {
throw new Error('Invalid coverage.json file');
}
} catch (error) {
console.log('Failed to parse json file with coverage data: ', error);
process.exit(1);
}
process.on('unhandledRejection', error => {
console.log(error);
process.exit(1);
});
const pk = process.env['SIZE_CHECK_APP_PRIVATE_KEY'];
if (!pk) {
console.log('Fork PR; not publishing size.');
process.exit(0);
}
const key = Buffer.from(pk, 'base64').toString('binary');
const payload = {
exp: Math.floor(Date.now() / 1000) + 60,
iat: Math.floor(Date.now() / 1000),
iss: SIZE_CHECK_APP_ID
};
const token = jwt.sign(payload, key, {algorithm: 'RS256'});
github.authenticate({type: 'app', token});
github.apps.createInstallationToken({installation_id: SIZE_CHECK_APP_INSTALLATION_ID})
.then(({data}) => {
github.authenticate({type: 'token', token: data.token});
const percentage = coverage.documented * 100 / coverage.total;
const title = `${percentage.toFixed(2)}%`;
return github.checks.create({
owner: 'mapbox',
repo: 'mapbox-gl-native',
name: 'Doxygen coverage',
head_branch: process.env['CIRCLE_BRANCH'],
head_sha: process.env['CIRCLE_SHA1'],
status: 'completed',
conclusion: 'success',
completed_at: new Date().toISOString(),
output: {
title,
summary: `There is doxygen documentation for ${percentage}% of the public symbols (${coverage.documented} out of ${coverage.total})`
}
});
});