cloudsnorkel.cdk-github-runners 0.14.15__tar.gz → 0.14.19__tar.gz

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 (17) hide show
  1. {cloudsnorkel_cdk_github_runners-0.14.15/src/cloudsnorkel.cdk_github_runners.egg-info → cloudsnorkel_cdk_github_runners-0.14.19}/PKG-INFO +189 -4
  2. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/README.md +187 -2
  3. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/setup.py +3 -3
  4. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/src/cloudsnorkel/cdk_github_runners/__init__.py +2289 -1084
  5. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/src/cloudsnorkel/cdk_github_runners/_jsii/__init__.py +2 -2
  6. cloudsnorkel_cdk_github_runners-0.14.19/src/cloudsnorkel/cdk_github_runners/_jsii/cdk-github-runners@0.14.19.jsii.tgz +0 -0
  7. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19/src/cloudsnorkel.cdk_github_runners.egg-info}/PKG-INFO +189 -4
  8. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/src/cloudsnorkel.cdk_github_runners.egg-info/SOURCES.txt +1 -1
  9. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/src/cloudsnorkel.cdk_github_runners.egg-info/requires.txt +1 -1
  10. cloudsnorkel_cdk_github_runners-0.14.15/src/cloudsnorkel/cdk_github_runners/_jsii/cdk-github-runners@0.14.15.jsii.tgz +0 -0
  11. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/LICENSE +0 -0
  12. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/MANIFEST.in +0 -0
  13. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/pyproject.toml +0 -0
  14. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/setup.cfg +0 -0
  15. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/src/cloudsnorkel/cdk_github_runners/py.typed +0 -0
  16. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/src/cloudsnorkel.cdk_github_runners.egg-info/dependency_links.txt +0 -0
  17. {cloudsnorkel_cdk_github_runners-0.14.15 → cloudsnorkel_cdk_github_runners-0.14.19}/src/cloudsnorkel.cdk_github_runners.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cloudsnorkel.cdk-github-runners
3
- Version: 0.14.15
3
+ Version: 0.14.19
4
4
  Summary: CDK construct to create GitHub Actions self-hosted runners. Creates ephemeral runners on demand. Easy to deploy and highly customizable.
5
5
  Home-page: https://github.com/CloudSnorkel/cdk-github-runners.git
6
6
  Author: Amir Szekely<amir@cloudsnorkel.com>
@@ -21,7 +21,7 @@ Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  Requires-Dist: aws-cdk-lib<3.0.0,>=2.155.0
23
23
  Requires-Dist: constructs<11.0.0,>=10.0.5
24
- Requires-Dist: jsii<2.0.0,>=1.120.0
24
+ Requires-Dist: jsii<2.0.0,>=1.124.0
25
25
  Requires-Dist: publication>=0.0.3
26
26
  Requires-Dist: typeguard==2.13.3
27
27
 
@@ -350,11 +350,196 @@ new GitHubRunners(this, 'runners', {
350
350
  });
