diff --git a/.github/workflows/docs-review-collect.yml b/.github/workflows/docs-review-collect.yml index cf89d2f129..afa5815dc6 100644 --- a/.github/workflows/docs-review-collect.yml +++ b/.github/workflows/docs-review-collect.yml @@ -1,7 +1,7 @@ name: Add docs-reviewers request to the docs-content review board # **What it does**: Adds PRs in github/github and github/audit-log-allowlists that requested a review from docs-reviewers to the docs-content review board -# **Why we have it**: To catch docs-reviewers requests in github/github and github/audit-log-allowlists +# **Why we have it**: To catch docs-reviewers requests in github/audit-log-allowlists # **Who does it impact**: docs-content maintainers on: @@ -31,17 +31,6 @@ jobs: - name: Install dependencies run: npm install @octokit/graphql - - name: Run script for github - run: | - node src/workflows/fr-add-docs-reviewers-requests.js - env: - TOKEN: ${{ secrets.DOCS_BOT_PAT_WRITEORG_PROJECT }} - PROJECT_NUMBER: 2936 - ORGANIZATION: 'github' - REPO: 'github' - REVIEWER: 'docs-reviewers' - FEATURE: 'OpenAPI schema update' - - name: Run script for audit-log-allowlists run: | node src/workflows/fr-add-docs-reviewers-requests.js diff --git a/.github/workflows/ready-for-doc-review.yml b/.github/workflows/ready-for-doc-review.yml index 958ee59a60..a995e5acc0 100644 --- a/.github/workflows/ready-for-doc-review.yml +++ b/.github/workflows/ready-for-doc-review.yml @@ -1,8 +1,8 @@ name: Ready for docs-content review -# **What it does**: Adds pull requests in the docs-internal repository to the docs-content review board when the "ready-for-doc-review" label is added or when a review by docs-content is requested +# **What it does**: Adds pull requests in the docs-internal repository to the docs-content review board when the "ready-for-doc-review" label is added or when a review by docs-content or docs-reviewers is requested. This workflow is also called as a reusable workflow from other repos including docs-content, docs-strategy, docs-early-access, and github. # **Why we have it**: So that other GitHub teams can easily request reviews from the docs-content team, and so that writers can see when a PR is ready for review -# **Who does it impact**: Writers working in the docs-internal repository +# **Who does it impact**: Writers who need to review docs-related PRs on: pull_request: @@ -16,8 +16,8 @@ jobs: request_doc_review: name: Request a review from the docs-content team if: >- - github.repository_owner == 'github' && github.repository != 'github/docs' && - (github.event.label.name == 'ready-for-doc-review' || github.event.requested_team.name == 'docs-content') + github.repository_owner == 'github' && github.repository != 'github/docs' && + (github.event.label.name == 'ready-for-doc-review' || github.event.requested_team.name == 'docs-content' || github.event.requested_team.name == 'docs-reviewers') runs-on: ubuntu-latest steps: - name: Check out repo content diff --git a/src/workflows/projects.js b/src/workflows/projects.js index 63deb83d99..afbc248a07 100644 --- a/src/workflows/projects.js +++ b/src/workflows/projects.js @@ -273,6 +273,116 @@ export function generateUpdateProjectV2ItemFieldMutation({ return mutation } +// Guess the affected docs sets based on the files that the PR changed +export function getFeature(data) { + // For issues, just use an empty string + if (data.item.__typename !== 'PullRequest') { + return '' + } + + const paths = data.item.files.nodes.map((node) => node.path) + + // For docs and docs-internal and docs-early-access PRs, + // determine the affected docs sets by looking at which + // directories under `content/` were affected. + // (Ignores changes to the data files.) + if ( + process.env.REPO === 'github/docs-internal' || + process.env.REPO === 'github/docs' || + process.env.REPO === 'github/docs-early-access' + ) { + const features = new Set([]) + paths.forEach((path) => { + const pathComponents = path.split('/') + if (pathComponents[0] === 'content') { + features.add(pathComponents[1]) + } + }) + const feature = Array.from(features).join() + + return feature + } + + // for github/github PRs, try to classify the OpenAPI files + if (process.env.REPO === 'github/github') { + const features = new Set([]) + if (paths.some((path) => path.startsWith('app/api/description'))) { + features.add('OpenAPI') + paths.forEach((path) => { + if (path.startsWith('app/api/description/operations')) { + features.add(path.split('/')[4]) + features.add('rest') + } + if (path.startsWith('app/api/description/webhooks')) { + features.add(path.split('/')[4]) + features.add('webhooks') + } + if (path.startsWith('app/api/description/components/schemas/webhooks')) { + features.add('webhooks') + } + }) + } + + const feature = Array.from(features).join() + + return feature + } + + if (process.env.REPO === 'github/docs-strategy') { + return 'CD plan' + } + + return '' +} + +// Guess the size of an item +export function getSize(data) { + // We need to set something in case this is an issue, so just guesstimate small + if (data.item.__typename !== 'PullRequest') { + return 'S' + } + + // for github/github PRs, estimate the size based on the number of OpenAPI files that were changed + if (process.env.REPO === 'github/github') { + let numFiles = 0 + let numChanges = 0 + data.item.files.nodes.forEach((node) => { + if (node.path.startsWith('app/api/description')) { + numFiles += 1 + numChanges += node.additions + numChanges += node.deletions + } + }) + if (numFiles < 5 && numChanges < 10) { + return 'XS' + } else if (numFiles < 10 && numChanges < 50) { + return 'S' + } else if (numFiles < 10 && numChanges < 250) { + return 'M' + } else { + return 'L' + } + } else { + // Otherwise, estimated the size based on all files + let numFiles = 0 + let numChanges = 0 + data.item.files.nodes.forEach((node) => { + numFiles += 1 + numChanges += node.additions + numChanges += node.deletions + }) + if (numFiles < 5 && numChanges < 10) { + return 'XS' + } else if (numFiles < 10 && numChanges < 50) { + return 'S' + } else if (numFiles < 10 && numChanges < 250) { + return 'M' + } else { + return 'L' + } + } +} + export default { addItemsToProject, addItemToProject, @@ -283,4 +393,6 @@ export default { formatDateForProject, calculateDueDate, generateUpdateProjectV2ItemFieldMutation, + getFeature, + getSize, } diff --git a/src/workflows/ready-for-docs-review.js b/src/workflows/ready-for-docs-review.js index 2aff55aedc..b2844e3faa 100644 --- a/src/workflows/ready-for-docs-review.js +++ b/src/workflows/ready-for-docs-review.js @@ -8,6 +8,8 @@ import { findFieldID, findSingleSelectID, generateUpdateProjectV2ItemFieldMutation, + getFeature, + getSize, } from './projects.js' async function run() { @@ -77,51 +79,14 @@ async function run() { const hubberTypeID = findSingleSelectID('Hubber or partner', 'Contributor type', data) const docsMemberTypeID = findSingleSelectID('Docs team', 'Contributor type', data) const osContributorTypeID = findSingleSelectID('OS contributor', 'Contributor type', data) - const sizeXS = findSingleSelectID('XS', 'Size', data) - const sizeS = findSingleSelectID('S', 'Size', data) - const sizeM = findSingleSelectID('M', 'Size', data) - const sizeL = findSingleSelectID('L', 'Size', data) // Add the PR to the project const newItemID = await addItemToProject(process.env.ITEM_NODE_ID, projectID) - // If the item is a PR, determine the feature and size - let feature = '' - let sizeType = sizeS // We need to set something in case this is an issue - if (data.item.__typename === 'PullRequest') { - // Get the - // - number of files changed - // - total number of additions/deletions - // - affected docs sets (not considering changes to data/assets) - let numFiles = 0 - let numChanges = 0 - const features = new Set([]) - data.item.files.nodes.forEach((node) => { - numFiles += 1 - numChanges += node.additions - numChanges += node.deletions - // To determine the feature, we are only looking at `content/*` paths - // and then pulling out the second part of the path, which corresponds to the docs set - const pathComponents = node.path.split('/') - if (pathComponents[0] === 'content') { - features.add(pathComponents[1]) - } - }) - - // Determine the size - if (numFiles < 5 && numChanges < 10) { - sizeType = sizeXS - } else if (numFiles < 10 && numChanges < 50) { - sizeType = sizeS - } else if (numFiles < 10 && numChanges < 250) { - sizeType = sizeM - } else { - sizeType = sizeL - } - - // Set the feature - feature = Array.from(features).join() - } + // Determine the feature and size + const feature = getFeature(data) + const size = getSize(data) + const sizeType = findSingleSelectID(size, 'Size', data) // If this is the OS repo, determine if this is a first time contributor // If yes, set the author to 'first time contributor' instead of to the author login