Skip to content

Commit 2fb2bbe

Browse files
committed
Check artifact size and warn if too large
1 parent b580d21 commit 2fb2bbe

File tree

6 files changed

+94
-19
lines changed

6 files changed

+94
-19
lines changed

coverage_badge.svg

+1-1
Loading

dist/index.js

+26-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/__tests__/internal/deployment.test.js

+40-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const core = require('@actions/core')
22
const nock = require('nock')
33

4-
const { Deployment, MAX_TIMEOUT } = require('../../internal/deployment')
4+
const { Deployment, MAX_TIMEOUT, ONE_GIGABYTE, SIZE_LIMIT_DESCRIPTION } = require('../../internal/deployment')
55

66
const fakeJwt =
77
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiNjllMWIxOC1jOGFiLTRhZGQtOGYxOC03MzVlMzVjZGJhZjAiLCJzdWIiOiJyZXBvOnBhcGVyLXNwYS9taW55aTplbnZpcm9ubWVudDpQcm9kdWN0aW9uIiwiYXVkIjoiaHR0cHM6Ly9naXRodWIuY29tL3BhcGVyLXNwYSIsInJlZiI6InJlZnMvaGVhZHMvbWFpbiIsInNoYSI6ImEyODU1MWJmODdiZDk3NTFiMzdiMmM0YjM3M2MxZjU3NjFmYWM2MjYiLCJyZXBvc2l0b3J5IjoicGFwZXItc3BhL21pbnlpIiwicmVwb3NpdG9yeV9vd25lciI6InBhcGVyLXNwYSIsInJ1bl9pZCI6IjE1NDY0NTkzNjQiLCJydW5fbnVtYmVyIjoiMzQiLCJydW5fYXR0ZW1wdCI6IjIiLCJhY3RvciI6IllpTXlzdHkiLCJ3b3JrZmxvdyI6IkNJIiwiaGVhZF9yZWYiOiIiLCJiYXNlX3JlZiI6IiIsImV2ZW50X25hbWUiOiJwdXNoIiwicmVmX3R5cGUiOiJicmFuY2giLCJlbnZpcm9ubWVudCI6IlByb2R1Y3Rpb24iLCJqb2Jfd29ya2Zsb3dfcmVmIjoicGFwZXItc3BhL21pbnlpLy5naXRodWIvd29ya2Zsb3dzL2JsYW5rLnltbEByZWZzL2hlYWRzL21haW4iLCJpc3MiOiJodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwibmJmIjoxNjM4ODI4MDI4LCJleHAiOjE2Mzg4Mjg5MjgsImlhdCI6MTYzODgyODYyOH0.1wyupfxu1HGoTyIqatYg0hIxy2-0bMO-yVlmLSMuu2w'
@@ -248,6 +248,45 @@ describe('Deployment', () => {
248248
createDeploymentScope.done()
249249
})
250250

