Skip to content

Commit

Permalink
devops: Add ci warning for swizzled docusaurus components
Browse files Browse the repository at this point in the history
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#9287

Solves badges#9287
  • Loading branch information
jNullj committed Aug 9, 2023
1 parent 5d71c1c commit 90c9490
Show file tree
Hide file tree
Showing 6 changed files with 455 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .github/actions/docusaurus-swizzled-warning/action.yml
Original file line number Diff line number Diff line change
@@ -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'
66 changes: 66 additions & 0 deletions .github/actions/docusaurus-swizzled-warning/helpers.js
Original file line number Diff line number Diff line change
@@ -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 }
102 changes: 102 additions & 0 deletions .github/actions/docusaurus-swizzled-warning/index.js
Original file line number Diff line number Diff line change
@@ -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()
Loading

0 comments on commit 90c9490

Please sign in to comment.