351
351
  ```
352
352
 
353
+ ### Composite Providers
354
+
355
+ Composite providers allow you to combine multiple runner providers with different strategies. There are two types:
356
+
357
+ **Fallback Strategy**: Try providers in order until one succeeds. Useful for trying spot instances first, then falling back to on-demand if spot capacity is unavailable.
358
+
359
+ ```python
360
+ // Try spot instances first, fall back to on-demand if spot is unavailable
361
+ const ecsFallback = CompositeProvider.fallback(this, 'ECS Fallback', [
362
+ new EcsRunnerProvider(this, 'ECS Spot', {
363
+ labels: ['ecs', 'linux', 'x64'],
364
+ spot: true,
365
+ // ... other config
366
+ }),
367
+ new EcsRunnerProvider(this, 'ECS On-Demand', {
368
+ labels: ['ecs', 'linux', 'x64'],
369
+ spot: false,
370
+ // ... other config
371
+ }),
372
+ ]);
373
+
374
+ new GitHubRunners(this, 'runners', {
375
+ providers: [ecsFallback],
376
+ });
377
+ ```
378
+
379
+ **Weighted Distribution Strategy**: Randomly select a provider based on weights. Useful for distributing load across multiple availability zones or instance types.
380
+
381
+ ```python
382
+ // Distribute 60% of traffic to AZ-1, 40% to AZ-2
383
+ const distributedProvider = CompositeProvider.distribute(this, 'Fargate Distribution', [
384
+ {
385
+ weight: 3, // 3/(3+2) = 60%
386
+ provider: new FargateRunnerProvider(this, 'Fargate AZ-1', {
387
+ labels: ['fargate', 'linux', 'x64'],
388
+ subnetSelection: vpc.selectSubnets({
389
+ availabilityZones: [vpc.availabilityZones[0]],
390
+ }),
391
+ // ... other config
392
+ }),
393
+ },
394
+ {
395
+ weight: 2, // 2/(3+2) = 40%
396
+ provider: new FargateRunnerProvider(this, 'Fargate AZ-2', {
397
+ labels: ['fargate', 'linux', 'x64'],
398
+ subnetSelection: vpc.selectSubnets({
399
+ availabilityZones: [vpc.availabilityZones[1]],
400
+ }),
401
+ // ... other config
402
+ }),
403
+ },
404
+ ]);
405
+
406
+ new GitHubRunners(this, 'runners', {
407
+ providers: [distributedProvider],
408
+ });
409
+ ```
410
+
411
+ **Important**: All providers in a composite must have the exact same labels. This ensures any provisioned runner can match the labels requested by the GitHub workflow job.
412
+
413
+ ### Custom Provider Selection
414
+
415
+ By default, providers are selected based on label matching: the first provider that has all the labels requested by the job is selected. You can customize this behavior using a provider selector Lambda function to:
416
+
417
+ * Filter out certain jobs (prevent runner provisioning)
418
+ * Dynamically select a provider based on job characteristics (repository, branch, time of day, etc.)
419
+ * Customize labels for the runner (add, remove, or modify labels dynamically)
420
+
421
+ The selector function receives the full GitHub webhook payload, a map of all available providers and their labels, and the default provider/labels that would have been selected. It returns the provider to use (or `undefined` to skip runner creation) and the labels to assign to the runner.
422
+
423
+ **Example: Route jobs to different providers based on repository**
424
+
425
+ ```python
426
+ import { ComputeType } from 'aws-cdk-lib/aws-codebuild';
427
+ import { Function, Code, Runtime } from 'aws-cdk-lib/aws-lambda';
428
+ import { GitHubRunners, CodeBuildRunnerProvider } from '@cloudsnorkel/cdk-github-runners';
429
+
430
+ const defaultProvider = new CodeBuildRunnerProvider(this, 'default', {
431
+ labels: ['custom-runner', 'default'],
432
+ });
433
+ const productionProvider = new CodeBuildRunnerProvider(this, 'production', {
434
+ labels: ['custom-runner', 'production'],
435
+ computeType: ComputeType.LARGE,
436
+ });
437
+
438
+ const providerSelector = new Function(this, 'provider-selector', {
439
+ runtime: Runtime.NODEJS_LATEST,
440
+ handler: 'index.handler',
441
+ code: Code.fromInline(`
442
+ exports.handler = async (event) => {
443
+ const { payload, providers, defaultProvider, defaultLabels } = event;
444
+
445
+ // Route production repos to dedicated provider
446
+ if (payload.repository.name.includes('prod')) {
447
+ return {
448
+ provider: '${productionProvider.node.path}',
449
+ labels: ['custom-runner', 'production', 'modified-via-selector'],
450
+ };
451
+ }
452
+
453
+ // Filter out draft PRs
454
+ if (payload.workflow_job.head_branch?.startsWith('draft/')) {
455
+ return { provider: undefined }; // Skip runner provisioning
456
+ }
457
+
458
+ // Use default for everything else
459
+ return {
460
+ provider: defaultProvider,
461
+ labels: defaultLabels,
462
+ };
463
+ };
464
+ `),
465
+ });
466
+
467
+ new GitHubRunners(this, 'runners', {
468
+ providers: [defaultProvider, productionProvider],
469
+ providerSelector: providerSelector,
470
+ });
471
+ ```
472
+
473
+ **Example: Add dynamic labels based on job metadata**
474
+
475
+ ```python
476
+ const providerSelector = new Function(this, 'provider-selector', {
477
+ runtime: Runtime.NODEJS_LATEST,
478
+ handler: 'index.handler',
479
+ code: Code.fromInline(`
480
+ exports.handler = async (event) => {
481
+ const { payload, defaultProvider, defaultLabels } = event;
482
+
483
+ // Add branch name as a label
484
+ const branch = payload.workflow_job.head_branch || 'unknown';
485
+ const labels = [...(defaultLabels || []), 'branch:' + branch];
486
+
487
+ return {
488
+ provider: defaultProvider,
489
+ labels: labels,
490
+ };
491
+ };
492
+ `),
493
+ });
494
+ ```
495
+
496
+ **Important considerations:**
497
+
498
+ * ⚠️ **Label matching responsibility**: You are responsible for ensuring the selected provider's labels match what the job requires. If labels don't match, the runner will be provisioned but GitHub Actions won't assign the job to it.
499
+ * ⚠️ **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).
500
+ * ⚡ **Performance**: The selector runs synchronously during webhook processing. Keep it fast and efficient—the webhook has a 30-second timeout total.
501
+
353
502
  ## Examples
354
503
 
355
- Beyond the code snippets above, the fullest example available is the [integration test](test/default.integ.ts).
504
+ We provide comprehensive examples in the [`examples/`](examples/) folder to help you get started quickly:
505
+
506
+ ### Getting Started
507
+
508
+ * **[Simple CodeBuild](examples/typescript/simple-codebuild/)** - Basic setup with just a CodeBuild provider (also available in [Python](examples/python/simple-codebuild/))
509
+
510
+ ### Provider Configuration
511
+
512
+ * **[Composite Provider](examples/typescript/composite-provider/)** - Fallback and weighted distribution strategies (also available in [Python](examples/python/composite-provider/))
513
+ * **[Provider Selector](examples/typescript/provider-selector/)** - Custom provider selection with Lambda function (also available in [Python](examples/python/provider-selector/))
514
+ * **[EC2 Windows Provider](examples/typescript/ec2-windows-provider/)** - EC2 configuration for Windows runners (also available in [Python](examples/python/ec2-windows-provider/))
515
+
516
+ ### Compute & Performance
517
+
518
+ * **[Compute Options](examples/typescript/compute-options/)** - Configure CPU, memory, and instance types for different providers (also available in [Python](examples/python/compute-options/))
519
+ * **[Spot Instances](examples/typescript/spot-instances/)** - Use spot instances for cost savings across EC2, Fargate, and ECS (also available in [Python](examples/python/spot-instances/))
520
+ * **[Storage Options](examples/typescript/storage-options/)** - Custom EBS storage options for EC2 runners (also available in [Python](examples/python/storage-options/))
521
+ * **[ECS Scaling](examples/typescript/ecs-scaling/)** - Custom autoscaling group scaling policies for ECS providers (also available in [Python](examples/python/ecs-scaling/))
522
+
523
+ ### Security & Access
524
+
525
+ * **[IAM Permissions](examples/typescript/iam-permissions/)** - Grant AWS IAM permissions to runners (also available in [Python](examples/python/iam-permissions/))
526
+ * **[Network Access](examples/typescript/network-access/)** - Configure network access with VPCs and security groups (also available in [Python](examples/python/network-access/))
527
+ * **[Access Control](examples/typescript/access-control/)** - Configure access control for webhook and setup functions (also available in [Python](examples/python/access-control/))
528
+
529
+ ### Customization
530
+
531
+ * **[Add Software](examples/typescript/add-software/)** - Add custom software to runner images (also available in [Python](examples/python/add-software/))
532
+
533
+ ### Enterprise & Monitoring
534
+
535
+ * **[GHES](examples/typescript/ghes/)** - Configure runners for GitHub Enterprise Server (also available in [Python](examples/python/ghes/))
536
+ * **[Monitoring](examples/typescript/monitoring/)** - Set up CloudWatch alarms and SNS notifications (also available in [Python](examples/python/monitoring/))
537
+
538
+ Each example is self-contained with its own dependencies and README. Start with the simple examples and work your way up to more advanced configurations.
539
+
540
+ Another good and very full example is the [integration test](test/default.integ.ts).
356
541
 
357
- If you have more to share, please open a PR adding them to the `examples` folder.
542
+ If you have more to share, please open a PR adding examples to the `examples` folder.
358
543
 
359
544
  ## Architecture
360
545
 
@@ -323,11 +323,196 @@ new GitHubRunners(this, 'runners', {
323
323
  });
324
324
  ```
