chore: add remaining tests
This commit is contained in:
parent
a61ce85bf3
commit
49bbbeb420
12 changed files with 798 additions and 209 deletions
2
.gitignore
generated
vendored
2
.gitignore
generated
vendored
|
|
@ -30,6 +30,8 @@ jspm_packages/
|
|||
*.tgz
|
||||
.yarn-integrity
|
||||
.cache
|
||||
.vscode
|
||||
.env
|
||||
!/.projenrc.js
|
||||
/test-reports/
|
||||
junit.xml
|
||||
|
|
|
|||
4
.projen/deps.json
generated
4
.projen/deps.json
generated
|
|
@ -4,6 +4,10 @@
|
|||
"name": "@aws-sdk/credential-provider-env",
|
||||
"type": "build"
|
||||
},
|
||||
{
|
||||
"name": "@aws-sdk/property-provider",
|
||||
"type": "build"
|
||||
},
|
||||
{
|
||||
"name": "@jest/globals",
|
||||
"type": "build"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ const project = new GitHubActionTypeScriptProject({
|
|||
'@aws-sdk/credential-provider-env',
|
||||
'aws-sdk-client-mock',
|
||||
'@jest/globals',
|
||||
'@aws-sdk/property-provider',
|
||||
],
|
||||
deps: ['@aws-sdk/client-sts@^3'],
|
||||
name: 'configure-aws-credentials',
|
||||
|
|
@ -21,6 +22,7 @@ const project = new GitHubActionTypeScriptProject({
|
|||
authorUrl: 'https://aws.amazon.com',
|
||||
packageManager: NodePackageManager.NPM,
|
||||
sampleCode: false,
|
||||
gitignore: ['.vscode', '.env'],
|
||||
actionMetadata: {
|
||||
name: '"Configure AWS Credentials" Action for GitHub Actions',
|
||||
description: 'Configures AWS credentials for use in subsequent steps in a GitHub Action workflow',
|
||||
|
|
@ -135,6 +137,7 @@ const project = new GitHubActionTypeScriptProject({
|
|||
target: 'es2022',
|
||||
module: 'commonjs',
|
||||
outDir: 'build',
|
||||
noUnusedLocals: false,
|
||||
},
|
||||
},
|
||||
prettier: true,
|
||||
|
|
|
|||
165
package-lock.json
generated
165
package-lock.json
generated
|
|
@ -15,7 +15,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@aws-sdk/credential-provider-env": "^3.186.0",
|
||||
"@aws-sdk/credential-providers": "^3.188.0",
|
||||
"@aws-sdk/property-provider": "^3.188.0",
|
||||
"@jest/globals": "^29.1.2",
|
||||
"@types/jest": "^29.1.2",
|
||||
"@types/node": "^14",
|
||||
|
|
@ -179,51 +179,6 @@
|
|||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/client-cognito-identity": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.188.0.tgz",
|
||||
"integrity": "sha512-lpl8yxAjER3xUDYQxJR8oyQzfcw4TQbsgTY+kZzVTIsHVLIuZfJoWBNA/ONWkmuCOylH8jEu5jcZ3a45fyx5fg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha256-browser": "2.0.0",
|
||||
"@aws-crypto/sha256-js": "2.0.0",
|
||||
"@aws-sdk/client-sts": "3.188.0",
|
||||
"@aws-sdk/config-resolver": "3.188.0",
|
||||
"@aws-sdk/credential-provider-node": "3.188.0",
|
||||
"@aws-sdk/fetch-http-handler": "3.188.0",
|
||||
"@aws-sdk/hash-node": "3.188.0",
|
||||
"@aws-sdk/invalid-dependency": "3.188.0",
|
||||
"@aws-sdk/middleware-content-length": "3.188.0",
|
||||
"@aws-sdk/middleware-host-header": "3.188.0",
|
||||
"@aws-sdk/middleware-logger": "3.188.0",
|
||||
"@aws-sdk/middleware-recursion-detection": "3.188.0",
|
||||
"@aws-sdk/middleware-retry": "3.188.0",
|
||||
"@aws-sdk/middleware-serde": "3.188.0",
|
||||
"@aws-sdk/middleware-signing": "3.188.0",
|
||||
"@aws-sdk/middleware-stack": "3.188.0",
|
||||
"@aws-sdk/middleware-user-agent": "3.188.0",
|
||||
"@aws-sdk/node-config-provider": "3.188.0",
|
||||
"@aws-sdk/node-http-handler": "3.188.0",
|
||||
"@aws-sdk/protocol-http": "3.188.0",
|
||||
"@aws-sdk/smithy-client": "3.188.0",
|
||||
"@aws-sdk/types": "3.188.0",
|
||||
"@aws-sdk/url-parser": "3.188.0",
|
||||
"@aws-sdk/util-base64-browser": "3.188.0",
|
||||
"@aws-sdk/util-base64-node": "3.188.0",
|
||||
"@aws-sdk/util-body-length-browser": "3.188.0",
|
||||
"@aws-sdk/util-body-length-node": "3.188.0",
|
||||
"@aws-sdk/util-defaults-mode-browser": "3.188.0",
|
||||
"@aws-sdk/util-defaults-mode-node": "3.188.0",
|
||||
"@aws-sdk/util-user-agent-browser": "3.188.0",
|
||||
"@aws-sdk/util-user-agent-node": "3.188.0",
|
||||
"@aws-sdk/util-utf8-browser": "3.188.0",
|
||||
"@aws-sdk/util-utf8-node": "3.188.0",
|
||||
"tslib": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/client-sso": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.188.0.tgz",
|
||||
|
|
@ -325,21 +280,6 @@
|
|||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-cognito-identity": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.188.0.tgz",
|
||||
"integrity": "sha512-PK+a5wiQT/xz3CVVXulkYBdvejrHSmQ/JI38jW0GPQaa6zWobk1kkNOLUTqcpAaiYsyZUm+3guDUSobdHWnJ2A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-cognito-identity": "3.188.0",
|
||||
"@aws-sdk/property-provider": "3.188.0",
|
||||
"@aws-sdk/types": "3.188.0",
|
||||
"tslib": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-provider-env": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.188.0.tgz",
|
||||
|
|
@ -448,32 +388,6 @@
|
|||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/credential-providers": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.188.0.tgz",
|
||||
"integrity": "sha512-RNf0nolOqPKGUzq2wZHo0qYz14r9W+liX5BeUK9+fqhZtYY1LOoL+Jb3SFCIMPSnYekmMfEZ7JSU00QgMrBsmA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-cognito-identity": "3.188.0",
|
||||
"@aws-sdk/client-sso": "3.188.0",
|
||||
"@aws-sdk/client-sts": "3.188.0",
|
||||
"@aws-sdk/credential-provider-cognito-identity": "3.188.0",
|
||||
"@aws-sdk/credential-provider-env": "3.188.0",
|
||||
"@aws-sdk/credential-provider-imds": "3.188.0",
|
||||
"@aws-sdk/credential-provider-ini": "3.188.0",
|
||||
"@aws-sdk/credential-provider-node": "3.188.0",
|
||||
"@aws-sdk/credential-provider-process": "3.188.0",
|
||||
"@aws-sdk/credential-provider-sso": "3.188.0",
|
||||
"@aws-sdk/credential-provider-web-identity": "3.188.0",
|
||||
"@aws-sdk/property-provider": "3.188.0",
|
||||
"@aws-sdk/shared-ini-file-loader": "3.188.0",
|
||||
"@aws-sdk/types": "3.188.0",
|
||||
"tslib": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/fetch-http-handler": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.188.0.tgz",
|
||||
|
|
@ -8909,48 +8823,6 @@
|
|||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@aws-sdk/client-cognito-identity": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.188.0.tgz",
|
||||
"integrity": "sha512-lpl8yxAjER3xUDYQxJR8oyQzfcw4TQbsgTY+kZzVTIsHVLIuZfJoWBNA/ONWkmuCOylH8jEu5jcZ3a45fyx5fg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@aws-crypto/sha256-browser": "2.0.0",
|
||||
"@aws-crypto/sha256-js": "2.0.0",
|
||||
"@aws-sdk/client-sts": "3.188.0",
|
||||
"@aws-sdk/config-resolver": "3.188.0",
|
||||
"@aws-sdk/credential-provider-node": "3.188.0",
|
||||
"@aws-sdk/fetch-http-handler": "3.188.0",
|
||||
"@aws-sdk/hash-node": "3.188.0",
|
||||
"@aws-sdk/invalid-dependency": "3.188.0",
|
||||
"@aws-sdk/middleware-content-length": "3.188.0",
|
||||
"@aws-sdk/middleware-host-header": "3.188.0",
|
||||
"@aws-sdk/middleware-logger": "3.188.0",
|
||||
"@aws-sdk/middleware-recursion-detection": "3.188.0",
|
||||
"@aws-sdk/middleware-retry": "3.188.0",
|
||||
"@aws-sdk/middleware-serde": "3.188.0",
|
||||
"@aws-sdk/middleware-signing": "3.188.0",
|
||||
"@aws-sdk/middleware-stack": "3.188.0",
|
||||
"@aws-sdk/middleware-user-agent": "3.188.0",
|
||||
"@aws-sdk/node-config-provider": "3.188.0",
|
||||
"@aws-sdk/node-http-handler": "3.188.0",
|
||||
"@aws-sdk/protocol-http": "3.188.0",
|
||||
"@aws-sdk/smithy-client": "3.188.0",
|
||||
"@aws-sdk/types": "3.188.0",
|
||||
"@aws-sdk/url-parser": "3.188.0",
|
||||
"@aws-sdk/util-base64-browser": "3.188.0",
|
||||
"@aws-sdk/util-base64-node": "3.188.0",
|
||||
"@aws-sdk/util-body-length-browser": "3.188.0",
|
||||
"@aws-sdk/util-body-length-node": "3.188.0",
|
||||
"@aws-sdk/util-defaults-mode-browser": "3.188.0",
|
||||
"@aws-sdk/util-defaults-mode-node": "3.188.0",
|
||||
"@aws-sdk/util-user-agent-browser": "3.188.0",
|
||||
"@aws-sdk/util-user-agent-node": "3.188.0",
|
||||
"@aws-sdk/util-utf8-browser": "3.188.0",
|
||||
"@aws-sdk/util-utf8-node": "3.188.0",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@aws-sdk/client-sso": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.188.0.tgz",
|
||||
|
|
@ -9043,18 +8915,6 @@
|
|||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@aws-sdk/credential-provider-cognito-identity": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.188.0.tgz",
|
||||
"integrity": "sha512-PK+a5wiQT/xz3CVVXulkYBdvejrHSmQ/JI38jW0GPQaa6zWobk1kkNOLUTqcpAaiYsyZUm+3guDUSobdHWnJ2A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@aws-sdk/client-cognito-identity": "3.188.0",
|
||||
"@aws-sdk/property-provider": "3.188.0",
|
||||
"@aws-sdk/types": "3.188.0",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@aws-sdk/credential-provider-env": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.188.0.tgz",
|
||||
|
|
@ -9142,29 +9002,6 @@
|
|||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@aws-sdk/credential-providers": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.188.0.tgz",
|
||||
"integrity": "sha512-RNf0nolOqPKGUzq2wZHo0qYz14r9W+liX5BeUK9+fqhZtYY1LOoL+Jb3SFCIMPSnYekmMfEZ7JSU00QgMrBsmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@aws-sdk/client-cognito-identity": "3.188.0",
|
||||
"@aws-sdk/client-sso": "3.188.0",
|
||||
"@aws-sdk/client-sts": "3.188.0",
|
||||
"@aws-sdk/credential-provider-cognito-identity": "3.188.0",
|
||||
"@aws-sdk/credential-provider-env": "3.188.0",
|
||||
"@aws-sdk/credential-provider-imds": "3.188.0",
|
||||
"@aws-sdk/credential-provider-ini": "3.188.0",
|
||||
"@aws-sdk/credential-provider-node": "3.188.0",
|
||||
"@aws-sdk/credential-provider-process": "3.188.0",
|
||||
"@aws-sdk/credential-provider-sso": "3.188.0",
|
||||
"@aws-sdk/credential-provider-web-identity": "3.188.0",
|
||||
"@aws-sdk/property-provider": "3.188.0",
|
||||
"@aws-sdk/shared-ini-file-loader": "3.188.0",
|
||||
"@aws-sdk/types": "3.188.0",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@aws-sdk/fetch-http-handler": {
|
||||
"version": "3.188.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.188.0.tgz",
|
||||
|
|
|
|||
2
package.json
generated
2
package.json
generated
|
|
@ -26,7 +26,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@aws-sdk/credential-provider-env": "^3.186.0",
|
||||
"@aws-sdk/credential-providers": "^3.188.0",
|
||||
"@aws-sdk/property-provider": "^3.188.0",
|
||||
"@jest/globals": "^29.1.2",
|
||||
"@types/jest": "^29.1.2",
|
||||
"@types/node": "^14",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import assert from 'assert';
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import { AssumeRoleCommandInput, AssumeRoleWithWebIdentityCommand } from '@aws-sdk/client-sts';
|
||||
import { AssumeRoleCommand, AssumeRoleCommandInput, AssumeRoleWithWebIdentityCommand } from '@aws-sdk/client-sts';
|
||||
import { errorMessage, getStsClient, isDefined } from './helpers';
|
||||
|
||||
const SANITIZATION_CHARACTER = '_';
|
||||
|
|
@ -94,15 +94,16 @@ export async function assumeRole(params: assumeRoleParams) {
|
|||
const keys = Object.keys(commonAssumeRoleParams) as Array<keyof typeof commonAssumeRoleParams>;
|
||||
keys.forEach((k) => commonAssumeRoleParams[k] === undefined && delete commonAssumeRoleParams[k]);
|
||||
|
||||
let assumeRoleCommand: AssumeRoleWithWebIdentityCommand;
|
||||
const sts = getStsClient(region);
|
||||
switch (true) {
|
||||
case !!webIdentityToken: {
|
||||
delete commonAssumeRoleParams.Tags;
|
||||
assumeRoleCommand = new AssumeRoleWithWebIdentityCommand({
|
||||
...commonAssumeRoleParams,
|
||||
WebIdentityToken: webIdentityToken,
|
||||
});
|
||||
break;
|
||||
return sts.send(
|
||||
new AssumeRoleWithWebIdentityCommand({
|
||||
...commonAssumeRoleParams,
|
||||
WebIdentityToken: webIdentityToken,
|
||||
})
|
||||
);
|
||||
}
|
||||
case !!webIdentityTokenFile: {
|
||||
core.debug(
|
||||
|
|
@ -117,21 +118,20 @@ export async function assumeRole(params: assumeRoleParams) {
|
|||
}
|
||||
|
||||
try {
|
||||
const widt = await fs.promises.readFile(webIdentityTokenFilePath, 'utf8');
|
||||
const widt = fs.readFileSync(webIdentityTokenFilePath, 'utf8');
|
||||
delete commonAssumeRoleParams.Tags;
|
||||
assumeRoleCommand = new AssumeRoleWithWebIdentityCommand({
|
||||
...commonAssumeRoleParams,
|
||||
WebIdentityToken: widt,
|
||||
});
|
||||
return await sts.send(
|
||||
new AssumeRoleWithWebIdentityCommand({
|
||||
...commonAssumeRoleParams,
|
||||
WebIdentityToken: widt,
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
throw new Error(`Web identity token file could not be read: ${errorMessage(error)}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error('No web identity token or web identity token file provided.');
|
||||
default: {
|
||||
return sts.send(new AssumeRoleCommand({ ...commonAssumeRoleParams }));
|
||||
}
|
||||
}
|
||||
|
||||
const sts = getStsClient(region);
|
||||
return sts.send(assumeRoleCommand);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export async function cleanup() {
|
|||
core.setFailed(errorMessage(error));
|
||||
}
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
if (require.main === module) {
|
||||
(async () => {
|
||||
await cleanup();
|
||||
|
|
|
|||
35
src/index.ts
35
src/index.ts
|
|
@ -51,19 +51,19 @@ function exportRegion(region: string) {
|
|||
async function exportAccountId(region: string, maskAccountId?: boolean) {
|
||||
// Get the AWS account ID
|
||||
const client = getStsClient(region, USER_AGENT);
|
||||
const identity = (await client.send(new GetCallerIdentityCommand({}))).Account;
|
||||
if (!identity) {
|
||||
const identity = await client.send(new GetCallerIdentityCommand({}));
|
||||
const accountId = identity.Account;
|
||||
if (!accountId) {
|
||||
throw new Error('Could not get Account ID from STS. Did you set credentials?');
|
||||
}
|
||||
if (maskAccountId) {
|
||||
core.setSecret(identity);
|
||||
} else {
|
||||
core.setOutput('aws-account-id', identity);
|
||||
core.setSecret(accountId);
|
||||
}
|
||||
return identity;
|
||||
core.setOutput('aws-account-id', accountId);
|
||||
return accountId;
|
||||
}
|
||||
|
||||
function loadCredentials() {
|
||||
async function loadCredentials() {
|
||||
// Previously, this function forced the SDK to re-resolve credentials with the default provider chain.
|
||||
//
|
||||
// This action typically sets credentials in the environment via environment variables. The SDK never refreshed those
|
||||
|
|
@ -109,25 +109,19 @@ export async function run() {
|
|||
(core.getInput('mask-aws-account-id', { required: false }) || 'true').toLowerCase() === 'true';
|
||||
const roleToAssume = core.getInput('role-to-assume', { required: false });
|
||||
const roleExternalId = core.getInput('role-external-id', { required: false });
|
||||
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
|
||||
const roleSkipSessionTaggingInput = core.getInput('role-skip-session-tagging', { required: false }) || 'false';
|
||||
const roleSkipSessionTagging = roleSkipSessionTaggingInput.toLowerCase() === 'true';
|
||||
const webIdentityTokenFile = core.getInput('web-identity-token-file', { required: false });
|
||||
|
||||
// This wraps the logic for deciding if we should rely on the GH OIDC provider since we may need to reference
|
||||
// the decision in a few differennt places. Consolidating it here makes the logic clearer elsewhere.
|
||||
const useGitHubOIDCProvider = () => {
|
||||
// The assumption here is that self-hosted runners won't be populating the `ACTIONS_ID_TOKEN_REQUEST_TOKEN`
|
||||
// environment variable and they won't be providing a web idenity token file or access key either.
|
||||
// V2 of the action might relax this a bit and create an explicit precedence for these so that customers
|
||||
// can provide as much info as they want and we will follow the established credential loading precedence.
|
||||
return !!(roleToAssume && process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN && !AccessKeyId && !webIdentityTokenFile);
|
||||
};
|
||||
const useGitHubOIDCProvider =
|
||||
!!roleToAssume && !!process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN && !AccessKeyId && !webIdentityTokenFile;
|
||||
const roleDurationSeconds =
|
||||
parseInt(core.getInput('role-duration-seconds', { required: false })) ||
|
||||
(SessionToken && SESSION_ROLE_DURATION) ||
|
||||
(useGitHubOIDCProvider() && DEFAULT_ROLE_DURATION_FOR_OIDC_ROLES) ||
|
||||
(useGitHubOIDCProvider && DEFAULT_ROLE_DURATION_FOR_OIDC_ROLES) ||
|
||||
MAX_ACTION_RUNTIME;
|
||||
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
|
||||
const roleSkipSessionTaggingInput = core.getInput('role-skip-session-tagging', { required: false }) || 'false';
|
||||
const roleSkipSessionTagging = roleSkipSessionTaggingInput.toLowerCase() === 'true';
|
||||
|
||||
if (!region.match(REGION_REGEX)) {
|
||||
throw new Error(`Region is not valid: ${region}`);
|
||||
|
|
@ -153,7 +147,7 @@ export async function run() {
|
|||
// The only way to assume the role is via GitHub's OIDC provider.
|
||||
let sourceAccountId: string;
|
||||
let webIdentityToken: string;
|
||||
if (useGitHubOIDCProvider()) {
|
||||
if (useGitHubOIDCProvider) {
|
||||
webIdentityToken = await core.getIDToken(audience);
|
||||
// We don't validate the credentials here because we don't have them yet when using OIDC.
|
||||
} else {
|
||||
|
|
@ -203,6 +197,7 @@ export async function run() {
|
|||
}
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (require.main === module) {
|
||||
(async () => {
|
||||
await run();
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ describe('Configure AWS Credentials', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
jest.spyOn(core, 'exportVariable');
|
||||
jest.spyOn(core, 'setSecret');
|
||||
jest.spyOn(core, 'setOutput');
|
||||
jest.spyOn(core, 'setFailed');
|
||||
jest.spyOn(core, 'exportVariable').mockImplementation();
|
||||
jest.spyOn(core, 'setSecret').mockImplementation();
|
||||
jest.spyOn(core, 'setOutput').mockImplementation();
|
||||
jest.spyOn(core, 'setFailed').mockImplementation();
|
||||
process.env = { ...OLD_ENV, ...ACTION_ENVIRONMENT_VARIABLES };
|
||||
});
|
||||
|
||||
|
|
|
|||
747
test/index.test.ts
Normal file
747
test/index.test.ts
Normal file
|
|
@ -0,0 +1,747 @@
|
|||
import assert from 'assert';
|
||||
import * as core from '@actions/core';
|
||||
import {
|
||||
AssumeRoleCommand,
|
||||
AssumeRoleWithWebIdentityCommand,
|
||||
GetCallerIdentityCommand,
|
||||
STSClient,
|
||||
} from '@aws-sdk/client-sts';
|
||||
import { fromEnv } from '@aws-sdk/credential-provider-env';
|
||||
import { CredentialsProviderError } from '@aws-sdk/property-provider';
|
||||
import { mockClient } from 'aws-sdk-client-mock';
|
||||
import { withsleep, reset } from '../src/helpers';
|
||||
import { run } from '../src/index';
|
||||
|
||||
// #region
|
||||
const FAKE_ACCESS_KEY_ID = 'MY-AWS-ACCESS-KEY-ID';
|
||||
const FAKE_SECRET_ACCESS_KEY = 'MY-AWS-SECRET-ACCESS-KEY';
|
||||
const FAKE_SESSION_TOKEN = 'MY-AWS-SESSION-TOKEN';
|
||||
const FAKE_STS_ACCESS_KEY_ID = 'STS-AWS-ACCESS-KEY-ID';
|
||||
const FAKE_STS_SECRET_ACCESS_KEY = 'STS-AWS-SECRET-ACCESS-KEY';
|
||||
const FAKE_STS_SESSION_TOKEN = 'STS-AWS-SESSION-TOKEN';
|
||||
const FAKE_REGION = 'fake-region-1';
|
||||
const FAKE_ACCOUNT_ID = '123456789012';
|
||||
const FAKE_ROLE_ACCOUNT_ID = '111111111111';
|
||||
const ROLE_NAME = 'MY-ROLE';
|
||||
const ROLE_ARN = 'arn:aws:iam::111111111111:role/MY-ROLE';
|
||||
const ENVIRONMENT_VARIABLE_OVERRIDES = {
|
||||
SHOW_STACK_TRACE: 'false',
|
||||
GITHUB_REPOSITORY: 'MY-REPOSITORY-NAME',
|
||||
GITHUB_WORKFLOW: 'MY-WORKFLOW-ID',
|
||||
GITHUB_ACTION: 'MY-ACTION-NAME',
|
||||
GITHUB_ACTOR: 'MY-USERNAME[bot]',
|
||||
GITHUB_SHA: 'MY-COMMIT-ID',
|
||||
GITHUB_REF: 'MY-BRANCH',
|
||||
GITHUB_WORKSPACE: '/home/github',
|
||||
};
|
||||
const GITHUB_ACTOR_SANITIZED = 'MY-USERNAME_bot_';
|
||||
const CREDS_INPUTS = {
|
||||
'aws-access-key-id': FAKE_ACCESS_KEY_ID,
|
||||
'aws-secret-access-key': FAKE_SECRET_ACCESS_KEY,
|
||||
};
|
||||
const DEFAULT_INPUTS = {
|
||||
...CREDS_INPUTS,
|
||||
'aws-session-token': FAKE_SESSION_TOKEN,
|
||||
'aws-region': FAKE_REGION,
|
||||
'mask-aws-account-id': 'TRUE',
|
||||
};
|
||||
const ASSUME_ROLE_INPUTS = { ...CREDS_INPUTS, 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION };
|
||||
// #endregion
|
||||
|
||||
const mockedSTS = mockClient(STSClient);
|
||||
function mockGetInput(requestResponse: Record<string, string>) {
|
||||
return function (name: string, _options: unknown) {
|
||||
return requestResponse[name];
|
||||
};
|
||||
}
|
||||
|
||||
jest.mock('fs', () => ({
|
||||
...jest.requireActual('fs'),
|
||||
existsSync: jest.fn(() => true),
|
||||
readFileSync: jest.fn(() => 'testpayload'),
|
||||
}));
|
||||
jest.mock('@aws-sdk/credential-provider-env', () => ({
|
||||
// This is the actual implementation in the SDK ^_^
|
||||
fromEnv: jest.fn().mockImplementation(() => async () => {
|
||||
const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
|
||||
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
|
||||
const sessionToken = process.env.AWS_SESSION_TOKEN;
|
||||
const expiration = process.env.AWS_CREDENTIAL_EXPIRATION;
|
||||
return {
|
||||
accessKeyId,
|
||||
secretAccessKey,
|
||||
sessionToken,
|
||||
expiration,
|
||||
};
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('Configure AWS Credentials', () => {
|
||||
const OLD_ENV = process.env;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
process.env = { ...OLD_ENV, ...ENVIRONMENT_VARIABLE_OVERRIDES };
|
||||
jest.clearAllMocks();
|
||||
mockedSTS.reset();
|
||||
(fromEnv as jest.Mock).mockReset();
|
||||
jest.spyOn(core, 'getIDToken').mockImplementation(() => Promise.resolve('testtoken'));
|
||||
jest.spyOn(core, 'exportVariable').mockImplementation();
|
||||
jest.spyOn(core, 'setSecret').mockImplementation();
|
||||
jest.spyOn(core, 'setOutput').mockImplementation();
|
||||
jest.spyOn(core, 'setFailed').mockImplementation();
|
||||
jest.spyOn(core, 'debug').mockImplementation();
|
||||
(fromEnv as jest.Mock)
|
||||
.mockImplementationOnce(() => async () => ({
|
||||
accessKeyId: FAKE_ACCESS_KEY_ID,
|
||||
secretAccessKey: FAKE_SECRET_ACCESS_KEY,
|
||||
}))
|
||||
.mockImplementationOnce(() => async () => ({
|
||||
accessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
secretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||
}));
|
||||
mockedSTS
|
||||
.on(GetCallerIdentityCommand)
|
||||
.resolvesOnce({ Account: FAKE_ACCOUNT_ID })
|
||||
.resolvesOnce({ Account: FAKE_ROLE_ACCOUNT_ID });
|
||||
mockedSTS.on(AssumeRoleCommand).resolves({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||
Expiration: new Date(8640000000000000),
|
||||
},
|
||||
});
|
||||
mockedSTS.on(AssumeRoleWithWebIdentityCommand).resolves({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||
Expiration: new Date(8640000000000000),
|
||||
},
|
||||
});
|
||||
withsleep(() => {
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env = OLD_ENV;
|
||||
reset();
|
||||
});
|
||||
|
||||
test('exports env vars', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(4);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', FAKE_SESSION_TOKEN);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SESSION_TOKEN);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', FAKE_REGION);
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('action fails when github env vars are not set', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
delete process.env.GITHUB_SHA;
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
'Missing required environment variables. Are you running in GitHub Actions?'
|
||||
);
|
||||
});
|
||||
|
||||
test('action does not require GITHUB_REF env var', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||
delete process.env.GITHUB_REF;
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('hosted runners can pull creds from a self-hosted environment', async () => {
|
||||
const mockInputs = { 'aws-region': FAKE_REGION };
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(2);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(1);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', FAKE_REGION);
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('action with no accessible credentials fails', async () => {
|
||||
const mockInputs = { 'aws-region': FAKE_REGION };
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||
(fromEnv as jest.Mock).mockReset();
|
||||
(fromEnv as jest.Mock).mockImplementation(() => async () => {
|
||||
throw new CredentialsProviderError('test');
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
'Credentials could not be loaded, please check your action inputs: Could not load credentials from any providers'
|
||||
);
|
||||
});
|
||||
|
||||
test('action with empty credentials fails', async () => {
|
||||
const mockInputs = { 'aws-region': FAKE_REGION };
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||
(fromEnv as jest.Mock).mockReset();
|
||||
(fromEnv as jest.Mock).mockImplementation(
|
||||
() => async () => Promise.resolve({ accessKeyId: '', secretAccessKey: '' })
|
||||
);
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
'Credentials could not be loaded, please check your action inputs: Access key ID empty after loading credentials'
|
||||
);
|
||||
});
|
||||
|
||||
test('action fails when credentials are not set in the SDK correctly', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||
(fromEnv as jest.Mock).mockReset();
|
||||
(fromEnv as jest.Mock).mockImplementationOnce(() => async () => Promise.resolve({ accessKeyId: '123' }));
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
'Unexpected failure: Credentials loaded by the SDK do not match the access key ID configured by the action'
|
||||
);
|
||||
});
|
||||
|
||||
test('session token is optional', async () => {
|
||||
const mockInputs = { ...CREDS_INPUTS, 'aws-region': 'eu-west-1' };
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(3);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('existing env var creds are cleared', async () => {
|
||||
const mockInputs = { ...CREDS_INPUTS, 'aws-region': 'eu-west-1' };
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||
process.env.AWS_ACCESS_KEY_ID = 'foo';
|
||||
process.env.AWS_SECRET_ACCESS_KEY = 'bar';
|
||||
process.env.AWS_SESSION_TOKEN = 'helloworld';
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(3);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('validates region name', async () => {
|
||||
const mockInputs = { ...CREDS_INPUTS, 'aws-region': '$AWS_REGION' };
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith('Region is not valid: $AWS_REGION');
|
||||
});
|
||||
|
||||
test('throws error if access key id exists but missing secret access key', async () => {
|
||||
const inputsWIthoutSecretKey = { ...DEFAULT_INPUTS };
|
||||
//@ts-expect-error deleting a required property to test failure condition
|
||||
delete inputsWIthoutSecretKey['aws-secret-access-key'];
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(inputsWIthoutSecretKey));
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
"'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided"
|
||||
);
|
||||
});
|
||||
|
||||
test('can opt out of masking account ID', async () => {
|
||||
const mockInputs = { ...CREDS_INPUTS, 'aws-region': 'us-east-1', 'mask-aws-account-id': 'false' };
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'us-east-1');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'us-east-1');
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
test('error is caught by core.setFailed and caught', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||
mockedSTS.reset();
|
||||
mockedSTS.on(GetCallerIdentityCommand).rejects();
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('basic role assumption exports', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(1);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(7);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(7);
|
||||
expect(core.setOutput).toHaveBeenCalledTimes(2);
|
||||
|
||||
// first the source credentials are exported and masked
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_ACCOUNT_ID);
|
||||
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(1, 'AWS_DEFAULT_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(2, 'AWS_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(3, 'AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(4, 'AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
|
||||
expect(core.setOutput).toHaveBeenNthCalledWith(1, 'aws-account-id', FAKE_ACCOUNT_ID);
|
||||
|
||||
// then the role credentials are exported and masked
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(4, FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(5, FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(6, FAKE_STS_SESSION_TOKEN);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(7, FAKE_ROLE_ACCOUNT_ID);
|
||||
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(5, 'AWS_ACCESS_KEY_ID', FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(6, 'AWS_SECRET_ACCESS_KEY', FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(7, 'AWS_SESSION_TOKEN', FAKE_STS_SESSION_TOKEN);
|
||||
|
||||
expect(core.setOutput).toHaveBeenNthCalledWith(2, 'aws-account-id', FAKE_ROLE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('assume role can pull source credentials from self-hosted environment', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION }));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(1);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(5);
|
||||
expect(core.setOutput).toHaveBeenCalledTimes(2);
|
||||
|
||||
// first the source account is exported and masked
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_ACCOUNT_ID);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(1, 'AWS_DEFAULT_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(2, 'AWS_REGION', FAKE_REGION);
|
||||
expect(core.setOutput).toHaveBeenNthCalledWith(1, 'aws-account-id', FAKE_ACCOUNT_ID);
|
||||
|
||||
// then the role credentials are exported and masked
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(4, FAKE_STS_SESSION_TOKEN);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(5, FAKE_ROLE_ACCOUNT_ID);
|
||||
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(3, 'AWS_ACCESS_KEY_ID', FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(4, 'AWS_SECRET_ACCESS_KEY', FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(5, 'AWS_SESSION_TOKEN', FAKE_STS_SESSION_TOKEN);
|
||||
|
||||
expect(core.setOutput).toHaveBeenNthCalledWith(2, 'aws-account-id', FAKE_ROLE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('role assumption tags', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('role assumption duration provided', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-duration-seconds': '5' }));
|
||||
|
||||
await run();
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 5,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('role assumption session name provided', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-session-name': 'MySessionName' }));
|
||||
|
||||
await run();
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'MySessionName',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('sets durationSeconds to one hour when session token provided and no duration is provided', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'aws-session-token': FAKE_SESSION_TOKEN }));
|
||||
|
||||
await run();
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 3600,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('sets durationSeconds to one 6 hours no session token or duration is provided', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS }));
|
||||
|
||||
await run();
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('role name provided instead of ARN', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ ...CREDS_INPUTS, 'role-to-assume': ROLE_NAME, 'aws-region': FAKE_REGION }));
|
||||
|
||||
await run();
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: 'arn:aws:iam::123456789012:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('web identity token file provided with absolute path', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(
|
||||
mockGetInput({
|
||||
'role-to-assume': ROLE_ARN,
|
||||
'aws-region': FAKE_REGION,
|
||||
'web-identity-token-file': '/fake/token/file',
|
||||
})
|
||||
);
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
WebIdentityToken: 'testpayload',
|
||||
});
|
||||
});
|
||||
|
||||
test('web identity token file provided with relative path', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(
|
||||
mockGetInput({
|
||||
'role-to-assume': ROLE_ARN,
|
||||
'aws-region': FAKE_REGION,
|
||||
'web-identity-token-file': 'fake/token/file',
|
||||
})
|
||||
);
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
WebIdentityToken: 'testpayload',
|
||||
});
|
||||
});
|
||||
|
||||
test('only role arn and region provided to use GH OIDC Token', async () => {
|
||||
process.env.GITHUB_ACTIONS = 'true';
|
||||
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'test-token';
|
||||
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION }));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 3600,
|
||||
WebIdentityToken: 'testtoken',
|
||||
});
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_STS_SESSION_TOKEN);
|
||||
});
|
||||
|
||||
test('GH OIDC With custom role duration', async () => {
|
||||
const CUSTOM_ROLE_DURATION = '1234';
|
||||
process.env.GITHUB_ACTIONS = 'true';
|
||||
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'test-token';
|
||||
jest.spyOn(core, 'getInput').mockImplementation(
|
||||
mockGetInput({
|
||||
'role-to-assume': ROLE_ARN,
|
||||
'aws-region': FAKE_REGION,
|
||||
'role-duration-seconds': CUSTOM_ROLE_DURATION,
|
||||
})
|
||||
);
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: parseInt(CUSTOM_ROLE_DURATION),
|
||||
WebIdentityToken: 'testtoken',
|
||||
});
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_STS_SESSION_TOKEN);
|
||||
});
|
||||
|
||||
test('role assumption fails after maximum trials using OIDC provider', async () => {
|
||||
process.env.GITHUB_ACTIONS = 'true';
|
||||
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'test-token';
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION }));
|
||||
|
||||
mockedSTS.reset();
|
||||
mockedSTS.on(AssumeRoleWithWebIdentityCommand).rejects();
|
||||
|
||||
await run();
|
||||
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand).length).toEqual(12);
|
||||
});
|
||||
|
||||
test('role external ID provided', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-external-id': 'abcdef' }));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
ExternalId: 'abcdef',
|
||||
});
|
||||
});
|
||||
|
||||
test('workflow name sanitized in role assumption tags', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
|
||||
process.env = {
|
||||
...process.env,
|
||||
GITHUB_WORKFLOW:
|
||||
'Workflow!"#$%&\'()*+, -./:;<=>?@[]^_`{|}~🙂💥🍌1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZai9D2AN2RlWCxtMqChNtxuxjqeqhoQZo0oaq39sjcRZgAAAAAAA',
|
||||
};
|
||||
|
||||
const sanitizedWorkflowName =
|
||||
'Workflow__________+_ -./:;<=>?@____________1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZa';
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: sanitizedWorkflowName },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('skip tagging provided as true', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': 'true' }));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 21600,
|
||||
Tags: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
test('skip tagging provided as false', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': 'false' }));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 21600,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('skip tagging not provided', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS }));
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0].args[0].input).toEqual({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 21600,
|
||||
Tags: [
|
||||
{ Key: 'GitHub', Value: 'Actions' },
|
||||
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('masks variables before exporting', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
|
||||
const maskedValues: string[] = [];
|
||||
const publicFields = ['AWS_REGION', 'AWS_DEFAULT_REGION'];
|
||||
jest.spyOn(core, 'setSecret').mockImplementation((secret) => {
|
||||
maskedValues.push(secret);
|
||||
});
|
||||
jest.spyOn(core, 'exportVariable').mockImplementation((name, value) => {
|
||||
if (!maskedValues.includes(value) && !publicFields.includes(name)) {
|
||||
throw new Error(value + ' for variable ' + name + ' is not masked yet!');
|
||||
}
|
||||
process.env[name] = value;
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.exportVariable).toReturn();
|
||||
});
|
||||
});
|
||||
2
tsconfig.dev.json
generated
2
tsconfig.dev.json
generated
|
|
@ -15,7 +15,7 @@
|
|||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": true,
|
||||
"resolveJsonModule": true,
|
||||
"strict": true,
|
||||
|
|
|
|||
2
tsconfig.json
generated
2
tsconfig.json
generated
|
|
@ -17,7 +17,7 @@
|
|||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": true,
|
||||
"resolveJsonModule": true,
|
||||
"strict": true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue