mirror of
https://github.com/actions/deploy-pages.git
synced 2025-12-08 16:16:16 +00:00
Update tests + cleanup
This commit is contained in:
337
dist/index.js
generated
vendored
337
dist/index.js
generated
vendored
@@ -4090,104 +4090,6 @@ exports.restEndpointMethods = restEndpointMethods;
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 537:
|
||||
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// pkg/dist-src/index.js
|
||||
var dist_src_exports = {};
|
||||
__export(dist_src_exports, {
|
||||
RequestError: () => RequestError
|
||||
});
|
||||
module.exports = __toCommonJS(dist_src_exports);
|
||||
var import_deprecation = __nccwpck_require__(8932);
|
||||
var import_once = __toESM(__nccwpck_require__(1223));
|
||||
var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var logOnceHeaders = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var RequestError = class extends Error {
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
this.name = "HttpError";
|
||||
this.status = statusCode;
|
||||
let headers;
|
||||
if ("headers" in options && typeof options.headers !== "undefined") {
|
||||
headers = options.headers;
|
||||
}
|
||||
if ("response" in options) {
|
||||
this.response = options.response;
|
||||
headers = options.response.headers;
|
||||
}
|
||||
const requestCopy = Object.assign({}, options.request);
|
||||
if (options.request.headers.authorization) {
|
||||
requestCopy.headers = Object.assign({}, options.request.headers, {
|
||||
authorization: options.request.headers.authorization.replace(
|
||||
/ .*$/,
|
||||
" [REDACTED]"
|
||||
)
|
||||
});
|
||||
}
|
||||
requestCopy.url = requestCopy.url.replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]").replace(/\baccess_token=\w+/g, "access_token=[REDACTED]");
|
||||
this.request = requestCopy;
|
||||
Object.defineProperty(this, "code", {
|
||||
get() {
|
||||
logOnceCode(
|
||||
new import_deprecation.Deprecation(
|
||||
"[@octokit/request-error] `error.code` is deprecated, use `error.status`."
|
||||
)
|
||||
);
|
||||
return statusCode;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "headers", {
|
||||
get() {
|
||||
logOnceHeaders(
|
||||
new import_deprecation.Deprecation(
|
||||
"[@octokit/request-error] `error.headers` is deprecated, use `error.response.headers`."
|
||||
)
|
||||
);
|
||||
return headers || {};
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (0);
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 6234:
|
||||
@@ -4664,102 +4566,6 @@ class Deprecation extends Error {
|
||||
exports.Deprecation = Deprecation;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 3703:
|
||||
/***/ ((module) => {
|
||||
|
||||
// Source: 2014-06-11: http://en.wikipedia.org/wiki/HTTP_status_codes
|
||||
|
||||
module.exports = {
|
||||
100: "Continue",
|
||||
101: "Switching Protocols",
|
||||
102: "Processing",
|
||||
|
||||
200: "OK",
|
||||
201: "Created",
|
||||
202: "Accepted",
|
||||
203: "Non-Authoritative Information",
|
||||
204: "No Content",
|
||||
205: "Reset Content",
|
||||
206: "Partial Content",
|
||||
207: "Multi-Status",
|
||||
208: "Already Reported",
|
||||
226: "IM Used",
|
||||
|
||||
300: "Multiple Choices",
|
||||
301: "Moved Permanently",
|
||||
302: "Found",
|
||||
303: "See Other",
|
||||
304: "Not Modified",
|
||||
305: "Use Proxy",
|
||||
306: "Switch Proxy",
|
||||
307: "Temporary Redirect",
|
||||
308: "Permanent Redirect",
|
||||
|
||||
400: "Bad Request",
|
||||
401: "Unauthorized",
|
||||
402: "Payment Required",
|
||||
403: "Forbidden",
|
||||
404: "Not Found",
|
||||
405: "Method Not Allowed",
|
||||
406: "Not Acceptable",
|
||||
407: "Proxy Authentication Required",
|
||||
408: "Request Timeout",
|
||||
409: "Conflict",
|
||||
410: "Gone",
|
||||
411: "Length Required",
|
||||
412: "Precondition Failed",
|
||||
413: "Request Entity Too Large",
|
||||
414: "Request-URI Too Long",
|
||||
415: "Unsupported Media Type",
|
||||
416: "Requested Range Not Satisfiable",
|
||||
417: "Expectation Failed",
|
||||
418: "I'm a teapot",
|
||||
419: "Authentication Timeout",
|
||||
420: "Method Failure",
|
||||
420: "Enhance Your Calm",
|
||||
422: "Unprocessable Entity",
|
||||
423: "Locked",
|
||||
424: "Failed Dependency",
|
||||
426: "Upgrade Required",
|
||||
428: "Precondition Required",
|
||||
429: "Too Many Requests",
|
||||
431: "Request Header Fields Too Large",
|
||||
440: "Login Timeout",
|
||||
444: "No Response",
|
||||
449: "Retry With",
|
||||
450: "Blocked by Windows Parental Controls",
|
||||
451: "Unavailable For Legal Reasons",
|
||||
451: "Redirect",
|
||||
494: "Request Header Too Large",
|
||||
495: "Cert Error",
|
||||
496: "No Cert",
|
||||
497: "HTTP to HTTPS",
|
||||
499: "Client Closed Request",
|
||||
|
||||
500: "Internal Server Error",
|
||||
501: "Not Implemented",
|
||||
502: "Bad Gateway",
|
||||
503: "Service Unavailable",
|
||||
504: "Gateway Timeout",
|
||||
505: "HTTP Version Not Supported",
|
||||
506: "Variant Also Negotiates",
|
||||
507: "Insufficient Storage",
|
||||
508: "Loop Detected",
|
||||
509: "Bandwidth Limit Exceeded",
|
||||
510: "Not Extended",
|
||||
511: "Network Authentication Required",
|
||||
520: "Origin Error",
|
||||
521: "Web server is down",
|
||||
522: "Connection timed out",
|
||||
523: "Proxy Declined Request",
|
||||
524: "A timeout occurred",
|
||||
598: "Network read timeout error",
|
||||
599: "Network connect timeout error"
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 3287:
|
||||
@@ -9811,59 +9617,6 @@ function wrappy (fn, cb) {
|
||||
|
||||
const core = __nccwpck_require__(2186)
|
||||
const github = __nccwpck_require__(5438)
|
||||
const hc = __nccwpck_require__(6255)
|
||||
const { RequestError } = __nccwpck_require__(537)
|
||||
const HttpStatusMessages = __nccwpck_require__(3703)
|
||||
|
||||
// All variables we need from the runtime are loaded here
|
||||
const getContext = __nccwpck_require__(8454)
|
||||
|
||||
async function processRuntimeResponse(res, requestOptions) {
|
||||
// Parse the response body as JSON
|
||||
let obj = null
|
||||
try {
|
||||
const contents = await res.readBody()
|
||||
if (contents && contents.length > 0) {
|
||||
obj = JSON.parse(contents)
|
||||
}
|
||||
} catch (error) {
|
||||
// Invalid resource (contents not json); leaving resulting obj as null
|
||||
}
|
||||
|
||||
// Specific response shape aligned with Octokit
|
||||
const response = {
|
||||
url: res.message?.url || requestOptions.url,
|
||||
status: res.message?.statusCode || 0,
|
||||
headers: {
|
||||
...res.message?.headers
|
||||
},
|
||||
data: obj
|
||||
}
|
||||
|
||||
// Forcibly throw errors for negative HTTP status codes!
|
||||
// @actions/http-client doesn't do this by default.
|
||||
// Mimic the errors thrown by Octokit for consistency.
|
||||
if (response.status >= 400) {
|
||||
// Try to get an error message from the response body
|
||||
const errorMsg =
|
||||
(typeof response.data === 'string' && response.data) ||
|
||||
response.data?.error ||
|
||||
response.data?.message ||
|
||||
// Try the Node HTTP IncomingMessage's statusMessage property
|
||||
res.message?.statusMessage ||
|
||||
// Fallback to the HTTP status message based on the status code
|
||||
HttpStatusMessages[response.status] ||
|
||||
// Or if the status code is unexpected...
|
||||
`Unknown error (${response.status})`
|
||||
|
||||
throw new RequestError(errorMsg, response.status, {
|
||||
response,
|
||||
request: requestOptions
|
||||
})
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
async function getArtifactMetadata({ githubToken, runId, artifactName }) {
|
||||
const octokit = github.getOctokit(githubToken)
|
||||
@@ -9871,20 +9624,27 @@ async function getArtifactMetadata({ githubToken, runId, artifactName }) {
|
||||
try {
|
||||
core.info(`Fetching artifact metadata for ${artifactName} in run ${runId}`)
|
||||
|
||||
const response = await octokit.request("GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts?name={artifactName}", {
|
||||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
run_id: runId,
|
||||
artifactName: artifactName
|
||||
})
|
||||
const response = await octokit.request(
|
||||
'GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts?name={artifactName}',
|
||||
{
|
||||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
run_id: runId,
|
||||
artifactName: artifactName
|
||||
}
|
||||
)
|
||||
|
||||
const artifactCount = response.data.total_count
|
||||
core.debug(`List artifact count: ${artifactCount}`)
|
||||
|
||||
if (artifactCount === 0) {
|
||||
throw new Error(`No artifacts found for workflow run ${runId}. Ensure artifacts are uploaded with actions/artifact@v4 or later.`)
|
||||
throw new Error(
|
||||
`No artifacts found for workflow run ${runId}. Ensure artifacts are uploaded with actions/artifact@v4 or later.`
|
||||
)
|
||||
} else if (artifactCount > 1) {
|
||||
throw new Error(`Multiple artifact unexpectedly found for workflow run ${runId}. Artifact count is ${artifactCount}.`)
|
||||
throw new Error(
|
||||
`Multiple artifact unexpectedly found for workflow run ${runId}. Artifact count is ${artifactCount}.`
|
||||
)
|
||||
}
|
||||
|
||||
const artifact = response.data.artifacts[0]
|
||||
@@ -9905,61 +9665,6 @@ async function getArtifactMetadata({ githubToken, runId, artifactName }) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getSignedArtifactMetadata({ runtimeToken, workflowRunId, artifactName }) {
|
||||
const { runTimeUrl: RUNTIME_URL } = getContext()
|
||||
const artifactExchangeUrl = `${RUNTIME_URL}_apis/pipelines/workflows/${workflowRunId}/artifacts?api-version=6.0-preview`
|
||||
|
||||
const httpClient = new hc.HttpClient()
|
||||
let data = null
|
||||
|
||||
try {
|
||||
const requestHeaders = {
|
||||
accept: 'application/json',
|
||||
authorization: `Bearer ${runtimeToken}`
|
||||
}
|
||||
const requestOptions = {
|
||||
method: 'GET',
|
||||
url: artifactExchangeUrl,
|
||||
headers: {
|
||||
...requestHeaders
|
||||
},
|
||||
body: null
|
||||
}
|
||||
|
||||
core.info(`Artifact exchange URL: ${artifactExchangeUrl}`)
|
||||
const res = await httpClient.get(artifactExchangeUrl, requestHeaders)
|
||||
|
||||
// May throw a RequestError (HttpError)
|
||||
const response = await processRuntimeResponse(res, requestOptions)
|
||||
|
||||
data = response.data
|
||||
core.debug(JSON.stringify(data))
|
||||
} catch (error) {
|
||||
core.error('Getting signed artifact URL failed', error)
|
||||
throw error
|
||||
}
|
||||
|
||||
const artifact = data?.value?.find(artifact => artifact.name === artifactName)
|
||||
const artifactRawUrl = artifact?.url
|
||||
if (!artifactRawUrl) {
|
||||
throw new Error(
|
||||
'No uploaded artifact was found! Please check if there are any errors at build step, or uploaded artifact name is correct.'
|
||||
)
|
||||
}
|
||||
|
||||
const signedArtifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
|
||||
|
||||
const artifactSize = artifact?.size
|
||||
if (!artifactSize) {
|
||||
core.warning('Artifact size was not found. Unable to verify if artifact size exceeds the allowed size.')
|
||||
}
|
||||
|
||||
return {
|
||||
url: signedArtifactUrl,
|
||||
size: artifactSize
|
||||
}
|
||||
}
|
||||
|
||||
async function createPagesDeployment({ githubToken, artifactId, buildVersion, idToken, isPreview = false }) {
|
||||
const octokit = github.getOctokit(githubToken)
|
||||
|
||||
@@ -10025,7 +9730,6 @@ async function cancelPagesDeployment({ githubToken, deploymentId }) {
|
||||
|
||||
module.exports = {
|
||||
getArtifactMetadata,
|
||||
getSignedArtifactMetadata,
|
||||
createPagesDeployment,
|
||||
getPagesDeploymentStatus,
|
||||
cancelPagesDeployment
|
||||
@@ -10076,7 +9780,12 @@ const core = __nccwpck_require__(2186)
|
||||
|
||||
// All variables we need from the runtime are loaded here
|
||||
const getContext = __nccwpck_require__(8454)
|
||||
const { getArtifactMetadata, getPagesDeploymentStatus, createPagesDeployment, cancelPagesDeployment } = __nccwpck_require__(572)
|
||||
const {
|
||||
getArtifactMetadata,
|
||||
getPagesDeploymentStatus,
|
||||
createPagesDeployment,
|
||||
cancelPagesDeployment
|
||||
} = __nccwpck_require__(572)
|
||||
|
||||
const temporaryErrorStatus = {
|
||||
unknown_status: 'Unable to get deployment status.',
|
||||
@@ -10132,15 +9841,12 @@ class Deployment {
|
||||
core.debug(`Action ID: ${this.actionsId}`)
|
||||
core.debug(`Actions Workflow Run ID: ${this.workflowRun}`)
|
||||
|
||||
core.info("Getting artifact's metadata...")
|
||||
const artifactData = await getArtifactMetadata({
|
||||
githubToken: this.githubToken,
|
||||
runId: this.workflowRun,
|
||||
artifactName: this.artifactName
|
||||
})
|
||||
|
||||
console.log(artifactData)
|
||||
|
||||
if (artifactData?.size > ONE_GIGABYTE) {
|
||||
core.warning(
|
||||
`Uploaded artifact size of ${artifactData?.size} bytes exceeds the allowed size of ${SIZE_LIMIT_DESCRIPTION}. Deployment might fail.`
|
||||
@@ -10317,6 +10023,7 @@ class Deployment {
|
||||
|
||||
module.exports = { Deployment, MAX_TIMEOUT, ONE_GIGABYTE, SIZE_LIMIT_DESCRIPTION }
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 2877:
|
||||
|
||||
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/licenses.txt
generated
vendored
2
dist/licenses.txt
generated
vendored
@@ -453,8 +453,6 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
http-status-messages
|
||||
|
||||
is-plain-object
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
66
package-lock.json
generated
66
package-lock.json
generated
@@ -10,10 +10,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/github": "^5.1.1",
|
||||
"@actions/http-client": "^2.1.0",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"http-status-messages": "^1.1.0"
|
||||
"@actions/github": "^5.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "^0.36.1",
|
||||
@@ -1328,32 +1325,6 @@
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.0.tgz",
|
||||
"integrity": "sha512-1ue0DH0Lif5iEqT52+Rf/hf0RmGO9NWFjrzmrkArpG9trFfDM/efx00BJHdLGuro4BR/gECxCU2Twf5OKrRFsQ==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^11.0.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz",
|
||||
"integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw=="
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
|
||||
"integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
@@ -3577,11 +3548,6 @@
|
||||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/http-status-messages": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-status-messages/-/http-status-messages-1.1.0.tgz",
|
||||
"integrity": "sha512-zq9mKkNX6w6qYtNE0aAiH+urvEenUUIyoq8eAWQh2prhA5o03NETCOm/D2GIVt/qCFItt+23Sm1E7HyelPvi6w=="
|
||||
},
|
||||
"node_modules/human-signals": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||
@@ -7480,31 +7446,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.0.tgz",
|
||||
"integrity": "sha512-1ue0DH0Lif5iEqT52+Rf/hf0RmGO9NWFjrzmrkArpG9trFfDM/efx00BJHdLGuro4BR/gECxCU2Twf5OKrRFsQ==",
|
||||
"requires": {
|
||||
"@octokit/types": "^11.0.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz",
|
||||
"integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
|
||||
"integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^18.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "6.41.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
|
||||
@@ -9140,11 +9081,6 @@
|
||||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
||||
"dev": true
|
||||
},
|
||||
"http-status-messages": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-status-messages/-/http-status-messages-1.1.0.tgz",
|
||||
"integrity": "sha512-zq9mKkNX6w6qYtNE0aAiH+urvEenUUIyoq8eAWQh2prhA5o03NETCOm/D2GIVt/qCFItt+23Sm1E7HyelPvi6w=="
|
||||
},
|
||||
"human-signals": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
"main": "./dist/index.js",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/github": "^5.1.1",
|
||||
"@actions/http-client": "^2.1.0",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"http-status-messages": "^1.1.0"
|
||||
"@actions/github": "^5.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "^0.36.1",
|
||||
@@ -16,9 +13,9 @@
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-github": "^4.8.0",
|
||||
"jest": "^29.6.1",
|
||||
"make-coverage-badge": "^1.2.0",
|
||||
"nock": "^13.3.1",
|
||||
"prettier": "^3.0.0",
|
||||
"make-coverage-badge": "^1.2.0"
|
||||
"prettier": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"all": "npm run format && npm run lint && npm run prepare && npm run test && npm run coverage-badge",
|
||||
|
||||
@@ -4,9 +4,7 @@ const path = require('path')
|
||||
|
||||
describe('with all environment variables set', () => {
|
||||
beforeEach(() => {
|
||||
process.env.ACTIONS_RUNTIME_URL = 'http://my-url'
|
||||
process.env.GITHUB_RUN_ID = '123'
|
||||
process.env.ACTIONS_RUNTIME_TOKEN = 'a-token'
|
||||
process.env.GITHUB_REPOSITORY = 'actions/is-awesome'
|
||||
process.env.GITHUB_TOKEN = 'gha-token'
|
||||
process.env.GITHUB_SHA = '123abc'
|
||||
@@ -26,7 +24,7 @@ describe('with all environment variables set', () => {
|
||||
|
||||
describe('with variables missing', () => {
|
||||
it('execution fails if there are missing variables', done => {
|
||||
delete process.env.ACTIONS_RUNTIME_URL
|
||||
delete process.env.GITHUB_RUN_ID
|
||||
const ip = path.join(__dirname, '../index.js')
|
||||
cp.exec(`node ${ip}`, { env: process.env }, (err, stdout) => {
|
||||
expect(stdout).toBe('')
|
||||
|
||||
@@ -9,9 +9,7 @@ const fakeJwt =
|
||||
describe('Deployment', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
process.env.ACTIONS_RUNTIME_URL = 'http://my-url/'
|
||||
process.env.GITHUB_RUN_ID = '123'
|
||||
process.env.ACTIONS_RUNTIME_TOKEN = 'a-token'
|
||||
process.env.GITHUB_REPOSITORY = 'actions/is-awesome'
|
||||
process.env.GITHUB_TOKEN = 'gha-token'
|
||||
process.env.GITHUB_SHA = '123abc'
|
||||
@@ -53,18 +51,18 @@ describe('Deployment', () => {
|
||||
it('can successfully create a deployment', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -84,25 +82,25 @@ describe('Deployment', () => {
|
||||
expect.stringMatching(new RegExp(`^Created deployment for ${process.env.GITHUB_SHA}`))
|
||||
)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
})
|
||||
|
||||
it('can successfully create a preview deployment', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt,
|
||||
preview: true
|
||||
@@ -127,36 +125,44 @@ describe('Deployment', () => {
|
||||
expect.stringMatching(new RegExp(`^Created deployment for ${process.env.GITHUB_SHA}`))
|
||||
)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
})
|
||||
|
||||
it('reports errors with failed artifact exchange', async () => {
|
||||
it('reports errors with failed artifact metadata exchange', async () => {
|
||||
process.env.GITHUB_SHA = 'invalid-build-version'
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
.reply(400, {})
|
||||
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(400, { message: 'Bad request' })
|
||||
|
||||
// Create the deployment
|
||||
const deployment = new Deployment()
|
||||
await expect(deployment.create()).rejects.toEqual(
|
||||
new Error(
|
||||
`Failed to create deployment (status: 400) with build version ${process.env.GITHUB_SHA}. Responded with: Bad Request`
|
||||
`Failed to create deployment (status: 400) with build version ${process.env.GITHUB_SHA}. Responded with: Bad request`
|
||||
)
|
||||
)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
})
|
||||
|
||||
it('reports errors with a failed 500 in a deployment', async () => {
|
||||
process.env.GITHUB_SHA = 'build-version'
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
.reply(200, { value: [{ url: 'https://invalid-artifact.com', name: 'github-pages' }] })
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://invalid-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA
|
||||
})
|
||||
.reply(500, { message: 'oh no' })
|
||||
@@ -169,19 +175,24 @@ describe('Deployment', () => {
|
||||
)
|
||||
)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
})
|
||||
|
||||
it('reports errors with an unexpected 403 during deployment', async () => {
|
||||
process.env.GITHUB_SHA = 'build-version'
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
.reply(200, { value: [{ url: 'https://invalid-artifact.com', name: 'github-pages' }] })
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://invalid-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA
|
||||
})
|
||||
.reply(403, { message: 'You are forbidden' })
|
||||
@@ -194,19 +205,24 @@ describe('Deployment', () => {
|
||||
)
|
||||
)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
})
|
||||
|
||||
it('reports errors with an unexpected 404 during deployment', async () => {
|
||||
process.env.GITHUB_SHA = 'build-version'
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
.reply(200, { value: [{ url: 'https://invalid-artifact.com', name: 'github-pages' }] })
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://invalid-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA
|
||||
})
|
||||
.reply(404, { message: 'Not found' })
|
||||
@@ -219,19 +235,24 @@ describe('Deployment', () => {
|
||||
)
|
||||
)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
})
|
||||
|
||||
it('reports errors with failed deployments', async () => {
|
||||
process.env.GITHUB_SHA = 'invalid-build-version'
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
.reply(200, { value: [{ url: 'https://invalid-artifact.com', name: 'github-pages' }] })
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://invalid-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA
|
||||
})
|
||||
.reply(400, { message: 'Bad request' })
|
||||
@@ -244,26 +265,83 @@ describe('Deployment', () => {
|
||||
)
|
||||
)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
})
|
||||
|
||||
it('fails if there are multiple artifacts with the same name', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
total_count: 2,
|
||||
artifacts: [
|
||||
{
|
||||
id: 13,
|
||||
name: `github-pages`,
|
||||
size_in_bytes: 1400
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
name: `github-pages`,
|
||||
size_in_bytes: 1620
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const deployment = new Deployment()
|
||||
await expect(deployment.create(fakeJwt)).rejects.toThrow(
|
||||
`Multiple artifact unexpectedly found for workflow run ${process.env.GITHUB_RUN_ID}. Artifact count is 2.`
|
||||
)
|
||||
|
||||
artifactMetadataScope.done()
|
||||
})
|
||||
|
||||
it('fails if there are no artifacts found', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
total_count: 0,
|
||||
artifacts: []
|
||||
})
|
||||
|
||||
const deployment = new Deployment()
|
||||
await expect(deployment.create(fakeJwt)).rejects.toThrow(
|
||||
`No artifacts found for workflow run ${process.env.GITHUB_RUN_ID}. Ensure artifacts are uploaded with actions/artifact@v4 or later.`
|
||||
)
|
||||
|
||||
artifactMetadataScope.done()
|
||||
})
|
||||
|
||||
it('warns if the artifact size is bigger than maximum', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
const artifactSize = ONE_GIGABYTE + 1
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages', size: `${artifactSize}` },
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' }
|
||||
total_count: 1,
|
||||
artifacts: [
|
||||
{
|
||||
id: 12,
|
||||
name: `github-pages`,
|
||||
size_in_bytes: `${artifactSize}`
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 12,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -283,25 +361,25 @@ describe('Deployment', () => {
|
||||
expect.stringMatching(new RegExp(`^Created deployment for ${process.env.GITHUB_SHA}`))
|
||||
)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
})
|
||||
|
||||
it('warns when the timeout is greater than the maximum allowed', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -332,7 +410,7 @@ describe('Deployment', () => {
|
||||
`Warning: timeout value is greater than the allowed maximum - timeout set to the maximum of ${MAX_TIMEOUT} milliseconds.`
|
||||
)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
})
|
||||
})
|
||||
@@ -341,18 +419,18 @@ describe('Deployment', () => {
|
||||
it('sets output to success when deployment is successful', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -377,7 +455,7 @@ describe('Deployment', () => {
|
||||
expect(core.setOutput).toBeCalledWith('status', 'succeed')
|
||||
expect(core.info).toHaveBeenLastCalledWith('Reported success!')
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
deploymentStatusScope.done()
|
||||
})
|
||||
@@ -392,18 +470,18 @@ describe('Deployment', () => {
|
||||
it('exits early when deployment is not in progress', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -420,25 +498,25 @@ describe('Deployment', () => {
|
||||
await deployment.check()
|
||||
expect(core.setFailed).toBeCalledWith('Unable to get deployment status.')
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
})
|
||||
|
||||
it('enforces max timeout', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -485,7 +563,7 @@ describe('Deployment', () => {
|
||||
expect(core.error).toBeCalledWith('Timeout reached, aborting!')
|
||||
expect(core.setFailed).toBeCalledWith('Timeout reached, aborting!')
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
cancelDeploymentScope.done()
|
||||
})
|
||||
@@ -493,18 +571,18 @@ describe('Deployment', () => {
|
||||
it('sets timeout to user timeout if user timeout is less than max timeout', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -551,7 +629,7 @@ describe('Deployment', () => {
|
||||
expect(core.error).toBeCalledWith('Timeout reached, aborting!')
|
||||
expect(core.setFailed).toBeCalledWith('Timeout reached, aborting!')
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
cancelDeploymentScope.done()
|
||||
})
|
||||
@@ -559,18 +637,18 @@ describe('Deployment', () => {
|
||||
it('sets output to success when timeout is set but not reached', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -620,7 +698,7 @@ describe('Deployment', () => {
|
||||
expect(core.setOutput).toBeCalledWith('status', 'succeed')
|
||||
expect(core.info).toHaveBeenLastCalledWith('Reported success!')
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
deploymentStatusScope.done()
|
||||
})
|
||||
@@ -630,18 +708,18 @@ describe('Deployment', () => {
|
||||
it('can successfully cancel a deployment', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -665,7 +743,7 @@ describe('Deployment', () => {
|
||||
|
||||
expect(core.info).toHaveBeenLastCalledWith(`Canceled deployment with ID ${process.env.GITHUB_SHA}`)
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
cancelDeploymentScope.done()
|
||||
})
|
||||
@@ -686,18 +764,18 @@ describe('Deployment', () => {
|
||||
it('catches an error when trying to cancel a deployment', async () => {
|
||||
process.env.GITHUB_SHA = 'valid-build-version'
|
||||
|
||||
const artifactExchangeScope = nock(`http://my-url`)
|
||||
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
|
||||
const artifactMetadataScope = nock(`https://api.github.com`)
|
||||
.get(
|
||||
`/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts?name=github-pages`
|
||||
)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{ url: 'https://another-artifact.com', name: 'another-artifact' },
|
||||
{ url: 'https://fake-artifact.com', name: 'github-pages' }
|
||||
]
|
||||
total_count: 1,
|
||||
artifacts: [{ id: 11, name: `github-pages`, size_in_bytes: 221 }]
|
||||
})
|
||||
|
||||
const createDeploymentScope = nock('https://api.github.com')
|
||||
.post(`/repos/${process.env.GITHUB_REPOSITORY}/pages/deployments`, {
|
||||
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
|
||||
artifact_id: 11,
|
||||
pages_build_version: process.env.GITHUB_SHA,
|
||||
oidc_token: fakeJwt
|
||||
})
|
||||
@@ -722,7 +800,7 @@ describe('Deployment', () => {
|
||||
|
||||
expect(core.error).toHaveBeenCalledWith(`Canceling Pages deployment failed`, expect.anything())
|
||||
|
||||
artifactExchangeScope.done()
|
||||
artifactMetadataScope.done()
|
||||
createDeploymentScope.done()
|
||||
cancelDeploymentScope.done()
|
||||
})
|
||||
|
||||
@@ -1,58 +1,5 @@
|
||||
const core = require('@actions/core')
|
||||
const github = require('@actions/github')
|
||||
const hc = require('@actions/http-client')
|
||||
const { RequestError } = require('@octokit/request-error')
|
||||
const HttpStatusMessages = require('http-status-messages')
|
||||
|
||||
// All variables we need from the runtime are loaded here
|
||||
const getContext = require('./context')
|
||||
|
||||
async function processRuntimeResponse(res, requestOptions) {
|
||||
// Parse the response body as JSON
|
||||
let obj = null
|
||||
try {
|
||||
const contents = await res.readBody()
|
||||
if (contents && contents.length > 0) {
|
||||
obj = JSON.parse(contents)
|
||||
}
|
||||
} catch (error) {
|
||||
// Invalid resource (contents not json); leaving resulting obj as null
|
||||
}
|
||||
|
||||
// Specific response shape aligned with Octokit
|
||||
const response = {
|
||||
url: res.message?.url || requestOptions.url,
|
||||
status: res.message?.statusCode || 0,
|
||||
headers: {
|
||||
...res.message?.headers
|
||||
},
|
||||
data: obj
|
||||
}
|
||||
|
||||
// Forcibly throw errors for negative HTTP status codes!
|
||||
// @actions/http-client doesn't do this by default.
|
||||
// Mimic the errors thrown by Octokit for consistency.
|
||||
if (response.status >= 400) {
|
||||
// Try to get an error message from the response body
|
||||
const errorMsg =
|
||||
(typeof response.data === 'string' && response.data) ||
|
||||
response.data?.error ||
|
||||
response.data?.message ||
|
||||
// Try the Node HTTP IncomingMessage's statusMessage property
|
||||
res.message?.statusMessage ||
|
||||
// Fallback to the HTTP status message based on the status code
|
||||
HttpStatusMessages[response.status] ||
|
||||
// Or if the status code is unexpected...
|
||||
`Unknown error (${response.status})`
|
||||
|
||||
throw new RequestError(errorMsg, response.status, {
|
||||
response,
|
||||
request: requestOptions
|
||||
})
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
async function getArtifactMetadata({ githubToken, runId, artifactName }) {
|
||||
const octokit = github.getOctokit(githubToken)
|
||||
@@ -60,20 +7,27 @@ async function getArtifactMetadata({ githubToken, runId, artifactName }) {
|
||||
try {
|
||||
core.info(`Fetching artifact metadata for ${artifactName} in run ${runId}`)
|
||||
|
||||
const response = await octokit.request("GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts?name={artifactName}", {
|
||||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
run_id: runId,
|
||||
artifactName: artifactName
|
||||
})
|
||||
const response = await octokit.request(
|
||||
'GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts?name={artifactName}',
|
||||
{
|
||||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
run_id: runId,
|
||||
artifactName: artifactName
|
||||
}
|
||||
)
|
||||
|
||||
const artifactCount = response.data.total_count
|
||||
core.debug(`List artifact count: ${artifactCount}`)
|
||||
|
||||
if (artifactCount === 0) {
|
||||
throw new Error(`No artifacts found for workflow run ${runId}. Ensure artifacts are uploaded with actions/artifact@v4 or later.`)
|
||||
throw new Error(
|
||||
`No artifacts found for workflow run ${runId}. Ensure artifacts are uploaded with actions/artifact@v4 or later.`
|
||||
)
|
||||
} else if (artifactCount > 1) {
|
||||
throw new Error(`Multiple artifact unexpectedly found for workflow run ${runId}. Artifact count is ${artifactCount}.`)
|
||||
throw new Error(
|
||||
`Multiple artifact unexpectedly found for workflow run ${runId}. Artifact count is ${artifactCount}.`
|
||||
)
|
||||
}
|
||||
|
||||
const artifact = response.data.artifacts[0]
|
||||
@@ -94,61 +48,6 @@ async function getArtifactMetadata({ githubToken, runId, artifactName }) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getSignedArtifactMetadata({ runtimeToken, workflowRunId, artifactName }) {
|
||||
const { runTimeUrl: RUNTIME_URL } = getContext()
|
||||
const artifactExchangeUrl = `${RUNTIME_URL}_apis/pipelines/workflows/${workflowRunId}/artifacts?api-version=6.0-preview`
|
||||
|
||||
const httpClient = new hc.HttpClient()
|
||||
let data = null
|
||||
|
||||
try {
|
||||
const requestHeaders = {
|
||||
accept: 'application/json',
|
||||
authorization: `Bearer ${runtimeToken}`
|
||||
}
|
||||
const requestOptions = {
|
||||
method: 'GET',
|
||||
url: artifactExchangeUrl,
|
||||
headers: {
|
||||
...requestHeaders
|
||||
},
|
||||
body: null
|
||||
}
|
||||
|
||||
core.info(`Artifact exchange URL: ${artifactExchangeUrl}`)
|
||||
const res = await httpClient.get(artifactExchangeUrl, requestHeaders)
|
||||
|
||||
// May throw a RequestError (HttpError)
|
||||
const response = await processRuntimeResponse(res, requestOptions)
|
||||
|
||||
data = response.data
|
||||
core.debug(JSON.stringify(data))
|
||||
} catch (error) {
|
||||
core.error('Getting signed artifact URL failed', error)
|
||||
throw error
|
||||
}
|
||||
|
||||
const artifact = data?.value?.find(artifact => artifact.name === artifactName)
|
||||
const artifactRawUrl = artifact?.url
|
||||
if (!artifactRawUrl) {
|
||||
throw new Error(
|
||||
'No uploaded artifact was found! Please check if there are any errors at build step, or uploaded artifact name is correct.'
|
||||
)
|
||||
}
|
||||
|
||||
const signedArtifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
|
||||
|
||||
const artifactSize = artifact?.size
|
||||
if (!artifactSize) {
|
||||
core.warning('Artifact size was not found. Unable to verify if artifact size exceeds the allowed size.')
|
||||
}
|
||||
|
||||
return {
|
||||
url: signedArtifactUrl,
|
||||
size: artifactSize
|
||||
}
|
||||
}
|
||||
|
||||
async function createPagesDeployment({ githubToken, artifactId, buildVersion, idToken, isPreview = false }) {
|
||||
const octokit = github.getOctokit(githubToken)
|
||||
|
||||
@@ -214,7 +113,6 @@ async function cancelPagesDeployment({ githubToken, deploymentId }) {
|
||||
|
||||
module.exports = {
|
||||
getArtifactMetadata,
|
||||
getSignedArtifactMetadata,
|
||||
createPagesDeployment,
|
||||
getPagesDeploymentStatus,
|
||||
cancelPagesDeployment
|
||||
|
||||
@@ -2,7 +2,12 @@ const core = require('@actions/core')
|
||||
|
||||
// All variables we need from the runtime are loaded here
|
||||
const getContext = require('./context')
|
||||
const { getArtifactMetadata, getPagesDeploymentStatus, createPagesDeployment, cancelPagesDeployment } = require('./api-client')
|
||||
const {
|
||||
getArtifactMetadata,
|
||||
getPagesDeploymentStatus,
|
||||
createPagesDeployment,
|
||||
cancelPagesDeployment
|
||||
} = require('./api-client')
|
||||
|
||||
const temporaryErrorStatus = {
|
||||
unknown_status: 'Unable to get deployment status.',
|
||||
@@ -58,15 +63,12 @@ class Deployment {
|
||||
core.debug(`Action ID: ${this.actionsId}`)
|
||||
core.debug(`Actions Workflow Run ID: ${this.workflowRun}`)
|
||||
|
||||
core.info("Getting artifact's metadata...")
|
||||
const artifactData = await getArtifactMetadata({
|
||||
githubToken: this.githubToken,
|
||||
runId: this.workflowRun,
|
||||
artifactName: this.artifactName
|
||||
})
|
||||
|
||||
console.log(artifactData)
|
||||
|
||||
if (artifactData?.size > ONE_GIGABYTE) {
|
||||
core.warning(
|
||||
`Uploaded artifact size of ${artifactData?.size} bytes exceeds the allowed size of ${SIZE_LIMIT_DESCRIPTION}. Deployment might fail.`
|
||||
|
||||
Reference in New Issue
Block a user