325
325
 
326
+ ### Composite Providers
327
+
328
+ Composite providers allow you to combine multiple runner providers with different strategies. There are two types:
329
+
330
+ **Fallback Strategy**: Try providers in order until one succeeds. Useful for trying spot instances first, then falling back to on-demand if spot capacity is unavailable.
331
+
332
+ ```python
333
+ // Try spot instances first, fall back to on-demand if spot is unavailable
334
+ const ecsFallback = CompositeProvider.fallback(this, 'ECS Fallback', [
335
+ new EcsRunnerProvider(this, 'ECS Spot', {
336
+ labels: ['ecs', 'linux', 'x64'],
337
+ spot: true,
338
+ // ... other config
339
+ }),
340
+ new EcsRunnerProvider(this, 'ECS On-Demand', {
341
+ labels: ['ecs', 'linux', 'x64'],
342
+ spot: false,
343
+ // ... other config
344
+ }),
345
+ ]);
346
+
347
+ new GitHubRunners(this, 'runners', {
348
+ providers: [ecsFallback],
349
+ });
350
+ ```
351
+
352
+ **Weighted Distribution Strategy**: Randomly select a provider based on weights. Useful for distributing load across multiple availability zones or instance types.
353
+
354
+ ```python
355
+ // Distribute 60% of traffic to AZ-1, 40% to AZ-2
356
+ const distributedProvider = CompositeProvider.distribute(this, 'Fargate Distribution', [
357
+ {
358
+ weight: 3, // 3/(3+2) = 60%
359
+ provider: new FargateRunnerProvider(this, 'Fargate AZ-1', {
360
+ labels: ['fargate', 'linux', 'x64'],
361
+ subnetSelection: vpc.selectSubnets({
362
+ availabilityZones: [vpc.availabilityZones[0]],
363
+ }),
364
+ // ... other config
365
+ }),
366
+ },
367
+ {
368
+ weight: 2, // 2/(3+2) = 40%
369
+ provider: new FargateRunnerProvider(this, 'Fargate AZ-2', {
370
+ labels: ['fargate', 'linux', 'x64'],
371
+ subnetSelection: vpc.selectSubnets({
372
+ availabilityZones: [vpc.availabilityZones[1]],
373
+ }),
374
+ // ... other config
375
+ }),
376
+ },
377
+ ]);
378
+
379
+ new GitHubRunners(this, 'runners', {
380
+ providers: [distributedProvider],
381
+ });
382
+ ```
383
+
384
+ **Important**: All providers in a composite must have the exact same labels. This ensures any provisioned runner can match the labels requested by the GitHub workflow job.
385
+
386
+ ### Custom Provider Selection
387
+
388
+ By default, providers are selected based on label matching: the first provider that has all the labels requested by the job is selected. You can customize this behavior using a provider selector Lambda function to:
389
+
390
+ * Filter out certain jobs (prevent runner provisioning)
391
+ * Dynamically select a provider based on job characteristics (repository, branch, time of day, etc.)
392
+ * Customize labels for the runner (add, remove, or modify labels dynamically)
393
+
394
+ The selector function receives the full GitHub webhook payload, a map of all available providers and their labels, and the default provider/labels that would have been selected. It returns the provider to use (or `undefined` to skip runner creation) and the labels to assign to the runner.
395
+
396
+ **Example: Route jobs to different providers based on repository**
397
+
398
+ ```python
399
+ import { ComputeType } from 'aws-cdk-lib/aws-codebuild';
400
+ import { Function, Code, Runtime } from 'aws-cdk-lib/aws-lambda';
401
+ import { GitHubRunners, CodeBuildRunnerProvider } from '@cloudsnorkel/cdk-github-runners';
402
+
403
+ const defaultProvider = new CodeBuildRunnerProvider(this, 'default', {
404
+ labels: ['custom-runner', 'default'],
405
+ });
406
+ const productionProvider = new CodeBuildRunnerProvider(this, 'production', {
407
+ labels: ['custom-runner', 'production'],
408
+ computeType: ComputeType.LARGE,
409
+ });
410
+
411
+ const providerSelector = new Function(this, 'provider-selector', {
412
+ runtime: Runtime.NODEJS_LATEST,
413
+ handler: 'index.handler',
414
+ code: Code.fromInline(`
415
+ exports.handler = async (event) => {
416
+ const { payload, providers, defaultProvider, defaultLabels } = event;
417
+
418
+ // Route production repos to dedicated provider
419
+ if (payload.repository.name.includes('prod')) {
420
+ return {
421
+ provider: '${productionProvider.node.path}',
422
+ labels: ['custom-runner', 'production', 'modified-via-selector'],
423
+ };
424
+ }
425
+
426
+ // Filter out draft PRs
427
+ if (payload.workflow_job.head_branch?.startsWith('draft/')) {
428
+ return { provider: undefined }; // Skip runner provisioning
429
+ }
430
+
431
+ // Use default for everything else
432
+ return {
433
+ provider: defaultProvider,
434
+ labels: defaultLabels,
435
+ };
436
+ };
437
+ `),
438
+ });
439
+
440
+ new GitHubRunners(this, 'runners', {
441
+ providers: [defaultProvider, productionProvider],
442
+ providerSelector: providerSelector,
443
+ });
444
+ ```
445
+
446
+ **Example: Add dynamic labels based on job metadata**
447
+
448
+ ```python
449
+ const providerSelector = new Function(this, 'provider-selector', {
450
+ runtime: Runtime.NODEJS_LATEST,
451
+ handler: 'index.handler',
452
+ code: Code.fromInline(`
453
+ exports.handler = async (event) => {
454
+ const { payload, defaultProvider, defaultLabels } = event;
455
+
456
+ // Add branch name as a label
457
+ const branch = payload.workflow_job.head_branch || 'unknown';
458
+ const labels = [...(defaultLabels || []), 'branch:' + branch];
459
+
460
+ return {
461
+ provider: defaultProvider,
462
+ labels: labels,
463
+ };
464
+ };
465
+ `),
466
+ });
467
+ ```
468
+
469
+ **Important considerations:**
470
+
471
+ * ⚠️ **Label matching responsibility**: You are responsible for ensuring the selected provider's labels match what the job requires. If labels don't match, the runner will be provisioned but GitHub Actions won't assign the job to it.
472
+ * ⚠️ **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).
473
+ * ⚡ **Performance**: The selector runs synchronously during webhook processing. Keep it fast and efficient—the webhook has a 30-second timeout total.
474
+
326
475
  ## Examples
327
476
 
328
- Beyond the code snippets above, the fullest example available is the [integration test](test/default.integ.ts).
477
+ We provide comprehensive examples in the [`examples/`](examples/) folder to help you get started quickly:
478
+
479
+ ### Getting Started
480
+
481
+ * **[Simple CodeBuild](examples/typescript/simple-codebuild/)** - Basic setup with just a CodeBuild provider (also available in [Python](examples/python/simple-codebuild/))
482
+
483
+ ### Provider Configuration
484
+
485
+ * **[Composite Provider](examples/typescript/composite-provider/)** - Fallback and weighted distribution strategies (also available in [Python](examples/python/composite-provider/))
486
+ * **[Provider Selector](examples/typescript/provider-selector/)** - Custom provider selection with Lambda function (also available in [Python](examples/python/provider-selector/))
487
+ * **[EC2 Windows Provider](examples/typescript/ec2-windows-provider/)** - EC2 configuration for Windows runners (also available in [Python](examples/python/ec2-windows-provider/))
488
+
489
+ ### Compute & Performance
490
+
491
+ * **[Compute Options](examples/typescript/compute-options/)** - Configure CPU, memory, and instance types for different providers (also available in [Python](examples/python/compute-options/))
492
+ * **[Spot Instances](examples/typescript/spot-instances/)** - Use spot instances for cost savings across EC2, Fargate, and ECS (also available in [Python](examples/python/spot-instances/))
493
+ * **[Storage Options](examples/typescript/storage-options/)** - Custom EBS storage options for EC2 runners (also available in [Python](examples/python/storage-options/))
494
+ * **[ECS Scaling](examples/typescript/ecs-scaling/)** - Custom autoscaling group scaling policies for ECS providers (also available in [Python](examples/python/ecs-scaling/))
495
+
496
+ ### Security & Access
497
+
498
+ * **[IAM Permissions](examples/typescript/iam-permissions/)** - Grant AWS IAM permissions to runners (also available in [Python](examples/python/iam-permissions/))
499
+ * **[Network Access](examples/typescript/network-access/)** - Configure network access with VPCs and security groups (also available in [Python](examples/python/network-access/))
500
+ * **[Access Control](examples/typescript/access-control/)** - Configure access control for webhook and setup functions (also available in [Python](examples/python/access-control/))
501
+
502
+ ### Customization
503
+
504
+ * **[Add Software](examples/typescript/add-software/)** - Add custom software to runner images (also available in [Python](examples/python/add-software/))
505
+
506
+ ### Enterprise & Monitoring
507
+
508
+ * **[GHES](examples/typescript/ghes/)** - Configure runners for GitHub Enterprise Server (also available in [Python](examples/python/ghes/))
509
+ * **[Monitoring](examples/typescript/monitoring/)** - Set up CloudWatch alarms and SNS notifications (also available in [Python](examples/python/monitoring/))
510
+
511
+ Each example is self-contained with its own dependencies and README. Start with the simple examples and work your way up to more advanced configurations.
512
+
513
+ Another good and very full example is the [integration test](test/default.integ.ts).
329
514
 
330
- If you have more to share, please open a PR adding them to the `examples` folder.
515
+ If you have more to share, please open a PR adding examples to the `examples` folder.
331
516
 
332
517
  ## Architecture
333
518
 
@@ -5,7 +5,7 @@ kwargs = json.loads(
5
5
  """
6
6
  {
7
7
  "name": "cloudsnorkel.cdk-github-runners",
8
- "version": "0.14.15",
8
+ "version": "0.14.19",
9
9
  "description": "CDK construct to create GitHub Actions self-hosted runners. Creates ephemeral runners on demand. Easy to deploy and highly customizable.",
10
10
  "license": "Apache-2.0",
11
11
  "url": "https://github.com/CloudSnorkel/cdk-github-runners.git",
@@ -26,7 +26,7 @@ kwargs = json.loads(
26
26
  ],
27
27
  "package_data": {
28
28
  "cloudsnorkel.cdk_github_runners._jsii": [
29
- "cdk-github-runners@0.14.15.jsii.tgz"
29
+ "cdk-github-runners@0.14.19.jsii.tgz"
30
30
  ],
31
31
  "cloudsnorkel.cdk_github_runners": [
32
32
  "py.typed"
@@ -36,7 +36,7 @@ kwargs = json.loads(
36
36
  "install_requires": [
37
37
  "aws-cdk-lib>=2.155.0, <3.0.0",
38
38
  "constructs>=10.0.5, <11.0.0",
39
- "jsii>=1.120.0, <2.0.0",
39
+ "jsii>=1.124.0, <2.0.0",
40
40
  "publication>=0.0.3",
41
41
  "typeguard==2.13.3"
42
42
  ],