@cloudsnorkel/cdk-github-runners 0.14.24 → 0.15.1

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 (142) hide show
  1. package/.jsii +5953 -602
  2. package/API.md +1349 -115
  3. package/README.md +53 -1
  4. package/assets/delete-failed-runner.lambda/index.js +122 -9
  5. package/assets/idle-runner-repear.lambda/index.js +153 -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 +118 -8
  11. package/assets/status.lambda/index.js +121 -8
  12. package/assets/token-retriever.lambda/index.js +121 -8
  13. package/assets/warm-runner-manager.lambda/index.js +5909 -0
  14. package/assets/webhook-handler.lambda/index.js +126 -11
  15. package/assets/webhook-redelivery.lambda/index.js +139 -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 +18 -2
  39. package/lib/providers/codebuild.js +15 -4
  40. package/lib/providers/common.d.ts +47 -3
  41. package/lib/providers/common.js +29 -5
  42. package/lib/providers/composite.js +14 -19
  43. package/lib/providers/ec2.d.ts +9 -2
  44. package/lib/providers/ec2.js +84 -42
  45. package/lib/providers/ecs.d.ts +19 -2
  46. package/lib/providers/ecs.js +49 -44
  47. package/lib/providers/fargate.d.ts +2 -2
  48. package/lib/providers/fargate.js +19 -36
  49. package/lib/providers/lambda.d.ts +2 -2
  50. package/lib/providers/lambda.js +3 -3
  51. package/lib/runner.d.ts +31 -3
  52. package/lib/runner.js +171 -46
  53. package/lib/secrets.js +1 -1
  54. package/lib/setup.lambda.js +2 -2
  55. package/lib/utils.d.ts +10 -1
  56. package/lib/utils.js +15 -1
  57. package/lib/warm-runner-manager-function.d.ts +18 -0
  58. package/lib/warm-runner-manager-function.js +24 -0
  59. package/lib/warm-runner-manager.lambda.d.ts +41 -0
  60. package/lib/warm-runner-manager.lambda.js +487 -0
  61. package/lib/warm-runner.d.ts +155 -0
  62. package/lib/warm-runner.js +217 -0
  63. package/lib/webhook-handler.lambda.js +5 -3
  64. package/lib/webhook-redelivery.lambda.js +17 -16
  65. package/lib/webhook.d.ts +4 -0
  66. package/lib/webhook.js +2 -1
  67. package/node_modules/cron-parser/LICENSE +21 -0
  68. package/node_modules/cron-parser/README.md +408 -0
  69. package/node_modules/cron-parser/dist/CronDate.js +518 -0
  70. package/node_modules/cron-parser/dist/CronExpression.js +520 -0
  71. package/node_modules/cron-parser/dist/CronExpressionParser.js +382 -0
  72. package/node_modules/cron-parser/dist/CronFieldCollection.js +371 -0
  73. package/node_modules/cron-parser/dist/CronFileParser.js +109 -0
  74. package/node_modules/cron-parser/dist/fields/CronDayOfMonth.js +44 -0
  75. package/node_modules/cron-parser/dist/fields/CronDayOfWeek.js +51 -0
  76. package/node_modules/cron-parser/dist/fields/CronField.js +214 -0
  77. package/node_modules/cron-parser/dist/fields/CronHour.js +40 -0
  78. package/node_modules/cron-parser/dist/fields/CronMinute.js +40 -0
  79. package/node_modules/cron-parser/dist/fields/CronMonth.js +44 -0
  80. package/node_modules/cron-parser/dist/fields/CronSecond.js +40 -0
  81. package/node_modules/cron-parser/dist/fields/index.js +24 -0
  82. package/node_modules/cron-parser/dist/fields/types.js +2 -0
  83. package/node_modules/cron-parser/dist/index.js +31 -0
  84. package/node_modules/cron-parser/dist/types/CronDate.d.ts +288 -0
  85. package/node_modules/cron-parser/dist/types/CronExpression.d.ts +118 -0
  86. package/node_modules/cron-parser/dist/types/CronExpressionParser.d.ts +70 -0
  87. package/node_modules/cron-parser/dist/types/CronFieldCollection.d.ts +153 -0
  88. package/node_modules/cron-parser/dist/types/CronFileParser.d.ts +30 -0
  89. package/node_modules/cron-parser/dist/types/fields/CronDayOfMonth.d.ts +25 -0
  90. package/node_modules/cron-parser/dist/types/fields/CronDayOfWeek.d.ts +30 -0
  91. package/node_modules/cron-parser/dist/types/fields/CronField.d.ts +130 -0
  92. package/node_modules/cron-parser/dist/types/fields/CronHour.d.ts +23 -0
  93. package/node_modules/cron-parser/dist/types/fields/CronMinute.d.ts +23 -0
  94. package/node_modules/cron-parser/dist/types/fields/CronMonth.d.ts +24 -0
  95. package/node_modules/cron-parser/dist/types/fields/CronSecond.d.ts +23 -0
  96. package/node_modules/cron-parser/dist/types/fields/index.d.ts +8 -0
  97. package/node_modules/cron-parser/dist/types/fields/types.d.ts +18 -0
  98. package/node_modules/cron-parser/dist/types/index.d.ts +8 -0
  99. package/node_modules/cron-parser/dist/types/utils/random.d.ts +10 -0
  100. package/node_modules/cron-parser/dist/utils/random.js +38 -0
  101. package/node_modules/cron-parser/package.json +117 -0
  102. package/node_modules/luxon/LICENSE.md +7 -0
  103. package/node_modules/luxon/README.md +55 -0
  104. package/node_modules/luxon/build/amd/luxon.js +8741 -0
  105. package/node_modules/luxon/build/amd/luxon.js.map +1 -0
  106. package/node_modules/luxon/build/cjs-browser/luxon.js +8739 -0
  107. package/node_modules/luxon/build/cjs-browser/luxon.js.map +1 -0
  108. package/node_modules/luxon/build/es6/luxon.mjs +8133 -0
  109. package/node_modules/luxon/build/es6/luxon.mjs.map +1 -0
  110. package/node_modules/luxon/build/global/luxon.js +8744 -0
  111. package/node_modules/luxon/build/global/luxon.js.map +1 -0
  112. package/node_modules/luxon/build/global/luxon.min.js +1 -0
  113. package/node_modules/luxon/build/global/luxon.min.js.map +1 -0
  114. package/node_modules/luxon/build/node/luxon.js +7792 -0
  115. package/node_modules/luxon/build/node/luxon.js.map +1 -0
  116. package/node_modules/luxon/package.json +87 -0
  117. package/node_modules/luxon/src/datetime.js +2603 -0
  118. package/node_modules/luxon/src/duration.js +1009 -0
  119. package/node_modules/luxon/src/errors.js +61 -0
  120. package/node_modules/luxon/src/impl/conversions.js +206 -0
  121. package/node_modules/luxon/src/impl/diff.js +95 -0
  122. package/node_modules/luxon/src/impl/digits.js +94 -0
  123. package/node_modules/luxon/src/impl/english.js +233 -0
  124. package/node_modules/luxon/src/impl/formats.js +176 -0
  125. package/node_modules/luxon/src/impl/formatter.js +434 -0
  126. package/node_modules/luxon/src/impl/invalid.js +14 -0
  127. package/node_modules/luxon/src/impl/locale.js +569 -0
  128. package/node_modules/luxon/src/impl/regexParser.js +335 -0
  129. package/node_modules/luxon/src/impl/tokenParser.js +505 -0
  130. package/node_modules/luxon/src/impl/util.js +330 -0
  131. package/node_modules/luxon/src/impl/zoneUtil.js +34 -0
  132. package/node_modules/luxon/src/info.js +205 -0
  133. package/node_modules/luxon/src/interval.js +669 -0
  134. package/node_modules/luxon/src/luxon.js +26 -0
  135. package/node_modules/luxon/src/package.json +4 -0
  136. package/node_modules/luxon/src/settings.js +180 -0
  137. package/node_modules/luxon/src/zone.js +97 -0
  138. package/node_modules/luxon/src/zones/IANAZone.js +235 -0
  139. package/node_modules/luxon/src/zones/fixedOffsetZone.js +150 -0
  140. package/node_modules/luxon/src/zones/invalidZone.js +53 -0
  141. package/node_modules/luxon/src/zones/systemZone.js +61 -0
  142. 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)
