kuberoku 0.1.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.
- kuberoku-0.1.0/.editorconfig +15 -0
- kuberoku-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +32 -0
- kuberoku-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +17 -0
- kuberoku-0.1.0/.github/workflows/compat.yml +37 -0
- kuberoku-0.1.0/.github/workflows/release.yml +226 -0
- kuberoku-0.1.0/.github/workflows/tests.yml +144 -0
- kuberoku-0.1.0/.gitignore +35 -0
- kuberoku-0.1.0/CHANGELOG.md +22 -0
- kuberoku-0.1.0/CLAUDE.md +98 -0
- kuberoku-0.1.0/CODEOWNERS +2 -0
- kuberoku-0.1.0/CONTRIBUTING.md +147 -0
- kuberoku-0.1.0/LICENSE +190 -0
- kuberoku-0.1.0/PKG-INFO +326 -0
- kuberoku-0.1.0/README.md +289 -0
- kuberoku-0.1.0/SECURITY.md +34 -0
- kuberoku-0.1.0/docs/NORTHSTAR.txt +8751 -0
- kuberoku-0.1.0/docs/PROGRESS.md +389 -0
- kuberoku-0.1.0/kuberoku.spec +78 -0
- kuberoku-0.1.0/pyproject.toml +98 -0
- kuberoku-0.1.0/scripts/_common.sh +62 -0
- kuberoku-0.1.0/scripts/act-local.sh +36 -0
- kuberoku-0.1.0/scripts/dev-setup.sh +129 -0
- kuberoku-0.1.0/scripts/install.ps1 +72 -0
- kuberoku-0.1.0/scripts/install.sh +170 -0
- kuberoku-0.1.0/scripts/lint.sh +49 -0
- kuberoku-0.1.0/scripts/secure.sh +41 -0
- kuberoku-0.1.0/scripts/test-install.sh +179 -0
- kuberoku-0.1.0/scripts/test.sh +86 -0
- kuberoku-0.1.0/src/kuberoku/__init__.py +6 -0
- kuberoku-0.1.0/src/kuberoku/__main__.py +5 -0
- kuberoku-0.1.0/src/kuberoku/_version.py +1 -0
- kuberoku-0.1.0/src/kuberoku/addons/__init__.py +78 -0
- kuberoku-0.1.0/src/kuberoku/addons/_types.py +46 -0
- kuberoku-0.1.0/src/kuberoku/addons/postgres.py +95 -0
- kuberoku-0.1.0/src/kuberoku/addons/redis.py +52 -0
- kuberoku-0.1.0/src/kuberoku/branding.py +43 -0
- kuberoku-0.1.0/src/kuberoku/cli/__init__.py +0 -0
- kuberoku-0.1.0/src/kuberoku/cli/addons.py +473 -0
- kuberoku-0.1.0/src/kuberoku/cli/apps.py +282 -0
- kuberoku-0.1.0/src/kuberoku/cli/clusters.py +238 -0
- kuberoku-0.1.0/src/kuberoku/cli/config.py +155 -0
- kuberoku-0.1.0/src/kuberoku/cli/context.py +88 -0
- kuberoku-0.1.0/src/kuberoku/cli/deploy.py +77 -0
- kuberoku-0.1.0/src/kuberoku/cli/domains.py +147 -0
- kuberoku-0.1.0/src/kuberoku/cli/main.py +101 -0
- kuberoku-0.1.0/src/kuberoku/cli/output.py +92 -0
- kuberoku-0.1.0/src/kuberoku/cli/plugins.py +81 -0
- kuberoku-0.1.0/src/kuberoku/cli/ps.py +216 -0
- kuberoku-0.1.0/src/kuberoku/cli/releases.py +91 -0
- kuberoku-0.1.0/src/kuberoku/cli/services.py +475 -0
- kuberoku-0.1.0/src/kuberoku/client.py +97 -0
- kuberoku-0.1.0/src/kuberoku/config/__init__.py +0 -0
- kuberoku-0.1.0/src/kuberoku/config/project.py +196 -0
- kuberoku-0.1.0/src/kuberoku/config/user.py +179 -0
- kuberoku-0.1.0/src/kuberoku/exceptions.py +365 -0
- kuberoku-0.1.0/src/kuberoku/factory.py +246 -0
- kuberoku-0.1.0/src/kuberoku/k8s/__init__.py +0 -0
- kuberoku-0.1.0/src/kuberoku/k8s/client.py +598 -0
- kuberoku-0.1.0/src/kuberoku/k8s/labels.py +52 -0
- kuberoku-0.1.0/src/kuberoku/k8s/protocols.py +233 -0
- kuberoku-0.1.0/src/kuberoku/k8s/resources.py +669 -0
- kuberoku-0.1.0/src/kuberoku/models.py +293 -0
- kuberoku-0.1.0/src/kuberoku/plugins/__init__.py +5 -0
- kuberoku-0.1.0/src/kuberoku/plugins/loader.py +79 -0
- kuberoku-0.1.0/src/kuberoku/py.typed +0 -0
- kuberoku-0.1.0/src/kuberoku/sdk/__init__.py +0 -0
- kuberoku-0.1.0/src/kuberoku/sdk/addons.py +1645 -0
- kuberoku-0.1.0/src/kuberoku/sdk/apps.py +700 -0
- kuberoku-0.1.0/src/kuberoku/sdk/build.py +193 -0
- kuberoku-0.1.0/src/kuberoku/sdk/checks.py +837 -0
- kuberoku-0.1.0/src/kuberoku/sdk/clusters.py +186 -0
- kuberoku-0.1.0/src/kuberoku/sdk/config.py +462 -0
- kuberoku-0.1.0/src/kuberoku/sdk/deploy.py +566 -0
- kuberoku-0.1.0/src/kuberoku/sdk/doctor.py +78 -0
- kuberoku-0.1.0/src/kuberoku/sdk/domains.py +438 -0
- kuberoku-0.1.0/src/kuberoku/sdk/gateway.py +332 -0
- kuberoku-0.1.0/src/kuberoku/sdk/ingress.py +167 -0
- kuberoku-0.1.0/src/kuberoku/sdk/plugins.py +155 -0
- kuberoku-0.1.0/src/kuberoku/sdk/procfile.py +34 -0
- kuberoku-0.1.0/src/kuberoku/sdk/ps.py +476 -0
- kuberoku-0.1.0/src/kuberoku/sdk/rbac.py +252 -0
- kuberoku-0.1.0/src/kuberoku/sdk/registry.py +136 -0
- kuberoku-0.1.0/src/kuberoku/sdk/releases.py +323 -0
- kuberoku-0.1.0/src/kuberoku/sdk/services.py +1144 -0
- kuberoku-0.1.0/tests/__init__.py +0 -0
- kuberoku-0.1.0/tests/addons/__init__.py +0 -0
- kuberoku-0.1.0/tests/addons/test_cli_addons.py +138 -0
- kuberoku-0.1.0/tests/addons/test_connect.py +37 -0
- kuberoku-0.1.0/tests/addons/test_create.py +144 -0
- kuberoku-0.1.0/tests/addons/test_credentials.py +38 -0
- kuberoku-0.1.0/tests/addons/test_destroy.py +100 -0
- kuberoku-0.1.0/tests/addons/test_ephemeral.py +34 -0
- kuberoku-0.1.0/tests/addons/test_expose.py +152 -0
- kuberoku-0.1.0/tests/addons/test_expose_gateway.py +170 -0
- kuberoku-0.1.0/tests/addons/test_external.py +29 -0
- kuberoku-0.1.0/tests/addons/test_info.py +30 -0
- kuberoku-0.1.0/tests/addons/test_list.py +42 -0
- kuberoku-0.1.0/tests/addons/test_multi_instance.py +85 -0
- kuberoku-0.1.0/tests/addons/test_upgrade.py +29 -0
- kuberoku-0.1.0/tests/addons/test_versioning.py +409 -0
- kuberoku-0.1.0/tests/apps/__init__.py +0 -0
- kuberoku-0.1.0/tests/apps/conftest.py +14 -0
- kuberoku-0.1.0/tests/apps/test_create.py +153 -0
- kuberoku-0.1.0/tests/apps/test_destroy.py +200 -0
- kuberoku-0.1.0/tests/apps/test_info.py +106 -0
- kuberoku-0.1.0/tests/apps/test_link.py +245 -0
- kuberoku-0.1.0/tests/apps/test_list.py +62 -0
- kuberoku-0.1.0/tests/apps/test_maintenance.py +158 -0
- kuberoku-0.1.0/tests/apps/test_rename.py +169 -0
- kuberoku-0.1.0/tests/apps/test_status.py +140 -0
- kuberoku-0.1.0/tests/backends/__init__.py +0 -0
- kuberoku-0.1.0/tests/backends/fake.py +551 -0
- kuberoku-0.1.0/tests/backends/real.py +387 -0
- kuberoku-0.1.0/tests/clusters/__init__.py +0 -0
- kuberoku-0.1.0/tests/clusters/test_checks.py +290 -0
- kuberoku-0.1.0/tests/clusters/test_checks_phase9.py +154 -0
- kuberoku-0.1.0/tests/clusters/test_cli_clusters.py +359 -0
- kuberoku-0.1.0/tests/clusters/test_clusters.py +231 -0
- kuberoku-0.1.0/tests/config/__init__.py +0 -0
- kuberoku-0.1.0/tests/config/conftest.py +24 -0
- kuberoku-0.1.0/tests/config/test_get.py +110 -0
- kuberoku-0.1.0/tests/config/test_list.py +194 -0
- kuberoku-0.1.0/tests/config/test_set.py +289 -0
- kuberoku-0.1.0/tests/config/test_unset.py +141 -0
- kuberoku-0.1.0/tests/conftest.py +324 -0
- kuberoku-0.1.0/tests/contract/__init__.py +0 -0
- kuberoku-0.1.0/tests/contract/conftest.py +46 -0
- kuberoku-0.1.0/tests/contract/test_configmap_crud.py +124 -0
- kuberoku-0.1.0/tests/contract/test_deployment_crud.py +123 -0
- kuberoku-0.1.0/tests/contract/test_ingress_crud.py +196 -0
- kuberoku-0.1.0/tests/contract/test_namespace_crud.py +48 -0
- kuberoku-0.1.0/tests/contract/test_network_policy_crud.py +156 -0
- kuberoku-0.1.0/tests/contract/test_pvc_crud.py +85 -0
- kuberoku-0.1.0/tests/contract/test_secret_crud.py +111 -0
- kuberoku-0.1.0/tests/contract/test_service_crud.py +90 -0
- kuberoku-0.1.0/tests/contract/test_statefulset_crud.py +100 -0
- kuberoku-0.1.0/tests/deploy/__init__.py +0 -0
- kuberoku-0.1.0/tests/deploy/test_auto_domain_deploy.py +163 -0
- kuberoku-0.1.0/tests/deploy/test_build.py +230 -0
- kuberoku-0.1.0/tests/deploy/test_deploy_retry.py +85 -0
- kuberoku-0.1.0/tests/deploy/test_image.py +235 -0
- kuberoku-0.1.0/tests/deploy/test_multi_app.py +354 -0
- kuberoku-0.1.0/tests/deploy/test_procfile_deploy.py +101 -0
- kuberoku-0.1.0/tests/deploy/test_release_create.py +159 -0
- kuberoku-0.1.0/tests/deploy/test_releases_list.py +57 -0
- kuberoku-0.1.0/tests/deploy/test_releases_prune.py +44 -0
- kuberoku-0.1.0/tests/deploy/test_rollback.py +72 -0
- kuberoku-0.1.0/tests/deploy/test_wait.py +128 -0
- kuberoku-0.1.0/tests/domains/__init__.py +0 -0
- kuberoku-0.1.0/tests/domains/conftest.py +117 -0
- kuberoku-0.1.0/tests/domains/test_add.py +363 -0
- kuberoku-0.1.0/tests/domains/test_auto_domain.py +149 -0
- kuberoku-0.1.0/tests/domains/test_clear.py +50 -0
- kuberoku-0.1.0/tests/domains/test_cli_domains.py +316 -0
- kuberoku-0.1.0/tests/domains/test_list.py +42 -0
- kuberoku-0.1.0/tests/domains/test_remove.py +134 -0
- kuberoku-0.1.0/tests/e2e/__init__.py +0 -0
- kuberoku-0.1.0/tests/e2e/conftest.py +47 -0
- kuberoku-0.1.0/tests/e2e/helpers.py +476 -0
- kuberoku-0.1.0/tests/e2e/test_addon_lifecycle.py +786 -0
- kuberoku-0.1.0/tests/e2e/test_addon_versioning.py +522 -0
- kuberoku-0.1.0/tests/e2e/test_apps_rename.py +96 -0
- kuberoku-0.1.0/tests/e2e/test_clusters_config.py +115 -0
- kuberoku-0.1.0/tests/e2e/test_config_lifecycle.py +243 -0
- kuberoku-0.1.0/tests/e2e/test_doctor_setup.py +200 -0
- kuberoku-0.1.0/tests/e2e/test_domains_lifecycle.py +202 -0
- kuberoku-0.1.0/tests/e2e/test_expose_connect.py +283 -0
- kuberoku-0.1.0/tests/e2e/test_git_deploy.py +399 -0
- kuberoku-0.1.0/tests/e2e/test_hello_world.py +353 -0
- kuberoku-0.1.0/tests/e2e/test_link_lifecycle.py +116 -0
- kuberoku-0.1.0/tests/e2e/test_maintenance_lifecycle.py +350 -0
- kuberoku-0.1.0/tests/e2e/test_multi_port.py +119 -0
- kuberoku-0.1.0/tests/e2e/test_network_isolation.py +189 -0
- kuberoku-0.1.0/tests/e2e/test_plugins.py +85 -0
- kuberoku-0.1.0/tests/e2e/test_releases_prune.py +102 -0
- kuberoku-0.1.0/tests/e2e/test_services_logs_exec.py +277 -0
- kuberoku-0.1.0/tests/infrastructure/__init__.py +0 -0
- kuberoku-0.1.0/tests/infrastructure/test_addon_types.py +118 -0
- kuberoku-0.1.0/tests/infrastructure/test_branding.py +46 -0
- kuberoku-0.1.0/tests/infrastructure/test_cli_logs_exec.py +292 -0
- kuberoku-0.1.0/tests/infrastructure/test_cli_networking.py +226 -0
- kuberoku-0.1.0/tests/infrastructure/test_cli_phase4.py +311 -0
- kuberoku-0.1.0/tests/infrastructure/test_client.py +54 -0
- kuberoku-0.1.0/tests/infrastructure/test_colon_commands.py +36 -0
- kuberoku-0.1.0/tests/infrastructure/test_context.py +144 -0
- kuberoku-0.1.0/tests/infrastructure/test_doctor.py +372 -0
- kuberoku-0.1.0/tests/infrastructure/test_duration.py +51 -0
- kuberoku-0.1.0/tests/infrastructure/test_error_boundary.py +91 -0
- kuberoku-0.1.0/tests/infrastructure/test_exceptions.py +269 -0
- kuberoku-0.1.0/tests/infrastructure/test_factory.py +105 -0
- kuberoku-0.1.0/tests/infrastructure/test_gateway.py +256 -0
- kuberoku-0.1.0/tests/infrastructure/test_idempotent_cleanup.py +609 -0
- kuberoku-0.1.0/tests/infrastructure/test_ingress_detection.py +353 -0
- kuberoku-0.1.0/tests/infrastructure/test_k8s_client.py +487 -0
- kuberoku-0.1.0/tests/infrastructure/test_labels.py +62 -0
- kuberoku-0.1.0/tests/infrastructure/test_models.py +269 -0
- kuberoku-0.1.0/tests/infrastructure/test_networking_resources.py +132 -0
- kuberoku-0.1.0/tests/infrastructure/test_output.py +33 -0
- kuberoku-0.1.0/tests/infrastructure/test_port_parsing.py +49 -0
- kuberoku-0.1.0/tests/infrastructure/test_procfile.py +73 -0
- kuberoku-0.1.0/tests/infrastructure/test_rbac.py +335 -0
- kuberoku-0.1.0/tests/infrastructure/test_registry.py +262 -0
- kuberoku-0.1.0/tests/infrastructure/test_resources.py +382 -0
- kuberoku-0.1.0/tests/infrastructure/test_user_config.py +203 -0
- kuberoku-0.1.0/tests/plugins/__init__.py +0 -0
- kuberoku-0.1.0/tests/plugins/test_cli_plugins.py +121 -0
- kuberoku-0.1.0/tests/plugins/test_loader.py +195 -0
- kuberoku-0.1.0/tests/plugins/test_plugins_service.py +195 -0
- kuberoku-0.1.0/tests/ps/__init__.py +0 -0
- kuberoku-0.1.0/tests/ps/conftest.py +39 -0
- kuberoku-0.1.0/tests/ps/test_commands.py +23 -0
- kuberoku-0.1.0/tests/ps/test_list.py +52 -0
- kuberoku-0.1.0/tests/ps/test_restart.py +82 -0
- kuberoku-0.1.0/tests/ps/test_scale.py +48 -0
- kuberoku-0.1.0/tests/ps/test_set.py +82 -0
- kuberoku-0.1.0/tests/ps/test_stop.py +20 -0
- kuberoku-0.1.0/tests/ps/test_type.py +83 -0
- kuberoku-0.1.0/tests/services/__init__.py +0 -0
- kuberoku-0.1.0/tests/services/conftest.py +121 -0
- kuberoku-0.1.0/tests/services/test_connect.py +57 -0
- kuberoku-0.1.0/tests/services/test_exec.py +182 -0
- kuberoku-0.1.0/tests/services/test_expose.py +88 -0
- kuberoku-0.1.0/tests/services/test_expose_gateway.py +178 -0
- kuberoku-0.1.0/tests/services/test_logs.py +140 -0
- kuberoku-0.1.0/tests/services/test_logs_follow.py +145 -0
- kuberoku-0.1.0/tests/services/test_maintenance.py +148 -0
- kuberoku-0.1.0/tests/services/test_name_resolution.py +44 -0
- kuberoku-0.1.0/tests/services/test_open.py +192 -0
- kuberoku-0.1.0/tests/services/test_ports_add.py +141 -0
- kuberoku-0.1.0/tests/services/test_ports_list.py +52 -0
- kuberoku-0.1.0/tests/services/test_ports_remove.py +173 -0
- kuberoku-0.1.0/tests/services/test_unexpose.py +103 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Something isn't working as expected.
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what-happened
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened?
|
|
9
|
+
description: Describe the bug. What did you expect vs. what actually happened?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: reproduce
|
|
15
|
+
attributes:
|
|
16
|
+
label: Steps to reproduce
|
|
17
|
+
description: Minimal commands to reproduce the issue.
|
|
18
|
+
placeholder: |
|
|
19
|
+
kuberoku apps:create myapp
|
|
20
|
+
kuberoku deploy --app myapp --image nginx:1.27 --port 80/tcp
|
|
21
|
+
# error happens here
|
|
22
|
+
|
|
23
|
+
- type: textarea
|
|
24
|
+
id: environment
|
|
25
|
+
attributes:
|
|
26
|
+
label: Environment
|
|
27
|
+
description: Paste the output of the commands below.
|
|
28
|
+
placeholder: |
|
|
29
|
+
kuberoku --version
|
|
30
|
+
kubectl version
|
|
31
|
+
python --version
|
|
32
|
+
uname -a
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest an idea or improvement.
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: description
|
|
7
|
+
attributes:
|
|
8
|
+
label: What would you like?
|
|
9
|
+
description: Describe the feature or improvement.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: use-case
|
|
15
|
+
attributes:
|
|
16
|
+
label: Use case
|
|
17
|
+
description: Why do you need this? What problem does it solve?
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Compatibility Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 6 * * 1" # Weekly: Monday 06:00 UTC
|
|
6
|
+
workflow_dispatch: # Manual trigger
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
compat:
|
|
10
|
+
name: Compat (kind) — K8s ${{ matrix.k8s-version }}
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
k8s-version: ["v1.33.0", "v1.34.0", "v1.35.0"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
|
|
25
|
+
- name: Create kind cluster
|
|
26
|
+
uses: helm/kind-action@v1
|
|
27
|
+
with:
|
|
28
|
+
cluster_name: kuberoku-compat
|
|
29
|
+
node_image: kindest/node:${{ matrix.k8s-version }}
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: |
|
|
33
|
+
python -m pip install --upgrade pip
|
|
34
|
+
pip install -e ".[dev]"
|
|
35
|
+
|
|
36
|
+
- name: All tests against real K8s (kind)
|
|
37
|
+
run: pytest tests/ --backend real -v
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
actions: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
gate:
|
|
13
|
+
name: Release gate — verify CI passed on this commit
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Verify CI passed on this commit
|
|
19
|
+
env:
|
|
20
|
+
GH_TOKEN: ${{ github.token }}
|
|
21
|
+
run: |
|
|
22
|
+
SHA=$(git rev-parse HEAD)
|
|
23
|
+
echo "Checking CI status for commit $SHA..."
|
|
24
|
+
|
|
25
|
+
# Wait up to 5 minutes for the Tests workflow to complete (tag push may race with CI)
|
|
26
|
+
for i in $(seq 1 30); do
|
|
27
|
+
RUN_JSON=$(gh run list --commit "$SHA" --workflow "Tests" --json status,conclusion --limit 1)
|
|
28
|
+
RUN_STATUS=$(echo "$RUN_JSON" | jq -r '.[0].status // "none"')
|
|
29
|
+
RUN_CONCLUSION=$(echo "$RUN_JSON" | jq -r '.[0].conclusion // "none"')
|
|
30
|
+
echo " Attempt $i: status=$RUN_STATUS conclusion=$RUN_CONCLUSION"
|
|
31
|
+
|
|
32
|
+
if [ "$RUN_STATUS" = "completed" ]; then
|
|
33
|
+
if [ "$RUN_CONCLUSION" = "success" ]; then
|
|
34
|
+
echo "Tests workflow passed."
|
|
35
|
+
exit 0
|
|
36
|
+
else
|
|
37
|
+
echo "::error::Tests workflow failed ($RUN_CONCLUSION). Fix tests before releasing."
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# not found or still running — wait and retry
|
|
43
|
+
sleep 10
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
echo "::error::Tests workflow did not complete within 5 minutes. Push to main first and wait for green CI."
|
|
47
|
+
exit 1
|
|
48
|
+
|
|
49
|
+
- name: Verify tag matches package version
|
|
50
|
+
run: |
|
|
51
|
+
TAG="${GITHUB_REF#refs/tags/v}"
|
|
52
|
+
PKG_VERSION=$(python3 -c "exec(open('src/kuberoku/_version.py').read()); print(__version__)")
|
|
53
|
+
if [ "$TAG" != "$PKG_VERSION" ]; then
|
|
54
|
+
echo "::error::Tag v${TAG} does not match _version.py (${PKG_VERSION})"
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# ── Publish to PyPI ──────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
publish:
|
|
61
|
+
name: Publish to PyPI
|
|
62
|
+
needs: gate
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
environment: pypi
|
|
65
|
+
permissions:
|
|
66
|
+
contents: read
|
|
67
|
+
id-token: write
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/checkout@v4
|
|
70
|
+
|
|
71
|
+
- name: Set up Python
|
|
72
|
+
uses: actions/setup-python@v5
|
|
73
|
+
with:
|
|
74
|
+
python-version: "3.12"
|
|
75
|
+
|
|
76
|
+
- name: Install build tools
|
|
77
|
+
run: python -m pip install --upgrade pip build
|
|
78
|
+
|
|
79
|
+
- name: Verify tag matches package version
|
|
80
|
+
run: |
|
|
81
|
+
TAG="${GITHUB_REF#refs/tags/v}"
|
|
82
|
+
PKG_VERSION=$(python -c "exec(open('src/kuberoku/_version.py').read()); print(__version__)")
|
|
83
|
+
if [ "$TAG" != "$PKG_VERSION" ]; then
|
|
84
|
+
echo "::error::Tag v${TAG} does not match _version.py (${PKG_VERSION})"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
- name: Build sdist and wheel
|
|
89
|
+
run: python -m build
|
|
90
|
+
|
|
91
|
+
- name: Publish to PyPI
|
|
92
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
93
|
+
|
|
94
|
+
# ── Native binaries (4 targets) ─────────────────────────────────
|
|
95
|
+
|
|
96
|
+
binaries:
|
|
97
|
+
name: Binary — ${{ matrix.os }}-${{ matrix.arch }}
|
|
98
|
+
needs: gate
|
|
99
|
+
runs-on: ${{ matrix.runner }}
|
|
100
|
+
strategy:
|
|
101
|
+
fail-fast: false
|
|
102
|
+
matrix:
|
|
103
|
+
include:
|
|
104
|
+
- os: linux
|
|
105
|
+
arch: amd64
|
|
106
|
+
runner: ubuntu-latest
|
|
107
|
+
asset: kuberoku-linux-amd64
|
|
108
|
+
- os: darwin
|
|
109
|
+
arch: arm64
|
|
110
|
+
runner: macos-latest
|
|
111
|
+
asset: kuberoku-darwin-arm64
|
|
112
|
+
- os: darwin
|
|
113
|
+
arch: amd64
|
|
114
|
+
runner: macos-15-intel
|
|
115
|
+
asset: kuberoku-darwin-amd64
|
|
116
|
+
- os: windows
|
|
117
|
+
arch: amd64
|
|
118
|
+
runner: windows-latest
|
|
119
|
+
asset: kuberoku-windows-amd64.exe
|
|
120
|
+
|
|
121
|
+
steps:
|
|
122
|
+
- uses: actions/checkout@v4
|
|
123
|
+
|
|
124
|
+
- name: Set up Python
|
|
125
|
+
uses: actions/setup-python@v5
|
|
126
|
+
with:
|
|
127
|
+
python-version: "3.12"
|
|
128
|
+
|
|
129
|
+
- name: Install dependencies
|
|
130
|
+
run: |
|
|
131
|
+
python -m pip install --upgrade pip
|
|
132
|
+
pip install .
|
|
133
|
+
pip install pyinstaller
|
|
134
|
+
|
|
135
|
+
- name: Build binary
|
|
136
|
+
run: pyinstaller kuberoku.spec
|
|
137
|
+
|
|
138
|
+
- name: Rename binary (unix)
|
|
139
|
+
if: matrix.os != 'windows'
|
|
140
|
+
run: mv dist/kuberoku dist/${{ matrix.asset }}
|
|
141
|
+
|
|
142
|
+
- name: Rename binary (windows)
|
|
143
|
+
if: matrix.os == 'windows'
|
|
144
|
+
shell: bash
|
|
145
|
+
run: mv dist/kuberoku.exe dist/${{ matrix.asset }}
|
|
146
|
+
|
|
147
|
+
- name: Smoke test
|
|
148
|
+
if: matrix.os != 'windows'
|
|
149
|
+
run: ./dist/${{ matrix.asset }} --version
|
|
150
|
+
|
|
151
|
+
- name: Smoke test (windows)
|
|
152
|
+
if: matrix.os == 'windows'
|
|
153
|
+
shell: bash
|
|
154
|
+
run: ./dist/${{ matrix.asset }} --version
|
|
155
|
+
|
|
156
|
+
- name: Upload artifact
|
|
157
|
+
uses: actions/upload-artifact@v4
|
|
158
|
+
with:
|
|
159
|
+
name: ${{ matrix.asset }}
|
|
160
|
+
path: dist/${{ matrix.asset }}
|
|
161
|
+
|
|
162
|
+
# ── Linux ARM64 via QEMU ────────────────────────────────────────
|
|
163
|
+
|
|
164
|
+
binary-linux-arm64:
|
|
165
|
+
name: Binary — linux-arm64 (QEMU)
|
|
166
|
+
needs: gate
|
|
167
|
+
runs-on: ubuntu-latest
|
|
168
|
+
steps:
|
|
169
|
+
- uses: actions/checkout@v4
|
|
170
|
+
|
|
171
|
+
- name: Set up QEMU
|
|
172
|
+
uses: docker/setup-qemu-action@v3
|
|
173
|
+
|
|
174
|
+
- name: Build in ARM64 container
|
|
175
|
+
run: |
|
|
176
|
+
docker run --rm --platform linux/arm64 \
|
|
177
|
+
-v "${{ github.workspace }}:/work" \
|
|
178
|
+
-w /work \
|
|
179
|
+
python:3.12-slim \
|
|
180
|
+
sh -c '
|
|
181
|
+
apt-get update && apt-get install -y --no-install-recommends binutils &&
|
|
182
|
+
pip install --upgrade pip &&
|
|
183
|
+
pip install . &&
|
|
184
|
+
pip install pyinstaller &&
|
|
185
|
+
pyinstaller kuberoku.spec &&
|
|
186
|
+
mv dist/kuberoku dist/kuberoku-linux-arm64
|
|
187
|
+
'
|
|
188
|
+
|
|
189
|
+
- name: Upload artifact
|
|
190
|
+
uses: actions/upload-artifact@v4
|
|
191
|
+
with:
|
|
192
|
+
name: kuberoku-linux-arm64
|
|
193
|
+
path: dist/kuberoku-linux-arm64
|
|
194
|
+
|
|
195
|
+
# ── GitHub Release ──────────────────────────────────────────────
|
|
196
|
+
|
|
197
|
+
release:
|
|
198
|
+
name: Create GitHub Release
|
|
199
|
+
needs: [publish, binaries, binary-linux-arm64]
|
|
200
|
+
runs-on: ubuntu-latest
|
|
201
|
+
permissions:
|
|
202
|
+
contents: write
|
|
203
|
+
steps:
|
|
204
|
+
- uses: actions/checkout@v4
|
|
205
|
+
|
|
206
|
+
- name: Download all artifacts
|
|
207
|
+
uses: actions/download-artifact@v4
|
|
208
|
+
with:
|
|
209
|
+
path: artifacts
|
|
210
|
+
merge-multiple: true
|
|
211
|
+
|
|
212
|
+
- name: List artifacts
|
|
213
|
+
run: ls -lhR artifacts/
|
|
214
|
+
|
|
215
|
+
- name: Create release
|
|
216
|
+
uses: softprops/action-gh-release@v2
|
|
217
|
+
with:
|
|
218
|
+
generate_release_notes: true
|
|
219
|
+
files: |
|
|
220
|
+
artifacts/kuberoku-linux-amd64
|
|
221
|
+
artifacts/kuberoku-linux-arm64
|
|
222
|
+
artifacts/kuberoku-darwin-amd64
|
|
223
|
+
artifacts/kuberoku-darwin-arm64
|
|
224
|
+
artifacts/kuberoku-windows-amd64.exe
|
|
225
|
+
scripts/install.sh
|
|
226
|
+
scripts/install.ps1
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
name: Lint & Type Check
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
pip install -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Lint
|
|
27
|
+
run: ruff check src/ tests/
|
|
28
|
+
|
|
29
|
+
- name: Format check
|
|
30
|
+
run: ruff format --check src/ tests/
|
|
31
|
+
|
|
32
|
+
- name: Type check
|
|
33
|
+
run: mypy --strict src/kuberoku/
|
|
34
|
+
|
|
35
|
+
fake:
|
|
36
|
+
name: Tests (fake) — Python ${{ matrix.python-version }}
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
needs: lint
|
|
39
|
+
strategy:
|
|
40
|
+
fail-fast: false
|
|
41
|
+
matrix:
|
|
42
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
43
|
+
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
|
|
47
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
48
|
+
uses: actions/setup-python@v5
|
|
49
|
+
with:
|
|
50
|
+
python-version: ${{ matrix.python-version }}
|
|
51
|
+
|
|
52
|
+
- name: Install dependencies
|
|
53
|
+
run: |
|
|
54
|
+
python -m pip install --upgrade pip
|
|
55
|
+
pip install -e ".[dev]"
|
|
56
|
+
|
|
57
|
+
- name: Tests with coverage
|
|
58
|
+
run: pytest tests/ -v --backend fake -n auto --dist loadfile --cov=kuberoku --cov-report=term-missing
|
|
59
|
+
|
|
60
|
+
- name: Enforce coverage threshold
|
|
61
|
+
if: matrix.python-version == '3.12'
|
|
62
|
+
run: pytest tests/ -q --backend fake -n auto --dist loadfile --cov=kuberoku --cov-fail-under=90
|
|
63
|
+
|
|
64
|
+
integration:
|
|
65
|
+
name: Tests (real) — k3d K8s ${{ matrix.k8s-version }}
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
needs: lint
|
|
68
|
+
strategy:
|
|
69
|
+
fail-fast: false
|
|
70
|
+
matrix:
|
|
71
|
+
k8s-version: ["v1.33.7", "v1.34.3", "v1.35.0"]
|
|
72
|
+
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@v4
|
|
75
|
+
|
|
76
|
+
- name: Set up Python
|
|
77
|
+
uses: actions/setup-python@v5
|
|
78
|
+
with:
|
|
79
|
+
python-version: "3.12"
|
|
80
|
+
|
|
81
|
+
- name: Configure Docker for k3d insecure registry
|
|
82
|
+
run: |
|
|
83
|
+
echo '{"insecure-registries": ["k3d-registry.localhost:5000"]}' | sudo tee /etc/docker/daemon.json
|
|
84
|
+
sudo systemctl restart docker
|
|
85
|
+
|
|
86
|
+
- uses: AbsaOSS/k3d-action@v2
|
|
87
|
+
with:
|
|
88
|
+
cluster-name: kuberoku-test
|
|
89
|
+
k3d-version: v5.8.3
|
|
90
|
+
args: >-
|
|
91
|
+
--image rancher/k3s:${{ matrix.k8s-version }}-k3s1
|
|
92
|
+
--registry-create k3d-registry.localhost:5000
|
|
93
|
+
|
|
94
|
+
- name: Install dependencies
|
|
95
|
+
run: |
|
|
96
|
+
python -m pip install --upgrade pip
|
|
97
|
+
pip install -e ".[dev]"
|
|
98
|
+
|
|
99
|
+
- name: Setup cluster (cert-manager, etc.)
|
|
100
|
+
run: kuberoku clusters:setup
|
|
101
|
+
|
|
102
|
+
- name: All tests against real K8s
|
|
103
|
+
run: pytest tests/ --backend real -v -n4 --dist loadfile --runslow
|
|
104
|
+
env:
|
|
105
|
+
KUBEROKU_REGISTRY: k3d-registry.localhost:5000
|
|
106
|
+
|
|
107
|
+
smoke:
|
|
108
|
+
name: Smoke test (installed package)
|
|
109
|
+
needs: lint
|
|
110
|
+
runs-on: ubuntu-latest
|
|
111
|
+
steps:
|
|
112
|
+
- uses: actions/checkout@v4
|
|
113
|
+
|
|
114
|
+
- name: Set up Python
|
|
115
|
+
uses: actions/setup-python@v5
|
|
116
|
+
with:
|
|
117
|
+
python-version: "3.12"
|
|
118
|
+
|
|
119
|
+
- name: Install from built package
|
|
120
|
+
run: |
|
|
121
|
+
python -m pip install --upgrade pip
|
|
122
|
+
pip install .
|
|
123
|
+
|
|
124
|
+
- name: Verify entry point
|
|
125
|
+
run: |
|
|
126
|
+
kuberoku --version
|
|
127
|
+
kuberoku --help
|
|
128
|
+
|
|
129
|
+
- name: Verify SDK import
|
|
130
|
+
run: |
|
|
131
|
+
python -c "from kuberoku import Kuberoku, __version__; print('SDK OK: ' + __version__)"
|
|
132
|
+
|
|
133
|
+
installer:
|
|
134
|
+
name: Test install script (multi-distro)
|
|
135
|
+
needs: lint
|
|
136
|
+
runs-on: ubuntu-latest
|
|
137
|
+
steps:
|
|
138
|
+
- uses: actions/checkout@v4
|
|
139
|
+
|
|
140
|
+
- name: Install shellcheck
|
|
141
|
+
run: sudo apt-get install -y shellcheck
|
|
142
|
+
|
|
143
|
+
- name: Run installer test suite
|
|
144
|
+
run: sh scripts/test-install.sh
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
*.egg
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
|
|
10
|
+
# Virtual environments
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
|
|
14
|
+
# Type checking / linting
|
|
15
|
+
.mypy_cache/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
|
|
18
|
+
# Testing
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.coverage
|
|
21
|
+
htmlcov/
|
|
22
|
+
|
|
23
|
+
# IDE
|
|
24
|
+
.idea/
|
|
25
|
+
.vscode/
|
|
26
|
+
*.swp
|
|
27
|
+
*.swo
|
|
28
|
+
*~
|
|
29
|
+
|
|
30
|
+
# OS
|
|
31
|
+
.DS_Store
|
|
32
|
+
Thumbs.db
|
|
33
|
+
|
|
34
|
+
# Project
|
|
35
|
+
.kuberoku
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (unreleased)
|
|
4
|
+
|
|
5
|
+
Initial alpha release.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Apps**: create, destroy, info, rename, status, link, maintenance
|
|
10
|
+
- **Config**: set, get, unset with secret masking and optimistic concurrency
|
|
11
|
+
- **Deploy**: image deploy, build-from-git, multi-process types
|
|
12
|
+
- **PS**: scale, restart, stop, type, set commands
|
|
13
|
+
- **Releases**: info, rollback, prune with full audit trail
|
|
14
|
+
- **Services**: expose, ports, logs, exec, connect, maintenance
|
|
15
|
+
- **Addons**: PostgreSQL and Redis with credentials, backup, exec, connect
|
|
16
|
+
- **Addon versioning**: create with `--version`, `addons:migrate` (backup → PVC wipe → restore for Postgres), `addons:migrate-rollback`
|
|
17
|
+
- **Plugins**: install, uninstall, search via PyPI entry points
|
|
18
|
+
- **Domains**: add, remove, clear with Ingress management
|
|
19
|
+
- **Clusters**: add, remove, switch, current, info, doctor, setup
|
|
20
|
+
- **Networking**: default-deny NetworkPolicies, per-process allow rules
|
|
21
|
+
- **SDK**: full Python API matching CLI 1:1, frozen dataclasses, typed exceptions
|
|
22
|
+
- **Distribution**: PyPI package, pre-built binaries (Linux, macOS, Windows), curl installer
|
kuberoku-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Agent Instructions for kuberoku
|
|
2
|
+
|
|
3
|
+
Run `pytest tests/ -v && mypy src/kuberoku/ --strict && ruff check src/ tests/ && ruff format --check src/ tests/` to verify any file edits before prompting for input.
|
|
4
|
+
|
|
5
|
+
## What this is
|
|
6
|
+
|
|
7
|
+
Kuberoku is a Python CLI + SDK that gives developers Heroku-like DX on vanilla Kubernetes. Zero server-side components — CLI/SDK only, K8s is the database. The complete specification is in `docs/NORTHSTAR.txt` (~8000 lines, 19 sections).
|
|
8
|
+
|
|
9
|
+
## Architecture (strict three-layer)
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
CLI (Click) --> SDK (business logic) --> K8s (protocol + client)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- **CLI never touches K8s directly.** Calls one SDK method, formats the result.
|
|
16
|
+
- **SDK never prints.** Returns frozen dataclasses, raises typed exceptions, progress via `on_step` callback.
|
|
17
|
+
- **K8s client returns `dict[str, Any]`.** No K8s model objects leak upward. `typing.Protocol` defines the interface.
|
|
18
|
+
- **KuberokuFactory** is the DI container. Tests inject `FakeK8sClient`.
|
|
19
|
+
|
|
20
|
+
## Required before each commit
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pytest tests/ -v # tests pass
|
|
24
|
+
mypy src/kuberoku/ --strict # types check
|
|
25
|
+
ruff check src/ tests/ # lint clean
|
|
26
|
+
ruff format --check src/ tests/ # format clean
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Source layout
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
src/kuberoku/
|
|
33
|
+
branding.py # TOOL_NAME + all derived constants (single source)
|
|
34
|
+
models.py # Frozen dataclasses (App, Release, Dyno, etc.)
|
|
35
|
+
exceptions.py # KuberokuError hierarchy
|
|
36
|
+
factory.py # KuberokuFactory (DI container)
|
|
37
|
+
client.py # Public facade: from kuberoku import Kuberoku
|
|
38
|
+
k8s/
|
|
39
|
+
protocols.py # K8sClientProtocol (typing.Protocol)
|
|
40
|
+
client.py # Real K8s client (wraps kubernetes library)
|
|
41
|
+
labels.py # Label builders: for_app(), for_process(), selector()
|
|
42
|
+
resources.py # Resource dict builders: build_deployment(), safe_name()
|
|
43
|
+
sdk/ # One service per command group (apps.py, config.py, deploy.py, ...)
|
|
44
|
+
cli/ # One file per command group, mirrors sdk/ 1:1
|
|
45
|
+
main.py # ColonCommandGroup (colon commands), root group, entry point
|
|
46
|
+
tests/
|
|
47
|
+
backends/fake.py # FakeK8sClient (in-memory, implements K8sClientProtocol)
|
|
48
|
+
{feature}/ # tests/{apps,config,deploy,...}/test_{command}.py
|
|
49
|
+
infrastructure/ # tests for labels, resources, models, branding, factory
|
|
50
|
+
contract/ # FakeK8sClient matches real K8s behavior
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Key rules
|
|
54
|
+
|
|
55
|
+
- **Branding**: All identity constants derive from `branding.py`. No hardcoded "kuberoku" strings elsewhere.
|
|
56
|
+
- **Resource names**: `{PREFIX}-{type}-{app}[-{suffix}]`. Use `safe_name()` for 63-char K8s limit.
|
|
57
|
+
- **Labels**: `{DOMAIN}/managed-by`, `{DOMAIN}/app`, `{DOMAIN}/process-type`. See `k8s/labels.py`.
|
|
58
|
+
- **Optimistic concurrency**: All ConfigMap/Secret updates use `resourceVersion` + retry on 409.
|
|
59
|
+
- **Colon commands**: `apps:create` and `apps create` both work via `ColonCommandGroup.resolve_command()`.
|
|
60
|
+
- **LazyGroup**: Don't import sdk/ or k8s/ at CLI module level. Keeps `--help` under 100ms.
|
|
61
|
+
- **Cross-platform**: pathlib everywhere, no `shell=True`. Windows + Linux + macOS.
|
|
62
|
+
|
|
63
|
+
## Development workflow (TDD per command)
|
|
64
|
+
|
|
65
|
+
1. Write `tests/{feature}/test_{command}.py` first — SDK + CLI tests in same file
|
|
66
|
+
2. Implement SDK method in `src/kuberoku/sdk/`
|
|
67
|
+
3. Wire CLI command in `src/kuberoku/cli/`
|
|
68
|
+
4. Verify: tests, mypy, ruff all pass
|
|
69
|
+
|
|
70
|
+
## NORTHSTAR.txt section index
|
|
71
|
+
|
|
72
|
+
Read the relevant section when you need deeper context:
|
|
73
|
+
|
|
74
|
+
- Section 1: Vision & positioning
|
|
75
|
+
- Section 2: Branding & naming
|
|
76
|
+
- Section 3: End-to-end user experience
|
|
77
|
+
- Section 4: Command reference (all 62 commands)
|
|
78
|
+
- Section 5: Colon command implementation
|
|
79
|
+
- Section 6: SDK API design
|
|
80
|
+
- Section 7: Non-HTTP services & multi-port
|
|
81
|
+
- Section 8: Networking
|
|
82
|
+
- Section 9: Architecture & data storage
|
|
83
|
+
- Section 10: Data models
|
|
84
|
+
- Section 11: Exception hierarchy
|
|
85
|
+
- Section 12: Testing strategy (backends, fixtures, contract tests, TDD workflow)
|
|
86
|
+
- Section 13: Dependencies
|
|
87
|
+
- Section 14: Distribution
|
|
88
|
+
- Section 15: Plugin system
|
|
89
|
+
- Section 16: Implementation phases (0-14)
|
|
90
|
+
- Section 17: Cross-platform
|
|
91
|
+
- Section 18: Error UX
|
|
92
|
+
- Section 19: CI pipeline
|
|
93
|
+
|
|
94
|
+
## Dependencies
|
|
95
|
+
|
|
96
|
+
- Runtime: click >=8.1, kubernetes >=35, rich >=13, pyyaml >=6
|
|
97
|
+
- Dev: pytest, pytest-cov, pytest-mock, mypy (--strict), ruff, vulture, pip-audit, types-PyYAML
|
|
98
|
+
- Build: hatchling. Entry point: `kuberoku = "kuberoku.cli.main:run"`
|