Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion modules/runners/lambdas/runners/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"build": "ncc build src/lambda.ts -o dist",
"dist": "yarn build && cd dist && zip ../runners.zip index.js",
"format": "prettier --write \"**/*.ts\"",
"format-check": "prettier --check \"**/*.ts\""
"format-check": "prettier --check \"**/*.ts\"",
"all": "yarn build && yarn format && yarn lint && yarn test"
},
"devDependencies": {
"@types/aws-lambda": "^8.10.75",
Expand All @@ -22,10 +23,12 @@
"@typescript-eslint/parser": "^4.22.0",
"@vercel/ncc": "^0.27.0",
"eslint": "^7.22.0",
"eslint-plugin-prettier": "3.4.0",
"jest": "^26.6.3",
"jest-mock-extended": "^1.0.13",
"moment-timezone": "^0.5.33",
"nock": "^13.0.11",
"prettier": "2.3.1",
"ts-jest": "^26.5.5",
"ts-node-dev": "^1.1.6"
},
Expand All @@ -37,6 +40,7 @@
"@types/aws-lambda": "^8.10.75",
"@types/express": "^4.17.11",
"@types/node": "^14.14.34",
"aws-sdk": "^2.888.0",
"cron-parser": "^3.3.0",
"typescript": "^4.2.3",
"yn": "^4.0.0"
Expand Down
2 changes: 2 additions & 0 deletions modules/runners/lambdas/runners/src/lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { scaleUp } from './scale-runners/scale-up';
import { scaleDown } from './scale-runners/scale-down';
import { SQSEvent, ScheduledEvent, Context } from 'aws-lambda';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
module.exports.scaleUp = async (event: SQSEvent, context: Context, callback: any) => {
console.dir(event, { depth: 5 });
try {
Expand All @@ -15,6 +16,7 @@ module.exports.scaleUp = async (event: SQSEvent, context: Context, callback: any
}
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
module.exports.scaleDown = async (event: ScheduledEvent, context: Context, callback: any) => {
try {
scaleDown();
Expand Down
26 changes: 19 additions & 7 deletions modules/runners/lambdas/runners/src/scale-runners/gh-auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('Test createGithubAuth', () => {
});

describe('Test createGithubAuth', () => {
const mockedCreatAppAuth = (createAppAuth as unknown) as jest.Mock;
const mockedCreatAppAuth = createAppAuth as unknown as jest.Mock;
const mockedDefaults = jest.spyOn(request, 'defaults');
let mockedRequestInterface: MockProxy<RequestInterface>;

Expand All @@ -76,10 +76,14 @@ describe('Test createGithubAuth', () => {
};

const mockedGet = mocked(getParameterValue);
mockedGet.mockResolvedValueOnce(GITHUB_APP_ID).mockResolvedValueOnce(b64)
.mockResolvedValueOnce(GITHUB_APP_CLIENT_ID).mockResolvedValueOnce(GITHUB_APP_CLIENT_SECRET);
mockedGet
.mockResolvedValueOnce(GITHUB_APP_ID)
.mockResolvedValueOnce(b64)
.mockResolvedValueOnce(GITHUB_APP_CLIENT_ID)
.mockResolvedValueOnce(GITHUB_APP_CLIENT_SECRET);
const mockedAuth = jest.fn();
mockedAuth.mockResolvedValue({ token });
// eslint-disable-next-line @typescript-eslint/no-unused-vars
mockedCreatAppAuth.mockImplementation((authOptions: StrategyOptions) => {
return mockedAuth;
});
Expand Down Expand Up @@ -118,10 +122,14 @@ describe('Test createGithubAuth', () => {
};

const mockedGet = mocked(getParameterValue);
mockedGet.mockResolvedValueOnce(GITHUB_APP_ID).mockResolvedValueOnce(b64)
.mockResolvedValueOnce(GITHUB_APP_CLIENT_ID).mockResolvedValueOnce(GITHUB_APP_CLIENT_SECRET);
mockedGet
.mockResolvedValueOnce(GITHUB_APP_ID)
.mockResolvedValueOnce(b64)
.mockResolvedValueOnce(GITHUB_APP_CLIENT_ID)
.mockResolvedValueOnce(GITHUB_APP_CLIENT_SECRET);
const mockedAuth = jest.fn();
mockedAuth.mockResolvedValue({ token });
// eslint-disable-next-line @typescript-eslint/no-unused-vars
mockedCreatAppAuth.mockImplementation((authOptions: StrategyOptions) => {
return mockedAuth;
});
Expand Down Expand Up @@ -161,10 +169,14 @@ describe('Test createGithubAuth', () => {
};

const mockedGet = mocked(getParameterValue);
mockedGet.mockResolvedValueOnce(GITHUB_APP_ID).mockResolvedValueOnce(b64)
.mockResolvedValueOnce(GITHUB_APP_CLIENT_ID).mockResolvedValueOnce(GITHUB_APP_CLIENT_SECRET);
mockedGet
.mockResolvedValueOnce(GITHUB_APP_ID)
.mockResolvedValueOnce(b64)
.mockResolvedValueOnce(GITHUB_APP_CLIENT_ID)
.mockResolvedValueOnce(GITHUB_APP_CLIENT_SECRET);
const mockedAuth = jest.fn();
mockedAuth.mockResolvedValue({ token });
// eslint-disable-next-line @typescript-eslint/no-unused-vars
mockedCreatAppAuth.mockImplementation((authOptions: StrategyOptions) => {
return mockedAuth;
});
Expand Down
60 changes: 36 additions & 24 deletions modules/runners/lambdas/runners/src/scale-runners/runners.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,15 @@ describe('create runner', () => {
});

it('calls run instances with the correct config for repo', async () => {
await createRunner({
runnerServiceConfig: 'bla',
environment: ENVIRONMENT,
runnerType: 'Repo',
runnerOwner: REPO_NAME
}, LAUNCH_TEMPLATE);
await createRunner(
{
runnerServiceConfig: 'bla',
environment: ENVIRONMENT,
runnerType: 'Repo',
runnerOwner: REPO_NAME,
},
LAUNCH_TEMPLATE,
);
expect(mockEC2.runInstances).toBeCalledWith({
MaxCount: 1,
MinCount: 1,
Expand All @@ -144,12 +147,15 @@ describe('create runner', () => {
});

it('calls run instances with the correct config for org', async () => {
await createRunner({
runnerServiceConfig: 'bla',
environment: ENVIRONMENT,
runnerType: 'Org',
runnerOwner: ORG_NAME,
}, LAUNCH_TEMPLATE);
await createRunner(
{
runnerServiceConfig: 'bla',
environment: ENVIRONMENT,
runnerType: 'Org',
runnerOwner: ORG_NAME,
},
LAUNCH_TEMPLATE,
);
expect(mockEC2.runInstances).toBeCalledWith({
MaxCount: 1,
MinCount: 1,
Expand All @@ -168,12 +174,15 @@ describe('create runner', () => {
});

it('creates ssm parameters for each created instance', async () => {
await createRunner({
runnerServiceConfig: 'bla',
environment: ENVIRONMENT,
runnerType: 'Org',
runnerOwner: ORG_NAME,
}, LAUNCH_TEMPLATE);
await createRunner(
{
runnerServiceConfig: 'bla',
environment: ENVIRONMENT,
runnerType: 'Org',
runnerOwner: ORG_NAME,
},
LAUNCH_TEMPLATE,
);
expect(mockSSM.putParameter).toBeCalledWith({
Name: `${ENVIRONMENT}-i-1234`,
Value: 'bla',
Expand All @@ -185,12 +194,15 @@ describe('create runner', () => {
mockRunInstances.promise.mockReturnValue({
Instances: [],
});
await createRunner({
runnerServiceConfig: 'bla',
environment: ENVIRONMENT,
runnerType: 'Org',
runnerOwner: ORG_NAME,
}, LAUNCH_TEMPLATE);
await createRunner(
{
runnerServiceConfig: 'bla',
environment: ENVIRONMENT,
runnerType: 'Org',
runnerOwner: ORG_NAME,
},
LAUNCH_TEMPLATE,
);
expect(mockSSM.putParameter).not.toBeCalled();
});
});
4 changes: 2 additions & 2 deletions modules/runners/lambdas/runners/src/scale-runners/runners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export async function createRunner(runnerParameters: RunnerInputParameters, laun

function getInstanceParams(
launchTemplateName: string,
runnerParameters: RunnerInputParameters
runnerParameters: RunnerInputParameters,
): EC2.RunInstancesRequest {
return {
MaxCount: 1,
Expand All @@ -101,7 +101,7 @@ function getInstanceParams(
{ Key: 'Application', Value: 'github-action-runner' },
{
Key: runnerParameters.runnerType,
Value: runnerParameters.runnerOwner
Value: runnerParameters.runnerOwner,
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ function getConfig(cronTabs: string[]): ScalingDownConfigList {
}

describe('scaleDownConfig', () => {

describe('Check runners that should be kept idle based on config.', () => {
it('One active cron configuration', async () => {
const scaleDownConfig = getConfig(['* * * * * *']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ function inPeriod(period: ScalingDownConfig): boolean {

export function getIdleRunnerCount(scalingDownConfigs: ScalingDownConfigList): number {
for (const scalingDownConfig of scalingDownConfigs) {
if (inPeriod(scalingDownConfig)) { return scalingDownConfig.idleCount; }
if (inPeriod(scalingDownConfig)) {
return scalingDownConfig.idleCount;
}
}
return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ describe('scaleDown', () => {
type: 'app',
token: 'token',
appId: 1,
expiresAt: 'some-date'
expiresAt: 'some-date',
});
mockCreateClient.mockResolvedValue(new mocktokit);
mockCreateClient.mockResolvedValue(new mocktokit());
const mockListRunners = mocked(listRunners);
mockListRunners.mockImplementation(async () => []);
});
Expand Down
44 changes: 22 additions & 22 deletions modules/runners/lambdas/runners/src/scale-runners/scale-down.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ function createGitHubClientForRunnerFactory(): (runner: RunnerInfo, orgLevel: bo
console.debug(`[createGitHubClientForRunner] Cache miss for ${key}`);
const installationId = orgLevel
? (
await githubClient.apps.getOrgInstallation({
org: repo.repoOwner,
})
).data.id
await githubClient.apps.getOrgInstallation({
org: repo.repoOwner,
})
).data.id
: (
await githubClient.apps.getRepoInstallation({
owner: repo.repoOwner,
repo: repo.repoName,
})
).data.id;
await githubClient.apps.getRepoInstallation({
owner: repo.repoOwner,
repo: repo.repoName,
})
).data.id;
const ghAuth2 = await createGithubAuth(installationId, 'installation', ghesApiUrl);
const octokit = await createOctoClient(ghAuth2.token, ghesApiUrl);
cache.set(key, octokit);
Expand Down Expand Up @@ -82,12 +82,12 @@ function listGithubRunnersFactory(): (
console.debug(`[listGithubRunners] Cache miss for ${key}`);
const runners = enableOrgLevel
? await client.paginate(client.actions.listSelfHostedRunnersForOrg, {
org: repo.repoOwner,
})
org: repo.repoOwner,
})
: await client.paginate(client.actions.listSelfHostedRunnersForRepo, {
owner: repo.repoOwner,
repo: repo.repoName,
});
owner: repo.repoOwner,
repo: repo.repoName,
});
cache.set(key, runners);

return runners;
Expand All @@ -110,14 +110,14 @@ async function removeRunner(
try {
const result = enableOrgLevel
? await githubAppClient.actions.deleteSelfHostedRunnerFromOrg({
runner_id: ghRunnerId,
org: repo.repoOwner,
})
runner_id: ghRunnerId,
org: repo.repoOwner,
})
: await githubAppClient.actions.deleteSelfHostedRunnerFromRepo({
runner_id: ghRunnerId,
owner: repo.repoOwner,
repo: repo.repoName,
});
runner_id: ghRunnerId,
owner: repo.repoOwner,
repo: repo.repoName,
});

if (result.status == 204) {
await terminateRunner(ec2runner);
Expand All @@ -139,7 +139,7 @@ export async function scaleDown(): Promise<void> {
// list and sort runners, newest first. This ensure we keep the newest runners longer.
const runners = (
await listRunners({
environment
environment,
})
).sort((a, b): number => {
if (a.launchTime === undefined) return 1;
Expand Down
Loading