251+
it('warns if the artifact size is bigger than maximum', async () => {
252+
process.env.GITHUB_SHA = 'valid-build-version'
253+
const artifactSize = ONE_GIGABYTE + 1
254+
255+
const artifactExchangeScope = nock(`http://my-url`)
256+
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
257+
.reply(200, {
258+
value: [
259+
{ url: 'https://fake-artifact.com', name: 'github-pages', size: `${artifactSize}` },
260+
{ url: 'https://another-artifact.com', name: 'another-artifact' }
261+
]
262+
})
263+
264+
const createDeploymentScope = nock('https://api.github.com')
265+
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
266+
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
267+
pages_build_version: process.env.GITHUB_SHA,
268+
oidc_token: fakeJwt
269+
})
270+
.reply(200, {
271+
status_url: `https://api.github.com/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments/${process.env.GITHUB_SHA}`,
272+
page_url: 'https://actions.github.io/is-awesome'
273+
})
274+
275+
const deployment = new Deployment()
276+
await deployment.create(fakeJwt)
277+
278+
expect(core.warning).toBeCalledWith(
279+
`Uploaded artifact size of ${artifactSize} bytes exceeds the allowed size of ${SIZE_LIMIT_DESCRIPTION}. Deployment might fail.`
280+
)
281+
expect(core.setFailed).not.toHaveBeenCalled()
282+
expect(core.info).toHaveBeenLastCalledWith(
283+
expect.stringMatching(new RegExp(`^Created deployment for ${process.env.GITHUB_SHA}`))
284+
)
285+
286+
artifactExchangeScope.done()
287+
createDeploymentScope.done()
288+
})
289+
251290
it('warns when the timeout is greater than the maximum allowed', async () => {
252291
process.env.GITHUB_SHA = 'valid-build-version'
253292

src/internal/api-client.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ async function processRuntimeResponse(res, requestOptions) {
5454
return response
5555
}
5656

57-
async function getSignedArtifactUrl({ runtimeToken, workflowRunId, artifactName }) {
57+
async function getSignedArtifactMetadata({ runtimeToken, workflowRunId, artifactName }) {
5858
const { runTimeUrl: RUNTIME_URL } = getContext()
5959
const artifactExchangeUrl = `${RUNTIME_URL}_apis/pipelines/workflows/${workflowRunId}/artifacts?api-version=6.0-preview`
6060

@@ -88,15 +88,25 @@ async function getSignedArtifactUrl({ runtimeToken, workflowRunId, artifactName
8888
throw error
8989
}
9090

91-
const artifactRawUrl = data?.value?.find(artifact => artifact.name === artifactName)?.url
91+
const artifact = data?.value?.find(artifact => artifact.name === artifactName)
92+
const artifactRawUrl = artifact?.url
9293
if (!artifactRawUrl) {
9394
throw new Error(
9495
'No uploaded artifact was found! Please check if there are any errors at build step, or uploaded artifact name is correct.'
9596
)
9697
}
9798

9899
const signedArtifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
99-
return signedArtifactUrl
100+
101+
const artifactSize = artifact?.size
102+
if (!artifactSize) {
103+
core.warning('Artifact size was not found. Can not check if artifact size exceeds the allowed size.')
104+
}
105+
106+
return {
107+
url: signedArtifactUrl,
108+
size: artifactSize
109+
}
100110
}
101111

102112
async function createPagesDeployment({ githubToken, artifactUrl, buildVersion, idToken, isPreview = false }) {
@@ -163,7 +173,7 @@ async function cancelPagesDeployment({ githubToken, deploymentId }) {
163173
}
164174

165175
module.exports = {
166-
getSignedArtifactUrl,
176+
getSignedArtifactMetadata,
167177
createPagesDeployment,
168178
getPagesDeploymentStatus,
169179
cancelPagesDeployment

src/internal/deployment.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const core = require('@actions/core')
33
// All variables we need from the runtime are loaded here
44
const getContext = require('./context')
55
const {
6-
getSignedArtifactUrl,
6+
getSignedArtifactMetadata,
77
createPagesDeployment,
88
getPagesDeploymentStatus,
99
cancelPagesDeployment
@@ -24,6 +24,8 @@ const finalErrorStatus = {
2424
}
2525

2626
const MAX_TIMEOUT = 600000
27+
const ONE_GIGABYTE = 1073741824
28+
const SIZE_LIMIT_DESCRIPTION = '1 GB'
2729

2830
class Deployment {
2931
constructor() {
@@ -62,15 +64,21 @@ class Deployment {
6264
core.debug(`Action ID: ${this.actionsId}`)
6365
core.debug(`Actions Workflow Run ID: ${this.workflowRun}`)
6466

65-
const artifactUrl = await getSignedArtifactUrl({
67+
const artifactData = await getSignedArtifactMetadata({
6668
runtimeToken: this.runTimeToken,
6769
workflowRunId: this.workflowRun,
6870
artifactName: this.artifactName
6971
})
7072

73+
if (artifactData?.size > ONE_GIGABYTE) {
74+
core.warning(
75+
`Uploaded artifact size of ${artifactData?.size} bytes exceeds the allowed size of ${SIZE_LIMIT_DESCRIPTION}. Deployment might fail.`
76+
)
77+
}
78+
7179
const deployment = await createPagesDeployment({
7280
githubToken: this.githubToken,
73-
artifactUrl,
81+
artifactUrl: artifactData.url,
7482
buildVersion: this.buildVersion,
7583
idToken,
7684
isPreview: this.isPreview
@@ -243,4 +251,4 @@ class Deployment {
243251
}
244252
}
245253

246-
module.exports = { Deployment, MAX_TIMEOUT }
254+
module.exports = { Deployment, MAX_TIMEOUT, ONE_GIGABYTE, SIZE_LIMIT_DESCRIPTION }

0 commit comments

Comments
 (0)