Compare commits

..

54 Commits

Author SHA1 Message Date
James M. Greene
75c1124b14 Merge pull request #67 from actions/release-process-updates
Update release process in README
2022-09-26 15:45:28 -05:00
James M. Greene
766cde6ce5 Merge branch 'main' into release-process-updates 2022-09-26 15:43:11 -05:00
James M. Greene
1352fce070 Merge pull request #65 from actions/unused-deps
Clean up some unused dependencies
2022-09-26 15:37:52 -05:00
James M. Greene
12ecc67b1a Remove unnecessary Jest config 2022-09-26 15:30:15 -05:00
James M. Greene
b388ef8bf2 Remove unnecessary first-party use of Regenerator 2022-09-26 14:47:48 -05:00
James M. Greene
818dc836a0 Merge branch 'main' into unused-deps 2022-09-26 14:34:08 -05:00
James M. Greene
60e36109df Merge pull request #64 from actions/eslint-roller
Update ESLint config and expand usage
2022-09-26 14:12:25 -05:00
James M. Greene
7098b54017 Merge branch 'main' into eslint-roller 2022-09-26 14:10:15 -05:00
James M. Greene
539d415250 Merge pull request #63 from actions/i-feel-prettier
Expand Prettier usage
2022-09-26 14:08:33 -05:00
James M. Greene
af51f9ed91 Update release process in README 2022-09-19 10:53:48 -05:00
James M. Greene
6e7a81b68f Revise linter Actions workflow 2022-09-16 23:16:38 -05:00
James M. Greene
6bbc94d747 Remove unused deps related to Babel 2022-09-16 23:14:27 -05:00
James M. Greene
20ece23417 Remove unused packages 2022-09-16 23:10:54 -05:00
James M. Greene
503d9f28e7 Remove redundant require for global variables 2022-09-16 23:05:43 -05:00
James M. Greene
f8491fe25c Enhance ESLint configuration 2022-09-16 22:59:17 -05:00
James M. Greene
de75c272ff Expand ESLint usage and add check script 2022-09-16 22:52:58 -05:00
James M. Greene
5e811dcf4c Sort scripts alphabetically 2022-09-16 22:52:36 -05:00
James M. Greene
f14d75a58d Reformat all the things 2022-09-16 22:39:00 -05:00
James M. Greene
2727d0f5db Reorder dependencies alphabetically 2022-09-16 22:37:54 -05:00
James M. Greene
67de43d94c Remove unused dependency 2022-09-16 22:37:33 -05:00
James M. Greene
1996917397 Expand Prettier coverage 2022-09-16 22:36:35 -05:00
Jess Bees
44d4246912 Merge pull request #62 from actions/pages/get-build-conclusion
Add optional 'conclusion' argument to emitTelemetry
2022-09-16 09:33:36 -04:00
Jess Bees
5de668770e Gotta update npm deps to accurately compile it 2022-09-15 13:05:09 -04:00
Jess Bees
1c52af2b34 Add optional 'conclusion' argument to emitTelemetry
If present, will include the value of `conclusion` with the telemetry
POST body (gh/gh needs a separate PR to recognize this)
2022-09-15 12:14:23 -04:00
James M. Greene
c2379ec5e7 Merge pull request #61 from actions/upstream-preview-alpha
Add support for preview deployments internal alpha experiment 🧪
2022-09-13 19:58:43 -05:00
James M. Greene
e7d22decca Remove internal debugging from @actions/core 2022-09-09 18:54:00 -05:00
James M. Greene
9b78820d58 Update distributables 2022-09-09 18:51:52 -05:00
James M. Greene
dd23652c5c Adhere to Prettier formatting 2022-09-09 18:51:35 -05:00
James M. Greene
ec456f786c Correct outdated reference 2022-09-09 18:50:08 -05:00
James M. Greene
b68f047ef0 Merge branch 'main' into upstream-preview-alpha 2022-09-09 18:49:17 -05:00
James M. Greene
791c72a9c0 Merge pull request #60 from actions/yaml-consistency
Use single quotes in Action metadata for consistency
2022-09-09 18:48:39 -05:00
James M. Greene
b45768bc0f Merge branch 'main' into yaml-consistency 2022-09-09 18:47:11 -05:00
James M. Greene
3c12eff351 Merge pull request #59 from actions/fix-org-refs
Correct organization references
2022-09-09 18:46:55 -05:00
James M. Greene
f5fafd81c2 Remove '.only' from the new unit test 2022-09-09 18:46:36 -05:00
James M. Greene
f8578825e2 Update distributables 2022-09-09 18:44:20 -05:00
James M. Greene
d2d7f752d5 Add support for preview deployments 2022-09-09 18:44:03 -05:00
James M. Greene
ad109d8dbd Add failing test 2022-09-09 18:29:17 -05:00
James M. Greene
3ed1d6d9a8 Use single quotes in Action metadata for consistency 2022-09-09 17:09:19 -05:00
James M. Greene
71efac92ad Add 'preview' input parameter to Action metadata 2022-09-09 17:08:16 -05:00
James M. Greene
b742641b90 Correct organization references 2022-09-09 16:59:57 -05:00
Yoann Chaudet
e4de7aa8e4 Merge pull request #57 from actions/release-instructions
Add release instructions
2022-08-24 11:24:11 -07:00
Yoann Chaudet
84346747a3 v1 2022-08-24 10:55:10 -07:00
Yoann Chaudet
9113cc7efc fix lint 2022-08-24 10:54:29 -07:00
Yoann Chaudet
858592354e Add release instructions 2022-08-24 10:53:23 -07:00
Yoann Chaudet
114f9cc1f8 Merge pull request #56 from actions/cancel
Explicitly handle cancellation on errors
2022-08-24 10:46:21 -07:00
Yoann Chaudet
0dfe0f0668 Merge pull request #55 from actions/formatter
Bring back the formatter
2022-08-24 08:59:01 -07:00
Yoann Chaudet
c7c77bb21c Explicitly handle cancellation on errors 2022-08-23 21:32:40 -07:00
Yoann Chaudet
369d1aed92 Add linter 2022-08-23 17:28:44 -07:00
Yoann Chaudet
4865e84b02 Bring back the formatter 2022-08-23 17:19:21 -07:00
James M. Greene
b627026553 Merge pull request #54 from actions/codeowners-file
Add CODEOWNERS file
2022-08-19 13:29:24 -05:00
James M. Greene
9bd912c0ca Add CODEOWNERS file 2022-08-19 13:28:07 -05:00
James M. Greene
ed034ea1c3 Merge pull request #53 from actions/consistent-release-workflow
Make the major version release workflow consistent with other Actions
2022-08-19 13:27:01 -05:00
James M. Greene
8f9a38d5e7 Update major version only for full releases 2022-08-19 12:33:44 -05:00
James M. Greene
71b1669225 Make the major version release workflow consistent with other Actions
Based on https://github.com/paper-spa/configure-pages/edit/main/.github/workflows/release.yml
2022-08-19 12:26:27 -05:00
28 changed files with 1103 additions and 3205 deletions