@@ -53,7 +54,7 @@ A runner provider creates compute resources on-demand and uses [actions/runner][
53
54
 
54
55
  | | EC2 | CodeBuild | Fargate | ECS | Lambda |
55
56
  |------------------|-------------------|----------------------------|----------------|----------------|---------------|
56
- | **Time limit** | Unlimited | 8 hours | Unlimited | Unlimited | 15 minutes |
57
+ | **Time limit** | Unlimited | 36 hours (default 1 hour) | Unlimited | Unlimited | 15 minutes |
57
58
  | **vCPUs** | Unlimited | 2, 4, 8, or 72 | 0.25 to 4 | Unlimited | 1 to 6 |
58
59
  | **RAM** | Unlimited | 3gb, 7gb, 15gb, or 145gb | 512mb to 30gb | Unlimited | 128mb to 10gb |
59
60
  | **Storage** | Unlimited | 50gb to 824gb | 20gb to 200gb | Unlimited | Up to 10gb |
@@ -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,115 @@ 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, featureCache, 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" && noiseValue.test(value2);
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
+ featureCache = /* @__PURE__ */ new Map();
644
+ isContextSourceSupported = () => {
645
+ const parseFingerprint = JSON.parse.toString();
646
+ if (featureCache.has(parseFingerprint)) {
647
+ return featureCache.get(parseFingerprint);
648
+ }
649
+ try {
650
+ const result = JSON.parse(
651
+ "1",
652
+ (_, __, context) => !!context?.source && context.source === "1"
653
+ );
654
+ featureCache.set(parseFingerprint, result);
655
+ return result;
656
+ } catch {
657
+ featureCache.set(parseFingerprint, false);
658
+ return false;
659
+ }
660
+ };
661
+ convertMarkedBigIntsReviver = (key, value, context, userReviver) => {
662
+ const isCustomFormatBigInt = typeof value === "string" && customFormat.test(value);
663
+ if (isCustomFormatBigInt) return BigInt(value.slice(0, -1));
664
+ const isNoiseValue = typeof value === "string" && noiseValue.test(value);
665
+ if (isNoiseValue) return value.slice(0, -1);
666
+ if (typeof userReviver !== "function") return value;
667
+ return userReviver(key, value, context);
668
+ };
669
+ JSONParseV2 = (text, reviver) => {
670
+ return JSON.parse(text, (key, value, context) => {
671
+ const isBigNumber = typeof value === "number" && (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER);
672
+ const isInt = context && intRegex.test(context.source);
673
+ const isBigInt = isBigNumber && isInt;
674
+ if (isBigInt) return BigInt(context.source);
675
+ if (typeof reviver !== "function") return value;
676
+ return reviver(key, value, context);
677
+ });
678
+ };
679
+ MAX_INT = Number.MAX_SAFE_INTEGER.toString();
680
+ MAX_DIGITS = MAX_INT.length;
681
+ stringsOrLargeNumbers = /"(?:\\.|[^"])*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g;
682
+ noiseValueWithQuotes = /^"-?\d+n+"$/;
683
+ JSONParse = (text, reviver) => {
684
+ if (!text) return originalParse(text, reviver);
685
+ if (isContextSourceSupported()) return JSONParseV2(text, reviver);
686
+ const serializedData = text.replace(
687
+ stringsOrLargeNumbers,
688
+ (text2, digits, fractional, exponential) => {
689
+ const isString = text2[0] === '"';
690
+ const isNoise = isString && noiseValueWithQuotes.test(text2);
691
+ if (isNoise) return text2.substring(0, text2.length - 1) + 'n"';
692
+ const isFractionalOrExponential = fractional || exponential;
693
+ const isLessThanMaxSafeInt = digits && (digits.length < MAX_DIGITS || digits.length === MAX_DIGITS && digits <= MAX_INT);
694
+ if (isString || isFractionalOrExponential || isLessThanMaxSafeInt)
695
+ return text2;
696
+ return '"' + text2 + 'n"';
697
+ }
698
+ );
699
+ return originalParse(
700
+ serializedData,
701
+ (key, value, context) => convertMarkedBigIntsReviver(key, value, context, reviver)
702
+ );
703
+ };
704
+ }
705
+ });
706
+
598
707
  // node_modules/@octokit/request-error/dist-src/index.js
