chore: unstage devel changes (#1786)

* Revert "chore: Update dist"

This reverts commit e8614cfbf0.

* Revert "chore(deps): bump @aws-sdk/client-sts from 3.1045.0 to 3.1049.0 (#1782)"

This reverts commit 4684f47f89.

* Revert "chore: Update dist"

This reverts commit 48b8685c96.

* Revert "chore(deps-dev): bump @smithy/property-provider from 4.3.1 to 4.3.3 (#1783)"

This reverts commit fe6ad3af19.

* Revert "chore: Update dist"

This reverts commit 2520c5e921.

* Revert "chore(deps-dev): bump @aws-sdk/credential-provider-env (#1784)"

This reverts commit bc1093db1d.

* Revert "chore(deps-dev): bump @types/node from 25.7.0 to 25.9.0 (#1785)"

This reverts commit ffde832a1d.

* Revert "chore: Update dist"

This reverts commit 707acd96f6.

* Revert "chore(deps): bump @smithy/node-http-handler from 4.7.1 to 4.7.3 (#1781)"

This reverts commit a7c33ae483.

* Revert "chore: update README for additional claim support (#1779)"

This reverts commit 713aaabfec.

* Revert "chore: Update dist"

This reverts commit e6e8eba750.

* Revert "fix: skip credential check on output-env-credentials: false (#1778)"

This reverts commit 58e7c47adf.

* Revert "chore: document forgejo compatibility (#1776)"

This reverts commit f35a7d7d7e.

* Revert "chore: Update dist"

This reverts commit 3884f59ecd.

* Revert "feat: add additional session tags by default (#1775)"

This reverts commit e0ba768507.

* Revert "chore: Update dist"

This reverts commit 6795889618.

* Revert "feat: expose run id in STS client user-agent (#1774)"

This reverts commit 29d1be3027.

* Revert "chore(deps-dev): bump @types/node from 25.6.0 to 25.7.0 (#1773)"

This reverts commit ef734cca81.

* Revert "chore(deps-dev): bump @biomejs/biome from 2.4.14 to 2.4.15 (#1772)"

This reverts commit 7521c55910.

* Revert "chore: Update dist"

This reverts commit c0e2737f14.

* Revert "chore(deps): bump @smithy/node-http-handler from 4.6.1 to 4.7.1 (#1770)"

This reverts commit dbd503f368.

* Revert "chore: Update dist"

This reverts commit 18a236fbd1.

* Revert "chore(deps-dev): bump @smithy/property-provider from 4.2.14 to 4.3.1 (#1771)"

This reverts commit 1ab31502aa.

* Revert "chore(deps-dev): bump @vitest/coverage-v8 from 4.1.5 to 4.1.6 (#1768)"

This reverts commit 1fb495c4b2.

* Revert "chore: Update dist"

This reverts commit 1e8fec8ea1.

* Revert "chore(deps): bump @aws-sdk/client-sts from 3.1044.0 to 3.1045.0 (#1767)"

This reverts commit a388f23f7d.

* Revert "chore: update documentation for environment workflows (#1766)"

This reverts commit 3f7e1b63d7.

* Revert "feat: add regex validation to role-session-name (#1765)"

This reverts commit e35449909c.

* Revert "chore: Update dist"

This reverts commit 958a80fc34.

* Revert "feat: add more retry logic and better logging (#1764)"

This reverts commit 540d0c13ae.

* Revert "chore: automate README version bumping (#1763)"

This reverts commit 07ada0fe07.

* Revert "chore: Update dist"

This reverts commit f8d4eb68a9.

* Revert "feat: support custom STS endpoints (#1762)"

This reverts commit 8d52d05d7a.

* Revert "chore: Update dist"

This reverts commit 681892c11b.

* Revert "chore: configure codeql to ignore generated code (#1760)"

This reverts commit dc2353e57a.

* Revert "feat: Allow custom session tags to be passed when assuming a role (#1759)"

This reverts commit 61f50f630f.

* Revert "chore: automatic major version tagging (#1565)"

This reverts commit c36525a567.

* Revert "chore: bump unit test node version (#1758)"

This reverts commit 39d1702721.

* Revert "chore(deps): bump @aws-sdk/client-sts from 3.1043.0 to 3.1044.0 (#1754)"

This reverts commit 4cfda40a13.

* Revert "chore(deps-dev): bump @biomejs/biome from 2.4.13 to 2.4.14 (#1756)"

This reverts commit 8856e12f3a.

* Revert "chore(deps): bump @actions/core from 2.0.3 to 3.0.1 (#1746)"

This reverts commit 64d8e82527.

* Revert "chore(deps-dev): bump vitest from 3.2.4 to 4.1.5 (#1748)"

This reverts commit 78f374f6d1.
This commit is contained in:
Tom Keller
2026-05-25 12:19:31 -07:00
committed by GitHub
parent e8614cfbf0
commit 3cc0e19239
20 changed files with 24501 additions and 21311 deletions
+13 -8
View File
@@ -5,15 +5,20 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
import { cleanup } from '../src/cleanup';
import mocks from './mockinputs.test';
vi.mock('@actions/core');
const mockedSTSClient = mockClient(STSClient);
describe('Configure AWS Credentials cleanup', {}, () => {
beforeEach(() => {
vi.resetAllMocks();
// Reset mock state
vi.restoreAllMocks();
mockedSTSClient.reset();
vi.mocked(core.getInput).mockReturnValue('');
// Mock GitHub Actions core functions
vi.spyOn(core, 'exportVariable').mockImplementation((_n, _v) => {});
vi.spyOn(core, 'setSecret').mockImplementation((_s) => {});
vi.spyOn(core, 'setFailed').mockImplementation((_m) => {});
vi.spyOn(core, 'setOutput').mockImplementation((_n, _v) => {});
vi.spyOn(core, 'debug').mockImplementation((_m) => {});
vi.spyOn(core, 'info').mockImplementation((_m) => {});
process.env = {
...mocks.envs,
AWS_ACCESS_KEY_ID: 'CLEANUPTEST',
@@ -34,7 +39,7 @@ describe('Configure AWS Credentials cleanup', {}, () => {
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', '');
});
it('also clears AWS_PROFILE when aws-profile was set', {}, () => {
vi.mocked(core.getInput).mockImplementation((name: string) => {
vi.spyOn(core, 'getInput').mockImplementation((name: string) => {
if (name === 'aws-profile') return 'my-profile';
if (name === 'output-env-credentials') return 'true';
return '';
@@ -45,7 +50,7 @@ describe('Configure AWS Credentials cleanup', {}, () => {
expect(core.exportVariable).toHaveBeenCalledWith('AWS_PROFILE', '');
});
it('skips env cleanup when aws-profile is set without output-env-credentials', {}, () => {
vi.mocked(core.getInput).mockImplementation((name: string) => {
vi.spyOn(core, 'getInput').mockImplementation((name: string) => {
if (name === 'aws-profile') return 'my-profile';
return '';
});
@@ -54,14 +59,14 @@ describe('Configure AWS Credentials cleanup', {}, () => {
expect(core.exportVariable).toHaveBeenCalledTimes(0);
});
it('handles errors', {}, () => {
vi.mocked(core.exportVariable).mockImplementationOnce(() => {
vi.spyOn(core, 'exportVariable').mockImplementationOnce(() => {
throw new Error('Test error');
});
cleanup();
expect(core.setFailed).toHaveBeenCalled();
});
it(`doesn't export credentials as empty env variables if asked not to`, {}, () => {
vi.mocked(core.getInput).mockImplementation(mocks.getInput(mocks.NO_ENV_CREDS_INPUTS));
vi.spyOn(core, 'getInput').mockImplementation(mocks.getInput(mocks.NO_ENV_CREDS_INPUTS));
cleanup();
expect(core.exportVariable).toHaveBeenCalledTimes(0);
});
+17 -33
View File
@@ -2,11 +2,10 @@ import * as core from '@actions/core';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import * as helpers from '../src/helpers';
vi.mock('@actions/core');
describe('Configure AWS Credentials helpers', {}, () => {
beforeEach(() => {
vi.resetAllMocks();
vi.restoreAllMocks();
vi.spyOn(core, 'debug').mockImplementation(() => {});
});
it('removes brackets from GitHub Actor', {}, () => {
const actor = 'actor[bot]';
@@ -24,30 +23,10 @@ describe('Configure AWS Credentials helpers', {}, () => {
await expect(helpers.retryAndBackoff(fn, false)).rejects.toMatch('i am not retryable');
expect(fn).toHaveBeenCalledTimes(1);
});
it('retries and logs with label at info level', {}, async () => {
helpers.withsleep(() => Promise.resolve());
const fn = vi.fn().mockRejectedValueOnce(new Error('transient')).mockResolvedValueOnce('success');
const result = await helpers.retryAndBackoff(fn, true, 3, 0, 50, 'TestOp');
expect(result).toBe('success');
expect(fn).toHaveBeenCalledTimes(2);
expect(core.info).toHaveBeenCalledWith(expect.stringContaining('Retry TestOp: attempt 1 of 3 failed'));
helpers.reset();
});
it('logs max retries reached with label', {}, async () => {
helpers.withsleep(() => Promise.resolve());
const fn = vi.fn().mockRejectedValue(new Error('persistent'));
await expect(helpers.retryAndBackoff(fn, true, 2, 0, 50, 'TestOp')).rejects.toThrow('persistent');
expect(core.info).toHaveBeenCalledWith(expect.stringContaining('Retry TestOp: reached max retries (2)'));
helpers.reset();
});
it('retries without a label (backward compat)', {}, async () => {
helpers.withsleep(() => Promise.resolve());
const fn = vi.fn().mockRejectedValueOnce(new Error('transient')).mockResolvedValueOnce('ok');
await helpers.retryAndBackoff(fn, true, 3);
expect(core.info).toHaveBeenCalledWith(expect.stringContaining('Retry: attempt 1 of 3 failed'));
helpers.reset();
});
it('can output creds when told to', {}, () => {
vi.spyOn(core, 'setOutput').mockImplementation(() => {});
vi.spyOn(core, 'setSecret').mockImplementation(() => {});
vi.spyOn(core, 'exportVariable').mockImplementation(() => {});
helpers.exportCredentials(
{ AccessKeyId: 'test', SecretAccessKey: 'test', SessionToken: 'test', Expiration: new Date(8640000000000000) },
true,
@@ -68,6 +47,9 @@ describe('Configure AWS Credentials helpers', {}, () => {
process.env = env;
});
it(`won't output credentials to env if told not to`, {}, () => {
vi.spyOn(core, 'setOutput').mockImplementation(() => {});
vi.spyOn(core, 'setSecret').mockImplementation(() => {});
vi.spyOn(core, 'exportVariable').mockImplementation(() => {});
helpers.exportCredentials(
{ AccessKeyId: 'test', SecretAccessKey: 'test', SessionToken: 'test', Expiration: new Date(8640000000000000) },
true,
@@ -95,20 +77,22 @@ describe('Configure AWS Credentials helpers', {}, () => {
});
it('handles getBooleanInput correctly', {}, () => {
vi.mocked(core.getInput).mockReturnValue('true');
vi.spyOn(core, 'getInput').mockReturnValue('true');
expect(helpers.getBooleanInput('test')).toBe(true);
vi.mocked(core.getInput).mockReturnValue('false');
vi.spyOn(core, 'getInput').mockReturnValue('false');
expect(helpers.getBooleanInput('test')).toBe(false);
vi.mocked(core.getInput).mockReturnValue('');
vi.spyOn(core, 'getInput').mockReturnValue('');
expect(helpers.getBooleanInput('test', { default: true })).toBe(true);
vi.mocked(core.getInput).mockReturnValue('invalid');
vi.spyOn(core, 'getInput').mockReturnValue('invalid');
expect(() => helpers.getBooleanInput('test')).toThrow();
});
it('clears session token when not provided', {}, () => {
vi.spyOn(core, 'setSecret').mockImplementation(() => {});
vi.spyOn(core, 'exportVariable').mockImplementation(() => {});
process.env.AWS_SESSION_TOKEN = 'old-token';
helpers.exportCredentials({ AccessKeyId: 'test', SecretAccessKey: 'test' }, false, true);
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
+88 -625
View File
File diff suppressed because it is too large Load Diff
-57
View File
@@ -6,46 +6,6 @@ const inputs = {
'aws-region': 'fake-region-1',
'special-characters-workaround': 'true',
},
CUSTOM_TAGS_INVALID_JSON_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'retry-max-attempts': '1',
'custom-tags': 'not a json',
},
CUSTOM_TAGS_ARRAY_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'retry-max-attempts': '1',
'custom-tags': '[1, 2, 3]',
},
CUSTOM_TAGS_RESERVED_KEY_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'retry-max-attempts': '1',
'custom-tags': JSON.stringify({ Repository: 'evil-repo' }),
},
CUSTOM_TAGS_INVALID_KEY_CHARS_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'retry-max-attempts': '1',
'custom-tags': JSON.stringify({ 'invalid{key}': 'value' }),
},
CUSTOM_TAGS_OBJECT_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'retry-max-attempts': '1',
'custom-tags': JSON.stringify({ Environment: 'Production', Team: 'DevOps' }),
},
IAM_USER_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
@@ -83,14 +43,6 @@ const inputs = {
'output-env-credentials': 'false',
'output-credentials': 'true',
},
IAM_ASSUMEROLE_NO_ENV_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'output-env-credentials': 'false',
'output-credentials': 'true',
},
};
const envs = {
@@ -101,15 +53,6 @@ const envs = {
GITHUB_SHA: 'MY-COMMIT-ID',
GITHUB_WORKSPACE: '/home/github',
GITHUB_ACTIONS: 'true',
GITHUB_REF: 'refs/pull/42/merge',
GITHUB_EVENT_NAME: 'pull_request',
GITHUB_RUN_ID: '16412345678',
GITHUB_JOB: 'build',
GITHUB_REF_NAME: 'feature-branch',
GITHUB_REF_TYPE: 'branch',
GITHUB_BASE_REF: 'main',
GITHUB_HEAD_REF: 'feature-branch',
GITHUB_TRIGGERING_ACTOR: 'MY-USERNAME[bot]',
};
const outputs = {
+117 -131
View File
@@ -11,13 +11,13 @@ import {
writeProfileFiles,
} from '../src/profileManager';
vi.mock('@actions/core');
vi.mock('node:fs');
describe('Profile Manager', {}, () => {
beforeEach(() => {
vi.resetAllMocks();
vi.restoreAllMocks();
vi.mock('node:fs');
vol.reset();
vi.spyOn(core, 'debug').mockImplementation(() => {});
vi.spyOn(core, 'info').mockImplementation(() => {});
});
describe('parseIni', {}, () => {
@@ -95,10 +95,7 @@ describe('Profile Manager', {}, () => {
});
it('round-trips through parseIni', {}, () => {
const data = {
dev: { aws_access_key_id: 'AKIA', aws_secret_access_key: 'secret' },
'profile prod': { region: 'us-west-2' },
};
const data = { dev: { aws_access_key_id: 'AKIA', aws_secret_access_key: 'secret' }, 'profile prod': { region: 'us-west-2' } };
const roundTripped = parseIni(stringifyIni(data));
expect(roundTripped).toEqual(data);
});
@@ -199,15 +196,10 @@ describe('Profile Manager', {}, () => {
const filePath = '/home/runner/.aws/credentials';
fs.mkdirSync('/home/runner/.aws', { recursive: true });
mergeProfileSection(
filePath,
'dev',
{
aws_access_key_id: 'AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
},
false,
);
mergeProfileSection(filePath, 'dev', {
aws_access_key_id: 'AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
}, false);
const content = fs.readFileSync(filePath, 'utf-8');
const parsed = parseIni(content);
@@ -222,26 +214,16 @@ describe('Profile Manager', {}, () => {
fs.mkdirSync('/home/runner/.aws', { recursive: true });
// Create initial profile
mergeProfileSection(
filePath,
'dev',
{
aws_access_key_id: 'AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key: 'devSecretKey',
},
false,
);
mergeProfileSection(filePath, 'dev', {
aws_access_key_id: 'AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key: 'devSecretKey',
}, false);
// Add second profile
mergeProfileSection(
filePath,
'prod',
{
aws_access_key_id: 'AKIAPRODEXAMPLE',
aws_secret_access_key: 'prodSecretKey',
},
false,
);
mergeProfileSection(filePath, 'prod', {
aws_access_key_id: 'AKIAPRODEXAMPLE',
aws_secret_access_key: 'prodSecretKey',
}, false);
const content = fs.readFileSync(filePath, 'utf-8');
const parsed = parseIni(content);
@@ -257,28 +239,18 @@ describe('Profile Manager', {}, () => {
fs.mkdirSync('/home/runner/.aws', { recursive: true });
// Create initial profile
mergeProfileSection(
filePath,
'dev',
{
aws_access_key_id: 'OLD_KEY',
aws_secret_access_key: 'oldSecretKey',
aws_session_token: 'oldSessionToken',
},
false,
);
mergeProfileSection(filePath, 'dev', {
aws_access_key_id: 'OLD_KEY',
aws_secret_access_key: 'oldSecretKey',
aws_session_token: 'oldSessionToken'
}, false);
// Overwrite with new credentials
mergeProfileSection(
filePath,
'dev',
{
aws_access_key_id: 'NEW_KEY',
aws_secret_access_key: 'newSecretKey',
aws_session_token: 'newSessionToken',
},
true,
);
mergeProfileSection(filePath, 'dev', {
aws_access_key_id: 'NEW_KEY',
aws_secret_access_key: 'newSecretKey',
aws_session_token: 'newSessionToken',
}, true);
const content = fs.readFileSync(filePath, 'utf-8');
const parsed = parseIni(content);
@@ -293,27 +265,17 @@ describe('Profile Manager', {}, () => {
fs.mkdirSync('/home/runner/.aws', { recursive: true });
// Create profile with session token
mergeProfileSection(
filePath,
'dev',
{
aws_access_key_id: 'AKIA',
aws_secret_access_key: 'secret',
aws_session_token: 'old-token',
},
false,
);
mergeProfileSection(filePath, 'dev', {
aws_access_key_id: 'AKIA',
aws_secret_access_key: 'secret',
aws_session_token: 'old-token',
}, false);
// Overwrite without session token
mergeProfileSection(
filePath,
'dev',
{
aws_access_key_id: 'AKIA2',
aws_secret_access_key: 'secret2',
},
true,
);
mergeProfileSection(filePath, 'dev', {
aws_access_key_id: 'AKIA2',
aws_secret_access_key: 'secret2',
}, true);
const content = fs.readFileSync(filePath, 'utf-8');
const parsed = parseIni(content);
@@ -328,15 +290,10 @@ describe('Profile Manager', {}, () => {
fs.mkdirSync('/home/runner/.aws', { recursive: true });
fs.writeFileSync(filePath, '', { mode: 0o600 });
mergeProfileSection(
filePath,
'dev',
{
aws_access_key_id: 'AKIA',
aws_secret_access_key: 'secret',
},
false,
);
mergeProfileSection(filePath, 'dev', {
aws_access_key_id: 'AKIA',
aws_secret_access_key: 'secret',
}, false);
const content = fs.readFileSync(filePath, 'utf-8');
const parsed = parseIni(content);
@@ -350,31 +307,17 @@ describe('Profile Manager', {}, () => {
fs.mkdirSync('/home/runner/.aws', { recursive: true });
// Create initial profile
mergeProfileSection(
filePath,
'dev',
{
aws_access_key_id: 'OLD_KEY',
aws_secret_access_key: 'oldSecretKey',
},
false,
);
mergeProfileSection(filePath, 'dev', {
aws_access_key_id: 'OLD_KEY',
aws_secret_access_key: 'oldSecretKey',
}, false);
// Overwrite with new credentials
expect(() =>
mergeProfileSection(
filePath,
'dev',
{
aws_access_key_id: 'NEW_KEY',
aws_secret_access_key: 'newSecretKey',
aws_session_token: 'sessionToken',
},
false,
),
).toThrow(
`Profile with name "dev" already exists. Please use the overwrite-aws-profile input if you want to overwrite existing profiles.`,
);
expect(() => mergeProfileSection(filePath, 'dev', {
aws_access_key_id: 'NEW_KEY',
aws_secret_access_key: 'newSecretKey',
aws_session_token: 'sessionToken',
}, false)).toThrow(`Profile with name "dev" already exists. Please use the overwrite-aws-profile input if you want to overwrite existing profiles.`);
const content = fs.readFileSync(filePath, 'utf-8');
const parsed = parseIni(content);
@@ -525,7 +468,7 @@ describe('Profile Manager', {}, () => {
SecretAccessKey: 'secret',
},
'us-east-1',
false,
false
),
).toThrow('whitespace');
});
@@ -543,7 +486,7 @@ describe('Profile Manager', {}, () => {
SecretAccessKey: 'secret',
},
'us-east-1',
false,
false
);
expect(fs.existsSync('/custom/credentials')).toBe(true);
@@ -558,7 +501,7 @@ describe('Profile Manager', {}, () => {
SecretAccessKey: 'secret',
},
'us-east-1',
false,
false
);
expect(core.info).toHaveBeenCalledWith('Writing credentials to profile: dev');
@@ -574,7 +517,12 @@ describe('Profile Manager', {}, () => {
'[personal]\naws_access_key_id=AKIAPERSONAL\naws_secret_access_key=personalSecret\naws_session_token=personalToken\n',
);
writeProfileFiles('dev', { AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' }, 'us-east-1', false);
writeProfileFiles(
'dev',
{ AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' },
'us-east-1',
false,
);
const content = fs.readFileSync(credsPath, 'utf-8');
const parsed = parseIni(content);
@@ -592,9 +540,17 @@ describe('Profile Manager', {}, () => {
it('preserves pre-existing config with extra keys', {}, () => {
const configPath = getProfileFilePaths().config;
fs.mkdirSync(require('node:path').dirname(configPath), { recursive: true });
fs.writeFileSync(configPath, '[profile personal]\nregion=eu-west-1\noutput=json\ncli_pager=\n');
fs.writeFileSync(
configPath,
'[profile personal]\nregion=eu-west-1\noutput=json\ncli_pager=\n',
);
writeProfileFiles('dev', { AccessKeyId: 'AKIA', SecretAccessKey: 'secret' }, 'us-east-1', false);
writeProfileFiles(
'dev',
{ AccessKeyId: 'AKIA', SecretAccessKey: 'secret' },
'us-east-1',
false
);
const content = fs.readFileSync(configPath, 'utf-8');
const parsed = parseIni(content);
@@ -610,9 +566,17 @@ describe('Profile Manager', {}, () => {
it('preserves pre-existing default profile when writing a named profile', {}, () => {
const credsPath = getProfileFilePaths().credentials;
fs.mkdirSync(require('node:path').dirname(credsPath), { recursive: true });
fs.writeFileSync(credsPath, '[default]\naws_access_key_id=AKIADEFAULT\naws_secret_access_key=defaultSecret\n');
fs.writeFileSync(
credsPath,
'[default]\naws_access_key_id=AKIADEFAULT\naws_secret_access_key=defaultSecret\n',
);
writeProfileFiles('dev', { AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' }, 'us-west-2', false);
writeProfileFiles(
'dev',
{ AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' },
'us-west-2',
false
);
const content = fs.readFileSync(credsPath, 'utf-8');
const parsed = parseIni(content);
@@ -632,7 +596,12 @@ describe('Profile Manager', {}, () => {
'# My important comment\n[personal]\naws_access_key_id=AKIA\naws_secret_access_key=secret\n',
);
writeProfileFiles('dev', { AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' }, 'us-east-1', false);
writeProfileFiles(
'dev',
{ AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' },
'us-east-1',
false
);
const content = fs.readFileSync(credsPath, 'utf-8') as string;
@@ -666,7 +635,12 @@ describe('Profile Manager', {}, () => {
fs.mkdirSync('/custom-creds', { recursive: true });
writeProfileFiles('dev', { AccessKeyId: 'AKIA', SecretAccessKey: 'secret' }, 'us-east-1', false);
writeProfileFiles(
'dev',
{ AccessKeyId: 'AKIA', SecretAccessKey: 'secret' },
'us-east-1',
false
);
expect(fs.existsSync('/custom-creds/credentials')).toBe(true);
// Config file should be at the default path (under homedir)
@@ -683,7 +657,7 @@ describe('Profile Manager', {}, () => {
SessionToken: 'FwoGZXIvYXdzEBYaDEXAMPLE',
},
'us-east-1',
false,
false
);
const credsPath = getProfileFilePaths().credentials;
@@ -698,20 +672,28 @@ describe('Profile Manager', {}, () => {
// - LF line endings, trailing newline
expect(credContent).toBe(
'[dev]\n' +
'aws_access_key_id = AKIAIOSFODNN7EXAMPLE\n' +
'aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\n' +
'aws_session_token = FwoGZXIvYXdzEBYaDEXAMPLE\n',
'aws_access_key_id = AKIAIOSFODNN7EXAMPLE\n' +
'aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\n' +
'aws_session_token = FwoGZXIvYXdzEBYaDEXAMPLE\n',
);
expect(configContent).toBe(
'[profile dev]\n' +
'region = us-east-1\n',
);
expect(configContent).toBe('[profile dev]\n' + 'region = us-east-1\n');
});
it('golden file for multi-profile output', {}, () => {
writeProfileFiles('dev', { AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' }, 'us-east-1', false);
writeProfileFiles(
'dev',
{ AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' },
'us-east-1',
false
);
writeProfileFiles(
'prod',
{ AccessKeyId: 'AKIAPROD', SecretAccessKey: 'prodSecret', SessionToken: 'prodToken' },
'us-west-2',
false,
false
);
const credsPath = getProfileFilePaths().credentials;
@@ -722,16 +704,20 @@ describe('Profile Manager', {}, () => {
expect(credContent).toBe(
'[dev]\n' +
'aws_access_key_id = AKIADEV\n' +
'aws_secret_access_key = devSecret\n' +
'\n' +
'[prod]\n' +
'aws_access_key_id = AKIAPROD\n' +
'aws_secret_access_key = prodSecret\n' +
'aws_session_token = prodToken\n',
'aws_access_key_id = AKIADEV\n' +
'aws_secret_access_key = devSecret\n' +
'\n' +
'[prod]\n' +
'aws_access_key_id = AKIAPROD\n' +
'aws_secret_access_key = prodSecret\n' +
'aws_session_token = prodToken\n',
);
expect(configContent).toBe(
'[profile dev]\n' + 'region = us-east-1\n' + '\n' + '[profile prod]\n' + 'region = us-west-2\n',
'[profile dev]\n' +
'region = us-east-1\n' +
'\n' +
'[profile prod]\n' +
'region = us-west-2\n',
);
});
});