@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/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
+ }
@@ -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 }