re-enable canvas javascript coverage report
refs DE-989 flag=none TEST PLAN: confirm https://code-coverage.inseng.net/ is updated with new report Change-Id: I596ce0df04c920b096a875004bd765979dec344b Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/285861 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Aaron Ogata <aogata@instructure.com> QA-Review: Bobby Buten <bobby.buten@instructure.com> Product-Review: Bobby Buten <bobby.buten@instructure.com>
This commit is contained in:
parent
e9f0e22817
commit
e91a88762d
|
@ -0,0 +1,140 @@
|
|||
#!/usr/bin/env groovy
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
library "canvas-builds-library@${env.CANVAS_BUILDS_REFSPEC}"
|
||||
loadLocalLibrary('local-lib', 'build/new-jenkins/library')
|
||||
|
||||
def setupNode() {
|
||||
sh 'rm -vrf ./tmp'
|
||||
|
||||
checkout scm
|
||||
|
||||
distribution.stashBuildScripts()
|
||||
}
|
||||
|
||||
pipeline {
|
||||
agent none
|
||||
options {
|
||||
ansiColor('xterm')
|
||||
timeout(60)
|
||||
timestamps()
|
||||
}
|
||||
|
||||
environment {
|
||||
COMPOSE_FILE = 'docker-compose.new-jenkins.yml:docker-compose.new-jenkins-js.yml'
|
||||
FORCE_FAILURE = configuration.forceFailureJS()
|
||||
|
||||
TAG_SUFFIX = imageTag.suffix()
|
||||
IMAGE_CACHE_UNIQUE_SCOPE = "${imageTagVersion()}-$TAG_SUFFIX"
|
||||
KARMA_RUNNER_PREFIX = configuration.buildRegistryPath('karma-runner')
|
||||
KARMA_RUNNER_IMAGE = "$KARMA_RUNNER_PREFIX:$IMAGE_CACHE_UNIQUE_SCOPE"
|
||||
|
||||
BUILD_REGISTRY_FQDN = configuration.buildRegistryFQDN()
|
||||
COMPOSE_DOCKER_CLI_BUILD = 1
|
||||
DOCKER_BUILDKIT = 1
|
||||
PROGRESS_NO_TRUNC = 1
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Environment') {
|
||||
steps {
|
||||
script {
|
||||
def rspecNodeRequirements = [label: 'canvas-docker']
|
||||
|
||||
def postBuildHandler = [
|
||||
onNodeReleasing: { stageName, stageConfig, result ->
|
||||
buildSummaryReport.saveRunManifest()
|
||||
|
||||
copyArtifacts(
|
||||
filter: 'coverage-report-js/**',
|
||||
optional: false,
|
||||
projectName: env.JOB_NAME,
|
||||
selector: specific(env.BUILD_NUMBER),
|
||||
)
|
||||
|
||||
withEnv(['COMPOSE_FILE=docker-compose.new-jenkins.yml']) {
|
||||
sh """
|
||||
docker run --interactive \
|
||||
--volume \$(pwd)/coverage-report-js:/usr/src/app/tmp/coverage-report-js \
|
||||
--name coverage-collator \
|
||||
$KARMA_RUNNER_IMAGE bash -c "./build/new-jenkins/js/coverage-report.sh"
|
||||
"""
|
||||
|
||||
sh 'docker cp coverage-collator:/usr/src/app/report-html coverage-report-js/report-html'
|
||||
|
||||
publishHTML target: [
|
||||
allowMissing: false,
|
||||
alwaysLinkToLastBuild: false,
|
||||
keepAll: true,
|
||||
reportDir: './coverage-report-js/report-html',
|
||||
reportFiles: 'index.html',
|
||||
reportName: 'Coverage Report'
|
||||
]
|
||||
|
||||
uploadCoverage([
|
||||
uploadSource: '/coverage-report-js/report-html',
|
||||
uploadDest: 'canvas-lms-js/coverage'
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
extendedStage('Runner').obeysAllowStages(false).execute {
|
||||
extendedStage('Builder').hooks(postBuildHandler).obeysAllowStages(false).nodeRequirements(rspecNodeRequirements).execute {
|
||||
stage('Setup') {
|
||||
setupNode()
|
||||
}
|
||||
|
||||
extendedStage('Parallel Run Tests').obeysAllowStages(false).execute { stageConfig, buildConfig ->
|
||||
def jsStages = [:]
|
||||
|
||||
extendedStage('Runner - Jest').nodeRequirements(label: 'canvas-docker', podTemplate: jsStage.jestNodeRequirementsTemplate()).obeysAllowStages(false).timeout(10).queue(jsStages) {
|
||||
def tests = [:]
|
||||
|
||||
callableWithDelegate(jsStage.queueJestDistribution())(tests)
|
||||
|
||||
parallel(tests)
|
||||
}
|
||||
|
||||
extendedStage('Runner - Coffee').nodeRequirements(label: 'canvas-docker', podTemplate: jsStage.coffeeNodeRequirementsTemplate()).obeysAllowStages(false).timeout(10).queue(jsStages) {
|
||||
def tests = [:]
|
||||
|
||||
callableWithDelegate(jsStage.queueCoffeeDistribution())(tests)
|
||||
|
||||
parallel(tests)
|
||||
}
|
||||
|
||||
extendedStage('Runner - Karma').nodeRequirements(label: 'canvas-docker', podTemplate: jsStage.karmaNodeRequirementsTemplate()).obeysAllowStages(false).timeout(10).queue(jsStages) {
|
||||
def tests = [:]
|
||||
|
||||
callableWithDelegate(jsStage.queueKarmaDistribution())(tests)
|
||||
|
||||
parallel(tests)
|
||||
}
|
||||
|
||||
parallel(jsStages)
|
||||
} //parallel tests
|
||||
} //builder
|
||||
} //runner
|
||||
} //script
|
||||
} //steps
|
||||
} //environment
|
||||
} //stages
|
||||
} //pipeline
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Due to an issue with babel-plugin-istanbul, we get different versions of
|
||||
coverage reports, for example:
|
||||
|
||||
"<...>/src/app.js": {"path":"<...>/src/app.js","statementMap":{"0":{"start"...
|
||||
vs
|
||||
"<...>/src/aws.js": {"data":{"path":"<...>/src/aws.js","statementMap":{"0":{"start"...
|
||||
|
||||
The difference is the added "data" key, which when present, will crash istanbul-merge
|
||||
with the error:
|
||||
Error: Invalid file coverage object, missing keys, found:data
|
||||
|
||||
This script loops through all our js generated coverage reports and strips
|
||||
the "data" key where present so we can merge all coverage reports into one
|
||||
|
||||
Currently this script is called from ~/buid/new-jenkins/js/coverage-report.sh
|
||||
which is in turn called from Jenkinsfile.coverage
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
|
||||
const dirArgs = process.argv.slice(2)
|
||||
|
||||
const normalizeJestCoverage = obj => {
|
||||
const result = {...obj}
|
||||
|
||||
Object.entries(result).forEach(([k, v]) => {
|
||||
if (v.data) result[k] = v.data
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Get the contents of the directory and loop over it.
|
||||
const dirName = dirArgs[0]
|
||||
fs.readdir(dirName, function (err, list) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
// Get the contents of each file on iteration.
|
||||
const filename = list[i]
|
||||
|
||||
fs.readFile(dirName + '/' + filename, function (err, data) {
|
||||
const parsedData = JSON.parse(data)
|
||||
const cleanedCoverage = normalizeJestCoverage(parsedData)
|
||||
fs.writeFileSync(
|
||||
dirArgs[1] + filename.slice(0, -5) + '-out.json',
|
||||
JSON.stringify(cleanedCoverage, null, 4)
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
|
@ -2,48 +2,24 @@
|
|||
|
||||
set -o errexit -o errtrace -o nounset -o pipefail -o xtrace
|
||||
|
||||
# we have to premake the directories because... docker.. or something..
|
||||
# we have to premake the directories because for docker
|
||||
# sub directories are problematic when making it on a mounted
|
||||
# directory. permissions errors happen when making sub directories.
|
||||
rm -vrf ./coverage-report-js
|
||||
mkdir -v coverage-report-js
|
||||
chmod -vvR 777 coverage-report-js
|
||||
rm -vrf ./coverage-report-dir
|
||||
mkdir -v coverage-report-dir
|
||||
chmod -vvR 777 coverage-report-dir
|
||||
|
||||
# copy all the coverage reports and rename them so there are no
|
||||
# file name collisions
|
||||
counter=0
|
||||
for coverage_file in `find $(pwd)/tmp -name coverage*.json`
|
||||
do
|
||||
echo $coverage_file
|
||||
cp $coverage_file ./coverage-report-js/coverage-$counter.json
|
||||
counter=$((counter+1))
|
||||
done
|
||||
|
||||
# lets see whats inside the directory before we start aggregations
|
||||
find ./coverage-report-js
|
||||
|
||||
# build the reports inside the canvas-lms image because it has the required executables
|
||||
inputs=()
|
||||
inputs+=("--volume $(pwd)/coverage-report-js:/usr/src/app/coverage-report-js")
|
||||
cat <<EOF | docker run --interactive ${inputs[@]} $PATCHSET_TAG /bin/bash -
|
||||
set -o errexit -o errtrace -o nounset -o pipefail -o xtrace
|
||||
# babel-plugin-istanbul will produce differently formatted
|
||||
# coverage json files, this script cleans them up to be uniform and what
|
||||
# istanbul-merge requires
|
||||
node ./build/new-jenkins/js/cleanup-coverage.js '/usr/src/app/tmp/coverage-report-js' '/usr/src/app/coverage-report-dir/'
|
||||
|
||||
# aggregate them to coverage-total
|
||||
./node_modules/.bin/istanbul-merge --out coverage-report-js/coverage-total.json "coverage-report-js/coverage-*.json"
|
||||
./node_modules/.bin/istanbul-merge --out coverage-report-dir/coverage-total.json "coverage-report-dir/coverage-*-out.json"
|
||||
|
||||
# prepare for creating reports
|
||||
mkdir -v .nyc_output
|
||||
cp -v coverage-report-js/coverage-total.json .nyc_output/total-coverage.json
|
||||
cp -v coverage-report-dir/coverage-total.json .nyc_output/total-coverage.json
|
||||
|
||||
# the html report
|
||||
./node_modules/.bin/nyc report --reporter=html --report-dir report-html
|
||||
tar cf coverage-report-js/report-html.tar report-html
|
||||
|
||||
# the json report
|
||||
./node_modules/.bin/nyc report --reporter=json-summary --report-dir report-json
|
||||
tar cf coverage-report-js/report-json.tar report-json
|
||||
EOF
|
||||
|
||||
# extract the reports
|
||||
tar -vxf coverage-report-js/report-html.tar -C coverage-report-js/
|
||||
tar -vxf coverage-report-js/report-json.tar -C coverage-report-js/
|
||||
./node_modules/.bin/nyc report --reporter=html --report-dir report-html
|
|
@ -64,6 +64,26 @@ def tearDownNode() {
|
|||
copyToWorkspace srcBaseDir: '/usr/src/app', path: env.TEST_RESULT_OUTPUT_DIR
|
||||
archiveArtifacts artifacts: "${env.TEST_RESULT_OUTPUT_DIR}/**/*.xml"
|
||||
junit "${env.TEST_RESULT_OUTPUT_DIR}/**/*.xml"
|
||||
|
||||
if (env.COVERAGE == '1') {
|
||||
/* groovylint-disable-next-line GStringExpressionWithinString */
|
||||
sh '''#!/bin/bash
|
||||
rm -vrf ./coverage-report-js
|
||||
mkdir -v coverage-report-js
|
||||
chmod -vvR 777 coverage-report-js
|
||||
|
||||
counter=0
|
||||
for coverage_file in `find . -type d -name node_modules -prune -o -name coverage*.json -print`
|
||||
do
|
||||
stagearray=($STAGE_NAME)
|
||||
new_file="./coverage-report-js/coverage-"${stagearray[0]}"-"$counter".json"
|
||||
cp $coverage_file $new_file
|
||||
((counter=counter+1))
|
||||
done
|
||||
'''
|
||||
copyToWorkspace srcBaseDir: '/usr/src/app', path: 'coverage-report-js'
|
||||
archiveArtifacts allowEmptyArchive: true, artifacts: 'coverage-report-js/*'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ if (process.env.COVERAGE === '1') {
|
|||
karmaConfig.webpack.module.rules.unshift({
|
||||
test: /\.(js|coffee)$/,
|
||||
use: {
|
||||
loader: 'istanbul-instrumenter-loader',
|
||||
loader: 'coverage-istanbul-loader',
|
||||
options: {esModules: true, produceSourceMap: true}
|
||||
},
|
||||
enforce: 'post',
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
"classnames": "^2.2.5",
|
||||
"color-slicer": "0.8.0",
|
||||
"confetti-js": "^0.0.17",
|
||||
"coverage-istanbul-loader": "^3.0.5",
|
||||
"create-react-class": "^15.6.3",
|
||||
"crypto-js": "^4.1.1",
|
||||
"d3": "3.5.17",
|
||||
|
|
|
@ -42,10 +42,10 @@ module.exports = {
|
|||
coveragePathIgnorePatterns: ['<rootDir>/src/i18n/flip-message.js'],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
branches: 85,
|
||||
functions: 85,
|
||||
lines: 85,
|
||||
statements: 85
|
||||
branches: 80,
|
||||
functions: 80,
|
||||
lines: 80,
|
||||
statements: 80
|
||||
}
|
||||
},
|
||||
testEnvironment: 'jest-environment-jsdom-fourteen'
|
||||
|
|
18
yarn.lock
18
yarn.lock
|
@ -4230,6 +4230,17 @@
|
|||
"@types/yargs" "^16.0.0"
|
||||
chalk "^4.0.0"
|
||||
|
||||
"@jsdevtools/coverage-istanbul-loader@3.0.5":
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz#2a4bc65d0271df8d4435982db4af35d81754ee26"
|
||||
integrity sha512-EUCPEkaRPvmHjWAAZkWMT7JDzpw7FKB00WTISaiXsbNOd5hCHg77XLA8sLYLFDo1zepYLo2w7GstN8YBqRXZfA==
|
||||
dependencies:
|
||||
convert-source-map "^1.7.0"
|
||||
istanbul-lib-instrument "^4.0.3"
|
||||
loader-utils "^2.0.0"
|
||||
merge-source-map "^1.1.0"
|
||||
schema-utils "^2.7.0"
|
||||
|
||||
"@lerna/package@^3":
|
||||
version "3.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@lerna/package/-/package-3.16.0.tgz#7e0a46e4697ed8b8a9c14d59c7f890e0d38ba13c"
|
||||
|
@ -9338,6 +9349,13 @@ cosmiconfig@^7.0.0:
|
|||
path-type "^4.0.0"
|
||||
yaml "^1.10.0"
|
||||
|
||||
coverage-istanbul-loader@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz#bf942efc0f4e3ac27565203c17dca5008eae6637"
|
||||
integrity sha512-xsw2phF0VNqUPk47V/vHXkdcTyl0tkMSmaZfLrTOhoPhPMXFelNju7utl5s7I93KXzipqDEK0YwofQSSflPz8A==
|
||||
dependencies:
|
||||
"@jsdevtools/coverage-istanbul-loader" "3.0.5"
|
||||
|
||||
cp-file@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd"
|
||||
|
|
Loading…
Reference in New Issue