-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add check artifact sizes action and add label for violation. (#3813)
b/291954423
- Loading branch information
1 parent
039052d
commit 9545024
Showing
3 changed files
with
164 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
name: Check Artifact Size | ||
description: Check if the increase in artifact size exceeds the threshold, and if so, apply a label to the pull request. | ||
inputs: | ||
workflow: | ||
description: "Workflow to check artifact binary size for." | ||
required: true | ||
name: | ||
description: "Name of the uploaded artifact, artifact is a zip file that can contain more than one binary" | ||
required: true | ||
path: | ||
description: "Path to the newly created binary artifacts being checked." | ||
required: true | ||
thresholds: | ||
description: "Thresholds is a JSON-formatted string that specifies the maximum permissible percentage increase in the size of each respective binary artifact." | ||
required: true | ||
token: | ||
description: "Github token needed for downloading artifacts." | ||
required: true | ||
runs: | ||
using: "composite" | ||
steps: | ||
- name: 'Download artifact from main branch' | ||
id: download-artifact | ||
uses: actions/github-script@v6 | ||
with: | ||
github-token: ${{inputs.token}} | ||
script: | | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
// Get the latest successful workflow run on the main branch. | ||
const workflowRuns = await github.rest.actions.listWorkflowRuns({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
workflow_id: '${{ inputs.workflow }}.yaml', | ||
branch: 'main', | ||
status: 'success', | ||
per_page: 1 | ||
}); | ||
const latestRun = workflowRuns.data.workflow_runs[0].id; | ||
// Get the artifact uploaded on the latest successful workflow run on the main branch. | ||
const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
run_id: latestRun | ||
}); | ||
const matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => { | ||
return artifact.name == '${{ inputs.name }}'; | ||
}); | ||
if (matchArtifacts.length == 1) { | ||
console.log(`Found the latest uploaded artifact ${{ inputs.name }} on the main branch.`); | ||
const download = await github.rest.actions.downloadArtifact({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
artifact_id: matchArtifacts[0].id, | ||
archive_format: 'zip', | ||
}); | ||
const downloadDir = path.join(process.env.GITHUB_WORKSPACE, 'artifact_tmp'); | ||
fs.mkdirSync(downloadDir); | ||
fs.writeFileSync(path.join(downloadDir, `${{ inputs.name }}.zip`), Buffer.from(download.data)); | ||
core.setOutput("downloadDir", downloadDir); | ||
} else { | ||
core.setFailed(`Expected one artifact with name ${{ inputs.name }}. Found ${matchArtifacts.length}.`); | ||
} | ||
- name: 'Unzip artifact from main branch' | ||
id: unzip-downloaded-artifact | ||
shell: bash | ||
run: | | ||
unzip "${{ steps.download-artifact.outputs.downloadDir }}/${{ inputs.name }}.zip" -d "${{ steps.download-artifact.outputs.downloadDir }}" | ||
- name: 'Check new artifact size against main branch' | ||
id: check-artifact-size | ||
uses: actions/github-script@v6 | ||
with: | ||
script: | | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const fileSizeThresholds = JSON.parse('${{ inputs.thresholds }}'); | ||
for (let file in fileSizeThresholds) { | ||
console.log(`Checking file size of ${file}.`); | ||
const downloadFilePath = path.join('${{ steps.download-artifact.outputs.downloadDir }}', file); | ||
if (!fs.existsSync(downloadFilePath)) { | ||
console.error(`File ${file} was not uploaded to the main branch.`); | ||
continue; | ||
} | ||
const filePath = path.join(process.env.GITHUB_WORKSPACE, '${{ inputs.path }}', file); | ||
if (!fs.existsSync(filePath)) { | ||
console.error(`File ${filePath} was not created in the current workflow run.`); | ||
continue; | ||
} | ||
const oldStats = fs.statSync(downloadFilePath); | ||
const oldSize = oldStats.size; | ||
const newStats = fs.statSync(filePath); | ||
const newSize = newStats.size; | ||
console.log(`Latest uploaded artifact size on the main branch is ${oldSize / 1024}kB, new artifact size generated in this PR is ${newSize / 1024}kB.`); | ||
const deltaSize = newSize - oldSize; | ||
const deltaThreshold = (Math.abs(deltaSize) / oldSize * 100).toFixed(4); | ||
if (deltaSize < 0) { | ||
console.log(`Artifact size is decreased by ${Math.abs(deltaSize)} (${deltaThreshold}%).`); | ||
} else { | ||
console.log(`Artifact size is increased by ${deltaSize} (${deltaThreshold}%).`); | ||
if (deltaThreshold > fileSizeThresholds[file]) { | ||
const threshold = (fileSizeThresholds[file] * 100).toFixed(4); | ||
console.error(`Artifact size increase exceeds threshold ${threshold}%.`); | ||
core.setOutput("addLabel", true); | ||
} | ||
} | ||
} | ||
- name: 'Remove downloaded artifact' | ||
id: remove-downloaded-artifact | ||
shell: bash | ||
run: rm -r "${{ steps.download-artifact.outputs.downloadDir }}" | ||
- name: 'Add label for artifact size increase violation' | ||
id: add-label | ||
if: | | ||
steps.check-artifact-size.outputs.addLabel && | ||
github.event.pull_request.merged == true && | ||
github.event.pull_request.merge_commit_sha != null | ||
shell: bash | ||
run: | | ||
curl -s -X POST -H "Authorization: token ${{ inputs.token }}" \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-d '["artifact size increase violation"]' \ | ||
"https://api.github.com/repos/${{ github.event.repository.full_name }}/issues/${{ github.event.number }}/labels" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters