fix: switch to actions-utils and update deps (#91)

This commit is contained in:
Seth Vargo 2021-12-22 10:45:18 -05:00 committed by GitHub
parent 5975d7549d
commit ec59fe8c8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 247 additions and 689 deletions

2
dist/main/index.js vendored

File diff suppressed because one or more lines are too long

2
dist/post/index.js vendored

File diff suppressed because one or more lines are too long

326
package-lock.json generated
View File

@ -9,23 +9,24 @@
"version": "0.4.0",
"license": "Apache-2.0",
"dependencies": {
"@actions/core": "^1.6.0"
"@actions/core": "^1.6.0",
"@google-github-actions/actions-utils": "^0.1.0"
},
"devDependencies": {
"@types/chai": "^4.2.22",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.0.0",
"@types/node": "^16.11.11",
"@typescript-eslint/eslint-plugin": "^5.5.0",
"@typescript-eslint/parser": "^5.5.0",
"@vercel/ncc": "^0.33.0",
"@types/node": "^17.0.2",
"@typescript-eslint/eslint-plugin": "^5.8.0",
"@typescript-eslint/parser": "^5.8.0",
"@vercel/ncc": "^0.33.1",
"chai": "^4.3.4",
"eslint": "^8.3.0",
"eslint": "^8.5.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"mocha": "^9.1.3",
"prettier": "^2.5.0",
"prettier": "^2.5.1",
"ts-node": "^10.4.0",
"typescript": "^4.5.2"
"typescript": "^4.5.4"
}
},
"node_modules/@actions/core": {
@ -66,14 +67,14 @@
}
},
"node_modules/@eslint/eslintrc": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz",
"integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz",
"integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
"espree": "^9.0.0",
"espree": "^9.2.0",
"globals": "^13.9.0",
"ignore": "^4.0.6",
"import-fresh": "^3.2.1",
@ -94,13 +95,21 @@
"node": ">= 4"
}
},
"node_modules/@google-github-actions/actions-utils": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@google-github-actions/actions-utils/-/actions-utils-0.1.0.tgz",
"integrity": "sha512-zGKODnHmCqLL6RQP6CFY+EtpS4J+VSX6RRUNdv1NGS3sSavKy+yD0O+7hzfEjqdZBPGK8lf1JhttYHYZ6KbMmA==",
"dependencies": {
"yaml": "^1.10.2"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz",
"integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==",
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
"integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==",
"dev": true,
"dependencies": {
"@humanwhocodes/object-schema": "^1.2.0",
"@humanwhocodes/object-schema": "^1.2.1",
"debug": "^4.1.1",
"minimatch": "^3.0.4"
},
@ -174,9 +183,9 @@
"dev": true
},
"node_modules/@types/chai": {
"version": "4.2.22",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz",
"integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz",
"integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==",
"dev": true
},
"node_modules/@types/json-schema": {
@ -192,19 +201,19 @@
"dev": true
},
"node_modules/@types/node": {
"version": "16.11.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.11.tgz",
"integrity": "sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw==",
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.2.tgz",
"integrity": "sha512-JepeIUPFDARgIs0zD/SKPgFsJEAF0X5/qO80llx59gOxFTboS9Amv3S+QfB7lqBId5sFXJ99BN0J6zFRvL9dDA==",
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.8.0.tgz",
"integrity": "sha512-spu1UW7QuBn0nJ6+psnfCc3iVoQAifjKORgBngKOmC8U/1tbe2YJMzYQqDGYB4JCss7L8+RM2kKLb1B1Aw9BNA==",
"dev": true,
"dependencies": {
"@typescript-eslint/experimental-utils": "5.5.0",
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/experimental-utils": "5.8.0",
"@typescript-eslint/scope-manager": "5.8.0",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
@ -230,15 +239,15 @@
}
},
"node_modules/@typescript-eslint/experimental-utils": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz",
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.8.0.tgz",
"integrity": "sha512-KN5FvNH71bhZ8fKtL+lhW7bjm7cxs1nt+hrDZWIqb6ViCffQcWyLunGrgvISgkRojIDcXIsH+xlFfI4RCDA0xA==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/typescript-estree": "5.5.0",
"@typescript-eslint/scope-manager": "5.8.0",
"@typescript-eslint/types": "5.8.0",
"@typescript-eslint/typescript-estree": "5.8.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
},
@ -250,18 +259,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "*"
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/@typescript-eslint/parser": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.8.0.tgz",
"integrity": "sha512-Gleacp/ZhRtJRYs5/T8KQR3pAQjQI89Dn/k+OzyCKOsLiZH2/Vh60cFBTnFsHNI6WAD+lNUo/xGZ4NeA5u0Ipw==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/typescript-estree": "5.5.0",
"@typescript-eslint/scope-manager": "5.8.0",
"@typescript-eslint/types": "5.8.0",
"@typescript-eslint/typescript-estree": "5.8.0",
"debug": "^4.3.2"
},
"engines": {
@ -281,13 +290,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz",
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.8.0.tgz",
"integrity": "sha512-x82CYJsLOjPCDuFFEbS6e7K1QEWj7u5Wk1alw8A+gnJiYwNnDJk0ib6PCegbaPMjrfBvFKa7SxE3EOnnIQz2Gg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/visitor-keys": "5.5.0"
"@typescript-eslint/types": "5.8.0",
"@typescript-eslint/visitor-keys": "5.8.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -298,9 +307,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz",
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.8.0.tgz",
"integrity": "sha512-LdCYOqeqZWqCMOmwFnum6YfW9F3nKuxJiR84CdIRN5nfHJ7gyvGpXWqL/AaW0k3Po0+wm93ARAsOdzlZDPCcXg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -311,13 +320,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz",
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.8.0.tgz",
"integrity": "sha512-srfeZ3URdEcUsSLbkOFqS7WoxOqn8JNil2NSLO9O+I2/Uyc85+UlfpEvQHIpj5dVts7KKOZnftoJD/Fdv0L7nQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/visitor-keys": "5.5.0",
"@typescript-eslint/types": "5.8.0",
"@typescript-eslint/visitor-keys": "5.8.0",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
@ -338,12 +347,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz",
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.8.0.tgz",
"integrity": "sha512-+HDIGOEMnqbxdAHegxvnOqESUH6RWFRR2b8qxP1W9CZnnYh4Usz6MBL+2KMAgPk/P0o9c1HqnYtwzVH6GTIqug==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/types": "5.8.0",
"eslint-visitor-keys": "^3.0.0"
},
"engines": {
@ -361,9 +370,9 @@
"dev": true
},
"node_modules/@vercel/ncc": {
"version": "0.33.0",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.33.0.tgz",
"integrity": "sha512-m21HzXD+L/YHoJTwyCCyGBXD0O2L4KR/Y6SSsS4qvRlz3NAYsiiYahzOsgfWEt4PJxpPVCMGiuWzsvb2tycmyA==",
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.33.1.tgz",
"integrity": "sha512-Mlsps/P0PLZwsCFtSol23FGqT3FhBGb4B1AuGQ52JTAtXhak+b0Fh/4T55r0/SVQPeRiX9pNItOEHwakGPmZYA==",
"dev": true,
"bin": {
"ncc": "dist/ncc/cli.js"
@ -805,13 +814,13 @@
}
},
"node_modules/eslint": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.3.0.tgz",
"integrity": "sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww==",
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.5.0.tgz",
"integrity": "sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.0.4",
"@humanwhocodes/config-array": "^0.6.0",
"@eslint/eslintrc": "^1.0.5",
"@humanwhocodes/config-array": "^0.9.2",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@ -822,7 +831,7 @@
"eslint-scope": "^7.1.0",
"eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.1.0",
"espree": "^9.1.0",
"espree": "^9.2.0",
"esquery": "^1.4.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@ -973,9 +982,9 @@
}
},
"node_modules/espree": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.1.0.tgz",
"integrity": "sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ==",
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz",
"integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==",
"dev": true,
"dependencies": {
"acorn": "^8.6.0",
@ -1314,9 +1323,9 @@
}
},
"node_modules/ignore": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz",
"integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true,
"engines": {
"node": ">= 4"
@ -1822,9 +1831,9 @@
}
},
"node_modules/prettier": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz",
"integrity": "sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==",
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
@ -2237,9 +2246,9 @@
}
},
"node_modules/typescript": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz",
"integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==",
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@ -2332,6 +2341,14 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
"engines": {
"node": ">= 6"
}
},
"node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
@ -2429,14 +2446,14 @@
}
},
"@eslint/eslintrc": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz",
"integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz",
"integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
"espree": "^9.0.0",
"espree": "^9.2.0",
"globals": "^13.9.0",
"ignore": "^4.0.6",
"import-fresh": "^3.2.1",
@ -2453,13 +2470,21 @@
}
}
},
"@google-github-actions/actions-utils": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@google-github-actions/actions-utils/-/actions-utils-0.1.0.tgz",
"integrity": "sha512-zGKODnHmCqLL6RQP6CFY+EtpS4J+VSX6RRUNdv1NGS3sSavKy+yD0O+7hzfEjqdZBPGK8lf1JhttYHYZ6KbMmA==",
"requires": {
"yaml": "^1.10.2"
}
},
"@humanwhocodes/config-array": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz",
"integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==",
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
"integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==",
"dev": true,
"requires": {
"@humanwhocodes/object-schema": "^1.2.0",
"@humanwhocodes/object-schema": "^1.2.1",
"debug": "^4.1.1",
"minimatch": "^3.0.4"
}
@ -2521,9 +2546,9 @@
"dev": true
},
"@types/chai": {
"version": "4.2.22",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz",
"integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz",
"integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==",
"dev": true
},
"@types/json-schema": {
@ -2539,19 +2564,19 @@
"dev": true
},
"@types/node": {
"version": "16.11.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.11.tgz",
"integrity": "sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw==",
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.2.tgz",
"integrity": "sha512-JepeIUPFDARgIs0zD/SKPgFsJEAF0X5/qO80llx59gOxFTboS9Amv3S+QfB7lqBId5sFXJ99BN0J6zFRvL9dDA==",
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.8.0.tgz",
"integrity": "sha512-spu1UW7QuBn0nJ6+psnfCc3iVoQAifjKORgBngKOmC8U/1tbe2YJMzYQqDGYB4JCss7L8+RM2kKLb1B1Aw9BNA==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "5.5.0",
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/experimental-utils": "5.8.0",
"@typescript-eslint/scope-manager": "5.8.0",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
@ -2561,55 +2586,55 @@
}
},
"@typescript-eslint/experimental-utils": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz",
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.8.0.tgz",
"integrity": "sha512-KN5FvNH71bhZ8fKtL+lhW7bjm7cxs1nt+hrDZWIqb6ViCffQcWyLunGrgvISgkRojIDcXIsH+xlFfI4RCDA0xA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/typescript-estree": "5.5.0",
"@typescript-eslint/scope-manager": "5.8.0",
"@typescript-eslint/types": "5.8.0",
"@typescript-eslint/typescript-estree": "5.8.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
}
},
"@typescript-eslint/parser": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.8.0.tgz",
"integrity": "sha512-Gleacp/ZhRtJRYs5/T8KQR3pAQjQI89Dn/k+OzyCKOsLiZH2/Vh60cFBTnFsHNI6WAD+lNUo/xGZ4NeA5u0Ipw==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/typescript-estree": "5.5.0",
"@typescript-eslint/scope-manager": "5.8.0",
"@typescript-eslint/types": "5.8.0",
"@typescript-eslint/typescript-estree": "5.8.0",
"debug": "^4.3.2"
}
},
"@typescript-eslint/scope-manager": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz",
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.8.0.tgz",
"integrity": "sha512-x82CYJsLOjPCDuFFEbS6e7K1QEWj7u5Wk1alw8A+gnJiYwNnDJk0ib6PCegbaPMjrfBvFKa7SxE3EOnnIQz2Gg==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/visitor-keys": "5.5.0"
"@typescript-eslint/types": "5.8.0",
"@typescript-eslint/visitor-keys": "5.8.0"
}
},
"@typescript-eslint/types": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz",
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.8.0.tgz",
"integrity": "sha512-LdCYOqeqZWqCMOmwFnum6YfW9F3nKuxJiR84CdIRN5nfHJ7gyvGpXWqL/AaW0k3Po0+wm93ARAsOdzlZDPCcXg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz",
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.8.0.tgz",
"integrity": "sha512-srfeZ3URdEcUsSLbkOFqS7WoxOqn8JNil2NSLO9O+I2/Uyc85+UlfpEvQHIpj5dVts7KKOZnftoJD/Fdv0L7nQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/visitor-keys": "5.5.0",
"@typescript-eslint/types": "5.8.0",
"@typescript-eslint/visitor-keys": "5.8.0",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
@ -2618,12 +2643,12 @@
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz",
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.8.0.tgz",
"integrity": "sha512-+HDIGOEMnqbxdAHegxvnOqESUH6RWFRR2b8qxP1W9CZnnYh4Usz6MBL+2KMAgPk/P0o9c1HqnYtwzVH6GTIqug==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/types": "5.8.0",
"eslint-visitor-keys": "^3.0.0"
}
},
@ -2634,9 +2659,9 @@
"dev": true
},
"@vercel/ncc": {
"version": "0.33.0",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.33.0.tgz",
"integrity": "sha512-m21HzXD+L/YHoJTwyCCyGBXD0O2L4KR/Y6SSsS4qvRlz3NAYsiiYahzOsgfWEt4PJxpPVCMGiuWzsvb2tycmyA==",
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.33.1.tgz",
"integrity": "sha512-Mlsps/P0PLZwsCFtSol23FGqT3FhBGb4B1AuGQ52JTAtXhak+b0Fh/4T55r0/SVQPeRiX9pNItOEHwakGPmZYA==",
"dev": true
},
"acorn": {
@ -2962,13 +2987,13 @@
"dev": true
},
"eslint": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.3.0.tgz",
"integrity": "sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww==",
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.5.0.tgz",
"integrity": "sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==",
"dev": true,
"requires": {
"@eslint/eslintrc": "^1.0.4",
"@humanwhocodes/config-array": "^0.6.0",
"@eslint/eslintrc": "^1.0.5",
"@humanwhocodes/config-array": "^0.9.2",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@ -2979,7 +3004,7 @@
"eslint-scope": "^7.1.0",
"eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.1.0",
"espree": "^9.1.0",
"espree": "^9.2.0",
"esquery": "^1.4.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@ -3081,9 +3106,9 @@
"dev": true
},
"espree": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.1.0.tgz",
"integrity": "sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ==",
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz",
"integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==",
"dev": true,
"requires": {
"acorn": "^8.6.0",
@ -3340,9 +3365,9 @@
"dev": true
},
"ignore": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz",
"integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true
},
"import-fresh": {
@ -3710,9 +3735,9 @@
"dev": true
},
"prettier": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz",
"integrity": "sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==",
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
"dev": true
},
"prettier-linter-helpers": {
@ -3967,9 +3992,9 @@
"dev": true
},
"typescript": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz",
"integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==",
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
"dev": true
},
"uri-js": {
@ -4037,6 +4062,11 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
},
"yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",

View File

@ -23,22 +23,23 @@
"author": "GoogleCloudPlatform",
"license": "Apache-2.0",
"dependencies": {
"@actions/core": "^1.6.0"
"@actions/core": "^1.6.0",
"@google-github-actions/actions-utils": "^0.1.0"
},
"devDependencies": {
"@types/chai": "^4.2.22",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.0.0",
"@types/node": "^16.11.11",
"@typescript-eslint/eslint-plugin": "^5.5.0",
"@typescript-eslint/parser": "^5.5.0",
"@vercel/ncc": "^0.33.0",
"@types/node": "^17.0.2",
"@typescript-eslint/eslint-plugin": "^5.8.0",
"@typescript-eslint/parser": "^5.8.0",
"@vercel/ncc": "^0.33.1",
"chai": "^4.3.4",
"eslint": "^8.3.0",
"eslint": "^8.5.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"mocha": "^9.1.3",
"prettier": "^2.5.0",
"prettier": "^2.5.1",
"ts-node": "^10.4.0",
"typescript": "^4.5.2"
"typescript": "^4.5.4"
}
}

View File

@ -1,8 +1,16 @@
'use strict';
import { createSign } from 'crypto';
import {
isServiceAccountKey,
parseCredential,
randomFilepath,
ServiceAccountKey,
toBase64,
writeSecureFile,
} from '@google-github-actions/actions-utils';
import { AuthClient } from './auth_client';
import { toBase64, fromBase64, trimmedString, writeSecureFile } from '../utils';
/**
* Available options to create the CredentialsJSONClient.
@ -22,49 +30,16 @@ interface CredentialsJSONClientOptions {
*/
export class CredentialsJSONClient implements AuthClient {
readonly #projectID: string;
readonly #credentials: Record<string, string>;
readonly #credentials: ServiceAccountKey;
constructor(opts: CredentialsJSONClientOptions) {
this.#credentials = this.parseServiceAccountKeyJSON(opts.credentialsJSON);
this.#projectID = opts.projectID || this.#credentials['project_id'];
}
/**
* parseServiceAccountKeyJSON attempts to parse the given string as a service
* account key JSON. It handles if the string is base64-encoded.
*/
parseServiceAccountKeyJSON(str: string): Record<string, string> {
str = trimmedString(str);
if (!str) {
throw new Error(`Missing service account key JSON (got empty value)`);
const credentials = parseCredential(opts.credentialsJSON);
if (!isServiceAccountKey(credentials)) {
throw new Error(`Provided credential is not a valid service account key JSON`);
}
this.#credentials = credentials;
// If the string doesn't start with a JSON object character, it is probably
// base64-encoded.
if (!str.startsWith('{')) {
str = fromBase64(str);
}
let creds: Record<string, string>;
try {
creds = JSON.parse(str);
} catch (e) {
throw new SyntaxError(`Failed to parse credentials as JSON: ${e}`);
}
const requireValue = (key: string) => {
const val = trimmedString(creds[key]);
if (!val) {
throw new Error(`Service account key JSON is missing required field "${key}"`);
}
};
requireValue('project_id');
requireValue('private_key_id');
requireValue('private_key');
requireValue('client_email');
return creds;
this.#projectID = opts.projectID || this.#credentials.project_id;
}
/**
@ -74,14 +49,14 @@ export class CredentialsJSONClient implements AuthClient {
const header = {
alg: 'RS256',
typ: 'JWT',
kid: this.#credentials['private_key_id'],
kid: this.#credentials.private_key_id,
};
const now = Math.floor(new Date().getTime() / 1000);
const body = {
iss: this.#credentials['client_email'],
sub: this.#credentials['client_email'],
iss: this.#credentials.client_email,
sub: this.#credentials.client_email,
aud: 'https://iamcredentials.googleapis.com/',
iat: now,
exp: now + 3599,
@ -94,7 +69,7 @@ export class CredentialsJSONClient implements AuthClient {
signer.write(message);
signer.end();
const signature = signer.sign(this.#credentials['private_key']);
const signature = signer.sign(this.#credentials.private_key);
return message + '.' + toBase64(signature);
} catch (err) {
throw new Error(`Failed to sign auth token using ${await this.getServiceAccount()}: ${err}`);
@ -110,7 +85,7 @@ export class CredentialsJSONClient implements AuthClient {
const header = {
alg: 'RS256',
typ: 'JWT',
kid: this.#credentials['private_key_id'],
kid: this.#credentials.private_key_id,
};
const message = toBase64(JSON.stringify(header)) + '.' + toBase64(unsignedJWT);
@ -120,7 +95,7 @@ export class CredentialsJSONClient implements AuthClient {
signer.write(message);
signer.end();
const signature = signer.sign(this.#credentials['private_key']);
const signature = signer.sign(this.#credentials.private_key);
const jwt = message + '.' + toBase64(signature);
return jwt;
} catch (err) {
@ -142,7 +117,7 @@ export class CredentialsJSONClient implements AuthClient {
* extracted from the Service Account Key JSON.
*/
async getServiceAccount(): Promise<string> {
return this.#credentials['client_email'];
return this.#credentials.client_email;
}
/**
@ -150,6 +125,7 @@ export class CredentialsJSONClient implements AuthClient {
* set as GOOGLE_APPLICATION_CREDENTIALS for gcloud and client libraries.
*/
async createCredentialsFile(outputDir: string): Promise<string> {
return await writeSecureFile(outputDir, JSON.stringify(this.#credentials));
const outputFile = randomFilepath(outputDir);
return await writeSecureFile(outputFile, JSON.stringify(this.#credentials));
}
}

View File

@ -1,8 +1,9 @@
'use strict';
import { URL } from 'url';
import { randomFilepath, writeSecureFile } from '@google-github-actions/actions-utils';
import { AuthClient } from './auth_client';
import { writeSecureFile } from '../utils';
import { BaseClient } from '../base';
/**
@ -208,6 +209,7 @@ export class WorkloadIdentityClient implements AuthClient {
},
};
return await writeSecureFile(outputDir, JSON.stringify(data));
const outputFile = randomFilepath(outputDir);
return await writeSecureFile(outputFile, JSON.stringify(data));
}
}

View File

@ -11,11 +11,18 @@ import {
setOutput,
setSecret,
} from '@actions/core';
import {
errorMessage,
exactlyOneOf,
parseCSV,
parseDuration,
} from '@google-github-actions/actions-utils';
import { WorkloadIdentityClient } from './client/workload_identity_client';
import { CredentialsJSONClient } from './client/credentials_json_client';
import { AuthClient } from './client/auth_client';
import { BaseClient } from './base';
import { buildDomainWideDelegationJWT, errorMessage, explodeStrings, parseDuration } from './utils';
import { buildDomainWideDelegationJWT } from './utils';
const secretsWarning =
`If you are specifying input values via GitHub secrets, ensure the secret ` +
@ -42,14 +49,11 @@ async function run(): Promise<void> {
const credentialsJSON = getInput('credentials_json');
const createCredentialsFile = getBooleanInput('create_credentials_file');
const tokenFormat = getInput('token_format');
const delegates = explodeStrings(getInput('delegates'));
const delegates = parseCSV(getInput('delegates'));
// Ensure exactly one of workload_identity_provider and credentials_json was
// provided.
if (
(!workloadIdentityProvider && !credentialsJSON) ||
(workloadIdentityProvider && credentialsJSON)
) {
if (!exactlyOneOf(workloadIdentityProvider, credentialsJSON)) {
throw new Error(
'The GitHub Action workflow must specify exactly one of ' +
'"workload_identity_provider" or "credentials_json"! ' +
@ -159,7 +163,7 @@ async function run(): Promise<void> {
logDebug(`Creating access token`);
const accessTokenLifetime = parseDuration(getInput('access_token_lifetime'));
const accessTokenScopes = explodeStrings(getInput('access_token_scopes'));
const accessTokenScopes = parseCSV(getInput('access_token_scopes'));
const accessTokenSubject = getInput('access_token_subject');
const serviceAccount = await client.getServiceAccount();

View File

@ -1,7 +1,7 @@
'use strict';
import { getBooleanInput, setFailed, info as logInfo } from '@actions/core';
import { removeExportedCredentials } from './utils';
import { errorMessage, removeFile } from '@google-github-actions/actions-utils';
/**
* Executes the post action, documented inline.
@ -13,14 +13,25 @@ export async function run(): Promise<void> {
return;
}
const exportedPath = await removeExportedCredentials();
if (exportedPath) {
logInfo(`Removed exported credentials at ${exportedPath}`);
// Look up the credentials path, if one exists. Note that we only check the
// environment variable set by our action, since we don't want to
// accidentially clean up if someone set GOOGLE_APPLICATION_CREDENTIALS or
// another environment variable manually.
const credentialsPath = process.env['GOOGLE_GHA_CREDS_PATH'];
if (!credentialsPath) {
return;
}
// Remove the file.
const removed = await removeFile(credentialsPath);
if (removed) {
logInfo(`Removed exported credentials at ${credentialsPath}`);
} else {
logInfo('No exported credentials found');
}
} catch (err) {
setFailed(`google-github-actions/auth post failed with: ${err}`);
const msg = errorMessage(err);
setFailed(`google-github-actions/auth post failed with: ${msg}`);
}
}

View File

@ -1,199 +1,5 @@
'use strict';
import { promises as fs } from 'fs';
import crypto from 'crypto';
import path from 'path';
/**
* writeSecureFile writes a file to disk in a given directory with a
* random name.
*
* @param outputDir Directory to create random file in.
* @param data Data to write to file.
* @returns Path to written file.
*/
export async function writeSecureFile(outputDir: string, data: string): Promise<string> {
// Generate a random filename to store the credential. 12 bytes is 24
// characters in hex. It's not the ideal entropy, but we have to be under
// the 255 character limit for Windows filenames (which includes their
// entire leading path).
const uniqueName = crypto.randomBytes(12).toString('hex');
const pth = path.join(outputDir, uniqueName);
// Write the file as 0640 so the owner has RW, group as R, and the file is
// otherwise unreadable. Also write with EXCL to prevent a symlink attack.
await fs.writeFile(pth, data, { mode: 0o640, flag: 'wx' });
return pth;
}
/**
* removeExportedCredentials removes any exported credentials file. If the file
* does not exist, it does nothing.
*
* @returns Path of the file that was removed.
*/
export async function removeExportedCredentials(): Promise<string> {
// Look up the credentials path, if one exists. Note that we only check the
// environment variable set by our action, since we don't want to
// accidentially clean up if someone set GOOGLE_APPLICATION_CREDENTIALS or
// another environment variable manually.
const credentialsPath = process.env['GOOGLE_GHA_CREDS_PATH'];
if (!credentialsPath) {
return '';
}
// Delete the file.
try {
await fs.unlink(credentialsPath);
return credentialsPath;
} catch (err) {
if (err instanceof Error)
if (err && err.message && err.message.includes('ENOENT')) {
return '';
}
throw new Error(`failed to remove exported credentials: ${err}`);
}
}
/**
* Converts a multi-line or comma-separated collection of strings into an array
* of trimmed strings.
*/
export function explodeStrings(input: string): Array<string> {
if (!input || input.trim().length === 0) {
return [];
}
const list = new Array<string>();
let curr = '';
let escaped = false;
for (const ch of input) {
if (escaped) {
curr += ch;
escaped = false;
continue;
}
switch (ch) {
case '\\':
escaped = true;
continue;
case ',':
case '\n': {
const val = curr.trim();
if (val) {
list.push(val);
}
curr = '';
break;
}
default:
curr += ch;
}
}
const val = curr.trim();
if (val) {
list.push(val);
}
return list;
}
/**
* toBase64 base64 URL encodes the result.
*/
export function toBase64(s: string | Buffer): string {
return Buffer.from(s)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
/**
* fromBase64 base64 decodes the result, taking into account URL and standard
* encoding with and without padding.
*/
export function fromBase64(s: string): string {
let str = s.replace(/-/g, '+').replace(/_/g, '/');
while (str.length % 4) str += '=';
return Buffer.from(str, 'base64').toString('utf8');
}
/**
* trimmedString returns a string trimmed of whitespace. If the input string is
* null, then it returns the empty string.
*/
export function trimmedString(s: string | undefined | null): string {
return s ? s.trim() : '';
}
/**
* parseDuration parses a user-supplied string duration with optional suffix and
* returns a number representing the number of seconds. It returns 0 when given
* the empty string.
*
* @param str Duration string
*/
export function parseDuration(str: string): number {
const given = (str || '').trim();
if (!given) {
return 0;
}
let total = 0;
let curr = '';
for (let i = 0; i < str.length; i++) {
const ch = str[i];
switch (ch) {
case ' ':
continue;
case ',':
continue;
case 's': {
total += +curr;
curr = '';
break;
}
case 'm': {
total += +curr * 60;
curr = '';
break;
}
case 'h': {
total += +curr * 60 * 60;
curr = '';
break;
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
curr += ch;
break;
default:
throw new SyntaxError(`Unsupported character "${ch}" at position ${i}`);
}
}
// Anything left over is seconds
if (curr) {
total += +curr;
}
return total;
}
/**
* buildDomainWideDelegationJWT constructs an _unsigned_ JWT to be used for a
* DWD exchange. The JWT must be signed and then exchanged with the OAuth
@ -229,27 +35,3 @@ export function buildDomainWideDelegationJWT(
return JSON.stringify(body);
}
/**
* errorMessage extracts the error message from the given error.
*
* TODO(sethvargo): Candidate for centralization.
*
*/
export function errorMessage(err: unknown): string {
if (!err) {
return '';
}
let msg = err instanceof Error ? err.message : `${err}`;
msg = msg.trim();
msg = msg.replace('Error: ', '');
msg = msg.trim();
if (!msg) {
return '';
}
msg = msg[0].toLowerCase() + msg.slice(1);
return msg;
}

View File

@ -3,258 +3,9 @@
import 'mocha';
import { expect } from 'chai';
import { tmpdir } from 'os';
import { existsSync, readFileSync } from 'fs';
import {
buildDomainWideDelegationJWT,
explodeStrings,
fromBase64,
parseDuration,
removeExportedCredentials,
toBase64,
trimmedString,
writeSecureFile,
} from '../src/utils';
import { buildDomainWideDelegationJWT } from '../src/utils';
describe('Utils', () => {
describe('#writeSecureFile', () => {
it('writes data to the file', async () => {
const tmp = tmpdir();
const filePath = await writeSecureFile(tmp, 'hi');
expect(existsSync(filePath)).to.be.true;
expect(readFileSync(filePath).toString('utf8')).to.eq('hi');
});
it('generates a random name', async () => {
const tmp = tmpdir();
const filePath1 = await writeSecureFile(tmp, 'hi');
const filePath2 = await writeSecureFile(tmp, 'bye');
expect(filePath1).to.not.eq(filePath2);
expect(filePath1).to.not.eq(filePath2);
});
});
describe('#removeExportedCredentials', () => {
it('does nothing when GOOGLE_GHA_CREDS_PATH is unset', async () => {
delete process.env.GOOGLE_GHA_CREDS_PATH;
const pth = await removeExportedCredentials();
expect(pth).to.eq('');
});
it('deletes the file', async () => {
const filePath = await writeSecureFile(tmpdir(), 'my data');
process.env.GOOGLE_GHA_CREDS_PATH = filePath;
const pth = await removeExportedCredentials();
expect(existsSync(filePath)).to.be.false;
expect(pth).to.eq(filePath);
});
it('does not fail if the file does not exist', async () => {
const filePath = '/not/a/file';
process.env.GOOGLE_GHA_CREDS_PATH = filePath;
const pth = await removeExportedCredentials();
expect(pth).to.eq('');
});
});
describe('#explodeStrings', () => {
const cases = [
{
name: 'empty string',
input: '',
expected: [],
},
{
name: 'padded empty string',
input: ' ',
expected: [],
},
{
name: 'comma-separated',
input: 'hello , world , and goodbye',
expected: ['hello', 'world', 'and goodbye'],
},
{
name: 'newline-separated',
input: `
hello
world
and goodbye`,
expected: ['hello', 'world', 'and goodbye'],
},
{
name: 'comma and newline-separated',
input: `
hello,
world,
and goodbye,`,
expected: ['hello', 'world', 'and goodbye'],
},
{
name: 'comma-escaped',
input: 'hello , world , and\\, goodbye',
expected: ['hello', 'world', 'and, goodbye'],
},
];
cases.forEach((tc) => {
it(tc.name, async () => {
expect(explodeStrings(tc.input)).to.eql(tc.expected);
});
});
});
describe('#toBase64', () => {
const cases = [
{
name: 'empty string',
input: '',
expected: '',
},
{
name: 'empty buffer',
input: Buffer.from(''),
expected: '',
},
{
name: 'encodes string',
input: 'hello',
expected: 'aGVsbG8',
},
{
name: 'encodes buffer',
input: Buffer.from('hello'),
expected: 'aGVsbG8',
},
];
cases.forEach((tc) => {
it(tc.name, async () => {
expect(toBase64(tc.input)).to.eq(tc.expected);
});
});
});
describe('#fromBase64', () => {
const cases = [
{
name: 'decodes',
input: 'aGVsbG8',
expected: 'hello',
},
{
name: 'decodes padded',
input: 'aGVsbG8==',
expected: 'hello',
},
{
name: 'decodes semi-padded',
input: 'aGVsbG8=',
expected: 'hello',
},
];
cases.forEach((tc) => {
it(tc.name, async () => {
expect(fromBase64(tc.input)).to.eq(tc.expected);
});
});
});
describe('#trimmedString', () => {
const cases = [
{
name: 'null',
input: null,
expected: '',
},
{
name: 'undefined',
input: undefined,
expected: '',
},
{
name: 'empty string',
input: '',
expected: '',
},
{
name: 'trims',
input: ' hello world ',
expected: 'hello world',
},
];
cases.forEach((tc) => {
it(tc.name, async () => {
expect(trimmedString(tc.input)).to.eq(tc.expected);
});
});
});
describe('#parseDuration', () => {
const cases = [
{
name: 'empty string',
input: '',
expected: 0,
},
{
name: 'unitless',
input: '149585',
expected: 149585,
},
{
name: 'with commas',
input: '149,585',
expected: 149585,
},
{
name: 'suffix seconds',
input: '149585s',
expected: 149585,
},
{
name: 'suffix minutes',
input: '25m',
expected: 1500,
},
{
name: 'suffix hours',
input: '12h',
expected: 43200,
},
{
name: 'suffix hours minutes seconds',
input: '12h10m55s',
expected: 43855,
},
{
name: 'commas and spaces',
input: '12h, 10m 55s',
expected: 43855,
},
{
name: 'invalid',
input: '12h blueberries',
error: 'Unsupported character "b" at position 4',
},
];
cases.forEach((tc) => {
it(tc.name, async () => {
if (tc.expected) {
expect(parseDuration(tc.input)).to.eq(tc.expected);
} else if (tc.error) {
expect(() => {
parseDuration(tc.input);
}).to.throw(tc.error);
}
});
});
});
describe('#buildDomainWideDelegationJWT', () => {
const cases = [
{

View File

@ -1,5 +1,6 @@
{
"compilerOptions": {
"alwaysStrict": true,
"target": "es6",
"module": "commonjs",
"lib": [