From 90c949019a623a5a44e3ffdd1107001dacca2cb2 Mon Sep 17 00:00:00 2001 From: jNullj <15849761+jNullj@users.noreply.github.com> Date: Wed, 9 Aug 2023 21:43:00 +0300 Subject: [PATCH] devops: Add ci warning for swizzled docusaurus components Add new action and workflow that runs on new dependabot PR. The action checks changes in components of docusaurus-theme-openapi that are swizzled and warns maintainers to review those changes. For more info see badges/shields#9287 Solves badges/shields#9287 --- .../docusaurus-swizzled-warning/action.yml | 12 + .../docusaurus-swizzled-warning/helpers.js | 66 +++++ .../docusaurus-swizzled-warning/index.js | 102 ++++++++ .../package-lock.json | 236 ++++++++++++++++++ .../docusaurus-swizzled-warning/package.json | 17 ++ .../workflows/docusaurus-swizzled-warning.yml | 22 ++ 6 files changed, 455 insertions(+) create mode 100644 .github/actions/docusaurus-swizzled-warning/action.yml create mode 100644 .github/actions/docusaurus-swizzled-warning/helpers.js create mode 100644 .github/actions/docusaurus-swizzled-warning/index.js create mode 100644 .github/actions/docusaurus-swizzled-warning/package-lock.json create mode 100644 .github/actions/docusaurus-swizzled-warning/package.json create mode 100644 .github/workflows/docusaurus-swizzled-warning.yml diff --git a/.github/actions/docusaurus-swizzled-warning/action.yml b/.github/actions/docusaurus-swizzled-warning/action.yml new file mode 100644 index 0000000000000..1775d97543ec6 --- /dev/null +++ b/.github/actions/docusaurus-swizzled-warning/action.yml @@ -0,0 +1,12 @@ +name: 'Docusaurus swizzled component changes warning' +description: 'Check for changes in Docusaurus components which are swizzled and prints out a warning' +branding: + icon: 'alert-triangle' + color: 'yellow' +inputs: + github-token: + description: 'The GITHUB_TOKEN secret' + required: true +runs: + using: 'node20' + main: 'index.js' diff --git a/.github/actions/docusaurus-swizzled-warning/helpers.js b/.github/actions/docusaurus-swizzled-warning/helpers.js new file mode 100644 index 0000000000000..43ae30e62a0f6 --- /dev/null +++ b/.github/actions/docusaurus-swizzled-warning/helpers.js @@ -0,0 +1,66 @@ +'use strict' + +/** + * Returns info about all files changed in a PR (max 3000 results) + * + * @param {object} client hydrated octokit ready to use for GitHub Actions + * @param {string} owner repo owner + * @param {string} repo repo name + * @param {number} pullNumber pull request number + * @returns {object[]} array of object that describe pr changed files - see https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#list-pull-requests-files + */ +async function getAllFilesForPullRequest(client, owner, repo, pullNumber) { + const perPage = 100 // Max number of items per page + let page = 1 // Start with the first page + let allFiles = [] + while (true) { + const response = await client.request( + 'GET /repos/{owner}/{repo}/pulls/{pull_number}/files', + { + owner, + repo, + pull_number: pullNumber, + per_page: perPage, + page, + }, + ) + + if (response.data.length === 0) { + // Break the loop if no more results + break + } + + allFiles = allFiles.concat(response.data) + page++ // Move to the next page + } + return allFiles +} + +/** + * Get a list of files changed betwen two tags for a github repo + * + * @param {object} client hydrated octokit ready to use for GitHub Actions + * @param {string} owner repo owner + * @param {string} repo repo name + * @param {string} baseTag base tag + * @param {string} headTag head tag + * @returns {string[]} Array listing all changed files betwen the base tag and the head tag + */ +async function getChangedFilesBetweenTags( + client, + owner, + repo, + baseTag, + headTag, +) { + const response = await client.repos.compareCommits({ + owner, + repo, + base: baseTag, + head: headTag, + }) + + return response.data.files.map(file => file.filename) +} + +module.exports = { getAllFilesForPullRequest, getChangedFilesBetweenTags } diff --git a/.github/actions/docusaurus-swizzled-warning/index.js b/.github/actions/docusaurus-swizzled-warning/index.js new file mode 100644 index 0000000000000..367e4b0398421 --- /dev/null +++ b/.github/actions/docusaurus-swizzled-warning/index.js @@ -0,0 +1,102 @@ +'use strict' + +const core = require('@actions/core') +const github = require('@actions/github') +const { + getAllFilesForPullRequest, + getChangedFilesBetweenTags, +} = require('./helpers') + +async function run() { + try { + const token = core.getInput('github-token', { required: true }) + + const { pull_request: pr } = github.context.payload + if (!pr) { + throw new Error('Event payload missing `pull_request`') + } + + const client = github.getOctokit(token) + const packageName = 'docusaurus-preset-openapi' + const overideComponents = ['Curl', 'Response'] + const messageTemplate = ` + | :large_orange_diamond:This PR contains changes to components of ${packageName} we've overridden | + --------------------------------------------------------------------------------------------------- + | We need to watch out for changes to the Curl and Response components | + ` + + if ( + ['dependabot[bot]', 'dependabot-preview[bot]'].includes(pr.user.login) + ) { + const files = getAllFilesForPullRequest( + client, + github.context.repo.owner, + github.context.repo.repo, + pr.number, + ) + + for (const file of files) { + if (!['package.json', 'package-lock.json'].includes(file.filename)) { + continue + } + + const patchLines = file.patch.split('\n') + const versionRegex = /\d+\.\d+\.\d+/ + + let oldVersion + let newVersion + + for (let i = 0; i < patchLines.length; i++) { + if ( + ['+', '-'].includes(patchLines[i][0]) && + patchLines[i].includes(packageName) + ) { + const match = patchLines[i].match(versionRegex) + if (patchLines[i][0] === '+') { + newVersion = match[0] + } else { + oldVersion = match[0] + } + } + } + + if (newVersion) { + const pkgChangedFiles = getChangedFilesBetweenTags( + client, + github.context.repo.owner, + github.context.repo.repo, + oldVersion, + newVersion, + ) + const changedComponents = overideComponents.filter( + componenet => + pkgChangedFiles.includes('docusaurus-theme-openapi/src/theme') && + pkgChangedFiles.includes(componenet), + ) + const versionReport = `| Old version | ${oldVersion} | + | New version | ${newVersion} | + ` + const changedComponentsReport = `| Overide components changed | ${changedComponents.join( + ', ', + )} | + ` + const body = messageTemplate + versionReport + changedComponentsReport + await client.rest.issues.createComment({ + owner: github.context.repo.owner, + repo: github.context.repo.repo, + issue_number: pr.number, + body, + }) + } + + core.debug('Found changes and posted comment, done.') + return + } + core.debug('No changes found, done.') + } + } catch (error) { + core.setFailed(error.message) + } +} + +run() diff --git a/.github/actions/docusaurus-swizzled-warning/package-lock.json b/.github/actions/docusaurus-swizzled-warning/package-lock.json new file mode 100644 index 0000000000000..5511c01825be6 --- /dev/null +++ b/.github/actions/docusaurus-swizzled-warning/package-lock.json @@ -0,0 +1,236 @@ +{ + "name": "docusaurus-swizzled-warning", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "docusaurus-swizzled-warning", + "version": "0.0.0", + "license": "CC0", + "dependencies": { + "@actions/core": "^1.10.0", + "@actions/github": "^5.1.1" + } + }, + "node_modules/@actions/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz", + "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==", + "dependencies": { + "@actions/http-client": "^2.0.1", + "uuid": "^8.3.2" + } + }, + "node_modules/@actions/github": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz", + "integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==", + "dependencies": { + "@actions/http-client": "^2.0.1", + "@octokit/core": "^3.6.0", + "@octokit/plugin-paginate-rest": "^2.17.0", + "@octokit/plugin-rest-endpoint-methods": "^5.13.0" + } + }, + "node_modules/@actions/http-client": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.1.tgz", + "integrity": "sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==", + "dependencies": { + "tunnel": "^0.0.6" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", + "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.3", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", + "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.21.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", + "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", + "dependencies": { + "@octokit/types": "^6.40.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.16.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", + "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", + "dependencies": { + "@octokit/types": "^6.39.0", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.41.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", + "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", + "dependencies": { + "@octokit/openapi-types": "^12.11.0" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + } + } +} diff --git a/.github/actions/docusaurus-swizzled-warning/package.json b/.github/actions/docusaurus-swizzled-warning/package.json new file mode 100644 index 0000000000000..a6417219cb8da --- /dev/null +++ b/.github/actions/docusaurus-swizzled-warning/package.json @@ -0,0 +1,17 @@ +{ + "name": "docusaurus-swizzled-warning", + "version": "0.0.0", + "description": "", + "main": "index.js", + "private": true, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "jNullj", + "license": "CC0", + "dependencies": { + "@actions/core": "^1.10.0", + "@actions/github": "^5.1.1" + } + } + \ No newline at end of file diff --git a/.github/workflows/docusaurus-swizzled-warning.yml b/.github/workflows/docusaurus-swizzled-warning.yml new file mode 100644 index 0000000000000..02a0682b538de --- /dev/null +++ b/.github/workflows/docusaurus-swizzled-warning.yml @@ -0,0 +1,22 @@ +name: Docusaurus swizzled component changes warning +on: + pull_request_target: + types: [opened] + +permissions: + pull-requests: write + +jobs: + auto-close: + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install action dependencies + run: cd .github/actions/docusaurus-swizzled-warning && npm ci + + - uses: ./.github/actions/docusaurus-swizzled-warning + with: + github-token: '${{ secrets.GITHUB_TOKEN }}'