Skip to content

Commit b6ddb83

Browse files
feat: allow to use dynamic instance type in multiple events
1 parent 45462d8 commit b6ddb83

1 file changed

Lines changed: 39 additions & 4 deletions

File tree

  • lambdas/functions/control-plane/src/scale-runners

lambdas/functions/control-plane/src/scale-runners/scale-up.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,11 @@ export async function scaleUp(payloads: ActionRequestMessageSQS[]): Promise<stri
273273
const enableOrgLevel = yn(process.env.ENABLE_ORGANIZATION_RUNNERS, { default: true });
274274
const maximumRunners = parseInt(process.env.RUNNERS_MAXIMUM_COUNT || '3');
275275
const runnerLabels = process.env.RUNNER_LABELS || '';
276-
277276
const runnerGroup = process.env.RUNNER_GROUP_NAME || 'Default';
278277
const environment = process.env.ENVIRONMENT;
279278
const ssmTokenPath = process.env.SSM_TOKEN_PATH;
280279
const subnets = process.env.SUBNET_IDS.split(',');
281-
const instanceTypes = process.env.INSTANCE_TYPES.split(',');
280+
let instanceTypes = process.env.INSTANCE_TYPES.split(',');
282281
const instanceTargetCapacityType = process.env.INSTANCE_TARGET_CAPACITY_TYPE;
283282
const ephemeralEnabled = yn(process.env.ENABLE_EPHEMERAL_RUNNERS, { default: false });
284283
const dynamicEc2ConfigEnabled = yn(process.env.ENABLE_DYNAMIC_EC2_CONFIG, { default: false });
@@ -321,7 +320,7 @@ export async function scaleUp(payloads: ActionRequestMessageSQS[]): Promise<stri
321320
const validMessages = new Map<string, MessagesWithClient>();
322321
const rejectedMessageIds = new Set<string>();
323322
for (const payload of payloads) {
324-
const { eventType, messageId, repositoryName, repositoryOwner } = payload;
323+
const { eventType, messageId, repositoryName, repositoryOwner, labels } = payload;
325324
if (ephemeralEnabled && eventType !== 'workflow_job') {
326325
logger.warn(
327326
'Event is not supported in combination with ephemeral runners. Please ensure you have enabled workflow_job events.',
@@ -345,7 +344,19 @@ export async function scaleUp(payloads: ActionRequestMessageSQS[]): Promise<stri
345344
continue;
346345
}
347346

348-
const key = enableOrgLevel ? payload.repositoryOwner : `${payload.repositoryOwner}/${payload.repositoryName}`;
347+
let key = enableOrgLevel ? payload.repositoryOwner : `${payload.repositoryOwner}/${payload.repositoryName}`;
348+
349+
if (dynamicEc2ConfigEnabled && labels?.length) {
350+
const requestedDynamicEc2Config = labels
351+
.find(l => l.startsWith('ghr-ec2-'))
352+
?.slice('ghr-ec2-'.length);
353+
354+
if (requestedDynamicEc2Config) {
355+
const ec2Hash = ec2LabelsHash(labels);
356+
key = `${key}/${ec2Hash}`;
357+
}
358+
}
359+
349360

350361
let entry = validMessages.get(key);
351362

@@ -385,13 +396,20 @@ export async function scaleUp(payloads: ActionRequestMessageSQS[]): Promise<stri
385396
let scaleUp = 0;
386397
const queuedMessages: ActionRequestMessageSQS[] = [];
387398

399+
if (messages.length > 0 && dynamicEc2ConfigEnabled) {
400+
const requestedInstanceType = messages[0].labels?.find(label => label.startsWith('ghr-ec2-instance-type'))?.replace('ghr-ec2-instance-type', '');
401+
instanceTypes = requestedInstanceType ? [requestedInstanceType] : instanceTypes;
402+
}
403+
404+
388405
for (const message of messages) {
389406
const messageLogger = logger.createChild({
390407
persistentKeys: {
391408
eventType: message.eventType,
392409
group,
393410
messageId: message.messageId,
394411
repository: `${message.repositoryOwner}/${message.repositoryName}`,
412+
labels: message.labels,
395413
},
396414
});
397415

@@ -640,3 +658,20 @@ async function createJitConfig(githubRunnerConfig: CreateGitHubRunnerConfig, ins
640658
}
641659
}
642660
}
661+
662+
function ec2LabelsHash(labels: string[]): string {
663+
const prefix = 'ghr-ec2-';
664+
665+
const input = labels
666+
.filter(l => l.startsWith(prefix))
667+
.sort() // ensure deterministic hash
668+
.join('|');
669+
670+
let hash = 0;
671+
for (let i = 0; i < input.length; i++) {
672+
hash = (hash << 5) - hash + input.charCodeAt(i);
673+
hash |= 0; // force 32-bit integer
674+
}
675+
676+
return Math.abs(hash).toString(36);
677+
}

0 commit comments

Comments
 (0)