@cloudsnorkel/cdk-github-runners 0.14.24 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/.jsii +5400 -255
  2. package/API.md +1048 -24
  3. package/README.md +52 -0
  4. package/assets/delete-failed-runner.lambda/index.js +105 -9
  5. package/assets/idle-runner-repear.lambda/index.js +136 -14
  6. package/assets/image-builders/aws-image-builder/delete-resources.lambda/index.js +1 -1
  7. package/assets/image-builders/build-image.lambda/index.js +1 -1
  8. package/assets/providers/ami-root-device.lambda/index.js +1 -1
  9. package/assets/setup.lambda/index.html +7 -7
  10. package/assets/setup.lambda/index.js +101 -8
  11. package/assets/status.lambda/index.js +104 -8
  12. package/assets/token-retriever.lambda/index.js +104 -8
  13. package/assets/warm-runner-manager.lambda/index.js +5892 -0
  14. package/assets/webhook-handler.lambda/index.js +109 -11
  15. package/assets/webhook-redelivery.lambda/index.js +122 -24
  16. package/lib/access.js +1 -1
  17. package/lib/delete-failed-runner.lambda.js +2 -2
  18. package/lib/idle-runner-repear.lambda.js +33 -7
  19. package/lib/image-builders/api.js +1 -1
  20. package/lib/image-builders/aws-image-builder/base-image.d.ts +13 -0
  21. package/lib/image-builders/aws-image-builder/base-image.js +36 -3
  22. package/lib/image-builders/aws-image-builder/builder.js +4 -4
  23. package/lib/image-builders/aws-image-builder/delete-resources.lambda.js +2 -2
  24. package/lib/image-builders/aws-image-builder/deprecated/ami.js +1 -1
  25. package/lib/image-builders/aws-image-builder/deprecated/container.js +1 -1
  26. package/lib/image-builders/aws-image-builder/deprecated/linux-components.js +1 -1
  27. package/lib/image-builders/aws-image-builder/deprecated/windows-components.js +1 -1
  28. package/lib/image-builders/build-image.lambda.js +2 -2
  29. package/lib/image-builders/codebuild-deprecated.js +1 -1
  30. package/lib/image-builders/components.js +3 -3
  31. package/lib/image-builders/static.js +1 -1
  32. package/lib/index.d.ts +1 -0
  33. package/lib/index.js +2 -1
  34. package/lib/lambda-github.d.ts +1 -1
  35. package/lib/lambda-github.js +3 -2
  36. package/lib/lambda-helpers.js +4 -4
  37. package/lib/providers/ami-root-device.lambda.js +2 -2
  38. package/lib/providers/codebuild.d.ts +16 -0
  39. package/lib/providers/codebuild.js +15 -4
  40. package/lib/providers/common.js +3 -3
  41. package/lib/providers/composite.js +1 -1
  42. package/lib/providers/ec2.d.ts +5 -0
  43. package/lib/providers/ec2.js +31 -17
  44. package/lib/providers/ecs.d.ts +17 -0
  45. package/lib/providers/ecs.js +43 -38
  46. package/lib/providers/fargate.js +9 -31
  47. package/lib/providers/lambda.js +2 -2
  48. package/lib/runner.d.ts +25 -2
  49. package/lib/runner.js +119 -17
  50. package/lib/secrets.js +1 -1
  51. package/lib/setup.lambda.js +2 -2
  52. package/lib/utils.d.ts +10 -1
  53. package/lib/utils.js +15 -1
  54. package/lib/warm-runner-manager-function.d.ts +18 -0
  55. package/lib/warm-runner-manager-function.js +24 -0
  56. package/lib/warm-runner-manager.lambda.d.ts +41 -0
  57. package/lib/warm-runner-manager.lambda.js +487 -0
  58. package/lib/warm-runner.d.ts +147 -0
  59. package/lib/warm-runner.js +210 -0
  60. package/lib/webhook-handler.lambda.js +5 -3
  61. package/lib/webhook-redelivery.lambda.js +17 -16
  62. package/lib/webhook.d.ts +4 -0
  63. package/lib/webhook.js +2 -1
  64. package/node_modules/cron-parser/LICENSE +21 -0
  65. package/node_modules/cron-parser/README.md +408 -0
  66. package/node_modules/cron-parser/dist/CronDate.js +518 -0
  67. package/node_modules/cron-parser/dist/CronExpression.js +520 -0
  68. package/node_modules/cron-parser/dist/CronExpressionParser.js +382 -0
  69. package/node_modules/cron-parser/dist/CronFieldCollection.js +371 -0
  70. package/node_modules/cron-parser/dist/CronFileParser.js +109 -0
  71. package/node_modules/cron-parser/dist/fields/CronDayOfMonth.js +44 -0
  72. package/node_modules/cron-parser/dist/fields/CronDayOfWeek.js +51 -0
  73. package/node_modules/cron-parser/dist/fields/CronField.js +214 -0
  74. package/node_modules/cron-parser/dist/fields/CronHour.js +40 -0
  75. package/node_modules/cron-parser/dist/fields/CronMinute.js +40 -0
  76. package/node_modules/cron-parser/dist/fields/CronMonth.js +44 -0
  77. package/node_modules/cron-parser/dist/fields/CronSecond.js +40 -0
  78. package/node_modules/cron-parser/dist/fields/index.js +24 -0
  79. package/node_modules/cron-parser/dist/fields/types.js +2 -0
  80. package/node_modules/cron-parser/dist/index.js +31 -0
  81. package/node_modules/cron-parser/dist/types/CronDate.d.ts +288 -0
  82. package/node_modules/cron-parser/dist/types/CronExpression.d.ts +118 -0
  83. package/node_modules/cron-parser/dist/types/CronExpressionParser.d.ts +70 -0
  84. package/node_modules/cron-parser/dist/types/CronFieldCollection.d.ts +153 -0
  85. package/node_modules/cron-parser/dist/types/CronFileParser.d.ts +30 -0
  86. package/node_modules/cron-parser/dist/types/fields/CronDayOfMonth.d.ts +25 -0
  87. package/node_modules/cron-parser/dist/types/fields/CronDayOfWeek.d.ts +30 -0
  88. package/node_modules/cron-parser/dist/types/fields/CronField.d.ts +130 -0
  89. package/node_modules/cron-parser/dist/types/fields/CronHour.d.ts +23 -0
  90. package/node_modules/cron-parser/dist/types/fields/CronMinute.d.ts +23 -0
  91. package/node_modules/cron-parser/dist/types/fields/CronMonth.d.ts +24 -0
  92. package/node_modules/cron-parser/dist/types/fields/CronSecond.d.ts +23 -0
  93. package/node_modules/cron-parser/dist/types/fields/index.d.ts +8 -0
  94. package/node_modules/cron-parser/dist/types/fields/types.d.ts +18 -0
  95. package/node_modules/cron-parser/dist/types/index.d.ts +8 -0
  96. package/node_modules/cron-parser/dist/types/utils/random.d.ts +10 -0
  97. package/node_modules/cron-parser/dist/utils/random.js +38 -0
  98. package/node_modules/cron-parser/package.json +117 -0
  99. package/node_modules/luxon/LICENSE.md +7 -0
  100. package/node_modules/luxon/README.md +55 -0
  101. package/node_modules/luxon/build/amd/luxon.js +8741 -0
  102. package/node_modules/luxon/build/amd/luxon.js.map +1 -0
  103. package/node_modules/luxon/build/cjs-browser/luxon.js +8739 -0
  104. package/node_modules/luxon/build/cjs-browser/luxon.js.map +1 -0
  105. package/node_modules/luxon/build/es6/luxon.mjs +8133 -0
  106. package/node_modules/luxon/build/es6/luxon.mjs.map +1 -0
  107. package/node_modules/luxon/build/global/luxon.js +8744 -0
  108. package/node_modules/luxon/build/global/luxon.js.map +1 -0
  109. package/node_modules/luxon/build/global/luxon.min.js +1 -0
  110. package/node_modules/luxon/build/global/luxon.min.js.map +1 -0
  111. package/node_modules/luxon/build/node/luxon.js +7792 -0
  112. package/node_modules/luxon/build/node/luxon.js.map +1 -0
  113. package/node_modules/luxon/package.json +87 -0
  114. package/node_modules/luxon/src/datetime.js +2603 -0
  115. package/node_modules/luxon/src/duration.js +1009 -0
  116. package/node_modules/luxon/src/errors.js +61 -0
  117. package/node_modules/luxon/src/impl/conversions.js +206 -0
  118. package/node_modules/luxon/src/impl/diff.js +95 -0
  119. package/node_modules/luxon/src/impl/digits.js +94 -0
  120. package/node_modules/luxon/src/impl/english.js +233 -0
  121. package/node_modules/luxon/src/impl/formats.js +176 -0
  122. package/node_modules/luxon/src/impl/formatter.js +434 -0
  123. package/node_modules/luxon/src/impl/invalid.js +14 -0
  124. package/node_modules/luxon/src/impl/locale.js +569 -0
  125. package/node_modules/luxon/src/impl/regexParser.js +335 -0
  126. package/node_modules/luxon/src/impl/tokenParser.js +505 -0
  127. package/node_modules/luxon/src/impl/util.js +330 -0
  128. package/node_modules/luxon/src/impl/zoneUtil.js +34 -0
  129. package/node_modules/luxon/src/info.js +205 -0
  130. package/node_modules/luxon/src/interval.js +669 -0
  131. package/node_modules/luxon/src/luxon.js +26 -0
  132. package/node_modules/luxon/src/package.json +4 -0
  133. package/node_modules/luxon/src/settings.js +180 -0
  134. package/node_modules/luxon/src/zone.js +97 -0
  135. package/node_modules/luxon/src/zones/IANAZone.js +235 -0
  136. package/node_modules/luxon/src/zones/fixedOffsetZone.js +150 -0
  137. package/node_modules/luxon/src/zones/invalidZone.js +53 -0
  138. package/node_modules/luxon/src/zones/systemZone.js +61 -0
  139. package/package.json +33 -24
