hexaqueue-github-runner 0.5.0__tar.gz → 0.6.0__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 (25) hide show
  1. hexaqueue_github_runner-0.6.0/PKG-INFO +125 -0
  2. hexaqueue_github_runner-0.6.0/README.md +110 -0
  3. {hexaqueue_github_runner-0.5.0 → hexaqueue_github_runner-0.6.0}/pyproject.toml +10 -4
  4. {hexaqueue_github_runner-0.5.0 → hexaqueue_github_runner-0.6.0}/pyproject.toml.orig +7 -3
  5. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/__init__.py +72 -0
  6. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/adapters/__init__.py +30 -0
  7. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/adapters/autoscaler.py +333 -0
  8. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/adapters/crypto.py +74 -0
  9. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/adapters/github_client.py +311 -0
  10. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/adapters/webhook_adapter.py +152 -0
  11. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/domain/__init__.py +38 -0
  12. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/domain/events.py +133 -0
  13. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/domain/jit.py +58 -0
  14. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/domain/labels.py +179 -0
  15. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/domain/pool.py +71 -0
  16. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/domain/traceability.py +87 -0
  17. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/infra/__init__.py +15 -0
  18. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/infra/router.py +91 -0
  19. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/ports/__init__.py +18 -0
  20. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/ports/autoscaler.py +76 -0
  21. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/ports/client.py +84 -0
  22. hexaqueue_github_runner-0.6.0/src/hexaqueue_github_runner/ports/verifier.py +44 -0
  23. hexaqueue_github_runner-0.5.0/PKG-INFO +0 -42
  24. hexaqueue_github_runner-0.5.0/README.md +0 -31
  25. hexaqueue_github_runner-0.5.0/src/hexaqueue_github_runner/__init__.py +0 -0
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: hexaqueue-github-runner
3
+ Version: 0.6.0
4
+ Summary: Hexaqueue GitHub Runner - Dynamic Self-Hosted GitHub Actions Autoscaler
5
+ Author: Richard West
6
+ Author-email: Richard West <dopplereffect.us@gmail.com>
7
+ License-Expression: Apache-2.0
8
+ Requires-Dist: cryptography>=42.0.0
9
+ Requires-Dist: fastapi>=0.115.0
10
+ Requires-Dist: hexaqueue-core
11
+ Requires-Dist: httpx>=0.27.0
12
+ Requires-Dist: pydantic>=2.10.0
13
+ Requires-Python: >=3.12
14
+ Description-Content-Type: text/markdown
15
+
16
+ # 🐙 `hexaqueue-github-runner`
17
+
18
+ > GitHub Actions Dynamic Self-Hosted Runner Autoscaler & Webhook Bridge.
19
+
20
+ [![PyPI: hexaqueue-github-runner](https://img.shields.io/pypi/v/hexaqueue-github-runner.svg)](https://pypi.org/project/hexaqueue-github-runner/)
21
+ [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
22
+ [![Coverage](https://codecov.io/github/TheTrueSCU/hexaqueue/graph/badge.svg?component=hexaqueue_github_runner)](https://codecov.io/github/TheTrueSCU/hexaqueue)
23
+ [![Part of Hexaqueue](https://img.shields.io/badge/part%20of-hexaqueue-blue.svg)](https://dopplereffect.us/hexaqueue/)
24
+ [![Built with Hexastack](https://img.shields.io/badge/built%20with-hexastack-blueviolet.svg)](https://dopplereffect.us/hexastack/)
25
+ [![Governed by Hexaqual](https://img.shields.io/badge/governed%20by-hexaqual-10b981.svg)](https://dopplereffect.us/hexaqual/)
26
+ [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](../../LICENSE)
27
+
28
+ > Part of the [**Hexaqueue Scheduler**](https://dopplereffect.us/hexaqueue/) · Built on [**Hexastack**](https://dopplereffect.us/hexastack/) · Governed by [**Hexaqual**](https://dopplereffect.us/hexaqual/).
29
+
30
+ ---
31
+
32
+ ## 🏗️ Architecture & Dependencies
33
+
34
+ ```mermaid
35
+ graph TD
36
+ subgraph S1["hexaqueue-github-runner"]
37
+ WEBHOOK["GitHub Webhook Ingress (workflow_job.queued)"]
38
+ AUTOSCALER["Dynamic GitHub Runner Autoscaler"]
39
+ JIT["GitHub App JIT Runner Token Minting"]
40
+ end
41
+
42
+ subgraph S2["Internal Dependencies"]
43
+ HQ_CORE["hexaqueue-core"]
44
+ end
45
+
46
+ S1 --> HQ_CORE
47
+ ```
48
+
49
+ ---
50
+
51
+ ## 🚀 Quickstart & Usage
52
+
53
+ ### 1. Ingress Webhook Router Setup (FastAPI)
54
+
55
+ ```python
56
+ from fastapi import FastAPI
57
+ from hexaqueue_github_runner import (
58
+ DynamicGitHubRunnerAutoscaler,
59
+ GitHubApiClient,
60
+ GitHubAppCredentials,
61
+ GitHubWebhookAdapter,
62
+ HmacSha256WebhookVerifier,
63
+ create_github_webhook_router,
64
+ )
65
+
66
+ app = FastAPI()
67
+
68
+ credentials = GitHubAppCredentials(
69
+ app_id="123456",
70
+ installation_id=7890,
71
+ private_key_pem="<PEM_ENCODED_APP_PRIVATE_KEY>",
72
+ )
73
+ api_client = GitHubApiClient(credentials=credentials)
74
+ autoscaler = DynamicGitHubRunnerAutoscaler(api_client=api_client)
75
+ verifier = HmacSha256WebhookVerifier()
76
+
77
+ adapter = GitHubWebhookAdapter(
78
+ verifier=verifier,
79
+ autoscaler=autoscaler,
80
+ secret="your-github-webhook-secret",
81
+ )
82
+
83
+ # Mount webhook route at /webhooks/github
84
+ app.include_router(create_github_webhook_router(adapter))
85
+ ```
86
+
87
+ ### 2. Supported Runner Labels
88
+
89
+ Hexaqueue translates GitHub Actions `runs-on` labels dynamically:
90
+ - `runs-on: [self-hosted, linux, 16-cores, 64gb, gpu-h100, 100gb-scratch, 2h-walltime]`
91
+ - CPU: `16-cores`, `cpu-8`, `4-cpu`
92
+ - RAM: `64gb`, `ram-32gb`, `512mb-ram`
93
+ - GPU: `gpu-h100`, `a100`, `l4`, `t4`, `v100`, `4-gpu-a100`
94
+ - Scratch: `100gb-scratch`, `scratch-50gb`
95
+ - Walltime: `2h-walltime`, `90m-walltime`
96
+ - Cloud Routing & Free-Tier: `oci`, `gcp`, `aws`, `azure`, `local`, `arm64`, `paid`
97
+
98
+ ---
99
+
100
+ ### 3. Multi-CSP Free-Tier Mesh Autoscaling ($0.00 Spend Invariant)
101
+
102
+ To burst GitHub Actions runner matrices beyond the standard 2 vCPU limit at zero cloud cost, configure the autoscaler with `MultiCspFreeTierGovernor`:
103
+
104
+ ```python
105
+ from hexaqueue_core.adapters.freetier.governor import MultiCspFreeTierGovernor
106
+ from hexaqueue_github_runner import DynamicGitHubRunnerAutoscaler
107
+
108
+ governor = MultiCspFreeTierGovernor()
109
+ autoscaler = DynamicGitHubRunnerAutoscaler(
110
+ api_client=api_client,
111
+ free_tier_governor=governor,
112
+ )
113
+ ```
114
+
115
+ The mesh pools Always-Free compute across all participating providers:
116
+ - **OCI Always-Free**: 4 Ampere A1 ARM vCPUs / 24 GB RAM (`runs-on: [self-hosted, arm64, 4-cores]`)
117
+ - **GCP Always-Free**: 2 x86 vCPUs / 1 GB RAM (`runs-on: [self-hosted, gcp, 2-cores]`)
118
+ - **AWS Free Tier**: 1 x86 vCPU / 1 GB RAM (`runs-on: [self-hosted, aws, 1-core]`)
119
+ - **Azure Free Tier**: 1 x86 vCPU / 1 GB RAM (`runs-on: [self-hosted, azure, 1-core]`)
120
+ - **Local Workstation**: 2 vCPUs / 2 GB RAM (`runs-on: [self-hosted, local, 2-cores]`)
121
+
122
+ **Key Invariants:**
123
+ 1. **10 Total Pooled Free vCPUs**: Matrix jobs dynamically fan out across OCI, GCP, AWS, Azure, and Local nodes concurrently at $0.00 spend.
124
+ 2. **Instant Quota Recycling**: When an ephemeral runner exits, single-job scratch storage is wiped and provider quota is freed immediately.
125
+ 3. **Step Summary Verification**: Automatically attaches Check Run summaries documenting the assigned CSP provider, resource footprint, and verified $0.00 cost claim.
@@ -0,0 +1,110 @@
1
+ # 🐙 `hexaqueue-github-runner`
2
+
3
+ > GitHub Actions Dynamic Self-Hosted Runner Autoscaler & Webhook Bridge.
4
+
5
+ [![PyPI: hexaqueue-github-runner](https://img.shields.io/pypi/v/hexaqueue-github-runner.svg)](https://pypi.org/project/hexaqueue-github-runner/)
6
+ [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
7
+ [![Coverage](https://codecov.io/github/TheTrueSCU/hexaqueue/graph/badge.svg?component=hexaqueue_github_runner)](https://codecov.io/github/TheTrueSCU/hexaqueue)
8
+ [![Part of Hexaqueue](https://img.shields.io/badge/part%20of-hexaqueue-blue.svg)](https://dopplereffect.us/hexaqueue/)
9
+ [![Built with Hexastack](https://img.shields.io/badge/built%20with-hexastack-blueviolet.svg)](https://dopplereffect.us/hexastack/)
10
+ [![Governed by Hexaqual](https://img.shields.io/badge/governed%20by-hexaqual-10b981.svg)](https://dopplereffect.us/hexaqual/)
11
+ [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](../../LICENSE)
12
+
13
+ > Part of the [**Hexaqueue Scheduler**](https://dopplereffect.us/hexaqueue/) · Built on [**Hexastack**](https://dopplereffect.us/hexastack/) · Governed by [**Hexaqual**](https://dopplereffect.us/hexaqual/).
14
+
15
+ ---
16
+
17
+ ## 🏗️ Architecture & Dependencies
18
+
19
+ ```mermaid
20
+ graph TD
21
+ subgraph S1["hexaqueue-github-runner"]
22
+ WEBHOOK["GitHub Webhook Ingress (workflow_job.queued)"]
23
+ AUTOSCALER["Dynamic GitHub Runner Autoscaler"]
24
+ JIT["GitHub App JIT Runner Token Minting"]
25
+ end
26
+
27
+ subgraph S2["Internal Dependencies"]
28
+ HQ_CORE["hexaqueue-core"]
29
+ end
30
+
31
+ S1 --> HQ_CORE
32
+ ```
33
+
34
+ ---
35
+
36
+ ## 🚀 Quickstart & Usage
37
+
38
+ ### 1. Ingress Webhook Router Setup (FastAPI)
39
+
40
+ ```python
41
+ from fastapi import FastAPI
42
+ from hexaqueue_github_runner import (
43
+ DynamicGitHubRunnerAutoscaler,
44
+ GitHubApiClient,
45
+ GitHubAppCredentials,
46
+ GitHubWebhookAdapter,
47
+ HmacSha256WebhookVerifier,
48
+ create_github_webhook_router,
49
+ )
50
+
51
+ app = FastAPI()
52
+
53
+ credentials = GitHubAppCredentials(
54
+ app_id="123456",
55
+ installation_id=7890,
56
+ private_key_pem="<PEM_ENCODED_APP_PRIVATE_KEY>",
57
+ )
58
+ api_client = GitHubApiClient(credentials=credentials)
59
+ autoscaler = DynamicGitHubRunnerAutoscaler(api_client=api_client)
60
+ verifier = HmacSha256WebhookVerifier()
61
+
62
+ adapter = GitHubWebhookAdapter(
63
+ verifier=verifier,
64
+ autoscaler=autoscaler,
65
+ secret="your-github-webhook-secret",
66
+ )
67
+
68
+ # Mount webhook route at /webhooks/github
69
+ app.include_router(create_github_webhook_router(adapter))
70
+ ```
71
+
72
+ ### 2. Supported Runner Labels
73
+
74
+ Hexaqueue translates GitHub Actions `runs-on` labels dynamically:
75
+ - `runs-on: [self-hosted, linux, 16-cores, 64gb, gpu-h100, 100gb-scratch, 2h-walltime]`
76
+ - CPU: `16-cores`, `cpu-8`, `4-cpu`
77
+ - RAM: `64gb`, `ram-32gb`, `512mb-ram`
78
+ - GPU: `gpu-h100`, `a100`, `l4`, `t4`, `v100`, `4-gpu-a100`
79
+ - Scratch: `100gb-scratch`, `scratch-50gb`
80
+ - Walltime: `2h-walltime`, `90m-walltime`
81
+ - Cloud Routing & Free-Tier: `oci`, `gcp`, `aws`, `azure`, `local`, `arm64`, `paid`
82
+
83
+ ---
84
+
85
+ ### 3. Multi-CSP Free-Tier Mesh Autoscaling ($0.00 Spend Invariant)
86
+
87
+ To burst GitHub Actions runner matrices beyond the standard 2 vCPU limit at zero cloud cost, configure the autoscaler with `MultiCspFreeTierGovernor`:
88
+
89
+ ```python
90
+ from hexaqueue_core.adapters.freetier.governor import MultiCspFreeTierGovernor
91
+ from hexaqueue_github_runner import DynamicGitHubRunnerAutoscaler
92
+
93
+ governor = MultiCspFreeTierGovernor()
94
+ autoscaler = DynamicGitHubRunnerAutoscaler(
95
+ api_client=api_client,
96
+ free_tier_governor=governor,
97
+ )
98
+ ```
99
+
100
+ The mesh pools Always-Free compute across all participating providers:
101
+ - **OCI Always-Free**: 4 Ampere A1 ARM vCPUs / 24 GB RAM (`runs-on: [self-hosted, arm64, 4-cores]`)
102
+ - **GCP Always-Free**: 2 x86 vCPUs / 1 GB RAM (`runs-on: [self-hosted, gcp, 2-cores]`)
103
+ - **AWS Free Tier**: 1 x86 vCPU / 1 GB RAM (`runs-on: [self-hosted, aws, 1-core]`)
104
+ - **Azure Free Tier**: 1 x86 vCPU / 1 GB RAM (`runs-on: [self-hosted, azure, 1-core]`)
105
+ - **Local Workstation**: 2 vCPUs / 2 GB RAM (`runs-on: [self-hosted, local, 2-cores]`)
106
+
107
+ **Key Invariants:**
108
+ 1. **10 Total Pooled Free vCPUs**: Matrix jobs dynamically fan out across OCI, GCP, AWS, Azure, and Local nodes concurrently at $0.00 spend.
109
+ 2. **Instant Quota Recycling**: When an ephemeral runner exits, single-job scratch storage is wiped and provider quota is freed immediately.
110
+ 3. **Step Summary Verification**: Automatically attaches Check Run summaries documenting the assigned CSP provider, resource footprint, and verified $0.00 cost claim.
@@ -1,18 +1,24 @@
1
1
  [project]
2
2
  name = "hexaqueue-github-runner"
3
- version = "0.5.0"
3
+ version = "0.6.0"
4
4
  description = "Hexaqueue GitHub Runner - Dynamic Self-Hosted GitHub Actions Autoscaler"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
7
- requires-python = ">=3.13"
8
- dependencies = ["hexaqueue-core"]
7
+ requires-python = ">=3.12"
8
+ dependencies = [
9
+ "cryptography>=42.0.0",
10
+ "fastapi>=0.115.0",
11
+ "hexaqueue-core",
12
+ "httpx>=0.27.0",
13
+ "pydantic>=2.10.0",
14
+ ]
9
15
 
10
16
  [[project.authors]]
11
17
  name = "Richard West"
12
18
  email = "dopplereffect.us@gmail.com"
13
19
 
14
20
  [build-system]
15
- requires = ["uv_build>=0.12.3,<0.13.0"]
21
+ requires = ["uv_build>=0.12.3,<0.14.0"]
16
22
  build-backend = "uv_build"
17
23
 
18
24
  [tool.uv.sources.hexaqueue-core]
@@ -1,19 +1,23 @@
1
1
  [project]
2
2
  name = "hexaqueue-github-runner"
3
- version = "0.5.0"
3
+ version = "0.6.0"
4
4
  description = "Hexaqueue GitHub Runner - Dynamic Self-Hosted GitHub Actions Autoscaler"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
7
7
  authors = [
8
8
  { name = "Richard West", email = "dopplereffect.us@gmail.com" }
9
9
  ]
10
- requires-python = ">=3.13"
10
+ requires-python = ">=3.12"
11
11
  dependencies = [
12
+ "cryptography>=42.0.0",
13
+ "fastapi>=0.115.0",
12
14
  "hexaqueue-core",
15
+ "httpx>=0.27.0",
16
+ "pydantic>=2.10.0",
13
17
  ]
14
18
 
15
19
  [build-system]
16
- requires = ["uv_build>=0.12.3,<0.13.0"]
20
+ requires = ["uv_build>=0.12.3,<0.14.0"]
17
21
  build-backend = "uv_build"
18
22
 
19
23
  [tool.uv.sources]
@@ -0,0 +1,72 @@
1
+ """Hexaqueue GitHub Runner - Dynamic Self-Hosted GitHub Actions Autoscaler.
2
+
3
+ Notes/Architectural Intent:
4
+ Root package export for GitHub Actions runner autoscaler, JIT manager,
5
+ cryptographic webhook verifier, and hardware resource translation.
6
+ """
7
+
8
+ from hexaqueue_github_runner.adapters.autoscaler import (
9
+ DynamicGitHubRunnerAutoscaler,
10
+ NaiveAutoscalerOracle,
11
+ )
12
+ from hexaqueue_github_runner.adapters.crypto import HmacSha256WebhookVerifier
13
+ from hexaqueue_github_runner.adapters.github_client import (
14
+ GitHubApiClient,
15
+ InMemoryGitHubApiClient,
16
+ create_github_app_jwt,
17
+ )
18
+ from hexaqueue_github_runner.adapters.webhook_adapter import (
19
+ GitHubWebhookAdapter,
20
+ )
21
+ from hexaqueue_github_runner.domain.events import (
22
+ GitHubRepository,
23
+ GitHubWorkflowJob,
24
+ GitHubWorkflowJobAction,
25
+ GitHubWorkflowJobPayload,
26
+ )
27
+ from hexaqueue_github_runner.domain.jit import (
28
+ GitHubAppCredentials,
29
+ JitRunnerConfig,
30
+ )
31
+ from hexaqueue_github_runner.domain.labels import LabelTranslator
32
+ from hexaqueue_github_runner.domain.pool import (
33
+ RunnerPoolState,
34
+ WarmPoolConfig,
35
+ WarmPoolRunner,
36
+ )
37
+ from hexaqueue_github_runner.domain.traceability import JobSummaryAnnotation
38
+ from hexaqueue_github_runner.infra.router import (
39
+ WebhookActionResponse,
40
+ create_github_webhook_router,
41
+ )
42
+ from hexaqueue_github_runner.ports.autoscaler import (
43
+ GitHubRunnerAutoscalerPort,
44
+ )
45
+ from hexaqueue_github_runner.ports.client import GitHubApiClientPort
46
+ from hexaqueue_github_runner.ports.verifier import WebhookVerifierPort
47
+
48
+ __all__ = [
49
+ "create_github_app_jwt",
50
+ "create_github_webhook_router",
51
+ "DynamicGitHubRunnerAutoscaler",
52
+ "GitHubApiClient",
53
+ "GitHubApiClientPort",
54
+ "GitHubAppCredentials",
55
+ "GitHubRepository",
56
+ "GitHubRunnerAutoscalerPort",
57
+ "GitHubWebhookAdapter",
58
+ "GitHubWorkflowJob",
59
+ "GitHubWorkflowJobAction",
60
+ "GitHubWorkflowJobPayload",
61
+ "HmacSha256WebhookVerifier",
62
+ "InMemoryGitHubApiClient",
63
+ "JitRunnerConfig",
64
+ "JobSummaryAnnotation",
65
+ "LabelTranslator",
66
+ "NaiveAutoscalerOracle",
67
+ "RunnerPoolState",
68
+ "WarmPoolConfig",
69
+ "WarmPoolRunner",
70
+ "WebhookActionResponse",
71
+ "WebhookVerifierPort",
72
+ ]
@@ -0,0 +1,30 @@
1
+ """Adapters for GitHub Actions runner autoscaler.
2
+
3
+ Notes/Architectural Intent:
4
+ Concrete implementations of GitHub API client, cryptographic HMAC
5
+ verification, autoscaling coordinator, and HTTP webhook ingestion.
6
+ """
7
+
8
+ from hexaqueue_github_runner.adapters.autoscaler import (
9
+ DynamicGitHubRunnerAutoscaler,
10
+ NaiveAutoscalerOracle,
11
+ )
12
+ from hexaqueue_github_runner.adapters.crypto import HmacSha256WebhookVerifier
13
+ from hexaqueue_github_runner.adapters.github_client import (
14
+ GitHubApiClient,
15
+ InMemoryGitHubApiClient,
16
+ create_github_app_jwt,
17
+ )
18
+ from hexaqueue_github_runner.adapters.webhook_adapter import (
19
+ GitHubWebhookAdapter,
20
+ )
21
+
22
+ __all__ = [
23
+ "create_github_app_jwt",
24
+ "DynamicGitHubRunnerAutoscaler",
25
+ "GitHubApiClient",
26
+ "GitHubWebhookAdapter",
27
+ "HmacSha256WebhookVerifier",
28
+ "InMemoryGitHubApiClient",
29
+ "NaiveAutoscalerOracle",
30
+ ]