@cypress/github-action 0.0.0-dev.5013
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +24 -0
- package/README.md +1983 -0
- package/action.yml +129 -0
- package/dist/835.index.js +16772 -0
- package/dist/912.index.js +13112 -0
- package/dist/index.js +104800 -0
- package/dist/thread.js +57 -0
- package/package.json +71 -0
- package/src/ping-cli.js +19 -0
- package/src/ping.js +85 -0
package/dist/thread.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const crypto = require('crypto');
|
|
4
|
+
const {parentPort} = require('worker_threads');
|
|
5
|
+
|
|
6
|
+
const handlers = {
|
|
7
|
+
hashFile: (algorithm, filePath) => new Promise((resolve, reject) => {
|
|
8
|
+
const hasher = crypto.createHash(algorithm);
|
|
9
|
+
fs.createReadStream(filePath)
|
|
10
|
+
// TODO: Use `Stream.pipeline` when targeting Node.js 12.
|
|
11
|
+
.on('error', reject)
|
|
12
|
+
.pipe(hasher)
|
|
13
|
+
.on('error', reject)
|
|
14
|
+
.on('finish', () => {
|
|
15
|
+
const {buffer} = new Uint8Array(hasher.read());
|
|
16
|
+
resolve({value: buffer, transferList: [buffer]});
|
|
17
|
+
});
|
|
18
|
+
}),
|
|
19
|
+
hash: async (algorithm, input) => {
|
|
20
|
+
const hasher = crypto.createHash(algorithm);
|
|
21
|
+
|
|
22
|
+
if (Array.isArray(input)) {
|
|
23
|
+
for (const part of input) {
|
|
24
|
+
hasher.update(part);
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
hasher.update(input);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const {buffer} = new Uint8Array(hasher.digest());
|
|
31
|
+
return {value: buffer, transferList: [buffer]};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
parentPort.on('message', async message => {
|
|
36
|
+
try {
|
|
37
|
+
const {method, args} = message;
|
|
38
|
+
const handler = handlers[method];
|
|
39
|
+
|
|
40
|
+
if (handler === undefined) {
|
|
41
|
+
throw new Error(`Unknown method '${method}'`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const {value, transferList} = await handler(...args);
|
|
45
|
+
parentPort.postMessage({id: message.id, value}, transferList);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
const newError = {message: error.message, stack: error.stack};
|
|
48
|
+
|
|
49
|
+
for (const [key, value] of Object.entries(error)) {
|
|
50
|
+
if (typeof value !== 'object') {
|
|
51
|
+
newError[key] = value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
parentPort.postMessage({id: message.id, error: newError});
|
|
56
|
+
}
|
|
57
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cypress/github-action",
|
|
3
|
+
"version": "0.0.0-dev.5013",
|
|
4
|
+
"description": "GitHub Action for running Cypress end-to-end and component tests",
|
|
5
|
+
"private": false,
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"src",
|
|
10
|
+
"action.yml"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "echo \"There are no tests :(\"",
|
|
14
|
+
"build": "rimraf dist && ncc build -o dist index.js",
|
|
15
|
+
"format": "prettier --write index.js src/ping.js action.yml",
|
|
16
|
+
"format:markdown": "prettier --write \"**/*.md\"",
|
|
17
|
+
"format:markdown:check": "prettier --check \"**/*.md\"",
|
|
18
|
+
"format:all": "prettier --write .",
|
|
19
|
+
"format:all:check": "prettier --check .",
|
|
20
|
+
"lint": "eslint",
|
|
21
|
+
"lint:fix": "eslint --fix",
|
|
22
|
+
"check:markdown-links": "find *.md docs/*.md -print0 | xargs -0 -n1 markdown-link-check -c markdownLinkConfig.json",
|
|
23
|
+
"update:cypress": "./scripts/update-cypress-latest.sh",
|
|
24
|
+
"prepare": "husky"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/cypress-io/github-action.git"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"actions",
|
|
32
|
+
"cypress-io"
|
|
33
|
+
],
|
|
34
|
+
"author": "Cypress-io",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"type": "commonjs",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/cypress-io/github-action/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/cypress-io/github-action#readme",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@actions/cache": "5.0.5",
|
|
43
|
+
"@actions/core": "2.0.3",
|
|
44
|
+
"@actions/exec": "2.0.0",
|
|
45
|
+
"@actions/io": "2.0.0",
|
|
46
|
+
"@octokit/core": "7.0.6",
|
|
47
|
+
"argument-vector": "1.0.2",
|
|
48
|
+
"debug": "4.4.3",
|
|
49
|
+
"find-yarn-workspace-root": "2.0.0",
|
|
50
|
+
"got": "16.0.0",
|
|
51
|
+
"hasha": "5.2.2",
|
|
52
|
+
"quote": "0.4.0",
|
|
53
|
+
"supports-color": "9.3.1"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@eslint/js": "10.0.1",
|
|
57
|
+
"@stylistic/eslint-plugin": "5.10.0",
|
|
58
|
+
"@types/node": "26.6.5",
|
|
59
|
+
"@vercel/ncc": "0.45.0",
|
|
60
|
+
"eslint": "10.13.0",
|
|
61
|
+
"eslint-plugin-cypress": "7.0.2",
|
|
62
|
+
"globals": "17.13.0",
|
|
63
|
+
"husky": "9.1.7",
|
|
64
|
+
"markdown-link-check": "3.15.0",
|
|
65
|
+
"prettier": "3.9.10",
|
|
66
|
+
"rimraf": "6.1.3"
|
|
67
|
+
},
|
|
68
|
+
"publishConfig": {
|
|
69
|
+
"access": "public"
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/ping-cli.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// a little CLI utility for testing pinging websites
|
|
2
|
+
// node ./src/ping-cli <url>
|
|
3
|
+
|
|
4
|
+
const { ping } = require('./ping')
|
|
5
|
+
const timeoutSeconds = 30
|
|
6
|
+
const url = process.argv[2]
|
|
7
|
+
console.log('pinging url %s for %d seconds', url, timeoutSeconds)
|
|
8
|
+
if (!url) {
|
|
9
|
+
console.error('Missing url to ping')
|
|
10
|
+
process.exit(1)
|
|
11
|
+
}
|
|
12
|
+
ping(url, timeoutSeconds * 1000)
|
|
13
|
+
.then(() => {
|
|
14
|
+
console.log('%s is responding', url)
|
|
15
|
+
})
|
|
16
|
+
.catch((err) => {
|
|
17
|
+
console.error('Could not connect to %s: %s', url, err.message)
|
|
18
|
+
process.exit(1)
|
|
19
|
+
})
|
package/src/ping.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const debug = require('debug')('@cypress/github-action')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A small utility for checking when an URL responds, kind of
|
|
5
|
+
* a poor man's https://www.npmjs.com/package/wait-on. This version
|
|
6
|
+
* is implemented using https://github.com/sindresorhus/got
|
|
7
|
+
*/
|
|
8
|
+
const ping = async (url, timeout) => {
|
|
9
|
+
if (!timeout) {
|
|
10
|
+
throw new Error('Expected timeout in ms')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// got@16 is ESM-only; dynamic import works from CommonJS
|
|
14
|
+
const { default: got } = await import('got')
|
|
15
|
+
|
|
16
|
+
// make copy of the error codes that "got" retries on
|
|
17
|
+
const errorCodes = [...got.defaults.options.retry.errorCodes]
|
|
18
|
+
errorCodes.push('ESOCKETTIMEDOUT')
|
|
19
|
+
|
|
20
|
+
// we expect the server to respond within a time limit
|
|
21
|
+
// and if it does not - retry up to total "timeout" duration
|
|
22
|
+
const individualPingTimeout = Math.min(timeout, 30000)
|
|
23
|
+
|
|
24
|
+
// add to the timeout max individual ping timeout
|
|
25
|
+
// to avoid long-waiting ping from "rolling" over the end
|
|
26
|
+
// and preventing pinging the last time
|
|
27
|
+
timeout += individualPingTimeout
|
|
28
|
+
const limit = Math.ceil(timeout / individualPingTimeout)
|
|
29
|
+
|
|
30
|
+
debug(`total ping timeout ${timeout}`)
|
|
31
|
+
debug(`individual ping timeout ${individualPingTimeout}ms`)
|
|
32
|
+
debug(`retries limit ${limit}`)
|
|
33
|
+
|
|
34
|
+
const start = +new Date()
|
|
35
|
+
return got(url, {
|
|
36
|
+
headers: {
|
|
37
|
+
Accept: 'text/html, application/json, text/plain, */*'
|
|
38
|
+
},
|
|
39
|
+
timeout: {
|
|
40
|
+
request: individualPingTimeout
|
|
41
|
+
},
|
|
42
|
+
retry: {
|
|
43
|
+
errorCodes,
|
|
44
|
+
// enforceRetryRules:false lets calculateDelay be the sole stop condition,
|
|
45
|
+
// matching got@11 behaviour. limit is a generous failsafe only.
|
|
46
|
+
enforceRetryRules: false,
|
|
47
|
+
limit,
|
|
48
|
+
calculateDelay({ error, attemptCount }) {
|
|
49
|
+
if (error) {
|
|
50
|
+
debug(`got error ${JSON.stringify(error)}`)
|
|
51
|
+
}
|
|
52
|
+
const now = +new Date()
|
|
53
|
+
const elapsed = now - start
|
|
54
|
+
debug(
|
|
55
|
+
`${elapsed}ms ${error.method} ${error.host} ${error.code} attempt ${attemptCount}`
|
|
56
|
+
)
|
|
57
|
+
if (elapsed > timeout) {
|
|
58
|
+
console.error(
|
|
59
|
+
'%s timed out after %d retries, elapsed %dms, limit %dms',
|
|
60
|
+
url,
|
|
61
|
+
attemptCount,
|
|
62
|
+
elapsed,
|
|
63
|
+
timeout
|
|
64
|
+
)
|
|
65
|
+
return 0
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// if the error code is ECONNREFUSED use shorter timeout
|
|
69
|
+
// because the server is probably starting
|
|
70
|
+
if (error.code === 'ECONNREFUSED') {
|
|
71
|
+
return 1000
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// default "long" timeout
|
|
75
|
+
return individualPingTimeout
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}).then(() => {
|
|
79
|
+
const now = +new Date()
|
|
80
|
+
const elapsed = now - start
|
|
81
|
+
debug(`pinging ${url} has finished ok after ${elapsed}ms`)
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = { ping }
|