package/README.md CHANGED
@@ -34,6 +34,7 @@ Ephemeral (or on-demand) runners are the [recommended way by GitHub][14] for aut
34
34
  - [Customizing](#customizing)
35
35
  - [Composite Providers](#composite-providers)
36
36
  - [Custom Provider Selection](#custom-provider-selection)
37
+ - [Warm Runners](#warm-runners)
37
38
  - [Examples](#examples)
38
39
  - [Architecture](#architecture)
39
40
  - [Troubleshooting](#troubleshooting)
@@ -463,12 +464,62 @@ const providerSelector = new Function(this, 'provider-selector', {
463
464
  * ⚠️ **No guarantee of assignment**: Provider selection only determines which provider will provision a runner. GitHub Actions may still route the job to any available runner with matching labels. For reliable provider assignment, consider repo-level runner registration (the default).
464
465
  * ⚡ **Performance**: The selector runs synchronously during webhook processing. Keep it fast and efficient—the webhook has a 30-second timeout total.
465
466
 
467
+ ### Warm Runners
468
+
469
+ Warm runners are pre-provisioned and stay idle until a job arrives, reducing startup latency. Use `AlwaysOnWarmRunner` for 24/7 pools or `ScheduledWarmRunner` for time-windowed pools. You specify the provider directly.
470
+
471
+ ```typescript
472
+ import { AlwaysOnWarmRunner, CodeBuildRunnerProvider, GitHubRunners } from '@cloudsnorkel/cdk-github-runners';
473
+
474
+ const provider = new CodeBuildRunnerProvider(this, 'provider', { labels: ['codebuild', 'linux'] });
475
+ const runners = new GitHubRunners(this, 'runners', { providers: [provider] });
476
+
477
+ new AlwaysOnWarmRunner(this, 'warm', {
478
+ runners,
479
+ provider,
480
+ count: 2,
481
+ owner: 'my-org',
482
+ repo: 'my-repo',
483
+ });
484
+ ```
485
+
486
+ Warm runner pools can be stacked. If you want 2 warm runners always available but 3 during peak work hours, you can create one pool with 2 runners always on and another pool with 1 runner during work hours.
487
+
488
+ ```typescript
489
+ import { aws_events as events, Duration } from 'aws-cdk-lib';
490
+ import { AlwaysOnWarmRunner, ScheduledWarmRunner, CodeBuildRunnerProvider, GitHubRunners } from '@cloudsnorkel/cdk-github-runners';
491
+
492
+ const provider = new CodeBuildRunnerProvider(this, 'provider', { labels: ['codebuild', 'linux'] });
493
+ const runners = new GitHubRunners(this, 'runners', { providers: [provider] });
494
+
495
+ new AlwaysOnWarmRunner(this, 'warm', {
496
+ runners,
497
+ provider,
498
+ count: 2,
499
+ owner: 'my-org',
500
+ repo: 'my-repo',
501
+ });
502
+
503
+ new ScheduledWarmRunner(this, 'work hours warm', {
504
+ runners,
505
+ provider,
506
+ count: 1,
507
+ owner: 'my-org',
508
+ repo: 'my-repo',
509
+ schedule: events.Schedule.cron({ hour: '13', minute: '0', weekDay: 'MON-FRI' }),
510
+ duration: Duration.hours(2),
511
+ });
512
+ ```
513
+
514
+ See the [warm-runners example](examples/typescript/warm-runners/) for a complete setup.
515
+
466
516
  ## Examples
467
517
 
468
518
  We provide comprehensive examples in the [`examples/`](examples/) folder to help you get started quickly:
469
519
 
470
520
  ### Getting Started
471
521
  - **[Simple CodeBuild](examples/typescript/simple-codebuild/)** - Basic setup with just a CodeBuild provider (also available in [Python](examples/python/simple-codebuild/))
522
+ - **[Warm Runners](examples/typescript/warm-runners/)** - Pre-provisioned runners for low-latency job starts (also available in [Python](examples/python/warm-runners/))
472
523
 
473
524
  ### Provider Configuration
474
525
  - **[Composite Provider](examples/typescript/composite-provider/)** - Fallback and weighted distribution strategies (also available in [Python](examples/python/composite-provider/))
@@ -489,6 +540,7 @@ We provide comprehensive examples in the [`examples/`](examples/) folder to help
489
540
 
490
541
  ### Customization
491
542
  - **[Add Software](examples/typescript/add-software/)** - Add custom software to runner images (also available in [Python](examples/python/add-software/))
543
+ - **[GPU](examples/typescript/gpu/)** - GPU support with NVIDIA drivers across EC2, CodeBuild, and ECS (also available in [Python](examples/python/gpu/))
492
544
 
493
545
  ### Enterprise & Monitoring
494
546
  - **[GHES](examples/typescript/ghes/)** - Configure runners for GitHub Enterprise Server (also available in [Python](examples/python/ghes/))
@@ -300,7 +300,7 @@ function isKeyOperator(operator) {
300
300
  function getValues(context, operator, key, modifier) {
301
301
  var value = context[key], result = [];
302
302
  if (isDefined(value) && value !== "") {
303
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
303
+ if (typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") {
304
304
  value = value.toString();
305
305
  if (modifier && modifier !== "*") {
306
306
  value = value.substring(0, parseInt(modifier, 10));
@@ -595,6 +595,98 @@ var require_fast_content_type_parse = __commonJS({
595
595
  }
596
596
  });
597
597
 
598
+ // node_modules/json-with-bigint/json-with-bigint.js
599
+ var intRegex, noiseValue, originalStringify, originalParse, customFormat, bigIntsStringify, noiseStringify, JSONStringify, isContextSourceSupported, convertMarkedBigIntsReviver, JSONParseV2, MAX_INT, MAX_DIGITS, stringsOrLargeNumbers, noiseValueWithQuotes, JSONParse;
600
+ var init_json_with_bigint = __esm({
601
+ "node_modules/json-with-bigint/json-with-bigint.js"() {
602
+ "use strict";
603
+ intRegex = /^-?\d+$/;
604
+ noiseValue = /^-?\d+n+$/;
605
+ originalStringify = JSON.stringify;
606
+ originalParse = JSON.parse;
607
+ customFormat = /^-?\d+n$/;
608
+ bigIntsStringify = /([\[:])?"(-?\d+)n"($|([\\n]|\s)*(\s|[\\n])*[,\}\]])/g;
609
+ noiseStringify = /([\[:])?("-?\d+n+)n("$|"([\\n]|\s)*(\s|[\\n])*[,\}\]])/g;
610
+ JSONStringify = (value, replacer, space) => {
611
+ if ("rawJSON" in JSON) {
612
+ return originalStringify(
613
+ value,
614
+ (key, value2) => {
615
+ if (typeof value2 === "bigint") return JSON.rawJSON(value2.toString());
616
+ if (typeof replacer === "function") return replacer(key, value2);
617
+ if (Array.isArray(replacer) && replacer.includes(key)) return value2;
618
+ return value2;
619
+ },
620
+ space
621
+ );
622
+ }
623
+ if (!value) return originalStringify(value, replacer, space);
624
+ const convertedToCustomJSON = originalStringify(
625
+ value,
626
+ (key, value2) => {
627
+ const isNoise = typeof value2 === "string" && Boolean(value2.match(noiseValue));
628
+ if (isNoise) return value2.toString() + "n";
629
+ if (typeof value2 === "bigint") return value2.toString() + "n";
630
+ if (typeof replacer === "function") return replacer(key, value2);
631
+ if (Array.isArray(replacer) && replacer.includes(key)) return value2;
632
+ return value2;
633
+ },
634
+ space
635
+ );
636
+ const processedJSON = convertedToCustomJSON.replace(
637
+ bigIntsStringify,
638
+ "$1$2$3"
639
+ );
640
+ const denoisedJSON = processedJSON.replace(noiseStringify, "$1$2$3");
641
+ return denoisedJSON;
642
+ };
643
+ isContextSourceSupported = () => JSON.parse("1", (_, __, context) => !!context && context.source === "1");
644
+ convertMarkedBigIntsReviver = (key, value, context, userReviver) => {
645
+ const isCustomFormatBigInt = typeof value === "string" && value.match(customFormat);
646
+ if (isCustomFormatBigInt) return BigInt(value.slice(0, -1));
647
+ const isNoiseValue = typeof value === "string" && value.match(noiseValue);
648
+ if (isNoiseValue) return value.slice(0, -1);
649
+ if (typeof userReviver !== "function") return value;
650
+ return userReviver(key, value, context);
651
+ };
652
+ JSONParseV2 = (text, reviver) => {
653
+ return JSON.parse(text, (key, value, context) => {
654
+ const isBigNumber = typeof value === "number" && (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER);
655
+ const isInt = context && intRegex.test(context.source);
656
+ const isBigInt = isBigNumber && isInt;
657
+ if (isBigInt) return BigInt(context.source);
658
+ if (typeof reviver !== "function") return value;
659
+ return reviver(key, value, context);
660
+ });
661
+ };
662
+ MAX_INT = Number.MAX_SAFE_INTEGER.toString();
663
+ MAX_DIGITS = MAX_INT.length;
664
+ stringsOrLargeNumbers = /"(?:\\.|[^"])*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g;
665
+ noiseValueWithQuotes = /^"-?\d+n+"$/;
666
+ JSONParse = (text, reviver) => {
667
+ if (!text) return originalParse(text, reviver);
668
+ if (isContextSourceSupported()) return JSONParseV2(text, reviver);
669
+ const serializedData = text.replace(
670
+ stringsOrLargeNumbers,
671
+ (text2, digits, fractional, exponential) => {
672
+ const isString = text2[0] === '"';
673
+ const isNoise = isString && Boolean(text2.match(noiseValueWithQuotes));
674
+ if (isNoise) return text2.substring(0, text2.length - 1) + 'n"';
675
+ const isFractionalOrExponential = fractional || exponential;
676
+ const isLessThanMaxSafeInt = digits && (digits.length < MAX_DIGITS || digits.length === MAX_DIGITS && digits <= MAX_INT);
677
+ if (isString || isFractionalOrExponential || isLessThanMaxSafeInt)
678
+ return text2;
679
+ return '"' + text2 + 'n"';
680
+ }
681
+ );
682
+ return originalParse(
683
+ serializedData,
684
+ (key, value, context) => convertMarkedBigIntsReviver(key, value, context, reviver)
685
+ );
686
+ };
687
+ }
688
+ });
689
+
598
690
  // node_modules/@octokit/request-error/dist-src/index.js
599
691
  var RequestError;
600
692
  var init_dist_src = __esm({
@@ -658,7 +750,7 @@ async function fetchWrapper(requestOptions) {
658
750
  }
659
751
  const log = requestOptions.request?.log || console;
660
752
  const parseSuccessResponseBody = requestOptions.request?.parseSuccessResponseBody !== false;
661
- const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSON.stringify(requestOptions.body) : requestOptions.body;
753
+ const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSONStringify(requestOptions.body) : requestOptions.body;
662
754
  const requestHeaders = Object.fromEntries(
663
755
  Object.entries(requestOptions.headers).map(([name, value]) => [
664
756
  name,
@@ -757,7 +849,7 @@ async function getResponseData(response) {
757
849
  let text = "";
758
850
  try {
759
851
  text = await response.text();
760
- return JSON.parse(text);
852
+ return JSONParse(text);
761
853
  } catch (err) {
762
854
  return text;
763
855
  }
@@ -816,8 +908,9 @@ var init_dist_bundle2 = __esm({
816
908
  init_dist_bundle();
817
909
  init_universal_user_agent();
818
910
  import_fast_content_type_parse = __toESM(require_fast_content_type_parse(), 1);
911
+ init_json_with_bigint();
819
912
  init_dist_src();
820
- VERSION2 = "10.0.7";
913
+ VERSION2 = "10.0.8";
821
914
  defaults_default = {
822
915
  headers: {
823
916
  "user-agent": `octokit-request.js/${VERSION2} ${getUserAgent()}`
@@ -5040,6 +5133,8 @@ function requiresAppAuth(url) {
5040
5133
  }
5041
5134
  function isNotTimeSkewError(error) {
5042
5135
  return !(error.message.match(
5136
+ /'Expiration time' claim \('exp'\) is too far in the future/
5137
+ ) || error.message.match(
5043
5138
  /'Expiration time' claim \('exp'\) must be a numeric value representing the future time at which the assertion expires/
5044
5139
  ) || error.message.match(
5045
5140
  /'Issued at' claim \('iat'\) must be an Integer representing the time that the assertion was issued/
@@ -5201,11 +5296,12 @@ var init_dist_node = __esm({
5201
5296
  "/marketplace_listing/stubbed/plans/{plan_id}/accounts",
5202
5297
  "/orgs/{org}/installation",
5203
5298
  "/repos/{owner}/{repo}/installation",
5204
- "/users/{username}/installation"
5299
+ "/users/{username}/installation",
5300
+ "/enterprises/{enterprise}/installation"
5205
5301
  ];
5206
5302
  REGEX = routeMatcher(PATHS);
5207
5303
  FIVE_SECONDS_IN_MS = 5 * 1e3;
5208
- VERSION12 = "8.1.2";
5304
+ VERSION12 = "8.2.0";
5209
5305
  }
5210
5306
  });
5211
5307
 
@@ -5224,11 +5320,11 @@ var import_client_secrets_manager = require("@aws-sdk/client-secrets-manager");
5224
5320
  var sm = new import_client_secrets_manager.SecretsManagerClient();
5225
5321
  async function getSecretValue(arn) {
5226
5322
  if (!arn) {
5227
- throw new Error("Missing secret ARN");
5323
+ throw new Error("Missing secret ARN. Check the Lambda configuration and required environment variables.");
5228
5324
  }
5229
5325
  const secret = await sm.send(new import_client_secrets_manager.GetSecretValueCommand({ SecretId: arn }));
5230
5326
  if (!secret.SecretString) {
5231
- throw new Error(`No SecretString in ${arn}`);
5327
+ throw new Error("Secrets Manager getSecretValue returned no SecretString. This often indicates that the secret was stored as binary data (SecretBinary) instead of a string. Ensure the secret is stored in SecretString or update the code to handle SecretBinary.");
5232
5328
  }
5233
5329
  return secret.SecretString;
5234
5330
  }
@@ -5402,7 +5498,7 @@ async function handler2(event) {
5402
5498
  repo: event.repo,
5403
5499
  runnerId: runner.id,
5404
5500
  runnerName: event.runnerName,
5405
- error: `${e}`
5501
+ error: e
5406
5502
  });
5407
5503
  }
5408
5504
  }
@@ -300,7 +300,7 @@ function isKeyOperator(operator) {
300
300
  function getValues(context, operator, key, modifier) {
301
301
  var value = context[key], result = [];
302
302
  if (isDefined(value) && value !== "") {
303
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
303
+ if (typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") {
304
304
  value = value.toString();
305
305
  if (modifier && modifier !== "*") {
306
306
  value = value.substring(0, parseInt(modifier, 10));
@@ -595,6 +595,98 @@ var require_fast_content_type_parse = __commonJS({
595
595
  }
596
596
  });
597
597
 
598
+ // node_modules/json-with-bigint/json-with-bigint.js
599
+ var intRegex, noiseValue, originalStringify, originalParse, customFormat, bigIntsStringify, noiseStringify, JSONStringify, isContextSourceSupported, convertMarkedBigIntsReviver, JSONParseV2, MAX_INT, MAX_DIGITS, stringsOrLargeNumbers, noiseValueWithQuotes, JSONParse;
600
+ var init_json_with_bigint = __esm({
601
+ "node_modules/json-with-bigint/json-with-bigint.js"() {
602
+ "use strict";
603
+ intRegex = /^-?\d+$/;
604
+ noiseValue = /^-?\d+n+$/;
605
+ originalStringify = JSON.stringify;
606
+ originalParse = JSON.parse;
607
+ customFormat = /^-?\d+n$/;
608
+ bigIntsStringify = /([\[:])?"(-?\d+)n"($|([\\n]|\s)*(\s|[\\n])*[,\}\]])/g;
609
+ noiseStringify = /([\[:])?("-?\d+n+)n("$|"([\\n]|\s)*(\s|[\\n])*[,\}\]])/g;
610
+ JSONStringify = (value, replacer, space) => {
611
+ if ("rawJSON" in JSON) {
612
+ return originalStringify(
613
+ value,
614
+ (key, value2) => {
615
+ if (typeof value2 === "bigint") return JSON.rawJSON(value2.toString());
616
+ if (typeof replacer === "function") return replacer(key, value2);
617
+ if (Array.isArray(replacer) && replacer.includes(key)) return value2;
618
+ return value2;
619
+ },
620
+ space
621
+ );
622
+ }
623
+ if (!value) return originalStringify(value, replacer, space);
624
+ const convertedToCustomJSON = originalStringify(
625
+ value,
626
+ (key, value2) => {
627
+ const isNoise = typeof value2 === "string" && Boolean(value2.match(noiseValue));
628
+ if (isNoise) return value2.toString() + "n";
629
+ if (typeof value2 === "bigint") return value2.toString() + "n";
630
+ if (typeof replacer === "function") return replacer(key, value2);
631
+ if (Array.isArray(replacer) && replacer.includes(key)) return value2;
632
+ return value2;
633
+ },
634
+ space
635
+ );
636
+ const processedJSON = convertedToCustomJSON.replace(
637
+ bigIntsStringify,
638
+ "$1$2$3"
639
+ );
640
+ const denoisedJSON = processedJSON.replace(noiseStringify, "$1$2$3");
641
+ return denoisedJSON;
642
+ };
643
+ isContextSourceSupported = () => JSON.parse("1", (_, __, context) => !!context && context.source === "1");
644
+ convertMarkedBigIntsReviver = (key, value, context, userReviver) => {
645
+ const isCustomFormatBigInt = typeof value === "string" && value.match(customFormat);
646
+ if (isCustomFormatBigInt) return BigInt(value.slice(0, -1));
647
+ const isNoiseValue = typeof value === "string" && value.match(noiseValue);
648
+ if (isNoiseValue) return value.slice(0, -1);
649
+ if (typeof userReviver !== "function") return value;
650
+ return userReviver(key, value, context);
651
+ };
652
+ JSONParseV2 = (text, reviver) => {
653
+ return JSON.parse(text, (key, value, context) => {
654
+ const isBigNumber = typeof value === "number" && (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER);
655
+ const isInt = context && intRegex.test(context.source);
656
+ const isBigInt = isBigNumber && isInt;
657
+ if (isBigInt) return BigInt(context.source);
658
+ if (typeof reviver !== "function") return value;
659
+ return reviver(key, value, context);
660
+ });
661
+ };
662
+ MAX_INT = Number.MAX_SAFE_INTEGER.toString();
663
+ MAX_DIGITS = MAX_INT.length;
664
+ stringsOrLargeNumbers = /"(?:\\.|[^"])*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g;
665
+ noiseValueWithQuotes = /^"-?\d+n+"$/;
666
+ JSONParse = (text, reviver) => {
667
+ if (!text) return originalParse(text, reviver);
668
+ if (isContextSourceSupported()) return JSONParseV2(text, reviver);
669
+ const serializedData = text.replace(
670
+ stringsOrLargeNumbers,
671
+ (text2, digits, fractional, exponential) => {
672
+ const isString = text2[0] === '"';
673
+ const isNoise = isString && Boolean(text2.match(noiseValueWithQuotes));
674
+ if (isNoise) return text2.substring(0, text2.length - 1) + 'n"';
675
+ const isFractionalOrExponential = fractional || exponential;
676
+ const isLessThanMaxSafeInt = digits && (digits.length < MAX_DIGITS || digits.length === MAX_DIGITS && digits <= MAX_INT);
677
+ if (isString || isFractionalOrExponential || isLessThanMaxSafeInt)
678
+ return text2;
679
+ return '"' + text2 + 'n"';
680
+ }
681
+ );
682
+ return originalParse(
683
+ serializedData,
684
+ (key, value, context) => convertMarkedBigIntsReviver(key, value, context, reviver)
685
+ );
686
+ };
687
+ }
688
+ });
689
+
598
690
  // node_modules/@octokit/request-error/dist-src/index.js
599
691
  var RequestError;
600
692
  var init_dist_src = __esm({
@@ -658,7 +750,7 @@ async function fetchWrapper(requestOptions) {
658
750
  }
659
751
  const log = requestOptions.request?.log || console;
660
752
  const parseSuccessResponseBody = requestOptions.request?.parseSuccessResponseBody !== false;
661
- const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSON.stringify(requestOptions.body) : requestOptions.body;
753
+ const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSONStringify(requestOptions.body) : requestOptions.body;
662
754
  const requestHeaders = Object.fromEntries(
663
755
  Object.entries(requestOptions.headers).map(([name, value]) => [
664
756
  name,
@@ -757,7 +849,7 @@ async function getResponseData(response) {
757
849
  let text = "";
758
850
  try {
759
851
  text = await response.text();
760
- return JSON.parse(text);
852
+ return JSONParse(text);
761
853
  } catch (err) {
762
854
  return text;
763
855
  }
@@ -816,8 +908,9 @@ var init_dist_bundle2 = __esm({
816
908
  init_dist_bundle();
817
909
  init_universal_user_agent();
818
910
  import_fast_content_type_parse = __toESM(require_fast_content_type_parse(), 1);
911
+ init_json_with_bigint();
819
912
  init_dist_src();
820
- VERSION2 = "10.0.7";
913
+ VERSION2 = "10.0.8";
821
914
  defaults_default = {
822
915
  headers: {
823
916
  "user-agent": `octokit-request.js/${VERSION2} ${getUserAgent()}`
@@ -5040,6 +5133,8 @@ function requiresAppAuth(url) {
5040
5133
  }
5041
5134
  function isNotTimeSkewError(error) {
5042
5135
  return !(error.message.match(
5136
+ /'Expiration time' claim \('exp'\) is too far in the future/
5137
+ ) || error.message.match(
5043
5138
  /'Expiration time' claim \('exp'\) must be a numeric value representing the future time at which the assertion expires/
5044
5139
  ) || error.message.match(
5045
5140
  /'Issued at' claim \('iat'\) must be an Integer representing the time that the assertion was issued/
@@ -5201,11 +5296,12 @@ var init_dist_node = __esm({
5201
5296
  "/marketplace_listing/stubbed/plans/{plan_id}/accounts",
5202
5297
  "/orgs/{org}/installation",
5203
5298
  "/repos/{owner}/{repo}/installation",
5204
- "/users/{username}/installation"
5299
+ "/users/{username}/installation",
5300
+ "/enterprises/{enterprise}/installation"
5205
5301
  ];
5206
5302
  REGEX = routeMatcher(PATHS);
5207
5303
  FIVE_SECONDS_IN_MS = 5 * 1e3;
5208
- VERSION12 = "8.1.2";
5304
+ VERSION12 = "8.2.0";
5209
5305
  }
5210
5306
  });
5211
5307
 
@@ -5225,11 +5321,11 @@ var import_client_secrets_manager = require("@aws-sdk/client-secrets-manager");
5225
5321
  var sm = new import_client_secrets_manager.SecretsManagerClient();
5226
5322
  async function getSecretValue(arn) {
5227
5323
  if (!arn) {
5228
- throw new Error("Missing secret ARN");
5324
+ throw new Error("Missing secret ARN. Check the Lambda configuration and required environment variables.");
5229
5325
  }
5230
5326
  const secret = await sm.send(new import_client_secrets_manager.GetSecretValueCommand({ SecretId: arn }));
5231
5327
  if (!secret.SecretString) {
5232
- throw new Error(`No SecretString in ${arn}`);
5328
+ throw new Error("Secrets Manager getSecretValue returned no SecretString. This often indicates that the secret was stored as binary data (SecretBinary) instead of a string. Ensure the secret is stored in SecretString or update the code to handle SecretBinary.");
5233
5329
  }
5234
5330
  return secret.SecretString;
5235
5331
  }
@@ -5364,6 +5460,7 @@ async function handler2(event) {
5364
5460
  const input = JSON.parse(record.body);
5365
5461
  console.log({
5366
5462
  notice: "Checking runner",
5463
+ runnerName: input.runnerName,
5367
5464
  input
5368
5465
  });
5369
5466
  const retryLater = () => result.batchItemFailures.push({ itemIdentifier: record.messageId });
@@ -5371,6 +5468,7 @@ async function handler2(event) {
5371
5468
  if (execution.status != "RUNNING") {
5372
5469
  console.log({
5373
5470
  notice: "Runner already finished",
5471
+ runnerName: input.runnerName,
5374
5472
  input
5375
5473
  });
5376
5474
  continue;
@@ -5391,6 +5489,7 @@ async function handler2(event) {
5391
5489
  if (!runner) {
5392
5490
  console.log({
5393
5491
  notice: "Runner not running yet",
5492
+ runnerName: input.runnerName,
5394
5493
  input
5395
5494
  });
5396
5495
  retryLater();
@@ -5399,6 +5498,8 @@ async function handler2(event) {
5399
5498
  if (runner.busy) {
5400
5499
  console.log({
5401
5500
  notice: "Runner is not idle",
5501
+ runnerId: runner.id,
5502
+ runnerName: input.runnerName,
5402
5503
  input
5403
5504
  });
5404
5505
  retryLater();
@@ -5412,17 +5513,27 @@ async function handler2(event) {
5412
5513
  const now = /* @__PURE__ */ new Date();
5413
5514
  const diffMs = now.getTime() - startedDate.getTime();
5414
5515
  console.log({
5415
- notice: `Runner ${input.runnerName} started ${diffMs / 1e3} seconds ago`,
5516
+ notice: "Runner is idle",
5517
+ runnerId: runner.id,
5518
+ runnerName: input.runnerName,
5519
+ idleSeconds: diffMs / 1e3,
5416
5520
  input
5417
5521
  });
5418
5522
  if (diffMs > 1e3 * input.maxIdleSeconds) {
5419
5523
  console.log({
5420
- notice: `Runner ${input.runnerName} is idle for too long`,
5524
+ notice: "Runner is idle for too long",
5525
+ runnerId: runner.id,
5526
+ runnerName: input.runnerName,
5527
+ idleSeconds: diffMs / 1e3,
5528
+ maxIdleSeconds: input.maxIdleSeconds,
5421
5529
  input
5422
5530
  });
5423
5531
  try {
5424
5532
  console.log({
5425
- notice: `Stopping step function ${input.executionArn}...`,
5533
+ notice: "Stopping step function",
5534
+ executionArn: input.executionArn,
5535
+ runnerId: runner.id,
5536
+ runnerName: input.runnerName,
5426
5537
  input
5427
5538
  });
5428
5539
  await sfn.send(new import_client_sfn.StopExecutionCommand({
@@ -5432,7 +5543,11 @@ async function handler2(event) {
5432
5543
  }));
5433
5544
  } catch (e) {
5434
5545
  console.error({
5435
- notice: `Failed to stop step function ${input.executionArn}: ${e}`,
5546
+ notice: "Failed to stop step function",
5547
+ executionArn: input.executionArn,
5548
+ runnerId: runner.id,
5549
+ runnerName: input.runnerName,
5550
+ error: e,
5436
5551
  input
5437
5552
  });
5438
5553
  retryLater();
@@ -5440,13 +5555,18 @@ async function handler2(event) {
5440
5555
  }
5441
5556
  try {
5442
5557
  console.log({
5443
- notice: `Deleting runner ${runner.id}...`,
5558
+ notice: "Deleting runner",
5559
+ runnerId: runner.id,
5560
+ runnerName: input.runnerName,
5444
5561
  input
5445
5562
  });
5446
5563
  await deleteRunner(octokit, secrets.runnerLevel, input.owner, input.repo, runner.id);
5447
5564
  } catch (e) {
5448
5565
  console.error({
5449
- notice: `Failed to delete runner ${runner.id}: ${e}`,
5566
+ notice: "Failed to delete runner",
5567
+ runnerId: runner.id,
5568
+ runnerName: input.runnerName,
5569
+ error: e,
5450
5570
  input
5451
5571
  });
5452
5572
  retryLater();
@@ -5462,6 +5582,8 @@ async function handler2(event) {
5462
5582
  if (!found) {
5463
5583
  console.error({
5464
5584
  notice: "No `cdkghr:started:xxx` label found???",
5585
+ runnerId: runner.id,
5586
+ runnerName: input.runnerName,
5465
5587
  input
5466
5588
  });
5467
5589
  retryLater();
@@ -197,7 +197,7 @@ async function handler(event, _context) {
197
197
  } catch (e) {
198
198
  console.error({
199
199
  notice: "Failed to delete Image Builder resources",
200
- error: `${e}`
200
+ error: e
201
201
  });
202
202
  await customResourceRespond(event, "FAILED", e.message || "Internal Error", "FAIL", {});
203
203
  }
@@ -105,7 +105,7 @@ async function handler(event, context) {
105
105
  } catch (e) {
106
106
  console.error({
107
107
  notice: "Failed to start CodeBuild project",
108
- error: `${e}`
108
+ error: e
109
109
  });
110
110
  await customResourceRespond(event, "FAILED", e.message || "Internal Error", context.logStreamName, {});
111
111
  }
@@ -184,7 +184,7 @@ async function handler(event, context) {
184
184
  } catch (e) {
185
185
  console.error({
186
186
  notice: "Failed to resolve AMI root device",
187
- error: `${e}`
187
+ error: e
188
188
  });
189
189
  await customResourceRespond(event, "FAILED", e.message || "Internal Error", context.logStreamName, {});
190
190
  }