From a73ffa20ce8f3b04af6425bc9d6d38bd98a7a718 Mon Sep 17 00:00:00 2001 From: Phillip Johnsen Date: Sun, 2 May 2021 21:34:54 +0200 Subject: [PATCH] chore: remove unused nodejs/node PR labelling code As labelling nodejs/node PRs has been replaced by a GitHub Action. Refs https://github.com/nodejs/node-pr-labeler --- lib/node-labels.js | 316 --------- lib/node-repo.js | 113 ---- package-lock.json | 13 +- package.json | 2 - test/_fixtures/repo-labels-page-2.json | 77 --- test/_fixtures/repo-labels.json | 179 ----- test/unit/node-build-label.test.js | 43 -- test/unit/node-js-subsystem-labels.test.js | 179 ----- test/unit/node-labels.test.js | 726 --------------------- test/unit/node-repo.test.js | 86 --- 10 files changed, 5 insertions(+), 1729 deletions(-) delete mode 100644 lib/node-labels.js delete mode 100644 test/_fixtures/repo-labels-page-2.json delete mode 100644 test/_fixtures/repo-labels.json delete mode 100644 test/unit/node-build-label.test.js delete mode 100644 test/unit/node-js-subsystem-labels.test.js delete mode 100644 test/unit/node-labels.test.js diff --git a/lib/node-labels.js b/lib/node-labels.js deleted file mode 100644 index cc3a3ee6..00000000 --- a/lib/node-labels.js +++ /dev/null @@ -1,316 +0,0 @@ -'use strict' - -const ciNeededFolderRx = /^(deps|lib|src|test)\// -// order of entries in this map *does* matter for the resolved labels -// earlier entries override later entries -const subSystemLabelsMap = new Map([ - /* src subsystems */ - [/^src\/async-wrap/, ['c++', 'async_wrap']], - [/^src\/(?:base64|node_buffer|string_)/, ['c++', 'buffer']], - [/^src\/cares/, ['c++', 'cares']], - [/^src\/(?:process_wrap|spawn_)/, ['c++', 'child_process']], - [/^src\/(?:node_)?crypto/, ['c++', 'crypto']], - [/^src\/(?:debug-|node_debug)/, ['c++', 'debugger']], - [/^src\/udp_/, ['c++', 'dgram']], - [/^src\/(?:fs_|node_file|node_stat_watcher)/, ['c++', 'fs']], - [/^src\/node_http_parser/, ['c++', 'http_parser']], - [/^src\/node_i18n/, ['c++', 'intl']], - [/^src\/uv\./, ['c++', 'libuv']], - [/^src\/(?:connect(?:ion)?|pipe|tcp)_/, ['c++', 'net']], - [/^src\/node_os/, ['c++', 'os']], - [/^src\/(?:node_main|signal_)/, ['c++', 'process']], - [/^src\/timer_/, ['c++', 'timers']], - [/^src\/(?:CNNICHashWhitelist|node_root_certs|tls_)/, ['c++', 'tls']], - [/^src\/tty_/, ['c++', 'tty']], - [/^src\/node_url/, ['c++', 'url-whatwg']], - [/^src\/node_util/, ['c++', 'util']], - [/^src\/(?:node_v8|v8abbr)/, ['c++', 'V8 Engine']], - [/^src\/node_contextify/, ['c++', 'vm']], - [/^src\/.*win32.*/, ['c++', 'windows']], - [/^src\/node_zlib/, ['c++', 'zlib']], - [/^src\/tracing/, ['c++', 'tracing']], - [/^src\/node_api/, ['c++', 'n-api']], - [/^src\/node_http2/, ['c++', 'http2', 'dont-land-on-v6.x']], - [/^src\/node_report/, ['c++', 'report']], - [/^src\/node_wasi/, ['c++', 'wasi']], - [/^src\/node_worker/, ['c++', 'worker']], - [/^src\/quic\/*/, ['c++', 'quic', 'dont-land-on-v14.x', 'dont-land-on-v12.x']], - [/^src\/node_bob*/, ['c++', 'quic', 'dont-land-on-v14.x', 'dont-land-on-v12.x']], - - // don't label python files as c++ - [/^src\/.+\.py$/, ['lib / src', 'needs-ci']], - - // properly label changes to v8 inspector integration-related files - [/^src\/inspector_/, ['c++', 'inspector', 'needs-ci']], - - // don't want to label it a c++ update when we're "only" bumping the Node.js version - [/^src\/(?!node_version\.h)/, 'c++'], - // BUILDING.md should be marked as 'build' in addition to 'doc' - [/^BUILDING\.md$/, ['build', 'doc']], - // meta is a very specific label for things that are policy and or meta-info related - [/^([A-Z]+$|CODE_OF_CONDUCT|ROADMAP|WORKING_GROUPS|GOVERNANCE|CHANGELOG|\.mail|\.git.+)/, 'meta'], - // things that edit top-level .md files are always a doc change - [/^\w+\.md$/, 'doc'], - // different variants of *Makefile and build files - [/^(tools\/)?(Makefile|BSDmakefile|create_android_makefiles|\.travis\.yml)$/, ['build', 'needs-ci']], - [/^tools\/(install\.py|genv8constants\.py|getnodeversion\.py|js2c\.py|utils\.py|configure\.d\/.*)$/, ['build', 'needs-ci']], - [/^vcbuild\.bat$/, ['build', 'windows', 'needs-ci']], - [/^(android-)?configure|node\.gyp|common\.gypi$/, ['build', 'needs-ci']], - // more specific tools - [/^tools\/gyp/, ['tools', 'build', 'needs-ci']], - [/^tools\/doc\//, ['tools', 'doc']], - [/^tools\/icu\//, ['tools', 'intl', 'needs-ci']], - [/^tools\/(?:osx-pkg\.pmdoc|pkgsrc)\//, ['tools', 'macos', 'install']], - [/^tools\/(?:(?:mac)?osx-)/, ['tools', 'macos']], - [/^tools\/test-npm/, ['tools', 'test', 'npm']], - [/^tools\/test/, ['tools', 'test']], - [/^tools\/(?:certdata|mkssldef|mk-ca-bundle)/, ['tools', 'openssl', 'tls']], - [/^tools\/msvs\//, ['tools', 'windows', 'install', 'needs-ci']], - [/^tools\/[^/]+\.bat$/, ['tools', 'windows', 'needs-ci']], - [/^tools\/make-v8/, ['tools', 'V8 Engine', 'needs-ci']], - [/^tools\/(code_cache|snapshot|v8_gypfiles)/, 'needs-ci'], - [/^tools\/build-addons.js/, 'needs-ci'], - // all other tool changes should be marked as such - [/^tools\//, 'tools'], - [/^\.eslint|\.remark|\.editorconfig/, 'tools'], - - /* Dependencies */ - // libuv needs an explicit mapping, as the ordinary /deps/ mapping below would - // end up as libuv changes labeled with "uv" (which is a non-existing label) - [/^deps\/uv\//, 'libuv'], - [/^deps\/v8\/tools\/gen-postmortem-metadata\.py/, ['V8 Engine', 'post-mortem']], - [/^deps\/v8\//, 'V8 Engine'], - [/^deps\/uvwasi\//, 'wasi'], - [/^deps\/nghttp2\/nghttp2\.gyp/, ['build', 'http2', 'dont-land-on-v6.x']], - [/^deps\/nghttp2\//, ['http2', 'dont-land-on-v6.x']], - [/^deps\/ngtcp2\//, 'quic', 'dont-land-on-v14.x', 'dont-land-on-v12.x'], - [/^deps\/nghttp3\//, 'quic', 'dont-land-on-v14.x', 'dont-land-on-v12.x'], - [/^deps\/([^/]+)/, '$1'], - - /* JS subsystems */ - // Oddities first - [/^lib\/(punycode|\w+\/freelist|sys\.js)/, ''], // TODO: ignore better? - [/^lib\/constants\.js$/, 'lib / src'], - [/^lib\/_(debug_agent|debugger)\.js$/, 'debugger'], - [/^lib(\/\w+)?\/(_)?link(ed)?list/, 'timers'], - [/^lib\/\w+\/bootstrap_node/, 'lib / src'], - [/^lib\/\w+\/v8_prof_/, 'tools'], - [/^lib\/\w+\/socket_list/, 'net'], - [/^lib\/\w+\/streams$/, 'stream'], - [/^lib\/.*http2/, ['http2', 'dont-land-on-v6.x']], - [/^lib\/worker_threads.js$/, ['worker']], - [/^lib\/internal\/url\.js$/, ['url-whatwg']], - [/^lib\/internal\/modules\/esm/, 'ES Modules'], - [/^lib\/internal\/quic\/*/, ['quic', 'dont-land-on-v14.x', 'dont-land-on-v12.x']], - // All other lib/ files map directly - [/^lib\/_(\w+)_\w+\.js?$/, '$1'], // e.g. _(stream)_wrap - [/^lib(\/internal)?\/(\w+)\.js?$/, '$2'], // other .js files - [/^lib\/internal\/(\w+)(?:\/|$)/, '$1'] // internal subfolders -]) - -const jsSubsystemList = [ - 'debugger', 'assert', 'async_hooks', 'buffer', 'child_process', 'cluster', - 'console', 'crypto', 'dgram', 'dns', 'domain', 'events', 'esm', 'fs', 'http', - 'https', 'http2', 'module', 'net', 'os', 'path', 'process', 'querystring', - 'quic', 'readline', 'repl', 'report', 'stream', 'string_decoder', 'timers', - 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'wasi', 'worker', 'zlib' -] - -const exclusiveLabelsMap = new Map([ - // more specific tests - [/^test\/addons\//, ['test', 'addons']], - [/^test\/debugger\//, ['test', 'debugger']], - [/^test\/doctool\//, ['test', 'doc', 'tools']], - [/^test\/timers\//, ['test', 'timers']], - [/^test\/pseudo-tty\//, ['test', 'tty']], - [/^test\/inspector\//, ['test', 'inspector']], - [/^test\/cctest\/test_inspector/, ['test', 'inspector']], - [/^test\/cctest\/test_url/, ['test', 'url-whatwg']], - [/^test\/addons-napi\//, ['test', 'n-api']], - [/^test\/async-hooks\//, ['test', 'async_hooks']], - [/^test\/report\//, ['test', 'report']], - [/^test\/fixtures\/es-module/, ['test', 'ES Modules']], - [/^test\/es-module\//, ['test', 'ES Modules']], - - [/^test\//, 'test'], - - // specific map for webcrypto.md as it should be labeled 'crypto' - [/^doc\/api\/webcrypto.md$/, ['doc', 'crypto']], - // specific map for modules.md as it should be labeled 'module' not 'modules' - [/^doc\/api\/modules.md$/, ['doc', 'module']], - // specific map for esm.md as it should be labeled 'ES Modules' not 'esm' - [/^doc\/api\/esm.md$/, ['doc', 'ES Modules']], - // n-api is treated separately since it is not a JS core module but is still - // considered a subsystem of sorts - [/^doc\/api\/n-api.md$/, ['doc', 'n-api']], - // quic - [/^doc\/api\/quic.md$/, ['doc', 'quic', 'dont-land-on-v14.x', 'dont-land-on-v12.x']], - // add worker label to PRs that affect doc/api/worker_threads.md - [/^doc\/api\/worker_threads.md$/, ['doc', 'worker']], - // automatically tag JS subsystem-specific API doc changes - [/^doc\/api\/(\w+)\.md$/, ['doc', '$1']], - // add deprecations label to PRs that affect doc/api/deprecations.md - [/^doc\/api\/deprecations.md$/, ['doc', 'deprecations']], - - [/^doc\//, 'doc'], - - // more specific benchmarks - [/^benchmark\/buffers\//, ['benchmark', 'buffer']], - [/^benchmark\/(?:arrays|es)\//, ['benchmark', 'V8 Engine']], - [/^benchmark\/_http/, ['benchmark', 'http']], - [/^benchmark\/(?:misc|fixtures)\//, 'benchmark'], - [/^benchmark\/streams\//, ['benchmark', 'stream']], - [/^benchmark\/([^/]+)\//, ['benchmark', '$1']], - - [/^benchmark\//, 'benchmark'] -]) - -function resolveLabels (filepathsChanged, baseBranch, limitLabels = true) { - const exclusiveLabels = matchExclusiveSubSystem(filepathsChanged) - - if (typeof baseBranch !== 'string') { - if (typeof baseBranch === 'boolean') { - limitLabels = baseBranch - } - baseBranch = '' - } - - const labels = (exclusiveLabels.length > 0) - ? exclusiveLabels - : matchAllSubSystem(filepathsChanged, limitLabels) - - // Add version labels if PR is made against a version branch - const m = /^(v\d+\.(?:\d+|x))(?:-staging|$)/.exec(baseBranch) - if (m) { - labels.push(m[1]) - } - - return labels -} - -function hasAllSubsystems (arr) { - return arr.every((val) => { - return jsSubsystemList.includes(val) - }) -} - -// This function is needed to help properly identify when a PR should always -// (just) be labeled as 'doc' when it is all changes in doc/api/ that do not -// match subsystem names (e.g. _toc.md, all.md) -function hasAllDocChanges (arr) { - return arr.every((val) => { - return /^doc\//.test(val) - }) -} - -function hasAllTestChanges (arr) { - return arr.every((val) => { - return /^test\//.test(val) - }) -} - -function matchExclusiveSubSystem (filepathsChanged) { - const isExclusive = filepathsChanged.every(matchesAnExclusiveLabel) - var labels = matchSubSystemsByRegex(exclusiveLabelsMap, filepathsChanged) - var nonMetaLabels = labels.filter((label) => { - return !/^dont-/.test(label) - }) - - // if there are multiple API doc changes, do not apply subsystem tags for now - if (isExclusive && - nonMetaLabels.includes('doc') && - nonMetaLabels.length > 2 && - !hasAllTestChanges(filepathsChanged)) { - const nonDocLabels = nonMetaLabels.filter((val) => { - return val !== 'doc' - }) - if (hasAllSubsystems(nonDocLabels) || hasAllDocChanges(filepathsChanged)) { - labels = ['doc'] - } else { - labels = [] - } - } - return isExclusive ? labels : [] -} - -function matchAllSubSystem (filepathsChanged, limitLabels) { - return matchSubSystemsByRegex( - subSystemLabelsMap, filepathsChanged, limitLabels) -} - -function matchSubSystemsByRegex (rxLabelsMap, filepathsChanged, limitLabels) { - const labelCount = [] - // by putting matched labels into a map, we avoid duplicate labels - const labelsMap = filepathsChanged.reduce((map, filepath) => { - if (ciNeededFolderRx.test(filepath) && !map['needs-ci']) { - map['needs-ci'] = true - } - - const mappedSubSystems = mappedSubSystemsForFile(rxLabelsMap, filepath) - - if (!mappedSubSystems) { - // short-circuit - return map - } - - for (var i = 0; i < mappedSubSystems.length; ++i) { - const mappedSubSystem = mappedSubSystems[i] - if (limitLabels && hasLibOrSrcChanges(filepathsChanged)) { - if (labelCount.length >= 4) { - for (const label of labelCount) { - // don't delete the `c++` or `needs-ci` labels as we always want those if they have matched - if (label !== 'c++' && label !== 'needs-ci') delete map[label] - } - map['lib / src'] = true - // short-circuit - return map - } else { - labelCount.push(mappedSubSystem) - } - } - - map[mappedSubSystem] = true - } - - return map - }, {}) - - return Object.keys(labelsMap) -} - -function hasLibOrSrcChanges (filepathsChanged) { - return filepathsChanged.some((filepath) => filepath.startsWith('lib/') || filepath.startsWith('src/')) -} - -function mappedSubSystemsForFile (labelsMap, filepath) { - for (const [regex, label] of labelsMap) { - const matches = regex.exec(filepath) - - if (matches === null) { - continue - } - - const ret = [] - const labels = Array.isArray(label) ? label : [label] - labels.forEach((label) => { - // label names starting with $ means we want to extract a matching - // group from the regex we've just matched against - if (label.startsWith('$')) { - const wantedMatchGroup = label.substr(1) - label = matches[wantedMatchGroup] - } - if (!label) { - return - } - // use label name as is when label doesn't look like a regex matching group - ret.push(label) - }) - return ret - } -} - -function matchesAnExclusiveLabel (filepath) { - return mappedSubSystemsForFile(exclusiveLabelsMap, filepath) !== undefined -} - -exports.resolveLabels = resolveLabels diff --git a/lib/node-repo.js b/lib/node-repo.js index 4855ba51..ae26f65f 100644 --- a/lib/node-repo.js +++ b/lib/node-repo.js @@ -2,80 +2,17 @@ /* eslint-disable camelcase */ -const LRU = require('lru-cache') const Aigle = require('aigle') const request = require('request') const githubClient = require('./github-client') const { createPrComment } = require('./github-comment') -const resolveLabels = require('./node-labels').resolveLabels const { Owners } = require('./node-owners') -const existingLabelsCache = new LRU({ max: 1, maxAge: 1000 * 60 * 60 }) const fiveSeconds = 5 * 1000 const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)) -async function deferredResolveLabelsThenUpdatePr (options) { - const timeoutMillis = (options.timeoutInSec || 0) * 1000 - await sleep(timeoutMillis) - return resolveLabelsThenUpdatePr(options) -} - -async function resolveLabelsThenUpdatePr (options) { - const times = options.retries || 5 - const interval = options.retryInterval || fiveSeconds - const retry = fn => Aigle.retry({ times, interval }, fn) - - const filepathsChanged = await retry(() => listFiles({ - owner: options.owner, - repo: options.repo, - pull_number: options.prId, - logger: options.logger - })) - options.logger.debug('Fetching PR files for labelling') - - const resolvedLabels = resolveLabels(filepathsChanged, options.baseBranch) - - return fetchExistingThenUpdatePr(options, resolvedLabels) -} - -async function fetchExistingThenUpdatePr (options, labels) { - try { - const existingLabels = await fetchExistingLabels(options) - const labelsToAdd = stringsInCommon(existingLabels, labels) - options.logger.debug('Resolved labels: ' + labelsToAdd, labels, existingLabels) - - return updatePrWithLabels(options, labelsToAdd) - } catch (err) { - options.logger.error(err, 'Error retrieving existing repo labels') - - return updatePrWithLabels(options, labels) - } -} - -async function updatePrWithLabels (options, labels) { - // no need to request github if we didn't resolve any labels - if (!labels.length) { - return - } - - options.logger.debug('Trying to add labels: ' + labels) - - try { - await githubClient.issues.addLabels({ - owner: options.owner, - repo: options.repo, - issue_number: options.prId, - labels: labels - }) - - options.logger.info('Added labels: ' + labels) - } catch (err) { - options.logger.error(err, 'Error while adding labels') - } -} - async function removeLabelFromPR (options, label) { // no need to request github if we didn't resolve a label if (!label) { @@ -104,46 +41,6 @@ async function removeLabelFromPR (options, label) { return label } -async function fetchExistingLabels (options) { - const cacheKey = `${options.owner}:${options.repo}` - - if (existingLabelsCache.has(cacheKey)) { - return existingLabelsCache.get(cacheKey) - } - - const labelsResult = await fetchLabelPages(options, 1) - const existingLabels = labelsResult.data || labelsResult || [] - const existingLabelNames = existingLabels.map((label) => label.name) - - // cache labels so we don't have to fetch these *all the time* - existingLabelsCache.set(cacheKey, existingLabelNames) - options.logger.debug('Filled existing repo labels cache: ' + existingLabelNames) - - return existingLabelNames -} - -async function fetchLabelPages (options, startPageNum, cb) { - // the github client API is somewhat misleading, - // this fetches *all* repo labels not just for an issue - const result = await githubClient.issues.listLabelsForRepo({ - owner: options.owner, - repo: options.repo, - page: startPageNum, - per_page: 100 - }) - - const existingLabels = result.data || [] - if (!githubClient.hasNextPage(result)) { - return existingLabels - } - - const remainingLabels = await fetchLabelPages( - options, - startPageNum + 1) - - return existingLabels.concat(remainingLabels) -} - function getBotPrLabels (options, cb) { githubClient.issues.listEvents({ owner: options.owner, @@ -175,13 +72,6 @@ function getBotPrLabels (options, cb) { }, cb) } -function stringsInCommon (arr1, arr2) { - const loweredArr2 = arr2.map((str) => str.toLowerCase()) - // we want the original string cases in arr1, therefore we don't lowercase them - // before comparing them cause that would wrongly make "V8" -> "v8" - return arr1.filter((str) => loweredArr2.indexOf(str.toLowerCase()) !== -1) -} - async function deferredResolveOwnersThenPingPr (options) { const timeoutMillis = (options.timeoutInSec || 0) * 1000 await sleep(timeoutMillis) @@ -288,12 +178,9 @@ async function pingOwners (options, owners) { exports.getBotPrLabels = getBotPrLabels exports.removeLabelFromPR = removeLabelFromPR -exports.fetchExistingThenUpdatePr = fetchExistingThenUpdatePr -exports.resolveLabelsThenUpdatePr = deferredResolveLabelsThenUpdatePr exports.resolveOwnersThenPingPr = deferredResolveOwnersThenPingPr // exposed for testability -exports._fetchExistingLabels = fetchExistingLabels exports._testExports = { pingOwners, getCodeOwnersFile, getCodeOwnersUrl, getDefaultBranch, listFiles, getCommentForOwners } diff --git a/package-lock.json b/package-lock.json index aca72b58..7a1ccdb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3187,12 +3187,6 @@ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true }, - "lolex": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", - "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", - "dev": true - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -3206,6 +3200,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -4197,7 +4192,8 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true }, "psl": { "version": "1.1.31", @@ -6794,7 +6790,8 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true }, "yaml": { "version": "1.8.3", diff --git a/package.json b/package.json index 5e9ebcb9..9e3158fa 100644 --- a/package.json +++ b/package.json @@ -26,12 +26,10 @@ "events-async": "^1.2.1", "express": "^4.13.4", "glob": "^7.0.3", - "lru-cache": "^4.0.1", "request": "^2.88.0" }, "devDependencies": { "eventsource": "^0.2.1", - "lolex": "^1.5.1", "nock": "^12.0.3", "nodemon": "^2.0.4", "proxyquire": "^1.7.10", diff --git a/test/_fixtures/repo-labels-page-2.json b/test/_fixtures/repo-labels-page-2.json deleted file mode 100644 index ad0ccb5c..00000000 --- a/test/_fixtures/repo-labels-page-2.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "data": [ - { - "id": 280213872, - "url": "https://api.github.com/repos/nodejs/node/labels/v0.12", - "name": "v0.12", - "color": "c7def8", - "default": false - }, - { - "id": 280213880, - "url": "https://api.github.com/repos/nodejs/node/labels/v4.x", - "name": "v4.x", - "color": "eb6420", - "default": false - }, - { - "id": 441404503, - "url": "https://api.github.com/repos/nodejs/node/labels/v7.x", - "name": "v7.x", - "color": "fbca04", - "default": false - }, - { - "id": 176191361, - "url": "https://api.github.com/repos/nodejs/node/labels/V8 Engine", - "name": "V8 Engine", - "color": "0052cc", - "default": false - }, - { - "id": 386816750, - "url": "https://api.github.com/repos/nodejs/node/labels/V8_inspector", - "name": "V8_inspector", - "color": "ededed", - "default": false - }, - { - "id": 155436007, - "url": "https://api.github.com/repos/nodejs/node/labels/vm", - "name": "vm", - "color": "bfdadc", - "default": false - }, - { - "id": 166236401, - "url": "https://api.github.com/repos/nodejs/node/labels/windows", - "name": "windows", - "color": "9944dd", - "default": false - }, - { - "id": 151728680, - "url": "https://api.github.com/repos/nodejs/node/labels/wontfix", - "name": "wontfix", - "color": "ededed", - "default": true - }, - { - "id": 155436008, - "url": "https://api.github.com/repos/nodejs/node/labels/zlib", - "name": "zlib", - "color": "009800", - "default": false - } - ], - "meta": { - "x-ratelimit-limit":"60", - "x-ratelimit-remaining":"52", - "x-ratelimit-reset":"1531354196", - "x-github-request-id":"EBA1:936F:5CE9930:7925DDD:5B4692FA", - "x-github-media-type":"github.v3; format=json", - "link":"; rel=\"prev\", ; rel=\"first\"", - "etag":"\"9408108c2d89606f9539deefc6d90acd\"", - "status":"200 OK" - } -} diff --git a/test/_fixtures/repo-labels.json b/test/_fixtures/repo-labels.json deleted file mode 100644 index b3d5e759..00000000 --- a/test/_fixtures/repo-labels.json +++ /dev/null @@ -1,179 +0,0 @@ -{ - "data": [ - { - "url": "https://api.github.com/repos/nodejs/node/labels/confirmed-bug", - "name": "confirmed-bug", - "color": "fc2929" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/duplicate", - "name": "duplicate", - "color": "ededed" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/help%20wanted", - "name": "help wanted", - "color": "159818" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/invalid", - "name": "invalid", - "color": "ededed" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/question", - "name": "question", - "color": "cc317c" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/wontfix", - "name": "wontfix", - "color": "ededed" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/in%20progress", - "name": "in progress", - "color": "ededed" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/tls", - "name": "tls", - "color": "fad8c7" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/crypto", - "name": "crypto", - "color": "009800" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/buffer", - "name": "buffer", - "color": "f7c6c7" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/http", - "name": "http", - "color": "c7def8" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/https", - "name": "https", - "color": "0052cc" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/assert", - "name": "assert", - "color": "d4c5f9" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/util", - "name": "util", - "color": "d4c5f9" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/cluster", - "name": "cluster", - "color": "f7c6c7" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/child_process", - "name": "child_process", - "color": "f7c6c7" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/dgram", - "name": "dgram", - "color": "fbca04" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/c++", - "name": "c++", - "color": "e11d21" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/doc", - "name": "doc", - "color": "006b75" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/debugger", - "name": "debugger", - "color": "bfd4f2" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/dns", - "name": "dns", - "color": "fbca04" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/domain", - "name": "domain", - "color": "e11d21" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/events", - "name": "events", - "color": "bfdadc" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/fs", - "name": "fs", - "color": "0052cc" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/module", - "name": "module", - "color": "fbca04" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/net", - "name": "net", - "color": "eb6420" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/os", - "name": "os", - "color": "d4c5f9" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/querystring", - "name": "querystring", - "color": "5319e7" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/readline", - "name": "readline", - "color": "d4c5f9" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/repl", - "name": "repl", - "color": "5319e7" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/V8 Engine", - "name": "V8 Engine", - "color": "0052cc" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/timers", - "name": "timers", - "color": "f7c6c7" - }, - { - "url": "https://api.github.com/repos/nodejs/node/labels/v6.x", - "name": "v6.x", - "color": "c2e0c6" - } - ], - "meta": { - "x-ratelimit-limit":"60", - "x-ratelimit-remaining":"53", - "x-ratelimit-reset":"1531354196", - "x-github-request-id":"EB9F:936D:4E2E967:6642386:5B469223", - "x-github-media-type":"github.v3; format=json", - "link":"; rel=\"next\", ; rel=\"last\"", - "etag":"\"86cc32d7673902f0b0774ab892d78f14\"", - "status":"200 OK" - } -} diff --git a/test/unit/node-build-label.test.js b/test/unit/node-build-label.test.js deleted file mode 100644 index c159dab5..00000000 --- a/test/unit/node-build-label.test.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict' - -const tap = require('tap') - -const nodeLabels = require('../../lib/node-labels') - -tap.test('label: "build" when build related files has been changed', (t) => { - const buildRelatedFiles = [ - 'configure', - 'node.gyp', - 'common.gypi', - 'BSDmakefile', - 'Makefile', - 'tools/Makefile', - 'tools/install.py', - 'tools/create_android_makefiles', - 'tools/genv8constants.py', - 'tools/getnodeversion.py', - 'tools/js2c.py', - 'tools/utils.py', - 'tools/configure.d/nodedownload.py' - ] - - buildRelatedFiles.forEach((filepath) => { - const labels = nodeLabels.resolveLabels([ filepath ]) - - t.ok(labels.includes('build'), filepath + ' should have "build" label') - t.ok(labels.includes('needs-ci'), filepath + ' should have "needs-ci" label') - }) - - t.end() -}) - -tap.test('labels: not "build" when Makefile in ./deps has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'deps/v8/Makefile' - ]) - - t.notOk(labels.includes('build')) - t.ok(labels.includes('needs-ci')) - - t.end() -}) diff --git a/test/unit/node-js-subsystem-labels.test.js b/test/unit/node-js-subsystem-labels.test.js deleted file mode 100644 index b2ac8df0..00000000 --- a/test/unit/node-js-subsystem-labels.test.js +++ /dev/null @@ -1,179 +0,0 @@ -/* eslint-disable no-multi-spaces */ -'use strict' - -const tap = require('tap') - -const nodeLabels = require('../../lib/node-labels') - -tap.test('label: lib oddities', (t) => { - const libFiles = [ - 'lib/_debug_agent.js', - 'lib/_http_agent.js', - 'lib/_http_client.js', - 'lib/_http_common.js', - 'lib/_http_incoming.js', - 'lib/_http_outgoing.js', - 'lib/_http_server.js', - 'lib/_linklist.js', - 'lib/_stream_duplex.js', - 'lib/_stream_passthrough.js', - 'lib/_stream_readable.js', - 'lib/_stream_transform.js', - 'lib/_stream_wrap.js', - 'lib/_stream_writable.js', - 'lib/_tls_common.js', - 'lib/_tls_legacy.js', - 'lib/_tls_wrap.js', - 'lib/constants.js', - 'lib/punycode.js', // ignored - 'lib/sys.js', // ignored - 'lib/internal/freelist.js', // ignored - 'lib/internal/process', - 'lib/internal/readme.md', // ignored - 'lib/internal/socket_list.js', - 'lib/internal/v8_prof_polyfill.js', - 'lib/internal/v8_prof_processor.js' - ] - - const labels = nodeLabels.resolveLabels(libFiles, false) - - t.same(labels, [ - 'needs-ci', // lib/ - 'debugger', // _debug_agent - 'http', // _http_* - 'timers', // linklist - 'stream', // _stream_* - 'tls', // _tls_* - 'lib / src', // constants - 'process', // internal/process/ - 'net', // socket_list - 'tools' // v8_prof_* - ]) - - t.end() -}) - -tap.test('label: lib internals oddities duplicates', (t) => { - const libFiles = [ - 'lib/internal/bootstrap_node.js', - 'lib/internal/linkedlist.js', - 'lib/internal/streams' - ] - - const labels = nodeLabels.resolveLabels(libFiles) - - t.same(labels, [ - 'needs-ci', // lib/ - 'lib / src', // bootstrap_node - 'timers', // linkedlist - 'stream' // internal/streams/ - ]) - - t.end() -}) - -tap.test('label: lib normal without "lib / src" limiting', (t) => { - const libFiles = [ - 'lib/_debugger.js', - 'lib/assert.js', - 'lib/buffer.js', - 'lib/child_process.js', - 'lib/cluster.js', - 'lib/console.js', - 'lib/crypto.js', - 'lib/dgram.js', - 'lib/dns.js', - 'lib/domain.js', - 'lib/events.js', - 'lib/fs.js', - 'lib/http.js', - 'lib/https.js', - 'lib/module.js', - 'lib/net.js', - 'lib/os.js', - 'lib/path.js', - 'lib/process.js', - 'lib/querystring.js', - 'lib/readline.js', - 'lib/repl.js', - 'lib/stream.js', - 'lib/string_decoder.js', - 'lib/timers.js', - 'lib/tls.js', - 'lib/tty.js', - 'lib/url.js', - 'lib/util.js', - 'lib/v8.js', - 'lib/vm.js', - 'lib/zlib.js' - ] - - const labels = nodeLabels.resolveLabels(libFiles, false) - - t.same(labels.shift(), 'needs-ci') - t.same(labels, libFiles.map((path) => /lib\/(_)?(\w+)\.js/.exec(path)[2])) - - t.end() -}) - -tap.test('label: lib internals without "lib / src" limiting', (t) => { - const libFiles = [ - 'lib/internal/child_process.js', - 'lib/internal/cluster.js', - 'lib/internal/module.js', - 'lib/internal/net.js', - 'lib/internal/process.js', - 'lib/internal/readline.js', - 'lib/internal/repl.js', - 'lib/internal/util.js' - ] - - const labels = nodeLabels.resolveLabels(libFiles, false) - - t.same(labels.shift(), 'needs-ci') - t.same(labels, libFiles.map((path) => /lib\/internal\/(\w+)\.js/.exec(path)[1])) - - t.end() -}) - -tap.test('label: add subsystem when ./doc/api/.md has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'doc/api/fs.md' - ], false) - - t.same(labels, ['doc', 'fs']) - - t.end() -}) - -tap.test('label: only "doc" with multiple API doc files changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'doc/api/fs.md', - 'doc/api/stream.md' - ], false) - - t.same(labels, ['doc']) - - t.end() -}) - -tap.test('label: "doc,module" when doc/api/modules.md was changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'doc/api/modules.md' - ], false) - - t.same(labels, ['doc', 'module']) - - t.end() -}) - -tap.test('label: appropriate labels for files in internal subdirectories', (t) => { - const labels = nodeLabels.resolveLabels([ - 'lib/internal/cluster/master.js', - 'lib/internal/process/next_tick.js' - ], false) - - t.same(labels, ['needs-ci', 'cluster', 'process']) - - t.end() -}) diff --git a/test/unit/node-labels.test.js b/test/unit/node-labels.test.js deleted file mode 100644 index 73ed28f8..00000000 --- a/test/unit/node-labels.test.js +++ /dev/null @@ -1,726 +0,0 @@ -'use strict' - -const tap = require('tap') - -const nodeLabels = require('../../lib/node-labels') - -tap.test('label: "needs-ci" when ./test/ and ./doc/ files has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'test/debugger/test-debugger-pid.js', - 'doc/api/fs.md' - ]) - - t.same(labels, ['needs-ci']) - - t.end() -}) - -// This ensures older mislabelling issues doesn't happen again -// https://github.com/nodejs/node/pull/6432 -// https://github.com/nodejs/node/pull/6448 -tap.test('label: "needs-ci" when ./test/ and ./lib/ files has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'lib/punycode.js', - 'test/parallel/test-assert.js' - ]) - - t.same(labels, ['needs-ci']) - - t.end() -}) - -tap.test('label: "doc" when only ./doc/ files has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'doc/api/fs.md', - 'doc/api/http.md', - 'doc/onboarding.md' - ]) - - t.same(labels, ['doc']) - - t.end() -}) - -tap.test('label: "doc" and "crypto" when webcrypto docs have been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'doc/api/webcrypto.md' - ]) - - t.same(labels, ['doc', 'crypto']) - - t.end() -}) - -tap.test('label: "doc" & "deprecations" when ./doc/api/deprecations.md has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'doc/api/deprecations.md' - ]) - - t.same(labels, ['doc', 'deprecations']) - - t.end() -}) - -tap.test('label: "c++" when ./src/* has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'src/node.cc' - ]) - - t.same(labels, ['needs-ci', 'c++']) - - t.end() -}) - -const srcCases = [ - ['async_wrap', ['async-wrap-inl.h', 'async-wrap.h', 'async-wrap.cc']], - ['buffer', - ['base64.h', - 'node_buffer.cc', - 'node_buffer.h', - 'string_bytes.cc', - 'string_bytes.h', - 'string_search.cc', - 'string_search.h']], - ['cares', ['cares_wrap.cc']], - ['child_process', ['process_wrap.cc', 'spawn_sync.cc', 'spawn_sync.h']], - ['crypto', - ['node_crypto.cc', - 'node_crypto.h', - 'node_crypto_bio.cc', - 'node_crypto_bio.h', - 'node_crypto_clienthello-inl.h', - 'node_crypto_clienthello.cc', - 'node_crypto_clienthello.h', - 'node_crypto_groups.h']], - ['debugger', ['debug-agent.cc', 'debug-agent.h', 'node_debug_options.cc']], - ['dgram', ['udp_wrap.cc', 'udp_wrap.h']], - ['fs', - ['fs_event_wrap.cc', - 'node_file.cc', - 'node_file.h', - 'node_stat_watcher.cc', - 'node_stat_watcher.h']], - ['http_parser', ['node_http_parser.cc', 'node_http_parser.h']], - ['intl', ['node_i18n.cc', 'node_i18n.h']], - ['libuv', ['uv.cc']], - ['net', - ['connect_wrap.cc', - 'connect_wrap.h', - 'connection_wrap.cc', - 'connection_wrap.h', - 'pipe_wrap.cc', - 'pipe_wrap.h', - 'tcp_wrap.cc', - 'tcp_wrap.h']], - ['os', ['node_os.cc']], - ['process', ['node_main.cc', 'signal_wrap.cc']], - ['timers', ['timer_wrap.cc']], - ['tracing', - ['tracing/agent.cc', - 'tracing/agent.h', - 'tracing/node_trace_buffer.cc', - 'tracing/node_trace_buffer.h', - 'tracing/node_trace_writer.cc', - 'tracing/node_trace_writer.h', - 'tracing/trace_event.cc', - 'tracing/trace_event.h']], - ['tls', - ['CNNICHashWhitelist.inc', - 'node_root_certs.h', - 'tls_wrap.cc', - 'tls_wrap.h']], - ['tty', ['tty_wrap.cc', 'tty_wrap.h']], - [['url-whatwg'], - ['node_url.cc', 'node_url.h']], - ['util', ['node_util.cc']], - ['V8 Engine', ['node_v8.cc', 'v8abbr.h']], - ['vm', ['node_contextify.cc']], - ['windows', - ['backtrace_win32.cc', - 'node_win32_etw_provider-inl.h', - 'node_win32_etw_provider.cc', - 'node_win32_etw_provider.h', - 'node_win32_perfctr_provider.cc', - 'node_win32_perfctr_provider.h']], - ['zlib', ['node_zlib.cc']] -] -for (const info of srcCases) { - let labels = info[0] - if (!Array.isArray(labels)) { - labels = [labels] - } - const files = info[1] - for (const file of files) { - tap.test(`label: "${labels.join('","')}" when ./src/${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([`src/${file}`]) - - t.same(resolved, ['needs-ci', 'c++'].concat(labels)) - - t.end() - }) - } -} - -tap.test('label: not "c++" when ./src/node_version.h has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'src/node_version.h' - ]) - - t.same(labels, ['needs-ci']) - - t.end() -}) - -tap.test('label: not "c++" when ./src/*.py has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'src/nolttng_macros.py', - 'src/notrace_macros.py', - 'src/perfctr_macros.py' - ]) - - t.same(labels, ['needs-ci', 'lib / src']) - - t.end() -}) - -tap.test('label: "inspector" when ./src/inspector_* has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'src/inspector_socket.cc' - ]) - - t.same(labels, ['needs-ci', 'c++', 'inspector']) - - t.end() -}) - -tap.test('label: "V8 Engine" when ./deps/v8/ files has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'deps/v8/src/arguments.cc' - ]) - - t.same(labels, ['needs-ci', 'V8 Engine']) - - t.end() -}) - -tap.test('label: "libuv" when ./deps/uv/ files has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'deps/uv/src/fs-poll.c' - ]) - - t.same(labels, ['needs-ci', 'libuv']) - - t.end() -}) - -tap.test('label: "wasi" when ./deps/uvwasi/ files has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'deps/uvwasi/src/uvwasi.c' - ]) - - t.same(labels, ['needs-ci', 'wasi']) - - t.end() -}) - -tap.test('label: "V8 Engine", "openssl" when ./deps/v8/ and ./deps/openssl/ files has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'deps/v8/src/arguments.cc', - 'deps/openssl/openssl/ssl/ssl_rsa.c' - ]) - - t.same(labels, ['needs-ci', 'V8 Engine', 'openssl']) - - t.end() -}) - -// -// Planned tests to be resolved later -// - -tap.test('label: "repl" when ./lib/repl.js has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'lib/repl.js', - 'test/debugger/test-debugger-pid.js', - 'test/debugger/test-debugger-repl-break-in-module.js', - 'test/debugger/test-debugger-repl-term.js' - ]) - - t.same(labels, ['needs-ci', 'repl']) - - t.end() -}) - -tap.test('label: "lib / src" when 4 or more JS sub-systems have been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'lib/assert.js', - 'lib/dns.js', - 'lib/repl.js', - 'lib/process.js', - 'lib/module.js' - ]) - - t.same(labels, ['needs-ci', 'lib / src']) - - t.end() -}) - -// https://github.com/nodejs/node/pull/12366 should have been labelled "lib / src" -// https://github.com/nodejs/github-bot/issues/137 -tap.test('label: "lib / src" when 4 or more native files have been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'node.gyp', - 'src/cares_wrap.cc', - 'src/fs_event_wrap.cc', - 'src/node.cc', - 'src/node_api.cc', - 'src/node_buffer.cc', - 'src/node_config.cc', - 'src/node_constants.cc', - 'src/node_contextify.cc', - 'src/node_file.cc', - 'src/node_file.h', - 'src/node_http_parser.cc', - 'src/node_http_parser.h', - 'src/node_i18n.cc', - 'src/node_revert.cc', - 'src/node_serdes.cc', - 'src/node_zlib.cc', - 'src/process_wrap.cc', - 'src/signal_wrap.cc', - 'src/string_bytes.cc', - 'src/timer_wrap.cc', - 'src/uv.cc' - ]) - - t.same(labels, ['needs-ci', 'c++', 'lib / src']) - - t.end() -}) - -// https://github.com/nodejs/node/pull/7488 wrongfully labelled with "lib / src" -tap.test('label: not "lib / src" when only deps have been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden', - 'deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiteralsWide.golden', - 'deps/v8/test/cctest/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden', - 'deps/v8/test/cctest/interpreter/bytecode_expectations/BasicBlockToBoolean.golden', - 'deps/v8/test/cctest/interpreter/bytecode_expectations/BasicLoops.golden' - ]) - - t.same(labels, ['needs-ci', 'V8 Engine']) - - t.end() -}) - -tap.test('label: "JS sub-systems when less than 4 sub-systems have changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'lib/assert.js', - 'lib/dns.js', - 'lib/repl.js', - 'lib/process.js' - ]) - - t.same(labels, ['needs-ci', 'assert', 'dns', 'repl', 'process']) - - t.end() -}) - -tap.test('label: "meta" when meta-info files have changed', (t) => { - // e.g. LICENSE, AUTHORS, some ./*.md files - const labels = nodeLabels.resolveLabels([ - '.gitattributes', - '.gitignore', - '.mailmap', - 'AUTHORS', - 'LICENSE', - 'CHANGELOG.md', - 'CODE_OF_CONDUCT.md', - 'GOVERNANCE.md', - 'ROADMAP.md', - 'WORKING_GROUPS.md' - ]) - - t.same(labels, ['meta']) - - t.end() -}) - -tap.test('label: not "meta" when other top-level have been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'BUILDING.md', - 'README.md', - 'COLLABORATOR_GUIDE.md', - 'CONTRIBUTING.md', - 'configure' - ]) - - t.same(labels.indexOf('meta'), -1) - - t.end() -}) - -tap.test('label: "doc" when top-level .md files have changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'BUILDING.md', - 'README.md' - ]) - - t.same(labels, ['build', 'doc']) - - t.end() -}) - -tap.test('label: not "doc" when other top-level files have been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'LICENSE', - 'configure', - '.mailmap' - ]) - - t.same(labels.indexOf('doc'), -1) - - t.end() -}) - -tap.test('label: version labels (old)', (t) => { - const labels = nodeLabels.resolveLabels([ - 'common.gypi' - ], 'v0.12') - - t.same(labels, ['build', 'needs-ci', 'v0.12']) - - t.end() -}) - -tap.test('label: version labels (old, staging)', (t) => { - const labels = nodeLabels.resolveLabels([ - 'common.gypi' - ], 'v0.12-staging') - - t.same(labels, ['build', 'needs-ci', 'v0.12']) - - t.end() -}) - -tap.test('label: version labels (new)', (t) => { - const labels = nodeLabels.resolveLabels([ - 'deps/v8/include/v8-version.h', - 'deps/v8/src/crankshaft/hydrogen.cc', - 'deps/v8/test/mjsunit/regress/regress-5033.js' - ], 'v6.x') - - t.same(labels, ['needs-ci', 'V8 Engine', 'v6.x']) - - t.end() -}) - -tap.test('label: version labels (new, staging)', (t) => { - const labels = nodeLabels.resolveLabels([ - 'deps/v8/include/v8-version.h', - 'deps/v8/src/crankshaft/hydrogen.cc', - 'deps/v8/test/mjsunit/regress/regress-5033.js' - ], 'v6.x-staging') - - t.same(labels, ['needs-ci', 'V8 Engine', 'v6.x']) - - t.end() -}) - -tap.test('label: no version labels (master)', (t) => { - const labels = nodeLabels.resolveLabels([ - 'deps/v8/include/v8-version.h', - 'deps/v8/src/crankshaft/hydrogen.cc', - 'deps/v8/test/mjsunit/regress/regress-5033.js' - ], 'master') - - t.same(labels, ['needs-ci', 'V8 Engine']) - - t.end() -}) - -tap.test('label: build label (windows)', (t) => { - const labels = nodeLabels.resolveLabels([ - 'vcbuild.bat' - ]) - - t.same(labels, ['build', 'windows', 'needs-ci']) - - t.end() -}) - -tap.test('label: doc label for non-subsystem API doc changes', (t) => { - const labels = nodeLabels.resolveLabels([ - 'doc/api/_toc.md', - 'doc/api/all.md' - ]) - - t.same(labels, ['doc']) - - t.end() -}) - -const specificBenchmarks = [ - [[], ['fixtures/alice.html', 'misc/freelist.js']], - ['assert', ['assert/deepequal-buffer.js']], - ['buffer', ['buffers/buffer-base64-decode.js']], - ['child_process', ['child_process/child-process-exec-stdout.js']], - ['crypto', ['crypto/aes-gcm-throughput.js']], - ['dgram', ['dgram/bind-params.js']], - ['domain', ['domain/domain-fn-args.js']], - ['events', ['events/ee-emit.js']], - ['fs', ['fs/readfile.js']], - ['http', ['_http-benchmarkers.js', 'http/simple.js']], - ['module', ['module/module-loader.js']], - ['net', ['net/net-c2s.js']], - ['os', ['os/loadavg.js']], - ['path', ['path/basename-posix.js']], - ['process', ['process/memoryUsage.js']], - ['querystring', ['querystring/querystring-parse.js']], - ['stream', ['streams/readable-readall.js']], - ['string_decoder', ['string_decoder/string-decoder.js']], - ['timers', ['timers/set-immediate-depth.js']], - ['tls', ['tls/throughput.js']], - ['url', ['url/url-resolve.js']], - ['util', ['util/format.js']], - ['V8 Engine', ['arrays/var-int.js', 'es/defaultparams-bench.js']], - ['vm', ['vm/run-in-context.js']] -] -for (const info of specificBenchmarks) { - let labels = info[0] - if (!Array.isArray(labels)) { - labels = ['benchmark', labels] - } else { - labels = ['benchmark'].concat(labels) - } - const files = info[1] - for (const file of files) { - tap.test(`label: "${labels.join('","')}" when ./benchmark/${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([`benchmark/${file}`]) - - t.same(resolved, labels) - - t.end() - }) - } -} - -const moreTools = [ - '.eslintignore', '.editorconfig', '.eslintrc.yaml', '.remarkrc' -] -for (const file of moreTools) { - tap.test(`label: "tools" when ${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([`${file}`]) - - t.same(resolved, ['tools']) - - t.end() - }) -} - -const specificTests = [ - ['addons', ['addons/async-hello-world/binding.cc']], - ['debugger', ['debugger/test-debugger-repl.js']], - [['doc', 'tools'], ['doctool/test-doctool-html.js']], - [['inspector'], - ['inspector/test-inspector.js', 'cctest/test_inspector_socket.cc']], - ['timers', ['timers/test-timers-reliability.js']], - ['tty', ['pseudo-tty/stdin-setrawmode.js']], - [['url-whatwg'], - ['cctest/test_url.cc']] -] -for (const info of specificTests) { - let labels = info[0] - if (!Array.isArray(labels)) { - labels = ['needs-ci', 'test', labels] - } else { - labels = ['needs-ci', 'test'].concat(labels) - } - const files = info[1] - for (const file of files) { - tap.test(`label: "${labels.join('","')}" when ./test/${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([`test/${file}`]) - - t.same(resolved, labels) - - t.end() - }) - } -} - -const specificTools = [ - [['build', 'needs-ci'], ['gyp/gyp_main.py', 'gyp_node.py']], - ['doc', ['doc/generate.js']], - [['intl', 'needs-ci'], ['icu/icu-generate.gyp']], - ['macos', - ['macosx-firewall.sh', - 'osx-codesign.sh']], - [['macos', 'install'], - ['osx-pkg.pmdoc/index.xml.tmpl', - 'pkgsrc/description']], - [['test', 'npm'], ['test-npm.sh', 'test-npm-package.js']], - [['test'], ['test.py']], - [['openssl', 'tls'], ['certdata.txt', 'mkssldef.py', 'mk-ca-bundle.pl']], - [['windows', 'needs-ci'], ['sign.bat']], - [['windows', 'install', 'needs-ci'], ['msvs/msi/product.wxs']], - [['V8 Engine', 'needs-ci'], ['make-v8.sh']] -] -for (const info of specificTools) { - let labels = info[0] - if (!Array.isArray(labels)) { - labels = ['tools', labels] - } else { - labels = ['tools'].concat(labels) - } - const files = info[1] - for (const file of files) { - tap.test(`label: "${labels.join('","')}" when ./tools/${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([`tools/${file}`]) - - t.same(resolved, labels) - - t.end() - }) - } -} - -[ - [['needs-ci', 'V8 Engine', 'post-mortem'], - ['deps/v8/tools/gen-postmortem-metadata.py']], - [['needs-ci', 'c++', 'n-api'], - ['src/node_api.cc', 'src/node_api.h', 'src/node_api_types.h']], - [['needs-ci', 'test', 'n-api'], - ['test/addons-napi/foo']], - [['doc', 'n-api'], - ['doc/api/n-api.md']] -].forEach((info) => { - const labels = info[0] - const files = info[1] - for (const file of files) { - tap.test(`label: "${labels.join('","')}" when ./${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([file]) - - t.same(resolved, labels) - - t.end() - }) - } -}); - -[ - [['needs-ci', 'async_hooks'], ['lib/async_hooks.js']], - [['needs-ci', 'test', 'async_hooks'], ['test/async-hooks/test-connection.ssl.js']] -].forEach((info) => { - const labels = info[0] - const files = info[1] - for (const file of files) { - tap.test(`label: "${labels.join('","')}" when ./${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([file]) - - t.same(resolved, labels) - - t.end() - }) - } -}) - -tap.test('label: "build" when ./android-configure has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - 'android-configure' - ]) - - t.same(labels, ['build', 'needs-ci']) - - t.end() -}) - -tap.test('label: "build" when ./.travis.yml has been changed', (t) => { - const labels = nodeLabels.resolveLabels([ - '.travis.yml' - ]) - - t.same(labels, ['build', 'needs-ci']) - - t.end() -}); - -[ - [['needs-ci', 'http2', 'dont-land-on-v6.x'], - ['lib/http2.js', - 'lib/internal/http2/core.js', - 'deps/nghttp2/lib/nghttp2_buf.c']], - [['needs-ci', 'c++', 'http2', 'dont-land-on-v6.x'], - ['src/node_http2.cc', - 'src/node_http2.h', - 'src/node_http2_core.h', - 'src/node_http2_core-inl.h']], - [['needs-ci', 'build', 'http2', 'dont-land-on-v6.x'], - ['deps/nghttp2/nghttp2.gyp']], - [['doc', 'http2'], ['doc/api/http2.md']] -].forEach((info) => { - const labels = info[0] - const files = info[1] - for (const file of files) { - tap.test(`label: "${labels.join('","')}" when ./${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([file]) - - t.same(resolved, labels) - - t.end() - }) - } -}); - -[ - [['needs-ci', 'c++', 'report'], - ['src/node_report.cc', - 'src/node_report.h', - 'src/node_report_module.cc', - 'src/node_report_utils.cc']], - [['doc', 'report'], ['doc/api/report.md']], - [['needs-ci', 'test', 'report'], ['test/report/test-report-config.js']] -].forEach((info) => { - const labels = info[0] - const files = info[1] - for (const file of files) { - tap.test(`label: "${labels.join('","')}" when ./${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([file]) - - t.same(resolved, labels) - - t.end() - }) - } -}); - -[ - // wasi - [['needs-ci', 'wasi'], - ['lib/wasi.js']], - [['needs-ci', 'c++', 'wasi'], - ['src/node_wasi.cc', - 'src/node_wasi.h']], - [['doc', 'wasi'], ['doc/api/wasi.md']], - - // worker - [['needs-ci', 'worker'], - ['lib/worker_threads.js', - 'lib/internal/worker.js', - 'lib/internal/worker/io.js']], - [['needs-ci', 'c++', 'worker'], - ['src/node_worker.cc', - 'src/node_worker.h']], - [['doc', 'worker'], ['doc/api/worker_threads.md']] -].forEach((info) => { - const labels = info[0] - const files = info[1] - for (const file of files) { - tap.test(`label: "${labels.join('","')}" when ./${file} has been changed`, (t) => { - const resolved = nodeLabels.resolveLabels([file]) - - t.same(resolved, labels) - - t.end() - }) - } -}) diff --git a/test/unit/node-repo.test.js b/test/unit/node-repo.test.js index 1efcba95..32d12312 100644 --- a/test/unit/node-repo.test.js +++ b/test/unit/node-repo.test.js @@ -1,7 +1,6 @@ 'use strict' const tap = require('tap') -const lolex = require('lolex') const nock = require('nock') const nodeRepo = require('../../lib/node-repo') @@ -10,91 +9,6 @@ const logger = require('../../lib/logger') const readFixture = require('../read-fixture') const { ignoreQueryParams } = require('../common') -tap.test('fetchExistingLabels(): caches existing repository labels', async (t) => { - const owner = 'nodejs' - const repo = 'node1' - // Test passes if nock is only called once, no other checks to run - const scope = nock('https://api.github.com') - .filteringPath(ignoreQueryParams) - .get(`/repos/${owner}/${repo}/labels`) - .once() // should only be called once - .reply(200, []) - - await nodeRepo._fetchExistingLabels({ owner, repo, logger }) - await nodeRepo._fetchExistingLabels({ owner, repo, logger }) - scope.done() -}) - -tap.test('fetchExistingLabels(): cache expires after one hour', async (t) => { - const owner = 'nodejs' - const repo = 'node2' - const clock = lolex.install() - - // Test passes if nock is only called once, no other checks to run - const scope = nock('https://api.github.com') - .filteringPath(ignoreQueryParams) - .get(`/repos/${owner}/${repo}/labels`) - .twice() // should be called twice - .reply(200, []) - - t.tearDown(() => { - clock.uninstall() - }) - - await nodeRepo._fetchExistingLabels({ owner, repo, logger }) - - // fetch labels again after 1 hour and 1 minute - clock.tick(1000 * 60 * 61) - - await nodeRepo._fetchExistingLabels({ owner, repo, logger }) - scope.done() -}) - -tap.test('fetchExistingLabels(): yields an array of existing label names', async (t) => { - const labelsFixture = readFixture('repo-labels.json') - const owner = 'nodejs' - const repo = 'node3' - - const scope = nock('https://api.github.com') - .filteringPath(ignoreQueryParams) - .get(`/repos/${owner}/${repo}/labels`) - .reply(200, labelsFixture.data) - - t.plan(1) - - const existingLabels = await nodeRepo._fetchExistingLabels({ owner, repo, logger }) - t.ok(existingLabels.includes('cluster')) - scope.done() -}) - -tap.test('fetchExistingLabels(): can retrieve more than 100 labels', async (t) => { - const labelsFixturePage1 = readFixture('repo-labels.json') - const labelsFixturePage2 = readFixture('repo-labels-page-2.json') - const owner = 'nodejs' - const repo = 'node4' - const headers = { - 'Link': `; rel="next"` - } - - const firstPageScope = nock('https://api.github.com') - .filteringPath(ignoreQueryParams) - .get(`/repos/${owner}/${repo}/labels`) - .reply(200, labelsFixturePage1.data, headers) - - const secondPageScope = nock('https://api.github.com') - .get(`/repos/${owner}/${repo}/labels`) - .query({ page: 2, per_page: 100 }) - .reply(200, labelsFixturePage2.data) - - t.plan(2) - - const existingLabels = await nodeRepo._fetchExistingLabels({ owner, repo, logger }) - t.ok(existingLabels.includes('cluster')) - t.ok(existingLabels.includes('windows')) - firstPageScope.done() - secondPageScope.done() -}) - tap.test('getBotPrLabels(): returns labels added by nodejs-github-bot', (t) => { const events = readFixture('pull-request-events.json')