Compare commits

...

48 Commits

Author SHA1 Message Date
Mingzi
41f0a8ab89 Merge pull request #40 from actions/improve-error-message
Improve error message
2022-06-29 10:37:48 -07:00
yimysty
b918908973 run npm generate file 2022-06-29 10:35:08 -07:00
Mingzi
1ae5d2452b Update src/deployment.js
Co-authored-by: Yoann Chaudet <yoannchaudet@github.com>
2022-06-29 10:16:32 -07:00
yimysty
e2219a89b1 fix broken test cases 2022-06-28 18:18:42 -07:00
yimysty
72b116b825 fix unintended changes 2022-06-28 18:01:48 -07:00
yimysty
11a13019c2 adjust debugging message 2022-06-28 17:58:10 -07:00
yimysty
801d74db09 switch to console.log 2022-06-28 17:55:21 -07:00
yimysty
64c69a5fdf normalize error message 2022-06-28 17:50:08 -07:00
yimysty
03d70e4a19 info stack trace 2022-06-28 17:44:21 -07:00
yimysty
64e33b2a0d info stack trace 2022-06-28 17:39:10 -07:00
yimysty
c3d24faf75 info stack trace 2022-06-28 17:38:14 -07:00
yimysty
2b0c6eaf67 try output stacktrace as well 2022-06-28 17:35:03 -07:00
yimysty
358b034ef8 improve error message 2022-06-28 16:08:07 -07:00
Yoann Chaudet
13ef0cb0a0 Merge pull request #39 from actions/joshmgross/add-codeowners
Add CODEOWNERS
2022-06-14 13:30:16 -07:00
Josh Gross
2bf05927ae Add CODEOWNERS 2022-06-14 14:39:58 -04:00
Mingzi
0745e9700c Merge pull request #38 from actions/fix-cancell-token
Fix cancel deployment token is empty
2022-06-08 14:19:14 -07:00
yimysty
43dced9e8c add pack-lock.json 2022-06-08 12:57:34 -07:00
yimysty
fce105b3ea fix unable to cancel deployment due to cancel token nil 2022-06-08 11:47:06 -07:00
Yoann Chaudet
148e2ea9dd Create codeql-analysis.yml 2022-04-26 10:29:56 -07:00
Yoann Chaudet
506f839b97 Merge pull request #31 from fulldecent/patch-1
Correct documentation for reporting interval
2022-04-26 10:26:02 -07:00
Yoann Chaudet
f7a158aceb Merge branch 'main' into patch-1 2022-04-26 10:24:40 -07:00
Yoann Chaudet
ca23c7917e Merge pull request #29 from actions/dependabot/npm_and_yarn/minimist-1.2.6
Bump minimist from 1.2.5 to 1.2.6
2022-04-26 10:24:21 -07:00
dependabot[bot]
0c60998bd5 Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-26 17:21:30 +00:00
Yoann Chaudet
4154a47b87 Merge pull request #34 from actions/dependabot/npm_and_yarn/follow-redirects-1.14.9
Bump follow-redirects from 1.14.4 to 1.14.9
2022-04-26 10:20:47 -07:00
Yoann Chaudet
17fd28439d ci 2022-04-26 10:19:37 -07:00
Yoann Chaudet
0f19a8f78c Update dist 2022-04-26 09:58:05 -07:00
dependabot[bot]
595c840e2a Bump follow-redirects from 1.14.4 to 1.14.9
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.4 to 1.14.9.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.4...v1.14.9)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-26 16:55:09 +00:00
Mingzi
57f2f8bd29 Merge pull request #32 from fulldecent/patch-2
correct spelling of GitHub
2022-04-15 11:21:39 -07:00
Mingzi
68c14dcd2c Merge branch 'main' into patch-2 2022-04-15 11:20:55 -07:00
Jess Bees
a7af90c328 Merge pull request #30 from actions/decouple-telemetry
Remove the support for older dynamic jekyll workflows
2022-04-15 13:51:54 -04:00
William Entriken
ef910bd895 correct spelling of GitHub 2022-04-11 14:30:09 -04:00
William Entriken
53f4e898cd Correct documentation for reporting interval 2022-04-11 14:29:33 -04:00
Jess Bees
62c650c70d Remove the support for older dynamic jekyll workflows
The pages dynamic workflow now decouples telemetry from deploy for 100%
of users, so we can remove this old conditional.
2022-04-04 16:12:36 -04:00
Jess Bees
eaf36f48c9 Merge pull request #24 from actions/decouple-telemetry
Decouple telemetry API call from main action
2022-03-31 12:34:24 -04:00
Jess Bees
01f6ae5af2 Recompile action after pulling in PR suggestions 2022-03-31 12:05:36 -04:00
Jess Bees
82cb77089c Update action.yml
Co-authored-by: James M. Greene <JamesMGreene@github.com>
2022-03-31 11:47:49 -04:00
Jess Bees
ad36b7023a Don't bother converting action input to string
This has been an established pattern with Actions for a long time; we don't have to worry about it changing.