View File

@@ -1,2 +0,0 @@
node_modules/
dist/

View File

@@ -1,19 +1,17 @@
{
"env": {
"commonjs": true,
"es6": true,
"jest": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
"es2021": true,
"node": true,
"jest": true
},
"plugins": ["github"],
"extends": ["eslint:recommended", "prettier", "plugin:github/internal"],
"parserOptions": {
"ecmaVersion": 2018
"ecmaVersion": 12
},
"rules": {
"semi": ["error", "never"]
}
},
"ignorePatterns": ["/dist/", "/pre/"]
}

2
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,2 @@
# Default PR reviewers
* @actions/pages

View File

@@ -3,8 +3,10 @@ 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
See details of [all code changes](https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION) since previous release.
categories:
- title: '🚀 Features'
labels:

34
.github/workflows/check-formatting.yml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: Checking formatting
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.JS
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Verify formatting
run: npm run format:check

34
.github/workflows/check-linter.yml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: Check linter
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.JS
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Verify linter
run: npm run lint:check

View File

@@ -9,7 +9,7 @@
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
name: 'CodeQL'
on:
push:

View File

@@ -1,7 +1,7 @@
name: Release new action version
name: Release
on:
release:
types: [edited]
types: [released]
workflow_dispatch:
inputs:
TAG_NAME:
@@ -10,15 +10,17 @@ on:
env:
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
permissions:
contents: write
jobs:
update_tag:
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
environment:
name: releaseNewActionVersion
runs-on: ubuntu-latest
environment:
# Note: this environment is protected
name: Release
steps:
- name: Update the ${{ env.TAG_NAME }} tag
id: update-major-tag

View File

@@ -1 +1,6 @@
node_modules/
# Ignore build artifacts
/dist/
/pre/
# Ignore all Markdown files
*.md

View File

@@ -1,10 +0,0 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": false,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"arrowParens": "avoid"
}

10
.prettierrc.yml Normal file
View File

@@ -0,0 +1,10 @@
# Prettier (formatter) configuration
---
printWidth: 120
tabWidth: 2
useTabs: false
semi: false
singleQuote: true
trailingComma: none
bracketSpacing: true
arrowParens: avoid

View File