599
708
  var RequestError;
600
709
  var init_dist_src = __esm({
@@ -658,7 +767,7 @@ async function fetchWrapper(requestOptions) {
658
767
  }
659
768
  const log = requestOptions.request?.log || console;
660
769
  const parseSuccessResponseBody = requestOptions.request?.parseSuccessResponseBody !== false;
661
- const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSON.stringify(requestOptions.body) : requestOptions.body;
770
+ const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSONStringify(requestOptions.body) : requestOptions.body;
662
771
  const requestHeaders = Object.fromEntries(
663
772
  Object.entries(requestOptions.headers).map(([name, value]) => [
664
773
  name,
@@ -757,7 +866,7 @@ async function getResponseData(response) {
757
866
  let text = "";
758
867
  try {
759
868
  text = await response.text();
760
- return JSON.parse(text);
869
+ return JSONParse(text);
761
870
  } catch (err) {
762
871
  return text;
763
872
  }
@@ -816,8 +925,9 @@ var init_dist_bundle2 = __esm({
816
925
  init_dist_bundle();
817
926
  init_universal_user_agent();
818
927
  import_fast_content_type_parse = __toESM(require_fast_content_type_parse(), 1);
928
+ init_json_with_bigint();
819
929
  init_dist_src();
820
- VERSION2 = "10.0.7";
930
+ VERSION2 = "10.0.8";
821
931
  defaults_default = {
822
932
  headers: {
823
933
  "user-agent": `octokit-request.js/${VERSION2} ${getUserAgent()}`
@@ -5040,6 +5150,8 @@ function requiresAppAuth(url) {
5040
5150
  }
5041
5151
  function isNotTimeSkewError(error) {
5042
5152
  return !(error.message.match(
5153
+ /'Expiration time' claim \('exp'\) is too far in the future/
5154
+ ) || error.message.match(
5043
5155
  /'Expiration time' claim \('exp'\) must be a numeric value representing the future time at which the assertion expires/
5044
5156
  ) || error.message.match(
5045
5157
  /'Issued at' claim \('iat'\) must be an Integer representing the time that the assertion was issued/
@@ -5201,11 +5313,12 @@ var init_dist_node = __esm({
5201
5313
  "/marketplace_listing/stubbed/plans/{plan_id}/accounts",
5202
5314
  "/orgs/{org}/installation",
5203
5315
  "/repos/{owner}/{repo}/installation",
5204
- "/users/{username}/installation"
5316
+ "/users/{username}/installation",
5317
+ "/enterprises/{enterprise}/installation"
5205
5318
  ];
5206
5319
  REGEX = routeMatcher(PATHS);
5207
5320
  FIVE_SECONDS_IN_MS = 5 * 1e3;
5208
- VERSION12 = "8.1.2";
5321
+ VERSION12 = "8.2.0";
5209
5322
  }
5210
5323
  });
5211
5324
 
@@ -5224,11 +5337,11 @@ var import_client_secrets_manager = require("@aws-sdk/client-secrets-manager");
5224
5337
  var sm = new import_client_secrets_manager.SecretsManagerClient();
5225
5338
  async function getSecretValue(arn) {
5226
5339
  if (!arn) {
5227
- throw new Error("Missing secret ARN");
5340
+ throw new Error("Missing secret ARN. Check the Lambda configuration and required environment variables.");
5228
5341
  }
5229
5342
  const secret = await sm.send(new import_client_secrets_manager.GetSecretValueCommand({ SecretId: arn }));
5230
5343
  if (!secret.SecretString) {
5231
- throw new Error(`No SecretString in ${arn}`);
5344
+ 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
5345
  }
5233
5346
  return secret.SecretString;
5234
5347
  }
@@ -5402,7 +5515,7 @@ async function handler2(event) {
5402
5515
  repo: event.repo,
5403
5516
  runnerId: runner.id,
5404
5517
  runnerName: event.runnerName,
5405
- error: `${e}`
5518
+ error: e
5406
5519
  });
5407
5520
  }
5408
5521
  }
@@ -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,115 @@ 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, featureCache, 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" && noiseValue.test(value2);
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
+ featureCache = /* @__PURE__ */ new Map();
644
+ isContextSourceSupported = () => {
645
+ const parseFingerprint = JSON.parse.toString();
646
+ if (featureCache.has(parseFingerprint)) {
647
+ return featureCache.get(parseFingerprint);
648
+ }
649
+ try {
650
+ const result = JSON.parse(
651
+ "1",
652
+ (_, __, context) => !!context?.source && context.source === "1"
653
+ );
654
+ featureCache.set(parseFingerprint, result);
655
+ return result;
656
+ } catch {
657
+ featureCache.set(parseFingerprint, false);
658
+ return false;
659
+ }
660
+ };
661
+ convertMarkedBigIntsReviver = (key, value, context, userReviver) => {
662
+ const isCustomFormatBigInt = typeof value === "string" && customFormat.test(value);
663
+ if (isCustomFormatBigInt) return BigInt(value.slice(0, -1));
664
+ const isNoiseValue = typeof value === "string" && noiseValue.test(value);
665
+ if (isNoiseValue) return value.slice(0, -1);
666
+ if (typeof userReviver !== "function") return value;
667
+ return userReviver(key, value, context);
668
+ };
669
+ JSONParseV2 = (text, reviver) => {
670
+ return JSON.parse(text, (key, value, context) => {
671
+ const isBigNumber = typeof value === "number" && (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER);
672
+ const isInt = context && intRegex.test(context.source);
673
+ const isBigInt = isBigNumber && isInt;
674
+ if (isBigInt) return BigInt(context.source);
675
+ if (typeof reviver !== "function") return value;
676
+ return reviver(key, value, context);
677
+ });
678
+ };
679
+ MAX_INT = Number.MAX_SAFE_INTEGER.toString();
680
+ MAX_DIGITS = MAX_INT.length;
681
+ stringsOrLargeNumbers = /"(?:\\.|[^"])*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g;
682
+ noiseValueWithQuotes = /^"-?\d+n+"$/;
683
+ JSONParse = (text, reviver) => {
684
+ if (!text) return originalParse(text, reviver);
685
+ if (isContextSourceSupported()) return JSONParseV2(text, reviver);
686
+ const serializedData = text.replace(
687
+ stringsOrLargeNumbers,
688
+ (text2, digits, fractional, exponential) => {
689
+ const isString = text2[0] === '"';
690
+ const isNoise = isString && noiseValueWithQuotes.test(text2);
691
+ if (isNoise) return text2.substring(0, text2.length - 1) + 'n"';
692
+ const isFractionalOrExponential = fractional || exponential;
693
+ const isLessThanMaxSafeInt = digits && (digits.length < MAX_DIGITS || digits.length === MAX_DIGITS && digits <= MAX_INT);
694
+ if (isString || isFractionalOrExponential || isLessThanMaxSafeInt)
695
+ return text2;
696
+ return '"' + text2 + 'n"';
697
+ }
698
+ );
699
+ return originalParse(
700
+ serializedData,
701
+ (key, value, context) => convertMarkedBigIntsReviver(key, value, context, reviver)
702
+ );
703
+ };
704
+ }
705
+ });
706
+
598
707
  // node_modules/@octokit/request-error/dist-src/index.js
599
708
  var RequestError;
600
709
  var init_dist_src = __esm({
@@ -658,7 +767,7 @@ async function fetchWrapper(requestOptions) {
658
767
  }
659
768
  const log = requestOptions.request?.log || console;
660
769
  const parseSuccessResponseBody = requestOptions.request?.parseSuccessResponseBody !== false;
661
- const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSON.stringify(requestOptions.body) : requestOptions.body;
770
+ const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSONStringify(requestOptions.body) : requestOptions.body;
662
771
  const requestHeaders = Object.fromEntries(
663
772
  Object.entries(requestOptions.headers).map(([name, value]) => [
664
773
  name,
@@ -757,7 +866,7 @@ async function getResponseData(response) {
757
866
  let text = "";
758
867
  try {
759
868
  text = await response.text();
760
- return JSON.parse(text);
869
+ return JSONParse(text);
761
870
  } catch (err) {
762
871
  return text;
763
872
  }
@@ -816,8 +925,9 @@ var init_dist_bundle2 = __esm({
816
925
  init_dist_bundle();
817
926
  init_universal_user_agent();
818
927
  import_fast_content_type_parse = __toESM(require_fast_content_type_parse(), 1);
928
+ init_json_with_bigint();
819
929
  init_dist_src();
820
- VERSION2 = "10.0.7";
930
+ VERSION2 = "10.0.8";
821
931
  defaults_default = {
822
932
  headers: {
823
933
  "user-agent": `octokit-request.js/${VERSION2} ${getUserAgent()}`
@@ -5040,6 +5150,8 @@ function requiresAppAuth(url) {
5040
5150
  }
5041
5151
  function isNotTimeSkewError(error) {
5042
5152
  return !(error.message.match(
5153
+ /'Expiration time' claim \('exp'\) is too far in the future/
5154
+ ) || error.message.match(
5043
5155
  /'Expiration time' claim \('exp'\) must be a numeric value representing the future time at which the assertion expires/
5044
5156
  ) || error.message.match(
5045
5157
  /'Issued at' claim \('iat'\) must be an Integer representing the time that the assertion was issued/
@@ -5201,11 +5313,12 @@ var init_dist_node = __esm({
5201
5313
  "/marketplace_listing/stubbed/plans/{plan_id}/accounts",
5202
5314
  "/orgs/{org}/installation",
5203
5315
  "/repos/{owner}/{repo}/installation",
5204
- "/users/{username}/installation"
5316
+ "/users/{username}/installation",
5317
+ "/enterprises/{enterprise}/installation"
5205
5318
  ];
5206
5319
  REGEX = routeMatcher(PATHS);
5207
5320
  FIVE_SECONDS_IN_MS = 5 * 1e3;
5208
- VERSION12 = "8.1.2";
5321
+ VERSION12 = "8.2.0";
5209
5322
  }
5210
5323
  });
5211
5324
 
@@ -5225,11 +5338,11 @@ var import_client_secrets_manager = require("@aws-sdk/client-secrets-manager");
5225
5338
  var sm = new import_client_secrets_manager.SecretsManagerClient();
5226
5339
  async function getSecretValue(arn) {
5227
5340
  if (!arn) {
5228
- throw new Error("Missing secret ARN");
5341
+ throw new Error("Missing secret ARN. Check the Lambda configuration and required environment variables.");
5229
5342
  }
5230
5343
  const secret = await sm.send(new import_client_secrets_manager.GetSecretValueCommand({ SecretId: arn }));
5231
5344
  if (!secret.SecretString) {
5232
- throw new Error(`No SecretString in ${arn}`);
5345
+ 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
5346
  }
5234
5347
  return secret.SecretString;
5235
5348
  }
@@ -5364,6 +5477,7 @@ async function handler2(event) {
5364
5477
  const input = JSON.parse(record.body);
5365
5478
  console.log({
5366
5479
  notice: "Checking runner",
5480
+ runnerName: input.runnerName,
5367
5481
  input
5368
5482
  });
5369
5483
  const retryLater = () => result.batchItemFailures.push({ itemIdentifier: record.messageId });
@@ -5371,6 +5485,7 @@ async function handler2(event) {
5371
5485
  if (execution.status != "RUNNING") {
5372
5486
  console.log({
5373
5487
  notice: "Runner already finished",
5488
+ runnerName: input.runnerName,
5374
5489
  input
5375
5490
  });
5376
5491
  continue;
@@ -5391,6 +5506,7 @@ async function handler2(event) {
5391
5506
  if (!runner) {
5392
5507
  console.log({
5393
5508
  notice: "Runner not running yet",
5509
+ runnerName: input.runnerName,
5394
5510
  input
5395
5511
  });
5396
5512
  retryLater();
@@ -5399,6 +5515,8 @@ async function handler2(event) {
5399
5515
  if (runner.busy) {
5400
5516
  console.log({
5401
5517
  notice: "Runner is not idle",
5518
+ runnerId: runner.id,
5519
+ runnerName: input.runnerName,
5402
5520
  input
5403
5521
  });
5404
5522
  retryLater();
@@ -5412,17 +5530,27 @@ async function handler2(event) {
5412
5530
  const now = /* @__PURE__ */ new Date();
5413
5531
  const diffMs = now.getTime() - startedDate.getTime();
5414
5532
  console.log({
5415
- notice: `Runner ${input.runnerName} started ${diffMs / 1e3} seconds ago`,
5533
+ notice: "Runner is idle",
5534
+ runnerId: runner.id,
5535
+ runnerName: input.runnerName,
5536
+ idleSeconds: diffMs / 1e3,
5416
5537
  input
5417
5538
  });
5418
5539
  if (diffMs > 1e3 * input.maxIdleSeconds) {
5419
5540
  console.log({
5420
- notice: `Runner ${input.runnerName} is idle for too long`,
5541
+ notice: "Runner is idle for too long",
5542
+ runnerId: runner.id,
5543
+ runnerName: input.runnerName,
5544
+ idleSeconds: diffMs / 1e3,
5545
+ maxIdleSeconds: input.maxIdleSeconds,
5421
5546
  input
5422
5547
  });
5423
5548
  try {
5424
5549
  console.log({
5425
- notice: `Stopping step function ${input.executionArn}...`,
5550
+ notice: "Stopping step function",
5551
+ executionArn: input.executionArn,
5552
+ runnerId: runner.id,
5553
+ runnerName: input.runnerName,
5426
5554
  input
5427
5555
  });
5428
5556
  await sfn.send(new import_client_sfn.StopExecutionCommand({
@@ -5432,7 +5560,11 @@ async function handler2(event) {
5432
5560
  }));
5433
5561
  } catch (e) {
5434
5562
  console.error({
5435
- notice: `Failed to stop step function ${input.executionArn}: ${e}`,
5563
+ notice: "Failed to stop step function",
5564
+ executionArn: input.executionArn,
5565
+ runnerId: runner.id,
5566
+ runnerName: input.runnerName,
5567
+ error: e,
5436
5568
  input
5437
5569
  });
5438
5570
  retryLater();
@@ -5440,13 +5572,18 @@ async function handler2(event) {
5440
5572
  }
5441
5573
  try {
5442
5574
  console.log({
5443
- notice: `Deleting runner ${runner.id}...`,
5575
+ notice: "Deleting runner",
5576
+ runnerId: runner.id,
5577
+ runnerName: input.runnerName,
5444
5578
  input
5445
5579
  });
5446
5580
  await deleteRunner(octokit, secrets.runnerLevel, input.owner, input.repo, runner.id);
5447
5581
  } catch (e) {
5448
5582
  console.error({
5449
- notice: `Failed to delete runner ${runner.id}: ${e}`,
5583
+ notice: "Failed to delete runner",
5584
+ runnerId: runner.id,
5585
+ runnerName: input.runnerName,
5586
+ error: e,
5450
5587
  input
5451
5588
  });
5452
5589
  retryLater();
@@ -5462,6 +5599,8 @@ async function handler2(event) {
5462
5599
  if (!found) {
5463
5600
  console.error({
5464
5601
  notice: "No `cdkghr:started:xxx` label found???",
5602
+ runnerId: runner.id,
5603
+ runnerName: input.runnerName,
5465
5604
  input
5466
5605
  });
5467
5606
  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
  }