cloudsnorkel.cdk-github-runners 0.13.3__py3-none-any.whl → 0.14.21__py3-none-any.whl

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.
@@ -11,16 +11,31 @@ import jsii
11
11
  import publication
12
12
  import typing_extensions
13
13
 
14
- from typeguard import check_type
14
+ import typeguard
15
+ from importlib.metadata import version as _metadata_package_version
16
+ TYPEGUARD_MAJOR_VERSION = int(_metadata_package_version('typeguard').split('.')[0])
17
+
18
+ def check_type(argname: str, value: object, expected_type: typing.Any) -> typing.Any:
19
+ if TYPEGUARD_MAJOR_VERSION <= 2:
20
+ return typeguard.check_type(argname=argname, value=value, expected_type=expected_type) # type:ignore
21
+ else:
22
+ if isinstance(value, jsii._reference_map.InterfaceDynamicProxy): # pyright: ignore [reportAttributeAccessIssue]
23
+ pass
24
+ else:
25
+ if TYPEGUARD_MAJOR_VERSION == 3:
26
+ typeguard.config.collection_check_strategy = typeguard.CollectionCheckStrategy.ALL_ITEMS # type:ignore
27
+ typeguard.check_type(value=value, expected_type=expected_type) # type:ignore
28
+ else:
29
+ typeguard.check_type(value=value, expected_type=expected_type, collection_check_strategy=typeguard.CollectionCheckStrategy.ALL_ITEMS) # type:ignore
15
30
 
16
31
  import aws_cdk._jsii
17
32
  import constructs._jsii
18
33
 
19
34
  __jsii_assembly__ = jsii.JSIIAssembly.load(
20
35
  "@cloudsnorkel/cdk-github-runners",
21
- "0.13.3",
36
+ "0.14.21",
22
37
  __name__[0:-6],
23
- "cdk-github-runners@0.13.3.jsii.tgz",
38
+ "cdk-github-runners@0.14.21.jsii.tgz",
24
39
  )
25
40
 
