Skip to content

Commit

Permalink
Refactor diff action (#1094)
Browse files Browse the repository at this point in the history
* use external file
* add setup step
  • Loading branch information
lukasoppermann authored Nov 27, 2024
1 parent 68f79a8 commit 40d1343
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 160 deletions.
226 changes: 68 additions & 158 deletions .github/workflows/diff-design-tokens.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,25 @@ jobs:
changes:
uses: ./.github/workflows/hasChanged.yml

setup:
runs-on: ubuntu-latest
outputs:
diffs: ${{ steps.config.outputs.diffs }}
steps:
- name: Setup config
id: config
uses: actions/github-script@v7
with:
script: |
core.setOutput('diffs', `[{
"title": "## Design Token Diff (CSS)",
"folder": "dist/css",
"globString": "**/**/*.css",
"outputFile": "diff_css.json"
}]`)
diff:
needs: changes
needs: [changes, setup]
if: needs.changes.outputs.outputAffected == 'true' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
Expand All @@ -34,13 +51,13 @@ jobs:
run: npm ci --no-audit --no-fund --include=dev --ignore-scripts

- name: Build tokens (pr)
run: npm run build:tokens
run: npm run build

- name: Install dependencies (base)
run: pushd base; npm i --no-audit --no-fund --ignore-scripts; popd

- name: Build tokens (base)
run: pushd base; npm run build:tokens; popd
run: pushd base; npm run build; popd

- name: Install dependecies for diffing
run: npm install shelljs
Expand All @@ -50,188 +67,81 @@ jobs:
uses: actions/github-script@v7
with:
script: |
const cssFolder = 'dist/css'
const shell = require('shelljs')
const globber = await glob.create(cssFolder + '/**/**/*.css')
const files = await globber.glob()
const fs = require('fs')
// create file to store diffs
const diffFilePath = 'diff_output.json'
shell.touch(diffFilePath)
core.setOutput('diffFilePath', diffFilePath);
// create diffs
const diffs = files.map(file => {
// get filename
const regexRunnerPath = new RegExp('^[a-z\/]+\/dist', 'g')
const filename = file.replaceAll(regexRunnerPath,'')
// if file is new
if (!fs.existsSync(file.replace(cssFolder, 'base/' + cssFolder))) {
console.info('⚠️ File is new: ' + file + '\n')
return {
file: file.replaceAll('dist/', ''),
diff: ''
}
}
// run diff & store in file
const diff = shell.exec(`diff -u ${file.replace(cssFolder, 'base/' + cssFolder)} ${file}`)
console.log('Checking diff for ' + filename + '...')
if (diff.stderr) {
console.error(diff.stderr)
core.setFailed(diff.stderr)
}
if (diff.stdout === '') {
console.log('No diff for ' + filename + '\n')
} else {
console.log(diff.stdout + '\n')
const diffFiles = require('./.github/workflows/utilities/diffFiles.cjs')
// get config
const diffConfig = ${{ needs.setup.outputs.diffs }}
const output = []
// create sections
for (const config of diffConfig) {
await diffFiles(config.folder, config.globString, config.outputFile)
// read diff file
const diff = JSON.parse(fs.readFileSync(config.outputFile, 'utf8'))
// create sections
const sections = []
for (const {title, body} of diff) {
sections.push({
title,
body
})
}
return {
file: filename,
diff: diff.stdout || ''
}
})
// filter files with no diffs
.filter(item => {
return item.diff !== ''
})
output.push({
file: config.outputFile,
title: config.title,
sections
})
}
// store diffs in file
fs.writeFileSync(diffFilePath, JSON.stringify(diffs, null, ' '))
// set output
core.setOutput('diffFilePath', output);
- name: Write summary
uses: actions/github-script@v7
with:
script: |
const fs = require('fs')
const diffFilePath = "${{ steps.diff-files.outputs.diffFilePath }}"
// check if file exists
if(!fs.existsSync(diffFilePath)) {
return
}
// read file
const diffs = JSON.parse(fs.readFileSync(diffFilePath, 'utf8'))
core.summary.clear()
core.summary.addHeading('Design Token Diff', '1')
if (diffs.length === 0) {
core.summary.addRaw('No design tokens changed', true)
} else {
const addSummary = require('./.github/workflows/utilities/addSummary.cjs')
const diffFileArray = ${{ steps.diff-files.outputs.diffFilePath }}
diffs.forEach(({file: fileName, diff: content}) => {
const diffDetails = `<details><summary><h3>${fileName}</h3></summary>\n\n`+
'```diff\n'+
`${content}\n`+
'```\n\n'+
'</details>'
core.summary.addRaw(diffDetails, true)
})
}
// write summary
core.summary.write({overwrite: true})
// add summary
addSummary(diffFileArray, true)
- name: Comment on pr
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
env:
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_RUN_ID: ${{ github.run_id }}
with:
script: |
const fs = require('fs')
const diffFilePath = "${{ steps.diff-files.outputs.diffFilePath }}"
// check if file exists
if(!fs.existsSync(diffFilePath)) {
return
}
// read file
const diffs = JSON.parse(fs.readFileSync(diffFilePath, 'utf8'))
// prepare comment body
let body = '## Design Token Diff\n\n'
if (diffs.length === 0) {
body += 'No design tokens changed'
} else {
body += diffs.map(({file, diff}) =>
'<details>' +
`<summary><h3>${file}</h3></summary>\n` +
" \n"+
" ```diff"+
` ${diff}` +
" ```"+
'\n</details>'
).join('\n')
}
const addComment = require('./.github/workflows/utilities/addComment.cjs')
const diffFilePath = ${{ steps.diff-files.outputs.diffFilePath }}
const WORKFLOW_SUMMARY_URL = `https://github.com/${{env.GITHUB_REPOSITORY}}/actions/runs/${{env.GITHUB_RUN_ID}}`
// get comments
const {data: comments} = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
// overwrite body if to long
if(body.length > 65536) {
body = '## Design Token Diff\n\nThe diff is too long to be displayed here. Please check the job summary for more details.'
}
// get comment if exists
const existingComment = comments.filter(comment => comment.body.includes('## Design Token Diff'));
// if token issue exists, update it
if(existingComment.length > 0) {
await github.rest.issues.updateComment({
comment_id: existingComment[0].id,
owner: context.repo.owner,
repo: context.repo.repo,
body
})
}
// if comment does not exist, create it
else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body
})
for (const diff of diffFilePath) {
await addComment(diff, WORKFLOW_SUMMARY_URL, context, github)
}
remove_comment:
needs: changes
needs: [changes, setup]
if: needs.changes.outputs.outputAffected == 'false'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Remove comment and summary
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
// get comments
const {data: comments} = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
// get comment if exists
const existingComment = comments.filter(comment => comment.body.includes('## Design Token Diff'));
// if token issue exists, update it
if(existingComment.length > 0) {
await github.rest.issues.deleteComment({
comment_id: existingComment[0].id,
owner: context.repo.owner,
repo: context.repo.repo,
})
const deleteComment = require('./.github/workflows/utilities/deleteCommentByContent.cjs')
const diffs = ${{ needs.setup.outputs.diffs }}
const commentTitles = diffs.map(({title}) => title)
// delete all comments
for (const title of commentTitles) {
await deleteComment(`## ${title}`, context, github)
}
// remove summary
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/release_candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ jobs:
echo "### Latest release candidate" >> $GITHUB_STEP_SUMMARY
echo "[v$VERSION](https://unpkg.com/$PACKAGE_NAME@$VERSION/)" >> $GITHUB_STEP_SUMMARY
release-candidate-next-major:
if: ${{ github.repository == 'primer/primitives' && github.ref_name == 'changeset-release/next-major' }}
name: Candidate (@next-major)
Expand Down
53 changes: 53 additions & 0 deletions .github/workflows/utilities/addComment.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module.exports = async ({title, body, sections}, summaryLink, context, github) => {
// get comments
const {data: comments} = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
// prepare body
let commentBody = ''
if(title) {
commentBody = `## ${title}\n\n`
}
if (body) {
commentBody += body
}
if (sections) {
commentBody += sections.map(({title, body}) =>
'<details>' +
`<summary><h3>${title}</h3></summary>\n` +
" \n"+
" ```diff"+
` ${body}` +
" ```"+
'\n</details>'
).join('\n')
}

// overwrite body if to long
if(summaryLink && commentBody.length > 65536) {
commentBody = `## ${title}\n\nThe message is too long to be displayed here. For more details, please check the <a href="${summaryLink}">job summary</a>.`
}

// get comment if exists
const existingComment = comments.filter(comment => comment.body.includes(`## ${title}`));
// if comment exists, update it
if(existingComment.length > 0) {
await github.rest.issues.updateComment({
comment_id: existingComment[0].id,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
})
}
// if comment does not exist, create it
else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
})
}
}
31 changes: 31 additions & 0 deletions .github/workflows/utilities/addSummary.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const core = require('@actions/core')

module.exports = (content, overwrite = false) => {
if(!Array.isArray(content)) {
content = [content]
}
// core.summary.clear()

for (const {title, body, sections} of content) {
if(title) {
core.summary.addHeading(title, '1')
}

if(body) {
core.summary.addRaw(body, true)
}

if(sections) {
sections.forEach(({title, body}) => {
const section = `<details><summary><h3>${title}</h3></summary>\n\n`+
'```diff\n'+
`${body}\n`+
'```\n\n'+
'</details>'
core.summary.addRaw(section, true)
})
}
}
// write summary
core.summary.write({overwrite})
}
23 changes: 23 additions & 0 deletions .github/workflows/utilities/deleteCommentByContent.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = async (searchContent, context, github) => {
if (!Array.isArray(searchContent)) {
searchContent = [searchContent]
}
// get comments
const {data: comments} = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});

// get comments that match search content
const existingComment = comments.filter(comment => searchContent.some(searchValue => comment.body.includes(searchValue)));

// if token issue exists, update it
for (const comment of existingComment) {
await github.rest.issues.deleteComment({
comment_id: comment.id,
owner: context.repo.owner,
repo: context.repo.repo,
})
}
}
Loading

0 comments on commit 40d1343

Please sign in to comment.