@@ -62,6 +62,18 @@ There are a few important considerations to be aware of:
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)
# Release instructions
In order to release a new version of this Action:
1. Locate the semantic version of the [upcoming release][release-list] (a draft is maintained by the [`draft-release` workflow][draft-release]).
2. Publish the draft release from the `main` branch with semantic version as the tag name, _with_ the checkbox to publish to the GitHub Marketplace checked. :ballot_box_with_check:
3. After publishing the release, the [`release` workflow][release] will automatically run to create/update the corresponding the major version tag such as `v1`.
⚠️ Environment approval is required. Check the [Release workflow run list][release-workflow-runs].
## License
The scripts and documentation in this project are released under the [MIT License](LICENSE).
@@ -71,3 +83,7 @@ The scripts and documentation in this project are released under the [MIT Licens
[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
[release-list]: https://github.com/actions/deploy-pages/releases
[draft-release]: .github/workflows/draft-release.yml
[release]: .github/workflows/release.yml
[release-workflow-runs]: https://github.com/actions/deploy-pages/actions/workflows/release.yml

View File

@@ -8,7 +8,10 @@ inputs:
emit_telemetry:
description: 'Should this action only emit build telemetry instead of deploying the build artifact?'
required: false
default: "false"
default: 'false'
conclusion:
description: 'The status of the previous build.'
required: false
token:
description: 'GitHub token'
default: ${{ github.token }}
@@ -16,19 +19,23 @@ inputs:
timeout:
description: 'Time in milliseconds after which to timeout and cancel the deployment (default: 10 minutes)'
required: false
default: "600000"
default: '600000'
error_count:
description: 'Maximum number of status report errors before cancelling a deployment (default: 10)'
required: false
default: "10"
default: '10'
reporting_interval:
description: 'Time in milliseconds between two deployment status report (default: 5 seconds)'
required: false
default: "5000"
default: '5000'
artifact_name:
description: 'Name of the artifact to deploy'
required: false
default: "github-pages"
default: 'github-pages'
preview:
description: 'Is this attempting to deploy a pull request as a GitHub Pages preview site? (NOTE: This feature is only in alpha currently and is not available to the public!)'
required: false
default: 'false'
outputs:
page_url:
description: 'URL to deployed GitHub Pages'

View File

@@ -1 +0,0 @@
module.exports = {presets: ['@babel/preset-env']}

123
dist/index.js vendored
View File

@@ -8177,7 +8177,8 @@ function getRequiredVars() {
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'
artifactName: core.getInput('artifact_name') ?? 'github-pages',
isPreview: core.getInput('preview') === 'true'
}
}
@@ -8198,8 +8199,6 @@ module.exports = function getContext() {
/***/ 2877:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
__nccwpck_require__(4307)
const core = __nccwpck_require__(2186)
const axios = __nccwpck_require__(6545)
@@ -8207,9 +8206,9 @@ const axios = __nccwpck_require__(6545)
const getContext = __nccwpck_require__(1319)
const errorStatus = {
'unknown_status' : 'Unable to get deployment status.',
'not_found' : 'Deployment not found.',
'deployment_attempt_error' : 'Deployment temporarily failed, a retry will be automatically scheduled...'
unknown_status: 'Unable to get deployment status.',
not_found: 'Deployment not found.',
deployment_attempt_error: 'Deployment temporarily failed, a retry will be automatically scheduled...'
}
class Deployment {
@@ -8227,6 +8226,7 @@ class Deployment {
this.deploymentInfo = null
this.githubApiUrl = context.githubApiUrl
this.artifactName = context.artifactName
this.isPreview = context.isPreview === true
}
// Ask the runtime for the unsigned artifact URL and deploy to GitHub Pages
@@ -8247,7 +8247,9 @@ 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.')
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 artifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
@@ -8256,6 +8258,9 @@ class Deployment {
pages_build_version: this.buildVersion,
oidc_token: idToken
}
if (this.isPreview === true) {
payload.preview = true
}
core.info(`Creating deployment with payload:\n${JSON.stringify(payload, null, '\t')}`)
const response = await axios.post(pagesDeployEndpoint, payload, {
headers: {
@@ -8271,7 +8276,6 @@ class Deployment {
this.deploymentInfo = response.data
}
} catch (error) {
core.info(error.stack)
// output raw error in debug mode.
@@ -8281,20 +8285,18 @@ class Deployment {
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 = ""
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) {
} 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) {
} 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
@@ -8307,10 +8309,16 @@ class Deployment {
// 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']}`
core.setOutput('page_url', this.deploymentInfo != null ? this.deploymentInfo["page_url"] : "")
const statusUrl =
this.deploymentInfo != null
? this.deploymentInfo['status_url']
: `${this.githubApiUrl}/repos/${this.repositoryNwo}/pages/deployment/status/${this.buildVersion}`
let pageUrl = this.deploymentInfo != null ? this.deploymentInfo['page_url'] : ''
const previewUrl = this.deploymentInfo != null ? this.deploymentInfo['preview_url'] : ''
if (this.isPreview && previewUrl) {
pageUrl = previewUrl
}
core.setOutput('page_url', pageUrl)
const timeout = Number(core.getInput('timeout'))
const reportingInterval = Number(core.getInput('reporting_interval'))
const maxErrorCount = Number(core.getInput('error_count'))
@@ -8342,7 +8350,9 @@ class Deployment {
break
} else if (res.data.status == 'deployment_content_failed') {
// The uploaded artifact is invalid.
core.setFailed('Artifact could not be deployed. Please ensure the content does not contain any hard links, symlinks and total size is less than 10GB.')
core.setFailed(
'Artifact could not be deployed. Please ensure the content does not contain any hard links, symlinks and total size is less than 10GB.'
)
break
} else if (errorStatus[res.data.status]) {
// A temporary error happened, will query the status again
@@ -8356,7 +8366,7 @@ class Deployment {
// set the Maximum error reporting interval greater than 15 sec but below 30 sec.
if (errorReportingInterval < 1000 * 15) {
errorReportingInterval = errorReportingInterval << 1 | 1
errorReportingInterval = (errorReportingInterval << 1) | 1
}
} else {
// reset the error reporting interval once get the proper status back.
@@ -8366,13 +8376,19 @@ class Deployment {
if (errorCount >= maxErrorCount) {
core.info('Too many errors, aborting!')
core.setFailed('Failed with status code: ' + res.status)
break
// Explicitly cancel the deployment
await this.cancel()
return
}
// Handle timeout
if (Date.now() - startTime >= timeout) {
core.info('Timeout reached, aborting!')
core.setFailed('Timeout reached, aborting!')
// Explicitly cancel the deployment
await this.cancel()
return
}
}
@@ -8383,9 +8399,39 @@ class Deployment {
}
}
}
async cancel() {
// Don't attemp to cancel if no deployment was created
if (!this.requestedDeployment) {
return
}
// Cancel the deployment
try {
const pagesCancelDeployEndpoint = `${this.githubApiUrl}/repos/${this.repositoryNwo}/pages/deployment/cancel/${this.buildVersion}`
await axios.put(
pagesCancelDeployEndpoint,
{},
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${this.githubToken}`,
'Content-type': 'application/json'
}
}
)
core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`)
} catch (error) {
core.setFailed(error)
if (error.response && error.response.data) {
core.info(JSON.stringify(error.response.data))
}
}
}
}
module.exports = { Deployment }
/***/ }),
/***/ 9557:
@@ -8415,11 +8461,12 @@ 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`
core.info(`Sending telemetry for run id ${deployment.workflowRun}`)
const conclusion = core.getInput('conclusion') || null
core.info(`Sending telemetry for run id ${deployment.workflowRun}: ${conclusion}`)
await axios
.post(
telemetryUrl,
{github_run_id: deployment.workflowRun},
{ github_run_id: deployment.workflowRun, conclusion },
{
headers: {
Accept: 'application/vnd.github.v3+json',
@@ -8613,47 +8660,23 @@ module.exports = require("zlib");
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
__nccwpck_require__(4307)
// This package assumes a site has already been built and the files exist in the current workspace
// If there's an artifact named `artifact.tar`, it can upload that to actions on its own,
// without the user having to do the tar process themselves.
const core = __nccwpck_require__(2186)
// const github = require('@actions/github'); // TODO: Not used until we publish API endpoint to the @action/github package
const axios = __nccwpck_require__(6545)
const { Deployment } = __nccwpck_require__(2877)
const deployment = new Deployment()
// TODO: If the artifact hasn't been created, we can create it and upload to artifact storage ourselves
// const tar = require('tar')
async function cancelHandler(evtOrExitCodeOrError) {
try {
if (deployment.requestedDeployment) {
const pagesCancelDeployEndpoint = `${deployment.githubApiUrl}/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}`,
'Content-type': 'application/json'
}
}
)
core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`)
}
} catch (e) {
console.log('Deployment cancellation failed', e)
}
await deployment.cancel()
process.exit(isNaN(+evtOrExitCodeOrError) ? 1 : +evtOrExitCodeOrError)
}
async function main() {
let idToken = ""
let idToken = ''
try {
idToken = await core.getIDToken()
} catch (error) {
@@ -8674,8 +8697,8 @@ process.on('SIGINT', cancelHandler)
process.on('SIGTERM', cancelHandler)
// Main
const emitTelemetry = core.getInput("emit_telemetry")
if (emitTelemetry === "true") {
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

View File

@@ -1,5 +0,0 @@
module.exports = {
transform: {
'^.+\\.(js|jsx)$': 'babel-jest'
}
}

2704
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,17 +4,11 @@
"description": "Deploy an actions artifact to GitHub Pages",
"main": "./dist/index.js",
"dependencies": {
"@actions/artifact": "^0.5.2",
"@actions/core": "^1.9.1",
"@babel/plugin-transform-runtime": "^7.16.0",
"axios": "^0.24.0",
"regenerator-runtime": "^0.13.9",
"axios-retry": "^3.2.4",
"tar": "^6.1.11"
"axios-retry": "^3.2.4"
},
"devDependencies": {
"@babel/preset-env": "^7.16.0",
"@github/prettier-config": "0.0.4",
"@vercel/ncc": "^0.31.1",
"eslint": "^8.2.0",
"eslint-config-prettier": "^8.3.0",
@@ -24,14 +18,17 @@
"prettier": "^2.4.1"
},
"scripts": {
"lint": "eslint src",
"all": "npm run format && npm run lint && npm run prepare && npm run test",
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint": "DEBUG=eslint:cli-engine eslint --fix .",
"lint:check": "DEBUG=eslint:cli-engine eslint .",
"prepare": "ncc build src/index.js -o dist --source-map --license licenses.txt && ncc build src/pre.js -o pre --source-map --license licenses.txt",
"test": "jest",
"all": "npm run lint && npm run prepare && npm run test"
"test": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/paper-spa/deploy-pages.git"
"url": "git+https://github.com/actions/deploy-pages.git"
},
"keywords": [
"GitHub",
@@ -40,7 +37,7 @@
"author": "GitHub",
"license": "MIT",
"bugs": {
"url": "https://github.com/paper-spa/deploy-pages/issues"
"url": "https://github.com/actions/deploy-pages/issues"
},
"homepage": "https://github.com/paper-spa/deploy-pages#readme"
"homepage": "https://github.com/actions/deploy-pages#readme"
}

View File

@@ -8177,7 +8177,8 @@ function getRequiredVars() {
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'
artifactName: core.getInput('artifact_name') ?? 'github-pages',
isPreview: core.getInput('preview') === 'true'
}
}
@@ -8198,8 +8199,6 @@ module.exports = function getContext() {
/***/ 2877:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
__nccwpck_require__(4307)
const core = __nccwpck_require__(2186)
const axios = __nccwpck_require__(6545)
@@ -8207,9 +8206,9 @@ const axios = __nccwpck_require__(6545)
const getContext = __nccwpck_require__(1319)
const errorStatus = {
'unknown_status' : 'Unable to get deployment status.',
'not_found' : 'Deployment not found.',
'deployment_attempt_error' : 'Deployment temporarily failed, a retry will be automatically scheduled...'
unknown_status: 'Unable to get deployment status.',
not_found: 'Deployment not found.',
deployment_attempt_error: 'Deployment temporarily failed, a retry will be automatically scheduled...'
}
class Deployment {
@@ -8227,6 +8226,7 @@ class Deployment {
this.deploymentInfo = null
this.githubApiUrl = context.githubApiUrl
this.artifactName = context.artifactName
this.isPreview = context.isPreview === true
}
// Ask the runtime for the unsigned artifact URL and deploy to GitHub Pages
@@ -8247,7 +8247,9 @@ 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.')
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 artifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
@@ -8256,6 +8258,9 @@ class Deployment {
pages_build_version: this.buildVersion,
oidc_token: idToken
}
if (this.isPreview === true) {
payload.preview = true
}
core.info(`Creating deployment with payload:\n${JSON.stringify(payload, null, '\t')}`)
const response = await axios.post(pagesDeployEndpoint, payload, {
headers: {
@@ -8271,7 +8276,6 @@ class Deployment {
this.deploymentInfo = response.data
}
} catch (error) {
core.info(error.stack)
// output raw error in debug mode.
@@ -8281,20 +8285,18 @@ class Deployment {
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 = ""
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) {
} 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) {
} 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
@@ -8307,10 +8309,16 @@ class Deployment {
// 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']}`
core.setOutput('page_url', this.deploymentInfo != null ? this.deploymentInfo["page_url"] : "")
const statusUrl =
this.deploymentInfo != null
? this.deploymentInfo['status_url']
: `${this.githubApiUrl}/repos/${this.repositoryNwo}/pages/deployment/status/${this.buildVersion}`
let pageUrl = this.deploymentInfo != null ? this.deploymentInfo['page_url'] : ''
const previewUrl = this.deploymentInfo != null ? this.deploymentInfo['preview_url'] : ''
if (this.isPreview && previewUrl) {
pageUrl = previewUrl
}
core.setOutput('page_url', pageUrl)
const timeout = Number(core.getInput('timeout'))
const reportingInterval = Number(core.getInput('reporting_interval'))
const maxErrorCount = Number(core.getInput('error_count'))
@@ -8342,7 +8350,9 @@ class Deployment {
break
} else if (res.data.status == 'deployment_content_failed') {
// The uploaded artifact is invalid.
core.setFailed('Artifact could not be deployed. Please ensure the content does not contain any hard links, symlinks and total size is less than 10GB.')
core.setFailed(
'Artifact could not be deployed. Please ensure the content does not contain any hard links, symlinks and total size is less than 10GB.'
)
break
} else if (errorStatus[res.data.status]) {
// A temporary error happened, will query the status again
@@ -8356,7 +8366,7 @@ class Deployment {
// set the Maximum error reporting interval greater than 15 sec but below 30 sec.
if (errorReportingInterval < 1000 * 15) {
errorReportingInterval = errorReportingInterval << 1 | 1
errorReportingInterval = (errorReportingInterval << 1) | 1
}
} else {
// reset the error reporting interval once get the proper status back.
@@ -8366,13 +8376,19 @@ class Deployment {
if (errorCount >= maxErrorCount) {
core.info('Too many errors, aborting!')
core.setFailed('Failed with status code: ' + res.status)
break
// Explicitly cancel the deployment
await this.cancel()
return
}
// Handle timeout
if (Date.now() - startTime >= timeout) {
core.info('Timeout reached, aborting!')
core.setFailed('Timeout reached, aborting!')
// Explicitly cancel the deployment
await this.cancel()
return
}
}
@@ -8383,9 +8399,39 @@ class Deployment {
}
}
}
async cancel() {
// Don't attemp to cancel if no deployment was created
if (!this.requestedDeployment) {
return
}
// Cancel the deployment
try {
const pagesCancelDeployEndpoint = `${this.githubApiUrl}/repos/${this.repositoryNwo}/pages/deployment/cancel/${this.buildVersion}`
await axios.put(
pagesCancelDeployEndpoint,
{},
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${this.githubToken}`,
'Content-type': 'application/json'
}
}
)
core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`)
} catch (error) {
core.setFailed(error)
if (error.response && error.response.data) {
core.info(JSON.stringify(error.response.data))
}
}
}
}
module.exports = { Deployment }
/***/ }),
/***/ 9557:
@@ -8415,11 +8461,12 @@ 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`
core.info(`Sending telemetry for run id ${deployment.workflowRun}`)
const conclusion = core.getInput('conclusion') || null
core.info(`Sending telemetry for run id ${deployment.workflowRun}: ${conclusion}`)
await axios
.post(
telemetryUrl,
{github_run_id: deployment.workflowRun},
{ github_run_id: deployment.workflowRun, conclusion },
{
headers: {
Accept: 'application/vnd.github.v3+json',

File diff suppressed because one or more lines are too long

View File

@@ -12,7 +12,8 @@ function getRequiredVars() {
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'
artifactName: core.getInput('artifact_name') ?? 'github-pages',
isPreview: core.getInput('preview') === 'true'
}
}

View File

@@ -1,5 +1,3 @@
require('regenerator-runtime/runtime')
const core = require('@actions/core')
const axios = require('axios')
@@ -7,9 +5,9 @@ const axios = require('axios')
const getContext = require('./context')
const errorStatus = {
'unknown_status' : 'Unable to get deployment status.',
'not_found' : 'Deployment not found.',
'deployment_attempt_error' : 'Deployment temporarily failed, a retry will be automatically scheduled...'
unknown_status: 'Unable to get deployment status.',
not_found: 'Deployment not found.',
deployment_attempt_error: 'Deployment temporarily failed, a retry will be automatically scheduled...'
}
class Deployment {
@@ -27,6 +25,7 @@ class Deployment {
this.deploymentInfo = null
this.githubApiUrl = context.githubApiUrl
this.artifactName = context.artifactName
this.isPreview = context.isPreview === true
}
// Ask the runtime for the unsigned artifact URL and deploy to GitHub Pages
@@ -47,7 +46,9 @@ 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.')
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 artifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
@@ -56,6 +57,9 @@ class Deployment {
pages_build_version: this.buildVersion,
oidc_token: idToken
}
if (this.isPreview === true) {
payload.preview = true
}
core.info(`Creating deployment with payload:\n${JSON.stringify(payload, null, '\t')}`)
const response = await axios.post(pagesDeployEndpoint, payload, {
headers: {
@@ -71,7 +75,6 @@ class Deployment {
this.deploymentInfo = response.data
}
} catch (error) {
core.info(error.stack)
// output raw error in debug mode.
@@ -81,20 +84,18 @@ class Deployment {
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 = ""
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) {
} 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) {
} 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
@@ -107,10 +108,16 @@ class Deployment {
// 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']}`
core.setOutput('page_url', this.deploymentInfo != null ? this.deploymentInfo["page_url"] : "")
const statusUrl =
this.deploymentInfo != null
? this.deploymentInfo['status_url']
: `${this.githubApiUrl}/repos/${this.repositoryNwo}/pages/deployment/status/${this.buildVersion}`
let pageUrl = this.deploymentInfo != null ? this.deploymentInfo['page_url'] : ''
const previewUrl = this.deploymentInfo != null ? this.deploymentInfo['preview_url'] : ''
if (this.isPreview && previewUrl) {
pageUrl = previewUrl
}
core.setOutput('page_url', pageUrl)
const timeout = Number(core.getInput('timeout'))
const reportingInterval = Number(core.getInput('reporting_interval'))
const maxErrorCount = Number(core.getInput('error_count'))
@@ -142,7 +149,9 @@ class Deployment {
break
} else if (res.data.status == 'deployment_content_failed') {
// The uploaded artifact is invalid.
core.setFailed('Artifact could not be deployed. Please ensure the content does not contain any hard links, symlinks and total size is less than 10GB.')
core.setFailed(
'Artifact could not be deployed. Please ensure the content does not contain any hard links, symlinks and total size is less than 10GB.'
)
break
} else if (errorStatus[res.data.status]) {
// A temporary error happened, will query the status again
@@ -156,7 +165,7 @@ class Deployment {
// set the Maximum error reporting interval greater than 15 sec but below 30 sec.
if (errorReportingInterval < 1000 * 15) {
errorReportingInterval = errorReportingInterval << 1 | 1
errorReportingInterval = (errorReportingInterval << 1) | 1
}
} else {
// reset the error reporting interval once get the proper status back.
@@ -166,13 +175,19 @@ class Deployment {
if (errorCount >= maxErrorCount) {
core.info('Too many errors, aborting!')
core.setFailed('Failed with status code: ' + res.status)
break
// Explicitly cancel the deployment
await this.cancel()
return
}
// Handle timeout
if (Date.now() - startTime >= timeout) {
core.info('Timeout reached, aborting!')
core.setFailed('Timeout reached, aborting!')
// Explicitly cancel the deployment
await this.cancel()
return
}
}
@@ -183,5 +198,34 @@ class Deployment {
}
}
}
async cancel() {
// Don't attemp to cancel if no deployment was created
if (!this.requestedDeployment) {
return
}
// Cancel the deployment
try {
const pagesCancelDeployEndpoint = `${this.githubApiUrl}/repos/${this.repositoryNwo}/pages/deployment/cancel/${this.buildVersion}`
await axios.put(
pagesCancelDeployEndpoint,
{},
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${this.githubToken}`,
'Content-type': 'application/json'
}
}
)
core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`)
} catch (error) {
core.setFailed(error)
if (error.response && error.response.data) {
core.info(JSON.stringify(error.response.data))
}
}
}
}
module.exports = { Deployment }

View File

@@ -1,44 +1,20 @@
require('regenerator-runtime/runtime')
// This package assumes a site has already been built and the files exist in the current workspace
// If there's an artifact named `artifact.tar`, it can upload that to actions on its own,
// without the user having to do the tar process themselves.
const core = require('@actions/core')
// const github = require('@actions/github'); // TODO: Not used until we publish API endpoint to the @action/github package
const axios = require('axios')
const { Deployment } = require('./deployment')
const deployment = new Deployment()
// TODO: If the artifact hasn't been created, we can create it and upload to artifact storage ourselves
// const tar = require('tar')
async function cancelHandler(evtOrExitCodeOrError) {
try {
if (deployment.requestedDeployment) {
const pagesCancelDeployEndpoint = `${deployment.githubApiUrl}/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}`,
'Content-type': 'application/json'
}
}
)
core.info(`Deployment cancelled with ${pagesCancelDeployEndpoint}`)
}
} catch (e) {
console.log('Deployment cancellation failed', e)
}
await deployment.cancel()
process.exit(isNaN(+evtOrExitCodeOrError) ? 1 : +evtOrExitCodeOrError)
}
async function main() {
let idToken = ""
let idToken = ''
try {
idToken = await core.getIDToken()
} catch (error) {
@@ -59,8 +35,8 @@ process.on('SIGINT', cancelHandler)
process.on('SIGTERM', cancelHandler)
// Main
const emitTelemetry = core.getInput("emit_telemetry")
if (emitTelemetry === "true") {
const emitTelemetry = core.getInput('emit_telemetry')
if (emitTelemetry === 'true') {
require('./pre')
} else {
main()

View File

@@ -5,8 +5,6 @@ const path = require('path')
const nock = require('nock')
const axios = require('axios')
const { expect, jest } = require('@jest/globals')
const { Deployment } = require('./deployment')
describe('with all environment variables set', () => {
@@ -14,7 +12,7 @@ describe('with all environment variables set', () => {
process.env.ACTIONS_RUNTIME_URL = 'my-url'
process.env.GITHUB_RUN_ID = '123'
process.env.ACTIONS_RUNTIME_TOKEN = 'a-token'
process.env.GITHUB_REPOSITORY = 'paper-spa/is-awesome'
process.env.GITHUB_REPOSITORY = 'actions/is-awesome'
process.env.GITHUB_TOKEN = 'gha-token'
process.env.GITHUB_SHA = '123abc'
process.env.GITHUB_ACTOR = 'monalisa'
@@ -22,6 +20,11 @@ describe('with all environment variables set', () => {
process.env.GITHUB_ACTION_PATH = 'something'
})
afterEach(() => {
// Remove mock for `core.getInput('preview')`
delete process.env.INPUT_PREVIEW
})
it('Executes cleanly', done => {
const ip = path.join(__dirname, './index.js')
cp.exec(`node ${ip}`, { env: process.env }, (err, stdout) => {
@@ -36,7 +39,7 @@ describe('with variables missing', () => {
delete process.env.ACTIONS_RUNTIME_URL
const ip = path.join(__dirname, './index.js')
cp.exec(`node ${ip}`, { env: process.env }, (err, stdout) => {
expect(stdout).toBe("")
expect(stdout).toBe('')
expect(err).toBeTruthy()
expect(err.code).toBe(1)
done()
@@ -49,7 +52,7 @@ describe('create', () => {
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 = 'paper-spa/is-awesome'
process.env.GITHUB_REPOSITORY = 'actions/is-awesome'
process.env.GITHUB_TOKEN = 'gha-token'
process.env.GITHUB_SHA = '123abc'
process.env.GITHUB_ACTOR = 'monalisa'
@@ -61,6 +64,8 @@ describe('create', () => {
return 'github-pages'
case 'token':
return process.env.GITHUB_TOKEN
default:
return process.env[`INPUT_${param.toUpperCase()}`] || ''
}
})
@@ -80,10 +85,16 @@ describe('create', () => {
it('can successfully create a deployment', async () => {
process.env.GITHUB_SHA = 'valid-build-version'
const fakeJwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiNjllMWIxOC1jOGFiLTRhZGQtOGYxOC03MzVlMzVjZGJhZjAiLCJzdWIiOiJyZXBvOnBhcGVyLXNwYS9taW55aTplbnZpcm9ubWVudDpQcm9kdWN0aW9uIiwiYXVkIjoiaHR0cHM6Ly9naXRodWIuY29tL3BhcGVyLXNwYSIsInJlZiI6InJlZnMvaGVhZHMvbWFpbiIsInNoYSI6ImEyODU1MWJmODdiZDk3NTFiMzdiMmM0YjM3M2MxZjU3NjFmYWM2MjYiLCJyZXBvc2l0b3J5IjoicGFwZXItc3BhL21pbnlpIiwicmVwb3NpdG9yeV9vd25lciI6InBhcGVyLXNwYSIsInJ1bl9pZCI6IjE1NDY0NTkzNjQiLCJydW5fbnVtYmVyIjoiMzQiLCJydW5fYXR0ZW1wdCI6IjIiLCJhY3RvciI6IllpTXlzdHkiLCJ3b3JrZmxvdyI6IkNJIiwiaGVhZF9yZWYiOiIiLCJiYXNlX3JlZiI6IiIsImV2ZW50X25hbWUiOiJwdXNoIiwicmVmX3R5cGUiOiJicmFuY2giLCJlbnZpcm9ubWVudCI6IlByb2R1Y3Rpb24iLCJqb2Jfd29ya2Zsb3dfcmVmIjoicGFwZXItc3BhL21pbnlpLy5naXRodWIvd29ya2Zsb3dzL2JsYW5rLnltbEByZWZzL2hlYWRzL21haW4iLCJpc3MiOiJodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwibmJmIjoxNjM4ODI4MDI4LCJleHAiOjE2Mzg4Mjg5MjgsImlhdCI6MTYzODgyODYyOH0.1wyupfxu1HGoTyIqatYg0hIxy2-0bMO-yVlmLSMuu2w'
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://another-artifact.com', name: 'another-artifact' },
{ url: 'https://fake-artifact.com', name: 'github-pages' }
]
})
core.getIDToken = jest.fn().mockResolvedValue(fakeJwt)
axios.post = jest.fn().mockResolvedValue('test')
@@ -93,7 +104,7 @@ describe('create', () => {
await deployment.create(fakeJwt)
expect(axios.post).toBeCalledWith(
'https://api.github.com/repos/paper-spa/is-awesome/pages/deployment',
'https://api.github.com/repos/actions/is-awesome/pages/deployment',
{
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
pages_build_version: 'valid-build-version',
@@ -109,10 +120,54 @@ describe('create', () => {
)
expect(core.setFailed).not.toHaveBeenCalled()
expect(core.info).toHaveBeenCalledWith(
'Created deployment for valid-build-version'
expect(core.info).toHaveBeenCalledWith('Created deployment for valid-build-version')
scope.done()
})
it('can successfully create a preview deployment', async () => {
process.env.GITHUB_SHA = 'valid-build-version'
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' }
]
})
core.getIDToken = jest.fn().mockResolvedValue(fakeJwt)
axios.post = jest.fn().mockResolvedValue('test')
// Return `"true"` for `core.getInput("preview")`
process.env.INPUT_PREVIEW = 'true'
// Create the deployment
const deployment = new Deployment()
await deployment.create(fakeJwt)
expect(axios.post).toBeCalledWith(
'https://api.github.com/repos/actions/is-awesome/pages/deployment',
{
artifact_url: 'https://fake-artifact.com&%24expand=SignedContent',
pages_build_version: 'valid-build-version',
oidc_token: fakeJwt,
preview: true
},
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer gha-token`,
'Content-type': 'application/json'
}
}
)
expect(core.setFailed).not.toHaveBeenCalled()
expect(core.info).toHaveBeenCalledWith('Created deployment for valid-build-version')
scope.done()
})
@@ -131,9 +186,8 @@ describe('create', () => {
try {
deployment.create()
} catch (err) {
expect(axios.post).toBeCalledWith(
'https://api.github.com/repos/paper-spa/is-awesome/pages/deployment',
'https://api.github.com/repos/actions/is-awesome/pages/deployment',
{
artifact_url: 'https://invalid-artifact.com&%24expand=SignedContent',
pages_build_version: 'invalid-build-version'
@@ -147,15 +201,12 @@ describe('create', () => {
}
)
expect(core.info).toHaveBeenLastCalledWith(
'Failed to create deployment for invalid-build-version.'
)
expect(core.info).toHaveBeenLastCalledWith('Failed to create deployment for invalid-build-version.')
expect(core.setFailed).toHaveBeenCalledWith({ status: 400 })
scope.done()
}
})
})
describe('check', () => {
@@ -163,7 +214,7 @@ describe('check', () => {
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 = 'paper-spa/is-awesome'
process.env.GITHUB_REPOSITORY = 'actions/is-awesome'
process.env.GITHUB_TOKEN = 'gha-token'
process.env.GITHUB_SHA = '123abc'
process.env.GITHUB_ACTOR = 'monalisa'

View File

@@ -22,11 +22,12 @@ 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`
core.info(`Sending telemetry for run id ${deployment.workflowRun}`)
const conclusion = core.getInput('conclusion') || null
core.info(`Sending telemetry for run id ${deployment.workflowRun}: ${conclusion}`)
await axios
.post(
telemetryUrl,
{github_run_id: deployment.workflowRun},
{ github_run_id: deployment.workflowRun, conclusion },
{
headers: {
Accept: 'application/vnd.github.v3+json',

View File

@@ -2,8 +2,6 @@ const core = require('@actions/core')
const process = require('process')
const axios = require('axios')
const {expect, jest} = require('@jest/globals')
const { emitTelemetry } = require('./pre')
describe('emitTelemetry', () => {
@@ -11,12 +9,13 @@ describe('emitTelemetry', () => {
process.env.ACTIONS_RUNTIME_URL = 'my-url'
process.env.GITHUB_RUN_ID = '123'
process.env.ACTIONS_RUNTIME_TOKEN = 'a-token'
process.env.GITHUB_REPOSITORY = 'paper-spa/is-awesome'
process.env.GITHUB_REPOSITORY = 'actions/is-awesome'
process.env.GITHUB_TOKEN = 'gha-token'
process.env.GITHUB_SHA = '123abc'
process.env.GITHUB_ACTOR = 'monalisa'
process.env.GITHUB_ACTION = '__monalisa/octocat'
process.env.GITHUB_ACTION_PATH = 'something'
process.env.INPUT_CONCLUSION = 'success'
jest.spyOn(core, 'setOutput').mockImplementation(param => {
return param
@@ -45,9 +44,10 @@ describe('emitTelemetry', () => {
emitTelemetry()
expect(axios.post).toBeCalledWith(
'https://api.github.com/repos/paper-spa/is-awesome/pages/telemetry',
'https://api.github.com/repos/actions/is-awesome/pages/telemetry',
{
github_run_id: process.env.GITHUB_RUN_ID
github_run_id: process.env.GITHUB_RUN_ID,
conclusion: 'success'
},
{
headers: {