Co-authored-by: James M. Greene <JamesMGreene@github.com>
2022-03-31 11:47:33 -04:00
Jess Bees
32b8b86ff0 Support existing behavior of this action 2022-03-29 15:08:35 -04:00
Jess Bees
a598b2af14 Correctly test for boolean input's truthiness
It gets cast to a string! Eep!
2022-03-29 09:45:18 -04:00
Jess Bees
f511fa4665 Merge branch 'main' into decouple-telemetry 2022-03-29 09:05:35 -04:00
Yoann Chaudet
0e157789db Merge pull request #27 from actions/increase-default-query-interval
Increase default query interval and fix time exceed bug
2022-03-28 12:38:22 -07:00
yimysty
12940a5b99 fix the timeout not honor bug 2022-03-28 12:32:59 -07:00
yimysty
6afc4f2884 slow query seconds 2022-03-28 12:28:46 -07:00
Mingzi
a68b5a4ae1 Merge pull request #26 from actions/parsing-number
Parse correct timeout
2022-03-28 11:21:14 -07:00
yimysty
171a8a05dd update number parsing 2022-03-28 11:19:50 -07:00
Jess Bees
7a1dc4e394 update dist files 2022-03-23 14:56:28 -04:00
Jess Bees
92f6725bee Only emit telemetry when the emit_telemetry input is truthy 2022-03-23 14:40:57 -04:00
Jess Bees
e1279a88ef Don't call the telemetry pre-hook entrypoint 2022-03-23 14:22:16 -04:00
11 changed files with 507 additions and 230 deletions

View File

@@ -37,8 +37,13 @@ jobs:
- name: Compare the expected and actual dist/ directories - name: Compare the expected and actual dist/ directories
run: | run: |
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. See status below:" echo "Detected uncommitted changes after build in dist folder. See status below:"
git diff
exit 1
fi
if [ "$(git diff --ignore-space-at-eol pre/ | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build in pre folder. See status below:"
git diff git diff
exit 1 exit 1
fi fi
id: diff

70
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,70 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '40 0 * * 1'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

1
CODEOWNERS Normal file
View File

@@ -0,0 +1 @@
* @actions/pages

View File

@@ -3,8 +3,11 @@ description: 'A GitHub Action to deploy an artifact to GitHub Pages'
runs: runs:
using: 'node16' using: 'node16'
main: 'dist/index.js' main: 'dist/index.js'
pre: 'pre/index.js'
inputs: inputs:
emit_telemetry:
description: 'Should this action only emit build telemetry instead of deploying the build artifact?'
required: false
default: "false"
token: token:
description: 'GitHub token' description: 'GitHub token'
default: ${{ github.token }} default: ${{ github.token }}
@@ -18,9 +21,9 @@ inputs:
required: false required: false
default: "10" default: "10"
reporting_interval: reporting_interval:
description: 'Time in milliseconds between two deployment status report (default: 1 second)' description: 'Time in milliseconds between two deployment status report (default: 5 seconds)'
required: false required: false
default: "1000" default: "5000"
outputs: outputs:
page_url: page_url:
description: 'URL to deployed Github Pages' description: 'URL to deployed GitHub Pages'

269
dist/index.js vendored
View File

@@ -5068,7 +5068,7 @@ events.forEach(function (event) {
// Error types with codes // Error types with codes
var RedirectionError = createErrorType( var RedirectionError = createErrorType(
"ERR_FR_REDIRECTION_FAILURE", "ERR_FR_REDIRECTION_FAILURE",
"" "Redirected request failed"
); );
var TooManyRedirectsError = createErrorType( var TooManyRedirectsError = createErrorType(
"ERR_FR_TOO_MANY_REDIRECTS", "ERR_FR_TOO_MANY_REDIRECTS",
@@ -5219,10 +5219,16 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
// Stops a timeout from triggering // Stops a timeout from triggering
function clearTimer() { function clearTimer() {
// Clear the timeout
if (self._timeout) { if (self._timeout) {
clearTimeout(self._timeout); clearTimeout(self._timeout);
self._timeout = null; self._timeout = null;
} }
// Clean up all attached listeners
self.removeListener("abort", clearTimer);
self.removeListener("error", clearTimer);
self.removeListener("response", clearTimer);
if (callback) { if (callback) {
self.removeListener("timeout", callback); self.removeListener("timeout", callback);
} }
@@ -5246,8 +5252,9 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
// Clean up on events // Clean up on events
this.on("socket", destroyOnTimeout); this.on("socket", destroyOnTimeout);
this.once("response", clearTimer); this.on("abort", clearTimer);
this.once("error", clearTimer); this.on("error", clearTimer);
this.on("response", clearTimer);
return this; return this;
}; };
@@ -5379,84 +5386,101 @@ RedirectableRequest.prototype._processResponse = function (response) {
// the user agent MAY automatically redirect its request to the URI // the user agent MAY automatically redirect its request to the URI
// referenced by the Location field value, // referenced by the Location field value,
// even if the specific status code is not understood. // even if the specific status code is not understood.
// If the response is not a redirect; return it as-is
var location = response.headers.location; var location = response.headers.location;
if (location && this._options.followRedirects !== false && if (!location || this._options.followRedirects === false ||
statusCode >= 300 && statusCode < 400) { statusCode < 300 || statusCode >= 400) {
// Abort the current request
abortRequest(this._currentRequest);
// Discard the remainder of the response to avoid waiting for data
response.destroy();
// RFC7231§6.4: A client SHOULD detect and intervene
// in cyclical redirections (i.e., "infinite" redirection loops).
if (++this._redirectCount > this._options.maxRedirects) {
this.emit("error", new TooManyRedirectsError());
return;
}
// RFC7231§6.4: Automatic redirection needs to done with
// care for methods not known to be safe, […]
// RFC7231§6.4.23: For historical reasons, a user agent MAY change
// the request method from POST to GET for the subsequent request.
if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" ||
// RFC7231§6.4.4: The 303 (See Other) status code indicates that
// the server is redirecting the user agent to a different resource […]
// A user agent can perform a retrieval request targeting that URI
// (a GET or HEAD request if using HTTP) […]
(statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) {
this._options.method = "GET";
// Drop a possible entity and headers related to it
this._requestBodyBuffers = [];
removeMatchingHeaders(/^content-/i, this._options.headers);
}
// Drop the Host header, as the redirect might lead to a different host
var previousHostName = removeMatchingHeaders(/^host$/i, this._options.headers) ||
url.parse(this._currentUrl).hostname;
// Create the redirected request
var redirectUrl = url.resolve(this._currentUrl, location);
debug("redirecting to", redirectUrl);
this._isRedirect = true;
var redirectUrlParts = url.parse(redirectUrl);
Object.assign(this._options, redirectUrlParts);
// Drop the Authorization header if redirecting to another host
if (redirectUrlParts.hostname !== previousHostName) {
removeMatchingHeaders(/^authorization$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
if (typeof this._options.beforeRedirect === "function") {
var responseDetails = { headers: response.headers };
try {
this._options.beforeRedirect.call(null, this._options, responseDetails);
}
catch (err) {
this.emit("error", err);
return;
}
this._sanitizeOptions(this._options);
}
// Perform the redirected request
try {
this._performRequest();
}
catch (cause) {
var error = new RedirectionError("Redirected request failed: " + cause.message);
error.cause = cause;
this.emit("error", error);
}
}
else {
// The response is not a redirect; return it as-is
response.responseUrl = this._currentUrl; response.responseUrl = this._currentUrl;
response.redirects = this._redirects; response.redirects = this._redirects;
this.emit("response", response); this.emit("response", response);
// Clean up // Clean up
this._requestBodyBuffers = []; this._requestBodyBuffers = [];
return;
}
// The response is a redirect, so abort the current request
abortRequest(this._currentRequest);
// Discard the remainder of the response to avoid waiting for data
response.destroy();
// RFC7231§6.4: A client SHOULD detect and intervene
// in cyclical redirections (i.e., "infinite" redirection loops).
if (++this._redirectCount > this._options.maxRedirects) {
this.emit("error", new TooManyRedirectsError());
return;
}
// RFC7231§6.4: Automatic redirection needs to done with
// care for methods not known to be safe, […]
// RFC7231§6.4.23: For historical reasons, a user agent MAY change
// the request method from POST to GET for the subsequent request.
if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" ||
// RFC7231§6.4.4: The 303 (See Other) status code indicates that
// the server is redirecting the user agent to a different resource […]
// A user agent can perform a retrieval request targeting that URI
// (a GET or HEAD request if using HTTP) […]
(statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) {
this._options.method = "GET";
// Drop a possible entity and headers related to it
this._requestBodyBuffers = [];
removeMatchingHeaders(/^content-/i, this._options.headers);
}
// Drop the Host header, as the redirect might lead to a different host
var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
// If the redirect is relative, carry over the host of the last request
var currentUrlParts = url.parse(this._currentUrl);
var currentHost = currentHostHeader || currentUrlParts.host;
var currentUrl = /^\w+:/.test(location) ? this._currentUrl :
url.format(Object.assign(currentUrlParts, { host: currentHost }));
// Determine the URL of the redirection
var redirectUrl;
try {
redirectUrl = url.resolve(currentUrl, location);
}
catch (cause) {
this.emit("error", new RedirectionError(cause));
return;
}
// Create the redirected request
debug("redirecting to", redirectUrl);
this._isRedirect = true;
var redirectUrlParts = url.parse(redirectUrl);
Object.assign(this._options, redirectUrlParts);
// Drop confidential headers when redirecting to a less secure protocol
// or to a different domain that is not a superdomain
if (redirectUrlParts.protocol !== currentUrlParts.protocol &&
redirectUrlParts.protocol !== "https:" ||
redirectUrlParts.host !== currentHost &&
!isSubdomain(redirectUrlParts.host, currentHost)) {
removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
if (typeof this._options.beforeRedirect === "function") {
var responseDetails = { headers: response.headers };
try {
this._options.beforeRedirect.call(null, this._options, responseDetails);
}
catch (err) {
this.emit("error", err);
return;
}
this._sanitizeOptions(this._options);
}
// Perform the redirected request
try {
this._performRequest();
}
catch (cause) {
this.emit("error", new RedirectionError(cause));
} }
}; };
@@ -5560,13 +5584,20 @@ function removeMatchingHeaders(regex, headers) {
delete headers[header]; delete headers[header];
} }
} }
return lastValue; return (lastValue === null || typeof lastValue === "undefined") ?
undefined : String(lastValue).trim();
} }
function createErrorType(code, defaultMessage) { function createErrorType(code, defaultMessage) {
function CustomError(message) { function CustomError(cause) {
Error.captureStackTrace(this, this.constructor); Error.captureStackTrace(this, this.constructor);
this.message = message || defaultMessage; if (!cause) {
this.message = defaultMessage;
}
else {
this.message = defaultMessage + ": " + cause.message;
this.cause = cause;
}
} }
CustomError.prototype = new Error(); CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError; CustomError.prototype.constructor = CustomError;
@@ -5583,6 +5614,11 @@ function abortRequest(request) {
request.abort(); request.abort();
} }
function isSubdomain(subdomain, domain) {
const dot = subdomain.length - domain.length - 1;
return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
}
// Exports // Exports
module.exports = wrap({ http: http, https: https }); module.exports = wrap({ http: http, https: https });
module.exports.wrap = wrap; module.exports.wrap = wrap;
@@ -7106,15 +7142,41 @@ class Deployment {
}) })
this.requestedDeployment = true this.requestedDeployment = true
core.info(`Created deployment for ${this.buildVersion}`) core.info(`Created deployment for ${this.buildVersion}`)
core.info(JSON.stringify(response.data)) if (response && response.data) {
this.deploymentInfo = response.data core.info(JSON.stringify(response.data))
} catch (error) { this.deploymentInfo = response.data
core.info(`Failed to create deployment for ${this.buildVersion}.`) }
if (error.response && error.response.data) { } catch (error) {
core.info(JSON.stringify(error.response.data))
core.info(error.stack)
// output raw error in debug mode.
core.debug(JSON.stringify(error))
// build customized error message based on server response
if (error.response) {
let errorMessage = `Failed to create deployment (status: ${error.response.status}) with build version ${this.buildVersion}. `
if (error.response.status == 400) {
let message = ""
if (error.response.data && error.response.data.message) {
message = error.response.data.message
} else {
message = error.response.data
}
errorMessage += `Responded with: ${message}`
}
else if (error.response.status == 403) {
errorMessage += `Ensure GITHUB_TOKEN has permission "pages: write".`
} else if (error.response.status == 404) {
errorMessage += `Ensure GitHub Pages has been enabled.`
}
else if (error.response.status >= 500) {
errorMessage += `Server error, is githubstatus.com reporting a Pages outage? Please re-run the deployment at a later time.`
}
throw errorMessage
} else {
throw error
} }
core.setFailed(error)
throw error
} }
} }
@@ -7125,9 +7187,9 @@ class Deployment {
this.deploymentInfo["status_url"] : this.deploymentInfo["status_url"] :
`https://api.github.com/repos/${this.repositoryNwo}/pages/deployment/status/${process.env['GITHUB_SHA']}` `https://api.github.com/repos/${this.repositoryNwo}/pages/deployment/status/${process.env['GITHUB_SHA']}`
core.setOutput('page_url', this.deploymentInfo != null ? this.deploymentInfo["page_url"] : "") core.setOutput('page_url', this.deploymentInfo != null ? this.deploymentInfo["page_url"] : "")
const timeout = core.getInput('timeout') const timeout = Number(core.getInput('timeout'))
const reportingInterval = Number(core.getInput('reporting_interval')) const reportingInterval = Number(core.getInput('reporting_interval'))
const maxErrorCount = core.getInput('error_count') const maxErrorCount = Number(core.getInput('error_count'))
var startTime = Date.now() var startTime = Date.now()
var errorCount = 0 var errorCount = 0
@@ -7182,12 +7244,13 @@ class Deployment {
core.setFailed('Failed with status code: ' + res.status) core.setFailed('Failed with status code: ' + res.status)
break break
} }
}
// Handle timeout // Handle timeout
if (Date.now() - startTime >= timeout) { if (Date.now() - startTime >= timeout) {
core.info('Timeout reached, aborting!') core.info('Timeout reached, aborting!')
core.setFailed('Timeout reached, aborting!') core.setFailed('Timeout reached, aborting!')
return return
}
} }
} catch (error) { } catch (error) {
core.setFailed(error) core.setFailed(error)
@@ -7444,7 +7507,7 @@ async function cancelHandler(evtOrExitCodeOrError) {
{ {
headers: { headers: {
Accept: 'application/vnd.github.v3+json', Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, Authorization: `Bearer ${deployment.githubToken}`,
'Content-type': 'application/json' 'Content-type': 'application/json'
} }
} }
@@ -7452,14 +7515,21 @@ async function cancelHandler(evtOrExitCodeOrError) {
core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`) core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`)
} }
} catch (e) { } catch (e) {
console.info('Deployment cancellation failed', e) console.log('Deployment cancellation failed', e)
} }
process.exit(isNaN(+evtOrExitCodeOrError) ? 1 : +evtOrExitCodeOrError) process.exit(isNaN(+evtOrExitCodeOrError) ? 1 : +evtOrExitCodeOrError)
} }
async function main() { async function main() {
let idToken = ""
try {
idToken = await core.getIDToken()
} catch (error) {
console.log(error)
core.setFailed(`Ensure GITHUB_TOKEN has permission "idToken: write".`)
return
}
try { try {
const idToken = await core.getIDToken()
await deployment.create(idToken) await deployment.create(idToken)
await deployment.check() await deployment.check()
} catch (error) { } catch (error) {
@@ -7472,7 +7542,12 @@ process.on('SIGINT', cancelHandler)
process.on('SIGTERM', cancelHandler) process.on('SIGTERM', cancelHandler)
// Main // Main
main().then(() => __nccwpck_require__(9557)) const emitTelemetry = core.getInput("emit_telemetry")
if (emitTelemetry === "true") {
__nccwpck_require__(9557)
} else {
main()
}
})(); })();

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

