[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:
26
circle.yml
26
circle.yml
@@ -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:
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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=[])
|
||||
|
||||
|
||||
|
||||
64
scripts/publish_doxygen_coverage.js
Executable file
64
scripts/publish_doxygen_coverage.js
Executable 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})`
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user