chore: migrate to biomejs (#1167)

* chore: migrate to biomejs

* chore: migrate to biomejs

* chore: migrate from jest to vitest

* chore: error on lint warnings

* chore: remove obsolete depedencies
This commit is contained in:
Tom Keller
2024-11-04 10:19:12 -08:00
committed by GitHub
parent d90c1f89e1
commit ccbdafa425
17 changed files with 4393 additions and 8410 deletions
+29 -33
View File
@@ -1,35 +1,34 @@
import * as core from '@actions/core';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { cleanup } from '../src/cleanup';
import * as core from '@actions/core';
import { mockClient } from 'aws-sdk-client-mock';
import { STSClient } from '@aws-sdk/client-sts';
import mocks from './mockinputs.test';
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_REGION = 'fake-region-1';
const ACTION_ENVIRONMENT_VARIABLES = {
AWS_ACCESS_KEY_ID: FAKE_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY: FAKE_SECRET_ACCESS_KEY,
AWS_SESSION_TOKEN: FAKE_SESSION_TOKEN,
AWS_DEFAULT_REGION: FAKE_REGION,
AWS_REGION: FAKE_REGION,
};
describe('Configure AWS Credentials', () => {
const OLD_ENV = process.env;
const mockedSTSClient = mockClient(STSClient);
describe('Configure AWS Credentials cleanup', {}, () => {
beforeEach(() => {
jest.resetModules();
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 };
// Reset mock state
vi.restoreAllMocks();
mockedSTSClient.reset();
// 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',
AWS_SECRET_ACCESS_KEY: 'CLEANUPTEST',
AWS_SESSION_TOKEN: 'CLEANUPTEST',
AWS_REGION: 'CLEANUPTEST',
AWS_DEFAULT_REGION: 'CLEANUPTEST',
};
});
afterEach(() => {
process.env = OLD_ENV;
});
test('replaces AWS credential and region env vars with empty strings', () => {
it('replaces AWS credential and region environment variables with empty strings', {}, () => {
cleanup();
expect(core.setFailed).toHaveBeenCalledTimes(0);
expect(core.exportVariable).toHaveBeenCalledTimes(5);
@@ -39,14 +38,11 @@ describe('Configure AWS Credentials', () => {
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', '');
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', '');
});
test('error is caught and fails the action', () => {
jest.spyOn(core, 'exportVariable').mockImplementation(() => {
throw new Error();
it('handles errors', {}, () => {
vi.spyOn(core, 'exportVariable').mockImplementationOnce(() => {
throw new Error('Test error');
});
cleanup();
expect(core.setFailed).toHaveBeenCalled();
});
});
+35 -16
View File
@@ -1,26 +1,45 @@
import { describe, it, expect, vi } from 'vitest';
import * as helpers from '../src/helpers';
describe('helpers', () => {
import * as core from '@actions/core';
import { before, beforeEach } from 'node:test';
describe('Configure AWS Credentials helpers', {}, () => {
beforeEach(() => {
jest.resetModules();
jest.clearAllMocks();
vi.restoreAllMocks();
});
test('removes brackets from GitHub Actor', () => {
expect(helpers.sanitizeGitHubVariables('foo[bot]')).toEqual('foo_bot_');
it('removes brackets from GitHub Actor', {}, () => {
const actor = 'actor[bot]';
expect(helpers.sanitizeGitHubVariables(actor)).toBe('actor_bot_');
});
test('removes special characters from worflow names', () => {
it('can sleep', {}, () => {
const sleep = helpers.defaultSleep(10);
expect(Promise.race([sleep, new Promise((_, reject) => setTimeout(reject, 20))])).resolves.toBe(undefined);
});
it('removes special characters from workflow names', {}, () => {
expect(helpers.sanitizeGitHubVariables('sdf234@#$%$^&*()_+{}|:"<>?')).toEqual('sdf234@__________+___:____');
});
test('can sleep', () => {
const sleep = helpers.defaultSleep(10);
expect(Promise.race([sleep, new Promise((_res, rej) => setTimeout(rej, 20))])).resolves;
});
test("backoff function doesn't retry non-retryable errors", async () => {
const fn = jest.fn().mockRejectedValue('i am not retryable');
it("doesn't retry non-retryable errors", {}, async () => {
const fn = vi.fn().mockRejectedValue('i am not retryable');
await expect(helpers.retryAndBackoff(fn, false)).rejects.toMatch('i am not retryable');
expect(fn).toHaveBeenCalledTimes(1);
});
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' }, true);
expect(core.setOutput).toHaveBeenCalledTimes(3);
expect(core.setSecret).toHaveBeenCalledTimes(3);
expect(core.exportVariable).toHaveBeenCalledTimes(3);
});
it('can unset credentials', {}, () => {
const env = process.env;
helpers.unsetCredentials();
expect(process.env.AWS_ACCESS_KEY_ID).toBeUndefined;
expect(process.env.AWS_SECRET_ACCESS_KEY).toBeUndefined;
expect(process.env.AWS_SESSION_TOKEN).toBeUndefined;
expect(process.env.AWS_REGION).toBeUndefined;
expect(process.env.AWS_DEFAULT_REGION).toBeUndefined;
process.env = env;
});
});
+264 -817
View File
File diff suppressed because it is too large Load Diff
+98
View File
@@ -0,0 +1,98 @@
import type * as core from '@actions/core';
const inputs = {
GH_OIDC_INPUTS: {
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'special-characters-workaround': 'true',
},
IAM_USER_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
'aws-region': 'fake-region-1',
},
IAM_ASSUMEROLE_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',
},
WEBIDENTITY_TOKEN_FILE_INPUTS: {
'web-identity-token-file': 'file.txt',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
},
EXISTING_ROLE_INPUTS: {
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'role-chaining': 'true',
'aws-region': 'fake-region-1',
},
};
const envs = {
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_WORKSPACE: '/home/github',
GITHUB_ACTIONS: 'true',
};
const outputs = {
STS_CREDENTIALS: {
Credentials: {
AccessKeyId: 'STSAWSACCESSKEYID',
SecretAccessKey: 'STSAWSSECRETACCESSKEY',
SessionToken: 'STSAWSSESSIONTOKEN',
Expiration: new Date(8640000000000000),
},
AssumedRoleUser: {
Arn: 'arn:aws:sts::111111111111:assumed-role/MY-ROLE/',
AssumedRoleId: 'AROAFAKEASSUMEDROLEID',
},
},
GET_CALLER_IDENTITY: {
Account: '111111111111',
Arn: 'arn:aws:iam::111111111111:role/MY-ROLE',
},
FAKE_STS_ACCESS_KEY_ID: 'STSAWSACCESSKEYID',
FAKE_STS_SECRET_ACCESS_KEY: 'STSAWSSECRETACCESSKEY',
FAKE_STS_SESSION_TOKEN: 'STSAWSSESSIONTOKEN',
ODD_CHARACTER_CREDENTIALS: {
Credentials: {
AccessKeyId: 'STSA#$%^&',
SecretAccessKey: 'STSA#$%^&Key',
SessionToken: 'STSA#$%^',
Expiration: new Date(8640000000000000),
},
AssumedRoleUser: {
Arn: 'arn:aws:sts::111111111111:assumed-role/MY-ROLE/',
AssumedRoleId: 'AROAFAKEASSUMEDROLEID',
},
},
};
export default {
getInput: (fakeEnv: Record<string, string>) => {
return (name: string, options?: core.InputOptions): string => {
if (!fakeEnv[name]) {
if (options?.required) throw new Error(`Input ${name} not found`);
return '';
}
return fakeEnv[name];
};
},
getMultilineInput: (fakeEnv: Record<string, string[]>) => {
return (name: string, options?: core.InputOptions): string[] => {
if (!fakeEnv[name]) {
if (options?.required) throw new Error(`Input ${name} not found`);
return [];
}
return fakeEnv[name];
};
},
...inputs,
outputs,
envs,
} as const;