45
package-lock.json generated
View File

@@ -4211,9 +4211,9 @@
"dev": true "dev": true
}, },
"node_modules/follow-redirects": { "node_modules/follow-redirects": {
"version": "1.14.4", "version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==", "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@@ -5975,9 +5975,9 @@
} }
}, },
"node_modules/minimist": { "node_modules/minimist": {
"version": "1.2.5", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
}, },
"node_modules/minipass": { "node_modules/minipass": {
"version": "3.1.5", "version": "3.1.5",
@@ -7123,6 +7123,20 @@
"is-typedarray": "^1.0.0" "is-typedarray": "^1.0.0"
} }
}, },
"node_modules/typescript": {
"version": "4.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz",
"integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==",
"dev": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/unbox-primitive": { "node_modules/unbox-primitive": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
@@ -10546,9 +10560,9 @@
"dev": true "dev": true
}, },
"follow-redirects": { "follow-redirects": {
"version": "1.14.4", "version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==" "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
}, },
"form-data": { "form-data": {
"version": "3.0.1", "version": "3.0.1",
@@ -11859,9 +11873,9 @@
} }
}, },
"minimist": { "minimist": {
"version": "1.2.5", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
}, },
"minipass": { "minipass": {
"version": "3.1.5", "version": "3.1.5",
@@ -12709,6 +12723,13 @@
"is-typedarray": "^1.0.0" "is-typedarray": "^1.0.0"
} }
}, },
"typescript": {
"version": "4.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz",
"integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==",
"dev": true,
"peer": true
},
"unbox-primitive": { "unbox-primitive": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",

View File

@@ -5068,7 +5068,7 @@ events.forEach(function (event) {
// Error types with codes // Error types with codes
var RedirectionError = createErrorType( var RedirectionError = createErrorType(
"ERR_FR_REDIRECTION_FAILURE", "ERR_FR_REDIRECTION_FAILURE",
"" "Redirected request failed"
); );
var TooManyRedirectsError = createErrorType( var TooManyRedirectsError = createErrorType(
"ERR_FR_TOO_MANY_REDIRECTS", "ERR_FR_TOO_MANY_REDIRECTS",
@@ -5219,10 +5219,16 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
// Stops a timeout from triggering // Stops a timeout from triggering
function clearTimer() { function clearTimer() {
// Clear the timeout
if (self._timeout) { if (self._timeout) {
clearTimeout(self._timeout); clearTimeout(self._timeout);
self._timeout = null; self._timeout = null;
} }
// Clean up all attached listeners
self.removeListener("abort", clearTimer);
self.removeListener("error", clearTimer);
self.removeListener("response", clearTimer);
if (callback) { if (callback) {
self.removeListener("timeout", callback); self.removeListener("timeout", callback);
} }
@@ -5246,8 +5252,9 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
// Clean up on events // Clean up on events
this.on("socket", destroyOnTimeout); this.on("socket", destroyOnTimeout);
this.once("response", clearTimer); this.on("abort", clearTimer);
this.once("error", clearTimer); this.on("error", clearTimer);
this.on("response", clearTimer);
return this; return this;
}; };
@@ -5379,84 +5386,101 @@ RedirectableRequest.prototype._processResponse = function (response) {
// the user agent MAY automatically redirect its request to the URI // the user agent MAY automatically redirect its request to the URI
// referenced by the Location field value, // referenced by the Location field value,
// even if the specific status code is not understood. // even if the specific status code is not understood.
// If the response is not a redirect; return it as-is
var location = response.headers.location; var location = response.headers.location;
if (location && this._options.followRedirects !== false && if (!location || this._options.followRedirects === false ||
statusCode >= 300 && statusCode < 400) { statusCode < 300 || statusCode >= 400) {
// Abort the current request
abortRequest(this._currentRequest);
// Discard the remainder of the response to avoid waiting for data
response.destroy();
// RFC7231§6.4: A client SHOULD detect and intervene
// in cyclical redirections (i.e., "infinite" redirection loops).
if (++this._redirectCount > this._options.maxRedirects) {
this.emit("error", new TooManyRedirectsError());
return;
}
// RFC7231§6.4: Automatic redirection needs to done with
// care for methods not known to be safe, […]
// RFC7231§6.4.23: For historical reasons, a user agent MAY change
// the request method from POST to GET for the subsequent request.
if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" ||
// RFC7231§6.4.4: The 303 (See Other) status code indicates that
// the server is redirecting the user agent to a different resource […]
// A user agent can perform a retrieval request targeting that URI
// (a GET or HEAD request if using HTTP) […]
(statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) {
this._options.method = "GET";
// Drop a possible entity and headers related to it
this._requestBodyBuffers = [];
removeMatchingHeaders(/^content-/i, this._options.headers);
}
// Drop the Host header, as the redirect might lead to a different host
var previousHostName = removeMatchingHeaders(/^host$/i, this._options.headers) ||
url.parse(this._currentUrl).hostname;
// Create the redirected request
var redirectUrl = url.resolve(this._currentUrl, location);
debug("redirecting to", redirectUrl);
this._isRedirect = true;
var redirectUrlParts = url.parse(redirectUrl);
Object.assign(this._options, redirectUrlParts);
// Drop the Authorization header if redirecting to another host
if (redirectUrlParts.hostname !== previousHostName) {
removeMatchingHeaders(/^authorization$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
if (typeof this._options.beforeRedirect === "function") {
var responseDetails = { headers: response.headers };
try {
this._options.beforeRedirect.call(null, this._options, responseDetails);
}
catch (err) {
this.emit("error", err);
return;
}
this._sanitizeOptions(this._options);
}
// Perform the redirected request
try {
this._performRequest();
}
catch (cause) {
var error = new RedirectionError("Redirected request failed: " + cause.message);
error.cause = cause;
this.emit("error", error);
}
}
else {
// The response is not a redirect; return it as-is
response.responseUrl = this._currentUrl; response.responseUrl = this._currentUrl;
response.redirects = this._redirects; response.redirects = this._redirects;
this.emit("response", response); this.emit("response", response);
// Clean up // Clean up
this._requestBodyBuffers = []; this._requestBodyBuffers = [];
return;
}
// The response is a redirect, so abort the current request
abortRequest(this._currentRequest);
// Discard the remainder of the response to avoid waiting for data
response.destroy();
// RFC7231§6.4: A client SHOULD detect and intervene
// in cyclical redirections (i.e., "infinite" redirection loops).
if (++this._redirectCount > this._options.maxRedirects) {
this.emit("error", new TooManyRedirectsError());
return;
}
// RFC7231§6.4: Automatic redirection needs to done with
// care for methods not known to be safe, […]
// RFC7231§6.4.23: For historical reasons, a user agent MAY change
// the request method from POST to GET for the subsequent request.
if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" ||
// RFC7231§6.4.4: The 303 (See Other) status code indicates that
// the server is redirecting the user agent to a different resource […]
// A user agent can perform a retrieval request targeting that URI
// (a GET or HEAD request if using HTTP) […]
(statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) {
this._options.method = "GET";
// Drop a possible entity and headers related to it
this._requestBodyBuffers = [];
removeMatchingHeaders(/^content-/i, this._options.headers);
}
// Drop the Host header, as the redirect might lead to a different host
var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
// If the redirect is relative, carry over the host of the last request
var currentUrlParts = url.parse(this._currentUrl);
var currentHost = currentHostHeader || currentUrlParts.host;
var currentUrl = /^\w+:/.test(location) ? this._currentUrl :
url.format(Object.assign(currentUrlParts, { host: currentHost }));
// Determine the URL of the redirection
var redirectUrl;
try {
redirectUrl = url.resolve(currentUrl, location);
}
catch (cause) {
this.emit("error", new RedirectionError(cause));
return;
}
// Create the redirected request
debug("redirecting to", redirectUrl);
this._isRedirect = true;
var redirectUrlParts = url.parse(redirectUrl);
Object.assign(this._options, redirectUrlParts);
// Drop confidential headers when redirecting to a less secure protocol
// or to a different domain that is not a superdomain
if (redirectUrlParts.protocol !== currentUrlParts.protocol &&
redirectUrlParts.protocol !== "https:" ||
redirectUrlParts.host !== currentHost &&
!isSubdomain(redirectUrlParts.host, currentHost)) {
removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
if (typeof this._options.beforeRedirect === "function") {
var responseDetails = { headers: response.headers };
try {
this._options.beforeRedirect.call(null, this._options, responseDetails);
}
catch (err) {
this.emit("error", err);
return;
}
this._sanitizeOptions(this._options);
}
// Perform the redirected request
try {
this._performRequest();
}
catch (cause) {
this.emit("error", new RedirectionError(cause));
} }
}; };
@@ -5560,13 +5584,20 @@ function removeMatchingHeaders(regex, headers) {
delete headers[header]; delete headers[header];
} }
} }
return lastValue; return (lastValue === null || typeof lastValue === "undefined") ?
undefined : String(lastValue).trim();
} }
function createErrorType(code, defaultMessage) { function createErrorType(code, defaultMessage) {
function CustomError(message) { function CustomError(cause) {
Error.captureStackTrace(this, this.constructor); Error.captureStackTrace(this, this.constructor);
this.message = message || defaultMessage; if (!cause) {
this.message = defaultMessage;
}
else {
this.message = defaultMessage + ": " + cause.message;
this.cause = cause;
}
} }
CustomError.prototype = new Error(); CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError; CustomError.prototype.constructor = CustomError;
@@ -5583,6 +5614,11 @@ function abortRequest(request) {
request.abort(); request.abort();
} }
function isSubdomain(subdomain, domain) {
const dot = subdomain.length - domain.length - 1;
return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
}
// Exports // Exports
module.exports = wrap({ http: http, https: https }); module.exports = wrap({ http: http, https: https });
module.exports.wrap = wrap; module.exports.wrap = wrap;
@@ -7106,15 +7142,41 @@ class Deployment {
}) })
this.requestedDeployment = true this.requestedDeployment = true
core.info(`Created deployment for ${this.buildVersion}`) core.info(`Created deployment for ${this.buildVersion}`)
core.info(JSON.stringify(response.data)) if (response && response.data) {
this.deploymentInfo = response.data core.info(JSON.stringify(response.data))
} catch (error) { this.deploymentInfo = response.data
core.info(`Failed to create deployment for ${this.buildVersion}.`) }
if (error.response && error.response.data) { } catch (error) {
core.info(JSON.stringify(error.response.data))
core.info(error.stack)
// output raw error in debug mode.
core.debug(JSON.stringify(error))
// build customized error message based on server response
if (error.response) {
let errorMessage = `Failed to create deployment (status: ${error.response.status}) with build version ${this.buildVersion}. `
if (error.response.status == 400) {
let message = ""
if (error.response.data && error.response.data.message) {
message = error.response.data.message
} else {
message = error.response.data
}
errorMessage += `Responded with: ${message}`
}
else if (error.response.status == 403) {
errorMessage += `Ensure GITHUB_TOKEN has permission "pages: write".`
} else if (error.response.status == 404) {
errorMessage += `Ensure GitHub Pages has been enabled.`
}
else if (error.response.status >= 500) {
errorMessage += `Server error, is githubstatus.com reporting a Pages outage? Please re-run the deployment at a later time.`
}
throw errorMessage
} else {
throw error
} }
core.setFailed(error)
throw error
} }
} }
@@ -7125,9 +7187,9 @@ class Deployment {
this.deploymentInfo["status_url"] : this.deploymentInfo["status_url"] :
`https://api.github.com/repos/${this.repositoryNwo}/pages/deployment/status/${process.env['GITHUB_SHA']}` `https://api.github.com/repos/${this.repositoryNwo}/pages/deployment/status/${process.env['GITHUB_SHA']}`
core.setOutput('page_url', this.deploymentInfo != null ? this.deploymentInfo["page_url"] : "") core.setOutput('page_url', this.deploymentInfo != null ? this.deploymentInfo["page_url"] : "")
const timeout = core.getInput('timeout') const timeout = Number(core.getInput('timeout'))
const reportingInterval = Number(core.getInput('reporting_interval')) const reportingInterval = Number(core.getInput('reporting_interval'))
const maxErrorCount = core.getInput('error_count') const maxErrorCount = Number(core.getInput('error_count'))
var startTime = Date.now() var startTime = Date.now()
var errorCount = 0 var errorCount = 0
@@ -7182,12 +7244,13 @@ class Deployment {
core.setFailed('Failed with status code: ' + res.status) core.setFailed('Failed with status code: ' + res.status)
break break
} }
}
// Handle timeout // Handle timeout
if (Date.now() - startTime >= timeout) { if (Date.now() - startTime >= timeout) {
core.info('Timeout reached, aborting!') core.info('Timeout reached, aborting!')
core.setFailed('Timeout reached, aborting!') core.setFailed('Timeout reached, aborting!')
return return
}
} }
} catch (error) { } catch (error) {
core.setFailed(error) core.setFailed(error)

File diff suppressed because one or more lines are too long

View File

@@ -62,15 +62,41 @@ class Deployment {
}) })
this.requestedDeployment = true this.requestedDeployment = true
core.info(`Created deployment for ${this.buildVersion}`) core.info(`Created deployment for ${this.buildVersion}`)
core.info(JSON.stringify(response.data)) if (response && response.data) {
this.deploymentInfo = response.data core.info(JSON.stringify(response.data))
} catch (error) { this.deploymentInfo = response.data
core.info(`Failed to create deployment for ${this.buildVersion}.`) }
if (error.response && error.response.data) { } catch (error) {
core.info(JSON.stringify(error.response.data))
core.info(error.stack)
// output raw error in debug mode.
core.debug(JSON.stringify(error))
// build customized error message based on server response
if (error.response) {
let errorMessage = `Failed to create deployment (status: ${error.response.status}) with build version ${this.buildVersion}. `
if (error.response.status == 400) {
let message = ""
if (error.response.data && error.response.data.message) {
message = error.response.data.message
} else {
message = error.response.data
}
errorMessage += `Responded with: ${message}`
}
else if (error.response.status == 403) {
errorMessage += `Ensure GITHUB_TOKEN has permission "pages: write".`
} else if (error.response.status == 404) {
errorMessage += `Ensure GitHub Pages has been enabled.`
}
else if (error.response.status >= 500) {
errorMessage += `Server error, is githubstatus.com reporting a Pages outage? Please re-run the deployment at a later time.`
}
throw errorMessage
} else {
throw error
} }
core.setFailed(error)
throw error
} }
} }
@@ -81,9 +107,9 @@ class Deployment {
this.deploymentInfo["status_url"] : this.deploymentInfo["status_url"] :
`https://api.github.com/repos/${this.repositoryNwo}/pages/deployment/status/${process.env['GITHUB_SHA']}` `https://api.github.com/repos/${this.repositoryNwo}/pages/deployment/status/${process.env['GITHUB_SHA']}`
core.setOutput('page_url', this.deploymentInfo != null ? this.deploymentInfo["page_url"] : "") core.setOutput('page_url', this.deploymentInfo != null ? this.deploymentInfo["page_url"] : "")
const timeout = core.getInput('timeout') const timeout = Number(core.getInput('timeout'))
const reportingInterval = Number(core.getInput('reporting_interval')) const reportingInterval = Number(core.getInput('reporting_interval'))
const maxErrorCount = core.getInput('error_count') const maxErrorCount = Number(core.getInput('error_count'))
var startTime = Date.now() var startTime = Date.now()
var errorCount = 0 var errorCount = 0
@@ -138,12 +164,13 @@ class Deployment {
core.setFailed('Failed with status code: ' + res.status) core.setFailed('Failed with status code: ' + res.status)
break break
} }
}
// Handle timeout // Handle timeout
if (Date.now() - startTime >= timeout) { if (Date.now() - startTime >= timeout) {
core.info('Timeout reached, aborting!') core.info('Timeout reached, aborting!')
core.setFailed('Timeout reached, aborting!') core.setFailed('Timeout reached, aborting!')
return return
}
} }
} catch (error) { } catch (error) {
core.setFailed(error) core.setFailed(error)

View File

@@ -24,7 +24,7 @@ async function cancelHandler(evtOrExitCodeOrError) {
{ {
headers: { headers: {
Accept: 'application/vnd.github.v3+json', Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, Authorization: `Bearer ${deployment.githubToken}`,
'Content-type': 'application/json' 'Content-type': 'application/json'
} }
} }
@@ -32,14 +32,21 @@ async function cancelHandler(evtOrExitCodeOrError) {
core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`) core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`)
} }
} catch (e) { } catch (e) {
console.info('Deployment cancellation failed', e) console.log('Deployment cancellation failed', e)
} }
process.exit(isNaN(+evtOrExitCodeOrError) ? 1 : +evtOrExitCodeOrError) process.exit(isNaN(+evtOrExitCodeOrError) ? 1 : +evtOrExitCodeOrError)
} }
async function main() { async function main() {
let idToken = ""
try {
idToken = await core.getIDToken()
} catch (error) {
console.log(error)
core.setFailed(`Ensure GITHUB_TOKEN has permission "idToken: write".`)
return
}
try { try {
const idToken = await core.getIDToken()
await deployment.create(idToken) await deployment.create(idToken)
await deployment.check() await deployment.check()
} catch (error) { } catch (error) {
@@ -52,4 +59,9 @@ process.on('SIGINT', cancelHandler)
process.on('SIGTERM', cancelHandler) process.on('SIGTERM', cancelHandler)
// Main // Main
main().then(() => require('./pre')) const emitTelemetry = core.getInput("emit_telemetry")
if (emitTelemetry === "true") {
require('./pre')
} else {
main()
}