Compare commits

..

1 Commits

Author SHA1 Message Date
yimysty
619e2a82bc add release actions 2022-01-31 07:39:14 -08:00
18 changed files with 265 additions and 671 deletions

View File

@@ -1,38 +0,0 @@
---
name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
template: |
# Changelog
$CHANGES
See details of [all code changes](https://github.com/actions/deploy-pages/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION) since previous release
categories:
- title: '🚀 Features'
labels:
- 'feature'
- 'enhancement'
- title: '🐛 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
- title: '🧰 Maintenance'
labels:
- 'infrastructure'
- 'automation'
- 'documentation'
- title: '🏎 Performance'
label: 'performance'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
version-resolver:
major:
labels:
- 'type: breaking'
minor:
labels:
- 'type: enhancement'
patch:
labels:
- 'type: bug'
- 'type: maintenance'
- 'type: documentation'
default: patch

View File

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

View File

@@ -1,70 +0,0 @@
# 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

View File

@@ -1,7 +1,7 @@
name: Release new action version
on:
release:
types: [edited]
types: [released]
workflow_dispatch:
inputs:
TAG_NAME:

View File

@@ -15,14 +15,10 @@ jobs:
- name: Set Node.JS
uses: actions/setup-node@v2
with:
node-version: 16.x
node-version: 12.x
- name: Install dependencies
run: npm install
- name: Run tests
run: npm run test
# Drafts your next Release notes as Pull Requests are merged into "main"
- uses: release-drafter/release-drafter@v5
if: github.ref_name == 'main'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

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

View File

@@ -1,73 +1,17 @@
# Deploy-Pages
This action is used to deploy [Actions artifacts][artifacts] to GitHub Pages.
This deploys artifacts to GitHub Pages.
## Scope
# Scope
⚠️ Official support for building Pages with Actions is in public beta at the moment.
⚠️ Official support for building Pages with Actions is in public beta at the moment. The scope is currently limited to **public repositories only**.
## Usage
# Usage
See [action.yml](action.yml) for the various `inputs` this action supports.
See [action.yml](action.yml)
For examples that make use of this action, check out our [starter-workflows][starter-workflows] in a variety of frameworks.
<!-- TODO: document custom workflow -->
This action expects an artifact named `github-pages` to have been created prior to execution. This is done automatically using [`actions/upload-pages-artifact`][upload-pages-artifact].
We recommend this action to be used in a dedicated job:
```yaml
jobs:
# Build job
build:
# <Not provided for brevity>
# At a minimum this job should upload artifacts using actions/upload-pages-artifact
# Deploy job
deploy:
# Add a dependency to the build job
needs: build
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source
# Deploy to the github-pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
# Specify runner + deployment step
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
```
## Security considerations
There are a few important considerations to be aware of:
1. The artifact being deployed must have been uploaded in a previous step, either in the same job or a separate job that doesn't execute until the upload is complete.
2. The job that executes the deployment must at minimum have the following permissions:
- `pages: write`
- `id-token: write`
3. The deployment should target the `github-pages` environment (you may use a different environment name if needed, but this is not recommended.)
4. If your Pages site is using a source branch, the deployment must originate from this source branch unless [your environment is protected][environment-protection] in which case the environment protection rules take precedence over the source branch rule
5. If your Pages site is using GitHub Actions as the source, while not required we highly recommend you also [protect your environment][environment-protection] (we do it by default for you)
## License
# License
The scripts and documentation in this project are released under the [MIT License](LICENSE).
<!-- references -->
[starter-workflows]: https://github.com/actions/starter-workflows/tree/main/pages
[upload-pages-artifact]: https://github.com/actions/upload-pages-artifact
[artifacts]: https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts
[environment-protection]: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#environment-protection-rules

View File

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

175
dist/index.js vendored
View File

@@ -5068,7 +5068,7 @@ events.forEach(function (event) {
// Error types with codes
var RedirectionError = createErrorType(
"ERR_FR_REDIRECTION_FAILURE",
"Redirected request failed"
""
);
var TooManyRedirectsError = createErrorType(
"ERR_FR_TOO_MANY_REDIRECTS",
@@ -5219,16 +5219,10 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
// Stops a timeout from triggering
function clearTimer() {
// Clear the timeout
if (self._timeout) {
clearTimeout(self._timeout);
self._timeout = null;
}
// Clean up all attached listeners
self.removeListener("abort", clearTimer);
self.removeListener("error", clearTimer);
self.removeListener("response", clearTimer);
if (callback) {
self.removeListener("timeout", callback);
}
@@ -5252,9 +5246,8 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
// Clean up on events
this.on("socket", destroyOnTimeout);
this.on("abort", clearTimer);
this.on("error", clearTimer);
this.on("response", clearTimer);
this.once("response", clearTimer);
this.once("error", clearTimer);
return this;
};
@@ -5386,21 +5379,10 @@ RedirectableRequest.prototype._processResponse = function (response) {
// the user agent MAY automatically redirect its request to the URI
// referenced by the Location field value,
// 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;
if (!location || this._options.followRedirects === false ||
statusCode < 300 || statusCode >= 400) {
response.responseUrl = this._currentUrl;
response.redirects = this._redirects;
this.emit("response", response);
// Clean up
this._requestBodyBuffers = [];
return;
}
// The response is a redirect, so abort the current request
if (location && this._options.followRedirects !== false &&
statusCode >= 300 && statusCode < 400) {
// Abort the current request
abortRequest(this._currentRequest);
// Discard the remainder of the response to avoid waiting for data
response.destroy();
@@ -5429,37 +5411,19 @@ RedirectableRequest.prototype._processResponse = function (response) {
}
// 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;
}
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 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);
// Drop the Authorization header if redirecting to another host
if (redirectUrlParts.hostname !== previousHostName) {
removeMatchingHeaders(/^authorization$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
@@ -5480,7 +5444,19 @@ RedirectableRequest.prototype._processResponse = function (response) {
this._performRequest();
}
catch (cause) {
this.emit("error", new RedirectionError(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.redirects = this._redirects;
this.emit("response", response);
// Clean up
this._requestBodyBuffers = [];
}
};
@@ -5584,20 +5560,13 @@ function removeMatchingHeaders(regex, headers) {
delete headers[header];
}
}
return (lastValue === null || typeof lastValue === "undefined") ?
undefined : String(lastValue).trim();
return lastValue;
}
function createErrorType(code, defaultMessage) {
function CustomError(cause) {
function CustomError(message) {
Error.captureStackTrace(this, this.constructor);
if (!cause) {
this.message = defaultMessage;
}
else {
this.message = defaultMessage + ": " + cause.message;
this.cause = cause;
}
this.message = message || defaultMessage;
}
CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError;
@@ -5614,11 +5583,6 @@ function abortRequest(request) {
request.abort();
}
function isSubdomain(subdomain, domain) {
const dot = subdomain.length - domain.length - 1;
return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
}
// Exports
module.exports = wrap({ http: http, https: https });
module.exports.wrap = wrap;
@@ -7057,9 +7021,7 @@ function getRequiredVars() {
buildVersion: process.env.GITHUB_SHA,
buildActor: process.env.GITHUB_ACTOR,
actionsId: process.env.GITHUB_ACTION,
githubToken: core.getInput('token'),
githubApiUrl: process.env.GITHUB_API_URL ?? 'https://api.github.com',
artifactName: core.getInput('artifact_name') ?? 'github-pages'
githubToken: core.getInput('token')
}
}
@@ -7107,8 +7069,6 @@ class Deployment {
this.workflowRun = context.workflowRun
this.requestedDeployment = false
this.deploymentInfo = null
this.githubApiUrl = context.githubApiUrl
this.artifactName = context.artifactName
}
// Ask the runtime for the unsigned artifact URL and deploy to GitHub Pages
@@ -7117,7 +7077,7 @@ class Deployment {
try {
core.info(`Actor: ${this.buildActor}`)
core.info(`Action ID: ${this.actionsId}`)
const pagesDeployEndpoint = `${this.githubApiUrl}/repos/${this.repositoryNwo}/pages/deployment`
const pagesDeployEndpoint = `https://api.github.com/repos/${this.repositoryNwo}/pages/deployment`
const artifactExgUrl = `${this.runTimeUrl}_apis/pipelines/workflows/${this.workflowRun}/artifacts?api-version=6.0-preview`
core.info(`Artifact URL: ${artifactExgUrl}`)
const {data} = await axios.get(artifactExgUrl, {
@@ -7127,12 +7087,10 @@ class Deployment {
}
})
core.info(JSON.stringify(data))
const artifactRawUrl = data?.value?.find(artifact => artifact.name === this.artifactName)?.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.')
if (data.value.length == 0) {
throw new Error('No uploaded artifact was found! Please check if there are any errors at build step.')
}
const artifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
const artifactUrl = `${data.value[0].url}&%24expand=SignedContent`
const payload = {
artifact_url: artifactUrl,
pages_build_version: this.buildVersion,
@@ -7148,54 +7106,28 @@ class Deployment {
})
this.requestedDeployment = true
core.info(`Created deployment for ${this.buildVersion}`)
if (response && response.data) {
core.info(JSON.stringify(response.data))
this.deploymentInfo = response.data
}
} catch (error) {
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
core.info(`Failed to create deployment for ${this.buildVersion}.`)
if (error.response && error.response.data) {
core.info(JSON.stringify(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 {
core.setFailed(error)
throw error
}
}
}
// Poll the deployment endpoint for status
async check() {
try {
const statusUrl = this.deploymentInfo != null ?
this.deploymentInfo["status_url"] :
`${this.githubApiUrl}/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"] : "")
const timeout = Number(core.getInput('timeout'))
const timeout = core.getInput('timeout')
const reportingInterval = Number(core.getInput('reporting_interval'))
const maxErrorCount = Number(core.getInput('error_count'))
const maxErrorCount = core.getInput('error_count')
var startTime = Date.now()
var errorCount = 0
@@ -7250,14 +7182,13 @@ class Deployment {
core.setFailed('Failed with status code: ' + res.status)
break
}
}
// Handle timeout
if (Date.now() - startTime >= timeout) {
core.info('Timeout reached, aborting!')
core.setFailed('Timeout reached, aborting!')
return
}
}
} catch (error) {
core.setFailed(error)
if (error.response && error.response.data) {
@@ -7296,7 +7227,7 @@ const {Deployment} = __nccwpck_require__(2877)
async function emitTelemetry() {
// All variables we need from the runtime are set in the Deployment constructor
const deployment = new Deployment()
const telemetryUrl = `${deployment.githubApiUrl}/repos/${deployment.repositoryNwo}/pages/telemetry`
const telemetryUrl = `https://api.github.com/repos/${deployment.repositoryNwo}/pages/telemetry`
core.info(`Sending telemetry for run id ${deployment.workflowRun}`)
await axios
.post(
@@ -7506,14 +7437,14 @@ const deployment = new Deployment()
async function cancelHandler(evtOrExitCodeOrError) {
try {
if (deployment.requestedDeployment) {
const pagesCancelDeployEndpoint = `${deployment.githubApiUrl}/repos/${process.env.GITHUB_REPOSITORY}/pages/deployment/cancel/${process.env.GITHUB_SHA}`
const pagesCancelDeployEndpoint = `https://api.github.com/repos/${process.env.GITHUB_REPOSITORY}/pages/deployment/cancel/${process.env.GITHUB_SHA}`
await axios.put(
pagesCancelDeployEndpoint,
{},
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${deployment.githubToken}`,
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
'Content-type': 'application/json'
}
}
@@ -7521,21 +7452,14 @@ async function cancelHandler(evtOrExitCodeOrError) {
core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`)
}
} catch (e) {
console.log('Deployment cancellation failed', e)
console.info('Deployment cancellation failed', e)
}
process.exit(isNaN(+evtOrExitCodeOrError) ? 1 : +evtOrExitCodeOrError)
}
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 {
const idToken = await core.getIDToken()
await deployment.create(idToken)
await deployment.check()
} catch (error) {
@@ -7548,12 +7472,7 @@ process.on('SIGINT', cancelHandler)
process.on('SIGTERM', cancelHandler)
// Main
const emitTelemetry = core.getInput("emit_telemetry")
if (emitTelemetry === "true") {
__nccwpck_require__(9557)
} else {
main()
}
main().then(() => __nccwpck_require__(9557))
})();

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
},
"node_modules/follow-redirects": {
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
"version": "1.14.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==",
"funding": [
{
"type": "individual",
@@ -5975,9 +5975,9 @@
}
},
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"node_modules/minipass": {
"version": "3.1.5",
@@ -7123,20 +7123,6 @@
"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": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
@@ -10560,9 +10546,9 @@
"dev": true
},
"follow-redirects": {
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
"version": "1.14.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g=="
},
"form-data": {
"version": "3.0.1",
@@ -11873,9 +11859,9 @@
}
},
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"minipass": {
"version": "3.1.5",
@@ -12723,13 +12709,6 @@
"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": {
"version": "1.0.1",
"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
var RedirectionError = createErrorType(
"ERR_FR_REDIRECTION_FAILURE",
"Redirected request failed"
""
);
var TooManyRedirectsError = createErrorType(
"ERR_FR_TOO_MANY_REDIRECTS",
@@ -5219,16 +5219,10 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
// Stops a timeout from triggering
function clearTimer() {
// Clear the timeout
if (self._timeout) {
clearTimeout(self._timeout);
self._timeout = null;
}
// Clean up all attached listeners
self.removeListener("abort", clearTimer);
self.removeListener("error", clearTimer);
self.removeListener("response", clearTimer);
if (callback) {
self.removeListener("timeout", callback);
}
@@ -5252,9 +5246,8 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
// Clean up on events
this.on("socket", destroyOnTimeout);
this.on("abort", clearTimer);
this.on("error", clearTimer);
this.on("response", clearTimer);
this.once("response", clearTimer);
this.once("error", clearTimer);
return this;
};
@@ -5386,21 +5379,10 @@ RedirectableRequest.prototype._processResponse = function (response) {
// the user agent MAY automatically redirect its request to the URI
// referenced by the Location field value,
// 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;
if (!location || this._options.followRedirects === false ||
statusCode < 300 || statusCode >= 400) {
response.responseUrl = this._currentUrl;
response.redirects = this._redirects;
this.emit("response", response);
// Clean up
this._requestBodyBuffers = [];
return;
}
// The response is a redirect, so abort the current request
if (location && this._options.followRedirects !== false &&
statusCode >= 300 && statusCode < 400) {
// Abort the current request
abortRequest(this._currentRequest);
// Discard the remainder of the response to avoid waiting for data
response.destroy();
@@ -5429,37 +5411,19 @@ RedirectableRequest.prototype._processResponse = function (response) {
}
// 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;
}
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 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);
// Drop the Authorization header if redirecting to another host
if (redirectUrlParts.hostname !== previousHostName) {
removeMatchingHeaders(/^authorization$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
@@ -5480,7 +5444,19 @@ RedirectableRequest.prototype._processResponse = function (response) {
this._performRequest();
}
catch (cause) {
this.emit("error", new RedirectionError(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.redirects = this._redirects;
this.emit("response", response);
// Clean up
this._requestBodyBuffers = [];
}
};
@@ -5584,20 +5560,13 @@ function removeMatchingHeaders(regex, headers) {
delete headers[header];
}
}
return (lastValue === null || typeof lastValue === "undefined") ?
undefined : String(lastValue).trim();
return lastValue;
}
function createErrorType(code, defaultMessage) {
function CustomError(cause) {
function CustomError(message) {
Error.captureStackTrace(this, this.constructor);
if (!cause) {
this.message = defaultMessage;
}
else {
this.message = defaultMessage + ": " + cause.message;
this.cause = cause;
}
this.message = message || defaultMessage;
}
CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError;
@@ -5614,11 +5583,6 @@ function abortRequest(request) {
request.abort();
}
function isSubdomain(subdomain, domain) {
const dot = subdomain.length - domain.length - 1;
return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
}
// Exports
module.exports = wrap({ http: http, https: https });
module.exports.wrap = wrap;
@@ -7057,9 +7021,7 @@ function getRequiredVars() {
buildVersion: process.env.GITHUB_SHA,
buildActor: process.env.GITHUB_ACTOR,
actionsId: process.env.GITHUB_ACTION,
githubToken: core.getInput('token'),
githubApiUrl: process.env.GITHUB_API_URL ?? 'https://api.github.com',
artifactName: core.getInput('artifact_name') ?? 'github-pages'
githubToken: core.getInput('token')
}
}
@@ -7107,8 +7069,6 @@ class Deployment {
this.workflowRun = context.workflowRun
this.requestedDeployment = false
this.deploymentInfo = null
this.githubApiUrl = context.githubApiUrl
this.artifactName = context.artifactName
}
// Ask the runtime for the unsigned artifact URL and deploy to GitHub Pages
@@ -7117,7 +7077,7 @@ class Deployment {
try {
core.info(`Actor: ${this.buildActor}`)
core.info(`Action ID: ${this.actionsId}`)
const pagesDeployEndpoint = `${this.githubApiUrl}/repos/${this.repositoryNwo}/pages/deployment`
const pagesDeployEndpoint = `https://api.github.com/repos/${this.repositoryNwo}/pages/deployment`
const artifactExgUrl = `${this.runTimeUrl}_apis/pipelines/workflows/${this.workflowRun}/artifacts?api-version=6.0-preview`
core.info(`Artifact URL: ${artifactExgUrl}`)
const {data} = await axios.get(artifactExgUrl, {
@@ -7127,12 +7087,10 @@ class Deployment {
}
})
core.info(JSON.stringify(data))
const artifactRawUrl = data?.value?.find(artifact => artifact.name === this.artifactName)?.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.')
if (data.value.length == 0) {
throw new Error('No uploaded artifact was found! Please check if there are any errors at build step.')
}
const artifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
const artifactUrl = `${data.value[0].url}&%24expand=SignedContent`
const payload = {
artifact_url: artifactUrl,
pages_build_version: this.buildVersion,
@@ -7148,54 +7106,28 @@ class Deployment {
})
this.requestedDeployment = true
core.info(`Created deployment for ${this.buildVersion}`)
if (response && response.data) {
core.info(JSON.stringify(response.data))
this.deploymentInfo = response.data
}
} catch (error) {
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
core.info(`Failed to create deployment for ${this.buildVersion}.`)
if (error.response && error.response.data) {
core.info(JSON.stringify(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 {
core.setFailed(error)
throw error
}
}
}
// Poll the deployment endpoint for status
async check() {
try {
const statusUrl = this.deploymentInfo != null ?
this.deploymentInfo["status_url"] :
`${this.githubApiUrl}/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"] : "")
const timeout = Number(core.getInput('timeout'))
const timeout = core.getInput('timeout')
const reportingInterval = Number(core.getInput('reporting_interval'))
const maxErrorCount = Number(core.getInput('error_count'))
const maxErrorCount = core.getInput('error_count')
var startTime = Date.now()
var errorCount = 0
@@ -7250,14 +7182,13 @@ class Deployment {
core.setFailed('Failed with status code: ' + res.status)
break
}
}
// Handle timeout
if (Date.now() - startTime >= timeout) {
core.info('Timeout reached, aborting!')
core.setFailed('Timeout reached, aborting!')
return
}
}
} catch (error) {
core.setFailed(error)
if (error.response && error.response.data) {
@@ -7296,7 +7227,7 @@ const {Deployment} = __nccwpck_require__(2877)
async function emitTelemetry() {
// All variables we need from the runtime are set in the Deployment constructor
const deployment = new Deployment()
const telemetryUrl = `${deployment.githubApiUrl}/repos/${deployment.repositoryNwo}/pages/telemetry`
const telemetryUrl = `https://api.github.com/repos/${deployment.repositoryNwo}/pages/telemetry`
core.info(`Sending telemetry for run id ${deployment.workflowRun}`)
await axios
.post(

File diff suppressed because one or more lines are too long

View File

@@ -10,9 +10,7 @@ function getRequiredVars() {
buildVersion: process.env.GITHUB_SHA,
buildActor: process.env.GITHUB_ACTOR,
actionsId: process.env.GITHUB_ACTION,
githubToken: core.getInput('token'),
githubApiUrl: process.env.GITHUB_API_URL ?? 'https://api.github.com',
artifactName: core.getInput('artifact_name') ?? 'github-pages'
githubToken: core.getInput('token')
}
}

View File

@@ -25,8 +25,6 @@ class Deployment {
this.workflowRun = context.workflowRun
this.requestedDeployment = false
this.deploymentInfo = null
this.githubApiUrl = context.githubApiUrl
this.artifactName = context.artifactName
}
// Ask the runtime for the unsigned artifact URL and deploy to GitHub Pages
@@ -35,7 +33,7 @@ class Deployment {
try {
core.info(`Actor: ${this.buildActor}`)
core.info(`Action ID: ${this.actionsId}`)
const pagesDeployEndpoint = `${this.githubApiUrl}/repos/${this.repositoryNwo}/pages/deployment`
const pagesDeployEndpoint = `https://api.github.com/repos/${this.repositoryNwo}/pages/deployment`
const artifactExgUrl = `${this.runTimeUrl}_apis/pipelines/workflows/${this.workflowRun}/artifacts?api-version=6.0-preview`
core.info(`Artifact URL: ${artifactExgUrl}`)
const {data} = await axios.get(artifactExgUrl, {
@@ -45,12 +43,10 @@ class Deployment {
}
})
core.info(JSON.stringify(data))
const artifactRawUrl = data?.value?.find(artifact => artifact.name === this.artifactName)?.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.')
if (data.value.length == 0) {
throw new Error('No uploaded artifact was found! Please check if there are any errors at build step.')
}
const artifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
const artifactUrl = `${data.value[0].url}&%24expand=SignedContent`
const payload = {
artifact_url: artifactUrl,
pages_build_version: this.buildVersion,
@@ -66,54 +62,28 @@ class Deployment {
})
this.requestedDeployment = true
core.info(`Created deployment for ${this.buildVersion}`)
if (response && response.data) {
core.info(JSON.stringify(response.data))
this.deploymentInfo = response.data
}
} catch (error) {
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
core.info(`Failed to create deployment for ${this.buildVersion}.`)
if (error.response && error.response.data) {
core.info(JSON.stringify(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 {
core.setFailed(error)
throw error
}
}
}
// Poll the deployment endpoint for status
async check() {
try {
const statusUrl = this.deploymentInfo != null ?
this.deploymentInfo["status_url"] :
`${this.githubApiUrl}/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"] : "")
const timeout = Number(core.getInput('timeout'))
const timeout = core.getInput('timeout')
const reportingInterval = Number(core.getInput('reporting_interval'))
const maxErrorCount = Number(core.getInput('error_count'))
const maxErrorCount = core.getInput('error_count')
var startTime = Date.now()
var errorCount = 0
@@ -168,14 +138,13 @@ class Deployment {
core.setFailed('Failed with status code: ' + res.status)
break
}
}
// Handle timeout
if (Date.now() - startTime >= timeout) {
core.info('Timeout reached, aborting!')
core.setFailed('Timeout reached, aborting!')
return
}
}
} catch (error) {
core.setFailed(error)
if (error.response && error.response.data) {

View File

@@ -17,14 +17,14 @@ const deployment = new Deployment()
async function cancelHandler(evtOrExitCodeOrError) {
try {
if (deployment.requestedDeployment) {
const pagesCancelDeployEndpoint = `${deployment.githubApiUrl}/repos/${process.env.GITHUB_REPOSITORY}/pages/deployment/cancel/${process.env.GITHUB_SHA}`
const pagesCancelDeployEndpoint = `https://api.github.com/repos/${process.env.GITHUB_REPOSITORY}/pages/deployment/cancel/${process.env.GITHUB_SHA}`
await axios.put(
pagesCancelDeployEndpoint,
{},
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${deployment.githubToken}`,
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
'Content-type': 'application/json'
}
}
@@ -32,21 +32,14 @@ async function cancelHandler(evtOrExitCodeOrError) {
core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`)
}
} catch (e) {
console.log('Deployment cancellation failed', e)
console.info('Deployment cancellation failed', e)
}
process.exit(isNaN(+evtOrExitCodeOrError) ? 1 : +evtOrExitCodeOrError)
}
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 {
const idToken = await core.getIDToken()
await deployment.create(idToken)
await deployment.check()
} catch (error) {
@@ -59,9 +52,4 @@ process.on('SIGINT', cancelHandler)
process.on('SIGTERM', cancelHandler)
// Main
const emitTelemetry = core.getInput("emit_telemetry")
if (emitTelemetry === "true") {
require('./pre')
} else {
main()
}
main().then(() => require('./pre'))

View File

@@ -55,14 +55,6 @@ describe('create', () => {
process.env.GITHUB_ACTOR = 'monalisa'
process.env.GITHUB_ACTION = '__monalisa/octocat'
process.env.GITHUB_ACTION_PATH = 'something'
jest.spyOn(core, 'getInput').mockImplementation(param => {
switch (param) {
case 'artifact_name':
return 'github-pages'
case 'token':
return process.env.GITHUB_TOKEN
}
})
jest.spyOn(core, 'setOutput').mockImplementation(param => {
return param
@@ -83,7 +75,7 @@ describe('create', () => {
const fakeJwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiNjllMWIxOC1jOGFiLTRhZGQtOGYxOC03MzVlMzVjZGJhZjAiLCJzdWIiOiJyZXBvOnBhcGVyLXNwYS9taW55aTplbnZpcm9ubWVudDpQcm9kdWN0aW9uIiwiYXVkIjoiaHR0cHM6Ly9naXRodWIuY29tL3BhcGVyLXNwYSIsInJlZiI6InJlZnMvaGVhZHMvbWFpbiIsInNoYSI6ImEyODU1MWJmODdiZDk3NTFiMzdiMmM0YjM3M2MxZjU3NjFmYWM2MjYiLCJyZXBvc2l0b3J5IjoicGFwZXItc3BhL21pbnlpIiwicmVwb3NpdG9yeV9vd25lciI6InBhcGVyLXNwYSIsInJ1bl9pZCI6IjE1NDY0NTkzNjQiLCJydW5fbnVtYmVyIjoiMzQiLCJydW5fYXR0ZW1wdCI6IjIiLCJhY3RvciI6IllpTXlzdHkiLCJ3b3JrZmxvdyI6IkNJIiwiaGVhZF9yZWYiOiIiLCJiYXNlX3JlZiI6IiIsImV2ZW50X25hbWUiOiJwdXNoIiwicmVmX3R5cGUiOiJicmFuY2giLCJlbnZpcm9ubWVudCI6IlByb2R1Y3Rpb24iLCJqb2Jfd29ya2Zsb3dfcmVmIjoicGFwZXItc3BhL21pbnlpLy5naXRodWIvd29ya2Zsb3dzL2JsYW5rLnltbEByZWZzL2hlYWRzL21haW4iLCJpc3MiOiJodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwibmJmIjoxNjM4ODI4MDI4LCJleHAiOjE2Mzg4Mjg5MjgsImlhdCI6MTYzODgyODYyOH0.1wyupfxu1HGoTyIqatYg0hIxy2-0bMO-yVlmLSMuu2w'
const scope = nock(`http://my-url`)
.get('/_apis/pipelines/workflows/123/artifacts?api-version=6.0-preview')
.reply(200, { value: [ {url: 'https://another-artifact.com', name: 'another-artifact'}, { url: 'https://fake-artifact.com', name: 'github-pages' }] })
.reply(200, { value: [{ url: 'https://fake-artifact.com' }] })
core.getIDToken = jest.fn().mockResolvedValue(fakeJwt)
axios.post = jest.fn().mockResolvedValue('test')
@@ -102,7 +94,7 @@ describe('create', () => {
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer gha-token`,
Authorization: 'Bearer ',
'Content-type': 'application/json'
}
}
@@ -120,7 +112,7 @@ describe('create', () => {
process.env.GITHUB_SHA = 'invalid-build-version'
const scope = 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' }] })
.reply(200, { value: [{ url: 'https://invalid-artifact.com' }] })
axios.post = jest.fn().mockRejectedValue({
status: 400
@@ -169,7 +161,6 @@ describe('check', () => {
process.env.GITHUB_ACTOR = 'monalisa'
process.env.GITHUB_ACTION = '__monalisa/octocat'
process.env.GITHUB_ACTION_PATH = 'something'
process.env.ARTIFACT_NAME = 'github-pages'
jest.spyOn(core, 'setOutput').mockImplementation(param => {
return param
@@ -218,7 +209,7 @@ describe('check', () => {
`https://api.github.com/repos/${repositoryNwo}/pages/deployment/status/${buildVersion}`,
{
headers: {
Authorization: 'token gha-token'
Authorization: 'token '
}
}
)

View File

@@ -21,7 +21,7 @@ const {Deployment} = require('./deployment')
async function emitTelemetry() {
// All variables we need from the runtime are set in the Deployment constructor
const deployment = new Deployment()
const telemetryUrl = `${deployment.githubApiUrl}/repos/${deployment.repositoryNwo}/pages/telemetry`
const telemetryUrl = `https://api.github.com/repos/${deployment.repositoryNwo}/pages/telemetry`
core.info(`Sending telemetry for run id ${deployment.workflowRun}`)
await axios
.post(