26
41
  __all__ = [
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cloudsnorkel.cdk-github-runners
3
- Version: 0.13.3
4
- Summary: CDK construct to create GitHub Actions self-hosted runners. A webhook listens to events and creates ephemeral runners on the fly.
3
+ Version: 0.14.21
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>
7
7
  License: Apache-2.0
@@ -10,21 +10,20 @@ Classifier: Intended Audience :: Developers
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: JavaScript
12
12
  Classifier: Programming Language :: Python :: 3 :: Only
13
- Classifier: Programming Language :: Python :: 3.8
14
13
  Classifier: Programming Language :: Python :: 3.9
15
14
  Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Typing :: Typed
18
17
  Classifier: Development Status :: 4 - Beta
19
18
  Classifier: License :: OSI Approved
20
- Requires-Python: ~=3.8
19
+ Requires-Python: ~=3.9
21
20
  Description-Content-Type: text/markdown
22
21
  License-File: LICENSE
23
- Requires-Dist: aws-cdk-lib <3.0.0,>=2.123.0
22
+ Requires-Dist: aws-cdk-lib <3.0.0,>=2.155.0
24
23
  Requires-Dist: constructs <11.0.0,>=10.0.5
25
- Requires-Dist: jsii <2.0.0,>=1.98.0
24
+ Requires-Dist: jsii <2.0.0,>=1.124.0
26
25
  Requires-Dist: publication >=0.0.3
27
- Requires-Dist: typeguard ~=2.13.3
26
+ Requires-Dist: typeguard ==2.13.3
28
27
 
29
28
  # GitHub Self-Hosted Runners CDK Constructs
30
29
 
@@ -38,17 +37,17 @@ Requires-Dist: typeguard ~=2.13.3
38
37
 
39
38
  Use this CDK construct to create ephemeral [self-hosted GitHub runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) on-demand inside your AWS account.
40
39
 
41
- * Easy to configure GitHub integration with a web-based interface
42
- * Customizable runners with decent defaults
43
- * Multiple runner configurations controlled by labels
44
- * Everything fully hosted in your account
45
- * Automatically updated build environment with latest runner version
40
+ * 🧩 Easy to configure GitHub integration with a web-based interface
41
+ * 🧠 Customizable runners with decent defaults
42
+ * 🏃🏻 Multiple runner configurations controlled by labels
43
+ * 🔐 Everything fully hosted in your account
44
+ * 🔃 Automatically updated build environment with latest runner version
46
45
 
47
46
  Self-hosted runners in AWS are useful when:
48
47
 
49
48
  * You need easy access to internal resources in your actions
50
49
  * You want to pre-install some software for your actions
51
- * You want to provide some basic AWS API access (but [aws-actions/configure-aws-credentials](https://github.com/marketplace/actions/configure-aws-credentials-for-github-actions) has more security controls)
50
+ * You want to provide some basic AWS API access (but [aws-actions/configure-aws-credentials](https://github.com/marketplace/actions/configure-aws-credentials-action-for-github-actions) has more security controls)
52
51
  * You are using GitHub Enterprise Server
53
52
 
54
53
  Ephemeral (or on-demand) runners are the [recommended way by GitHub](https://docs.github.com/en/actions/hosting-your-own-runners/autoscaling-with-self-hosted-runners#using-ephemeral-runners-for-autoscaling) for auto-scaling, and they make sure all jobs run with a clean image. Runners are started on-demand. You don't pay unless a job is running.
@@ -98,9 +97,14 @@ You can also create your own provider by implementing `IRunnerProvider`.
98
97
  ### Use
99
98
 
100
99
  ```python
100
+ from aws_cdk import App, Stack
101
101
  from cloudsnorkel.cdk_github_runners import GitHubRunners
102
102
 
103
- GitHubRunners(self, "runners")
103
+ app = App()
104
+ stack = Stack(app, "github-runners")
105
+ GitHubRunners(stack, "runners")
106
+
107
+ app.synth()
104
108
  ```
105
109
 
106
110
  </details>
@@ -117,9 +121,14 @@ You can also create your own provider by implementing `IRunnerProvider`.
117
121
  ### Use
118
122
 
119
123
  ```python
124
+ import { App, Stack } from 'aws-cdk-lib';
120
125
  import { GitHubRunners } from '@cloudsnorkel/cdk-github-runners';
121
126
 
122
- new GitHubRunners(this, "runners");
127
+ const app = new App();
128
+ const stack = new Stack(app, 'github-runners');
129
+ new GitHubRunners(stack, 'runners');
130
+
131
+ app.synth();
123
132
  ```
124
133
 
125
134
  </details>
@@ -139,9 +148,19 @@ You can also create your own provider by implementing `IRunnerProvider`.
139
148
  ### Use
140
149
 
141
150
  ```java
151
+ import software.amazon.awscdk.App;
152
+ import software.amazon.awscdk.Stack;
142
153
  import com.cloudsnorkel.cdk.github.runners.GitHubRunners;
143
154
 
144
- GitHubRunners.Builder.create(this, "runners").build();
155
+ public class Example {
156
+ public static void main(String[] args){
157
+ App app = new App();
158
+ Stack stack = new Stack(app, "github-runners");
159
+ GitHubRunners.Builder.create(stack, "runners").build();
160
+
161
+ app.synth();
162
+ }
163
+ }
145
164
  ```
146
165
 
147
166
  </details>
@@ -158,9 +177,21 @@ You can also create your own provider by implementing `IRunnerProvider`.
158
177
  ### Use
159
178
 
160
179
  ```go
161
- import "github.com/CloudSnorkel/cdk-github-runners-go/cloudsnorkelcdkgithubrunners"
180
+ package main
181
+
182
+ import (
183
+ "github.com/CloudSnorkel/cdk-github-runners-go/cloudsnorkelcdkgithubrunners"
184
+ "github.com/aws/aws-cdk-go/awscdk/v2"
185
+ "github.com/aws/jsii-runtime-go"
186
+ )
187
+
188
+ func main() {
189
+ app := awscdk.NewApp(nil)
190
+ stack := awscdk.NewStack(app, jsii.String("github-runners"), &awscdk.StackProps{})
191
+ cloudsnorkelcdkgithubrunners.NewGitHubRunners(stack, jsii.String("runners"), &cloudsnorkelcdkgithubrunners.GitHubRunnersProps{})
162
192
 
163
- NewGitHubRunners(this, jsii.String("runners"))
193
+ app.Synth(nil)
194
+ }
164
195
  ```
165
196
 
166
197
  </details>
@@ -177,9 +208,22 @@ You can also create your own provider by implementing `IRunnerProvider`.
177
208
  ### Use
178
209
 
179
210
  ```csharp
211
+ using Amazon.CDK;
180
212
  using CloudSnorkel;
181
213
 
182
- new GitHubRunners(this, "runners");
214
+ namespace Example
215
+ {
216
+ sealed class Program
217
+ {
218
+ public static void Main(string[] args)
219
+ {
220
+ var app = new App();
221
+ var stack = new Stack(app, "github-runners");
222
+ new GitHubRunners(stack, "runners");
223
+ app.Synth();
224
+ }
225
+ }
226
+ }
183
227
  ```
184
228
 
185
229
  </details>
@@ -198,7 +242,7 @@ You can also create your own provider by implementing `IRunnerProvider`.
198
242
  5. Execute the status command (you may need to specify `--profile` too) and open the resulting `status.json` file
199
243
  6. Open the URL in `github.setup.url` from `status.json` or [manually setup GitHub](SETUP_GITHUB.md) integration as an app or with personal access token
200
244
  7. Run status command again to confirm `github.auth.status` and `github.webhook.status` are OK
201
- 8. Trigger a GitHub action that has a `self-hosted` label with `runs-on: [self-hosted, linux, codebuild]` or similar
245
+ 8. Trigger a GitHub action that has a `self-hosted` label with `runs-on: [self-hosted, codebuild]` (or non-default labels you set in step 2)
202
246
  9. If the action is not successful, see [troubleshooting](#Troubleshooting)
203
247
 
204
248
  [![Demo](demo-thumbnail.jpg)](https://youtu.be/wlyv_3V8lIw)
@@ -306,6 +350,198 @@ new GitHubRunners(this, 'runners', {
306
350
  });
307
351
  ```
308
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
+
502
+ ## Examples
503
+
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
+ * **[Split Stacks](examples/typescript/split-stacks/)** - Split image builders and providers across multiple stacks (also available in [Python](examples/python/split-stacks/))
516
+
517
+ ### Compute & Performance
518
+
519
+ * **[Compute Options](examples/typescript/compute-options/)** - Configure CPU, memory, and instance types for different providers (also available in [Python](examples/python/compute-options/))
520
+ * **[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/))
521
+ * **[Storage Options](examples/typescript/storage-options/)** - Custom EBS storage options for EC2 runners (also available in [Python](examples/python/storage-options/))
522
+ * **[ECS Scaling](examples/typescript/ecs-scaling/)** - Custom autoscaling group scaling policies for ECS providers (also available in [Python](examples/python/ecs-scaling/))
523
+
524
+ ### Security & Access
525
+
526
+ * **[IAM Permissions](examples/typescript/iam-permissions/)** - Grant AWS IAM permissions to runners (also available in [Python](examples/python/iam-permissions/))
527
+ * **[Network Access](examples/typescript/network-access/)** - Configure network access with VPCs and security groups (also available in [Python](examples/python/network-access/))
528
+ * **[Access Control](examples/typescript/access-control/)** - Configure access control for webhook and setup functions (also available in [Python](examples/python/access-control/))
529
+
530
+ ### Customization
531
+
532
+ * **[Add Software](examples/typescript/add-software/)** - Add custom software to runner images (also available in [Python](examples/python/add-software/))
533
+
534
+ ### Enterprise & Monitoring
535
+
536
+ * **[GHES](examples/typescript/ghes/)** - Configure runners for GitHub Enterprise Server (also available in [Python](examples/python/ghes/))
537
+ * **[Monitoring](examples/typescript/monitoring/)** - Set up CloudWatch alarms and SNS notifications (also available in [Python](examples/python/monitoring/))
538
+
539
+ 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.
540
+
541
+ Another good and very full example is the [integration test](test/default.integ.ts).
542
+
543
+ If you have more to share, please open a PR adding examples to the `examples` folder.
544
+
309
545
  ## Architecture
310
546
 
311
547
  ![Architecture diagram](architecture.svg)
@@ -350,7 +586,21 @@ Other useful metrics to track:
350
586
  1. Use `GitHubRunners.metricJobCompleted()` to get a metric for the number of completed jobs broken down by labels and job success.
351
587
  2. Use `GitHubRunners.metricTime()` to get a metric for the total time a runner is running. This includes the overhead of starting the runner.
352
588
 
589
+ ## Contributing
590
+
591
+ If you use and love this project, please consider contributing.
592
+
593
+ 1. 🪳 If you see something, say something. [Issues](https://github.com/CloudSnorkel/cdk-github-runners/issues) help improve the quality of the project.
594
+
595
+ * Include relevant logs and package versions for bugs.
596
+ * When possible, describe the use-case behind feature requests.
597
+ 2. 🛠️ [Pull requests](https://github.com/CloudSnorkel/cdk-github-runners/pulls) are welcome.
598
+
599
+ * Run `npm run build` before submitting to make sure all tests pass.
600
+ * Allow edits from maintainers so small adjustments can be made easily.
601
+ 3. 💵 Consider [sponsoring](https://github.com/sponsors/CloudSnorkel) the project to show your support and optionally get your name listed below.
602
+
353
603
  ## Other Options
354
604
 
355
- 1. [philips-labs/terraform-aws-github-runner](https://github.com/philips-labs/terraform-aws-github-runner) if you're using Terraform
605
+ 1. [github-aws-runners/terraform-aws-github-runner](https://github.com/github-aws-runners/terraform-aws-github-runner) if you're using Terraform
356
606
  2. [actions/actions-runner-controller](https://github.com/actions/actions-runner-controller) if you're using Kubernetes
@@ -0,0 +1,9 @@
1
+ cloudsnorkel/cdk_github_runners/__init__.py,sha256=s1fznhel_1kk511FJpaBgdRcIOCjSBcPTBIurf8jpLY,723479
2
+ cloudsnorkel/cdk_github_runners/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
3
+ cloudsnorkel/cdk_github_runners/_jsii/__init__.py,sha256=Issv_0CyOVxbrDxZPKJDbEOIlAQQjvOIlX_X5iZ6f-w,1478
4
+ cloudsnorkel/cdk_github_runners/_jsii/cdk-github-runners@0.14.21.jsii.tgz,sha256=IZk85poW8I6RVt3sJSIvAhZipU0UCbZ_2LiP58OtxPw,905901
5
+ cloudsnorkel_cdk_github_runners-0.14.21.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
6
+ cloudsnorkel_cdk_github_runners-0.14.21.dist-info/METADATA,sha256=SkYg5enDirOGPBfTOw1Cy3ck_2-omYMzbneSHFbE-wk,26442
7
+ cloudsnorkel_cdk_github_runners-0.14.21.dist-info/WHEEL,sha256=WnJ8fYhv8N4SYVK2lLYNI6N0kVATA7b0piVUNvqIIJE,91
8
+ cloudsnorkel_cdk_github_runners-0.14.21.dist-info/top_level.txt,sha256=6vUrT-dcGOiRMT4Q6gEQPznoyS7nHOJ269MHpo4DEd8,13
9
+ cloudsnorkel_cdk_github_runners-0.14.21.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (75.3.3)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- cloudsnorkel/cdk_github_runners/__init__.py,sha256=ujO9tqWBYZP7a3dgjsmy6QWYBY5bGMH5WLmRA9pDg8Q,602385
2
- cloudsnorkel/cdk_github_runners/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
3
- cloudsnorkel/cdk_github_runners/_jsii/__init__.py,sha256=t78xFxuof8Y48ayy0qCw_sFWZu6hYERk-ZBOVQVJIFY,508
4
- cloudsnorkel/cdk_github_runners/_jsii/cdk-github-runners@0.13.3.jsii.tgz,sha256=VCbnCYwMGts_SVXHu30tcZYTIOoFDX33nN9mn48s_KI,1437512
5
- cloudsnorkel.cdk_github_runners-0.13.3.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
6
- cloudsnorkel.cdk_github_runners-0.13.3.dist-info/METADATA,sha256=nYlr8Oyr44ZvmnRechkAkgHrsXm9Jzs5QfRhRV4pF0s,15681
7
- cloudsnorkel.cdk_github_runners-0.13.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
8
- cloudsnorkel.cdk_github_runners-0.13.3.dist-info/top_level.txt,sha256=6vUrT-dcGOiRMT4Q6gEQPznoyS7nHOJ269MHpo4DEd8,13
9
- cloudsnorkel.cdk_github_runners-0.13.3.dist-info/RECORD,,