graph-agents-cli 0.3.1__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.
- graph_agents_cli/__init__.py +26 -0
- graph_agents_cli/_api_policy.py +2145 -0
- graph_agents_cli/_approvals.py +400 -0
- graph_agents_cli/_build.py +186 -0
- graph_agents_cli/_build_info.json +7 -0
- graph_agents_cli/_chat_client.py +462 -0
- graph_agents_cli/_click.py +157 -0
- graph_agents_cli/_defaults.py +139 -0
- graph_agents_cli/_experiments.py +64 -0
- graph_agents_cli/_http.py +192 -0
- graph_agents_cli/_output.py +83 -0
- graph_agents_cli/_project.py +462 -0
- graph_agents_cli/_remote.py +220 -0
- graph_agents_cli/_response_schema.py +264 -0
- graph_agents_cli/_runner.py +319 -0
- graph_agents_cli/_skills_check.py +274 -0
- graph_agents_cli/_tools.py +189 -0
- graph_agents_cli/_trust.py +66 -0
- graph_agents_cli/api/__init__.py +15 -0
- graph_agents_cli/api/_changes.py +506 -0
- graph_agents_cli/api/_files.py +658 -0
- graph_agents_cli/api/cmd_api.py +2480 -0
- graph_agents_cli/deploy/__init__.py +15 -0
- graph_agents_cli/deploy/_config.py +171 -0
- graph_agents_cli/deploy/_image.py +128 -0
- graph_agents_cli/deploy/_kube.py +286 -0
- graph_agents_cli/deploy/_modes.py +234 -0
- graph_agents_cli/deploy/_preflight.py +370 -0
- graph_agents_cli/deploy/_values.py +168 -0
- graph_agents_cli/deploy/cmd_deploy.py +1866 -0
- graph_agents_cli/deploy/gitops.py +562 -0
- graph_agents_cli/deploy/local_load.py +273 -0
- graph_agents_cli/dev/__init__.py +13 -0
- graph_agents_cli/dev/cmd_build.py +131 -0
- graph_agents_cli/dev/cmd_install.py +78 -0
- graph_agents_cli/dev/cmd_lint.py +119 -0
- graph_agents_cli/dev/cmd_playground.py +297 -0
- graph_agents_cli/dev/policy_check.py +1287 -0
- graph_agents_cli/eval/__init__.py +22 -0
- graph_agents_cli/eval/_client.py +670 -0
- graph_agents_cli/eval/_common.py +177 -0
- graph_agents_cli/eval/_judge.py +168 -0
- graph_agents_cli/eval/_judge_runner.py +238 -0
- graph_agents_cli/eval/_paths.py +212 -0
- graph_agents_cli/eval/checks.py +581 -0
- graph_agents_cli/eval/cmd_analyze.py +278 -0
- graph_agents_cli/eval/cmd_compare.py +284 -0
- graph_agents_cli/eval/cmd_eval_group.py +80 -0
- graph_agents_cli/eval/cmd_generate.py +558 -0
- graph_agents_cli/eval/cmd_grade.py +466 -0
- graph_agents_cli/eval/cmd_metric.py +156 -0
- graph_agents_cli/eval/cmd_run.py +370 -0
- graph_agents_cli/eval/cmd_submit.py +400 -0
- graph_agents_cli/eval/config.py +435 -0
- graph_agents_cli/eval/dataset.py +350 -0
- graph_agents_cli/eval/gate.py +420 -0
- graph_agents_cli/eval/transcript.py +192 -0
- graph_agents_cli/extension/__init__.py +13 -0
- graph_agents_cli/extension/_compat.py +86 -0
- graph_agents_cli/extension/_loader.py +293 -0
- graph_agents_cli/extension/_manifest.py +135 -0
- graph_agents_cli/extension/_overrides.py +195 -0
- graph_agents_cli/extension/_paths.py +91 -0
- graph_agents_cli/extension/_refs.py +193 -0
- graph_agents_cli/extension/_resolver.py +453 -0
- graph_agents_cli/extension/_schema.py +106 -0
- graph_agents_cli/extension/_spec.py +253 -0
- graph_agents_cli/extension/_sync.py +102 -0
- graph_agents_cli/extension/_trust.py +58 -0
- graph_agents_cli/extension/cmd_extension_add.py +259 -0
- graph_agents_cli/extension/cmd_extension_group.py +57 -0
- graph_agents_cli/extension/cmd_extension_list.py +56 -0
- graph_agents_cli/extension/cmd_extension_remove.py +61 -0
- graph_agents_cli/extension/cmd_extension_update.py +195 -0
- graph_agents_cli/info/__init__.py +13 -0
- graph_agents_cli/info/cmd_info.py +222 -0
- graph_agents_cli/infra/__init__.py +15 -0
- graph_agents_cli/infra/checks.py +1169 -0
- graph_agents_cli/infra/cmd_infra.py +103 -0
- graph_agents_cli/main.py +591 -0
- graph_agents_cli/peer/__init__.py +15 -0
- graph_agents_cli/peer/_generate.py +254 -0
- graph_agents_cli/peer/cmd_peer.py +1151 -0
- graph_agents_cli/run/__init__.py +13 -0
- graph_agents_cli/run/_local_server.py +1157 -0
- graph_agents_cli/run/_signals.py +141 -0
- graph_agents_cli/run/cmd_approvals.py +530 -0
- graph_agents_cli/run/cmd_run.py +1421 -0
- graph_agents_cli/scaffold/__init__.py +19 -0
- graph_agents_cli/scaffold/agents/README.md +24 -0
- graph_agents_cli/scaffold/agents/empty_py/.template/templateconfig.yaml +22 -0
- graph_agents_cli/scaffold/agents/langgraph/.env.example +292 -0
- graph_agents_cli/scaffold/agents/langgraph/.template/templateconfig.yaml +28 -0
- graph_agents_cli/scaffold/agents/langgraph/Dockerfile +59 -0
- graph_agents_cli/scaffold/agents/langgraph/Dockerfile.langgraph-server +59 -0
- graph_agents_cli/scaffold/agents/langgraph/README.md +571 -0
- graph_agents_cli/scaffold/agents/langgraph/api-policy.yaml +60 -0
- graph_agents_cli/scaffold/agents/langgraph/app/__init__.py +20 -0
- graph_agents_cli/scaffold/agents/langgraph/app/agent.py +174 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/__init__.py +15 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a.py +2162 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a_client.py +1167 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/api_client.py +4220 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/approvals.py +1349 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/auth.py +1986 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/chat.py +2962 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/checkpointer.py +432 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/content.py +569 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/db.py +580 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/limits.py +203 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/metrics.py +231 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/middleware.py +361 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/model.py +611 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/playground.py +230 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/run_locks.py +459 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/structured.py +755 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/telemetry.py +681 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/threads.py +493 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/token_exchange.py +959 -0
- graph_agents_cli/scaffold/agents/langgraph/app/fast_api_app.py +770 -0
- graph_agents_cli/scaffold/agents/langgraph/app/policies/__init__.py +55 -0
- graph_agents_cli/scaffold/agents/langgraph/app/policies/custom.py +97 -0
- graph_agents_cli/scaffold/agents/langgraph/app/tools/__init__.py +46 -0
- graph_agents_cli/scaffold/agents/langgraph/app/tools/example_api.py +92 -0
- graph_agents_cli/scaffold/agents/langgraph/app/tools/weather.py +33 -0
- graph_agents_cli/scaffold/agents/langgraph/langgraph.json +14 -0
- graph_agents_cli/scaffold/agents/langgraph/pyproject.toml +78 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/conftest.py +376 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/eval/datasets/basic-dataset.json +53 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/eval/eval_config.yaml +32 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/approval_graph.py +137 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_issuer.py +216 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_openai.py +357 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_outcomes.py +569 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_relay.py +479 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_api_surface.py +812 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals.py +1367 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals_server.py +794 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor.py +497 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor_server.py +247 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_history_repair.py +278 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_model_apis.py +242 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_postgres.py +637 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_resilience_postgres.py +770 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_runtime_guardrails.py +854 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_e2e.py +340 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_runtime.py +989 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_answers.py +584 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_server.py +222 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_token_exchange_issuer.py +650 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/.results/.placeholder +0 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/README.md +22 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/conftest.py +21 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/load_test.py +81 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_client.py +824 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_scoping.py +724 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client.py +1214 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client_hardening.py +716 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_policy_rpc.py +767 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_approval_ledger.py +1536 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_fake_model.py +115 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_jwt_policy.py +991 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_limits.py +310 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging.py +148 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging_hardening.py +271 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_policy.py +378 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_resilience.py +610 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_server_auth.py +702 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_structured.py +673 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_telemetry.py +404 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_thread_listing.py +255 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_threads.py +268 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_token_exchange.py +1320 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_untrusted_content.py +393 -0
- graph_agents_cli/scaffold/agents/langgraph/uv-fastapi.lock +2084 -0
- graph_agents_cli/scaffold/agents/langgraph/uv-langgraph-server.lock +2106 -0
- graph_agents_cli/scaffold/agents/langgraph/{{cookiecutter.agent_guidance_filename}} +129 -0
- graph_agents_cli/scaffold/base_templates/_shared/graph-agents-cli-manifest.yaml +36 -0
- graph_agents_cli/scaffold/base_templates/python/.dockerignore +32 -0
- graph_agents_cli/scaffold/base_templates/python/.github/CODEOWNERS +30 -0
- graph_agents_cli/scaffold/base_templates/python/.github/agent.env +7 -0
- graph_agents_cli/scaffold/base_templates/python/.github/workflows/pr_checks.yaml +214 -0
- graph_agents_cli/scaffold/base_templates/python/.gitignore +209 -0
- graph_agents_cli/scaffold/base_templates/python/tests/unit/test_dummy.py +23 -0
- graph_agents_cli/scaffold/base_templates/python/{{cookiecutter.agent_guidance_filename}} +35 -0
- graph_agents_cli/scaffold/cmd_scaffold_group.py +49 -0
- graph_agents_cli/scaffold/commands/__init__.py +13 -0
- graph_agents_cli/scaffold/commands/create.py +1424 -0
- graph_agents_cli/scaffold/commands/enhance.py +1652 -0
- graph_agents_cli/scaffold/commands/upgrade.py +570 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/agent.env +12 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/promote-to-prod.yaml +371 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/staging.yaml +450 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-dev.yaml +43 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-prod.yaml +41 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-staging.yaml +43 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/.helmignore +14 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/Chart.yaml +21 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/examples/networkpolicy.yaml +103 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/NOTES.txt +48 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/_helpers.tpl +189 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/certificate.yaml +15 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/configmap.yaml +10 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/deployment.yaml +199 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/hpa.yaml +22 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/httproute.yaml +30 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/ingress.yaml +39 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/networkpolicy.yaml +48 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/pdb.yaml +13 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/postgresql-secret.yaml +37 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/service.yaml +15 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/serviceaccount.yaml +13 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/servicemonitor.yaml +42 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-dev.yaml +22 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-prod.yaml +45 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-staging.yaml +29 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values.yaml +396 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/tests/integration/test_chart.py +269 -0
- graph_agents_cli/scaffold/deployment_targets/none/README.md +5 -0
- graph_agents_cli/scaffold/deployment_targets/none/python/README.md +6 -0
- graph_agents_cli/scaffold/utils/__init__.py +13 -0
- graph_agents_cli/scaffold/utils/backup.py +212 -0
- graph_agents_cli/scaffold/utils/build_record.py +257 -0
- graph_agents_cli/scaffold/utils/cli_options.py +184 -0
- graph_agents_cli/scaffold/utils/fs.py +83 -0
- graph_agents_cli/scaffold/utils/generate_locks.py +214 -0
- graph_agents_cli/scaffold/utils/generation_metadata.py +88 -0
- graph_agents_cli/scaffold/utils/keyedit.py +768 -0
- graph_agents_cli/scaffold/utils/keymerge.py +537 -0
- graph_agents_cli/scaffold/utils/language.py +138 -0
- graph_agents_cli/scaffold/utils/lock_utils.py +94 -0
- graph_agents_cli/scaffold/utils/logging.py +77 -0
- graph_agents_cli/scaffold/utils/manifest.py +292 -0
- graph_agents_cli/scaffold/utils/merge.py +970 -0
- graph_agents_cli/scaffold/utils/merge3.py +216 -0
- graph_agents_cli/scaffold/utils/openapi_seed.py +199 -0
- graph_agents_cli/scaffold/utils/remote_template.py +376 -0
- graph_agents_cli/scaffold/utils/template.py +1352 -0
- graph_agents_cli/scaffold/utils/upgrade.py +894 -0
- graph_agents_cli/scaffold/utils/version.py +438 -0
- graph_agents_cli/secrets/__init__.py +15 -0
- graph_agents_cli/secrets/_apply.py +954 -0
- graph_agents_cli/secrets/_required.py +188 -0
- graph_agents_cli/secrets/cmd_secrets.py +211 -0
- graph_agents_cli/setup/__init__.py +13 -0
- graph_agents_cli/setup/_antigravity.py +221 -0
- graph_agents_cli/setup/cmd_auth.py +1030 -0
- graph_agents_cli/setup/cmd_dev_token.py +513 -0
- graph_agents_cli/setup/cmd_setup.py +428 -0
- graph_agents_cli/setup/cmd_update.py +140 -0
- graph_agents_cli/skills/__init__.py +13 -0
- graph_agents_cli/skills/_bundle.py +65 -0
- graph_agents_cli/skills/data/README.md +19 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/SKILL.md +357 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/github-settings.md +113 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/gitops.md +137 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/kubernetes.md +315 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/secrets.md +160 -0
- graph_agents_cli/skills/data/graph-agents-cli-eval/SKILL.md +303 -0
- graph_agents_cli/skills/data/graph-agents-cli-eval/references/dataset_schema.md +282 -0
- graph_agents_cli/skills/data/graph-agents-cli-eval/references/metrics-guide.md +143 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/SKILL.md +659 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langchain-models.md +124 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langgraph.md +235 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/template-contract.md +477 -0
- graph_agents_cli/skills/data/graph-agents-cli-observability/SKILL.md +231 -0
- graph_agents_cli/skills/data/graph-agents-cli-observability/references/langsmith.md +46 -0
- graph_agents_cli/skills/data/graph-agents-cli-observability/references/otel.md +59 -0
- graph_agents_cli/skills/data/graph-agents-cli-scaffold/SKILL.md +414 -0
- graph_agents_cli/skills/data/graph-agents-cli-scaffold/references/flags.md +134 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/SKILL.md +478 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/brainstorming.md +118 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/commands.md +419 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/extension.md +156 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/internals.md +67 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/spec-template.md +56 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/terminology.md +119 -0
- graph_agents_cli/system/__init__.py +15 -0
- graph_agents_cli/system/_apply.py +519 -0
- graph_agents_cli/system/_checks.py +1023 -0
- graph_agents_cli/system/_deploy.py +215 -0
- graph_agents_cli/system/_model.py +363 -0
- graph_agents_cli/system/_system.py +664 -0
- graph_agents_cli/system/_views.py +208 -0
- graph_agents_cli/system/cmd_system.py +423 -0
- graph_agents_cli-0.3.1.dist-info/METADATA +162 -0
- graph_agents_cli-0.3.1.dist-info/RECORD +291 -0
- graph_agents_cli-0.3.1.dist-info/WHEEL +4 -0
- graph_agents_cli-0.3.1.dist-info/entry_points.txt +2 -0
- graph_agents_cli-0.3.1.dist-info/licenses/LICENSE +201 -0
- graph_agents_cli-0.3.1.dist-info/licenses/NOTICE +19 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# Copyright 2026 Google LLC
|
|
2
|
+
# Modifications Copyright 2026 graph-agents-cli contributors
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
# Promote the staging image to production. Runs in the GitHub
|
|
17
|
+
# `production` environment, which controls who may initiate a promotion, and
|
|
18
|
+
# only from main. Image tags are the SHORT commit SHA (${GITHUB_SHA::7}), as
|
|
19
|
+
# the staging workflow pushes them. According to CD in .github/agent.env:
|
|
20
|
+
# argocd: `graph-agents-cli deploy --env prod --image ...` updates
|
|
21
|
+
# values-prod.yaml on deploy/prod/<tag> and opens a PR; it is NOT
|
|
22
|
+
# merged here. The merge (code-owner review, no self-approval,
|
|
23
|
+
# pr_checks green) is the single production gate. After the merge
|
|
24
|
+
# an operator syncs Argo CD, whose health checks (the readiness
|
|
25
|
+
# probe, /ready) show whether the rollout landed.
|
|
26
|
+
# helm-push: `graph-agents-cli deploy --env prod --image ...` on the
|
|
27
|
+
# self-hosted runner runs helm with the already pushed image, with
|
|
28
|
+
# the kubeconfig of the `production` environment, then verifies the
|
|
29
|
+
# rollout (rollout status, /health and /ready through a port-forward),
|
|
30
|
+
# both in one kube context (environments.prod.context, else the
|
|
31
|
+
# kubeconfig's current one).
|
|
32
|
+
# This file is copied verbatim into the project (not rendered).
|
|
33
|
+
|
|
34
|
+
name: promote-to-prod
|
|
35
|
+
|
|
36
|
+
on:
|
|
37
|
+
workflow_dispatch:
|
|
38
|
+
inputs:
|
|
39
|
+
image_tag:
|
|
40
|
+
description: "Image tag (short commit SHA) to promote. Empty = the tag currently in values-staging.yaml."
|
|
41
|
+
required: false
|
|
42
|
+
default: ""
|
|
43
|
+
|
|
44
|
+
concurrency:
|
|
45
|
+
group: production
|
|
46
|
+
cancel-in-progress: false
|
|
47
|
+
|
|
48
|
+
jobs:
|
|
49
|
+
settings:
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
if: github.ref == 'refs/heads/main'
|
|
52
|
+
permissions:
|
|
53
|
+
contents: read
|
|
54
|
+
outputs:
|
|
55
|
+
cd: ${{ steps.settings.outputs.cd }}
|
|
56
|
+
image: ${{ steps.settings.outputs.image }}
|
|
57
|
+
tag: ${{ steps.settings.outputs.tag }}
|
|
58
|
+
chart_path: ${{ steps.settings.outputs.chart_path }}
|
|
59
|
+
release: ${{ steps.settings.outputs.release }}
|
|
60
|
+
namespace: ${{ steps.settings.outputs.namespace }}
|
|
61
|
+
kube_context: ${{ steps.settings.outputs.kube_context }}
|
|
62
|
+
graph_agents_cli_spec: ${{ steps.settings.outputs.graph_agents_cli_spec }}
|
|
63
|
+
steps:
|
|
64
|
+
- name: Checkout code
|
|
65
|
+
uses: actions/checkout@v4
|
|
66
|
+
|
|
67
|
+
- name: Load project settings
|
|
68
|
+
run: |
|
|
69
|
+
# .github/agent.env is data and is never sourced: each NAME=VALUE line is
|
|
70
|
+
# checked and copied to GITHUB_ENV, so a value may hold spaces or shell
|
|
71
|
+
# metacharacters (a PEP 508 install spec, for example). Only the settings
|
|
72
|
+
# listed in `known` are accepted: any other name (BASH_ENV, SHELLOPTS, PS4,
|
|
73
|
+
# PATH, PYTHONPATH, ...) could change how later steps run. To add a setting,
|
|
74
|
+
# extend `known` in all three workflows. Comment and blank lines are skipped;
|
|
75
|
+
# blanks around the value, one pair of quotes around it and a trailing
|
|
76
|
+
# " # comment" are dropped (no escapes, no expansion). Nothing reaches
|
|
77
|
+
# GITHUB_ENV unless the whole file is valid.
|
|
78
|
+
file=.github/agent.env
|
|
79
|
+
known="IMAGE_REPOSITORY RELEASE_NAME CHART_PATH RUNTIME CD GRAPH_AGENTS_CLI_SPEC"
|
|
80
|
+
if [ ! -f "$file" ]; then
|
|
81
|
+
echo "::error file=$file::$file is missing: it holds the project settings these workflows read." >&2
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
lineno=0
|
|
85
|
+
seen=" "
|
|
86
|
+
settings=()
|
|
87
|
+
while IFS= read -r line || [ -n "$line" ]; do
|
|
88
|
+
lineno=$((lineno + 1))
|
|
89
|
+
line="${line%$'\r'}"
|
|
90
|
+
if [ "$lineno" -eq 1 ]; then
|
|
91
|
+
line="${line#$'\xef\xbb\xbf'}"
|
|
92
|
+
fi
|
|
93
|
+
if [[ "$line" =~ ^[[:space:]]*(#|$) ]]; then
|
|
94
|
+
continue
|
|
95
|
+
fi
|
|
96
|
+
if ! [[ "$line" =~ ^[[:space:]]*([A-Za-z_][A-Za-z0-9_]*)[[:space:]]*=(.*)$ ]]; then
|
|
97
|
+
echo "::error file=$file,line=$lineno::expected NAME=VALUE, got: $line" >&2
|
|
98
|
+
exit 1
|
|
99
|
+
fi
|
|
100
|
+
name="${BASH_REMATCH[1]}"
|
|
101
|
+
value="${BASH_REMATCH[2]}"
|
|
102
|
+
case " $known " in
|
|
103
|
+
*" $name "*) ;;
|
|
104
|
+
*)
|
|
105
|
+
hint=""
|
|
106
|
+
if [ "$name" = CLI_VERSION_PIN ]; then
|
|
107
|
+
hint=" (replaced by GRAPH_AGENTS_CLI_SPEC=<install spec>)"
|
|
108
|
+
fi
|
|
109
|
+
echo "::error file=$file,line=$lineno::$name is not a setting these workflows read${hint}; known: $known." >&2
|
|
110
|
+
exit 1
|
|
111
|
+
;;
|
|
112
|
+
esac
|
|
113
|
+
case "$seen" in
|
|
114
|
+
*" $name "*)
|
|
115
|
+
echo "::error file=$file,line=$lineno::$name is set twice." >&2
|
|
116
|
+
exit 1
|
|
117
|
+
;;
|
|
118
|
+
esac
|
|
119
|
+
seen="$seen$name "
|
|
120
|
+
value="${value#"${value%%[![:space:]]*}"}"
|
|
121
|
+
quote="${value:0:1}"
|
|
122
|
+
if [ "$quote" = '"' ] || [ "$quote" = "'" ]; then
|
|
123
|
+
rest="${value:1}"
|
|
124
|
+
if [[ "$rest" != *"$quote"* ]]; then
|
|
125
|
+
echo "::error file=$file,line=$lineno::$name: unterminated $quote quote." >&2
|
|
126
|
+
exit 1
|
|
127
|
+
fi
|
|
128
|
+
value="${rest%%"$quote"*}"
|
|
129
|
+
else
|
|
130
|
+
value="${value%%[[:space:]]#*}"
|
|
131
|
+
value="${value%"${value##*[![:space:]]}"}"
|
|
132
|
+
fi
|
|
133
|
+
if [[ "$value" == *[[:cntrl:]]* ]]; then
|
|
134
|
+
echo "::error file=$file,line=$lineno::$name: control characters are not allowed in a value." >&2
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
settings+=("$name=$value")
|
|
138
|
+
done < "$file"
|
|
139
|
+
if [ "${#settings[@]}" -gt 0 ]; then
|
|
140
|
+
printf '%s\n' "${settings[@]}" >> "$GITHUB_ENV"
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
- name: Resolve the tag to promote
|
|
144
|
+
id: settings
|
|
145
|
+
# The dispatch input reaches the shell through `env`, never by expression
|
|
146
|
+
# interpolation into the script (that would let a collaborator run
|
|
147
|
+
# commands in the production-environment jobs below).
|
|
148
|
+
env:
|
|
149
|
+
IMAGE_TAG: ${{ inputs.image_tag }}
|
|
150
|
+
run: |
|
|
151
|
+
for var in IMAGE_REPOSITORY RELEASE_NAME CHART_PATH CD GRAPH_AGENTS_CLI_SPEC; do
|
|
152
|
+
if [ -z "${!var:-}" ]; then
|
|
153
|
+
echo "::error file=.github/agent.env::$var is not set in .github/agent.env." >&2
|
|
154
|
+
exit 1
|
|
155
|
+
fi
|
|
156
|
+
done
|
|
157
|
+
if [ "$CD" != argocd ] && [ "$CD" != helm-push ]; then
|
|
158
|
+
echo "::error file=.github/agent.env::CD must be argocd or helm-push for this workflow, got '$CD'." >&2
|
|
159
|
+
exit 1
|
|
160
|
+
fi
|
|
161
|
+
if [[ "$IMAGE_REPOSITORY" == *CHANGE-ME* ]] || ! [[ "$IMAGE_REPOSITORY" =~ ^[A-Za-z0-9.-]+(:[0-9]+)?(/[a-z0-9._-]+)+$ ]]; then
|
|
162
|
+
echo "::error file=.github/agent.env::IMAGE_REPOSITORY must be <registry>/<path> in lowercase with no placeholder, got '$IMAGE_REPOSITORY'." >&2
|
|
163
|
+
exit 1
|
|
164
|
+
fi
|
|
165
|
+
TAG="$IMAGE_TAG"
|
|
166
|
+
if [ -n "$TAG" ] && ! [[ "$TAG" =~ ^[0-9a-f]{7,40}$ ]]; then
|
|
167
|
+
echo "image_tag must be a short commit SHA (7-40 hex characters), got '$TAG'." >&2
|
|
168
|
+
exit 1
|
|
169
|
+
fi
|
|
170
|
+
if [ -z "$TAG" ]; then
|
|
171
|
+
TAG="$(yq -r '.image.tag // ""' "${CHART_PATH}/values-staging.yaml")"
|
|
172
|
+
fi
|
|
173
|
+
if [ -z "$TAG" ] || [ "$TAG" = "latest" ] || [ "$TAG" = "null" ]; then
|
|
174
|
+
echo "No promotable tag: pass image_tag or land a staging build first." >&2
|
|
175
|
+
exit 1
|
|
176
|
+
fi
|
|
177
|
+
# Docker tag grammar: no shell metacharacters or newlines can reach the outputs.
|
|
178
|
+
if ! [[ "$TAG" =~ ^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$ ]]; then
|
|
179
|
+
echo "Invalid image tag: '$TAG'" >&2
|
|
180
|
+
exit 1
|
|
181
|
+
fi
|
|
182
|
+
manifest=graph-agents-cli-manifest.yaml
|
|
183
|
+
NAMESPACE="$(yq -r '.environments.prod.namespace // ""' "$manifest")"
|
|
184
|
+
if [ -z "$NAMESPACE" ]; then
|
|
185
|
+
NAMESPACE="$(yq -r '.name // ""' "$manifest")-prod"
|
|
186
|
+
fi
|
|
187
|
+
if ! [[ "$NAMESPACE" =~ ^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$ ]]; then
|
|
188
|
+
echo "::error file=$manifest::Invalid prod namespace '$NAMESPACE'." >&2
|
|
189
|
+
exit 1
|
|
190
|
+
fi
|
|
191
|
+
# The kube context `deploy` uses; empty = the kubeconfig's current one.
|
|
192
|
+
KUBE_CONTEXT="$(yq -r '.environments.prod.context // ""' "$manifest")"
|
|
193
|
+
if [ -n "$KUBE_CONTEXT" ] && { ! [[ "$KUBE_CONTEXT" =~ ^[[:graph:]]+$ ]] || [[ "$KUBE_CONTEXT" == -* ]]; }; then
|
|
194
|
+
echo "::error file=$manifest::Invalid prod kube context '$KUBE_CONTEXT'." >&2
|
|
195
|
+
exit 1
|
|
196
|
+
fi
|
|
197
|
+
if ! [[ "$RELEASE_NAME" =~ ^[a-z0-9]([-a-z0-9]{0,51}[a-z0-9])?$ ]]; then
|
|
198
|
+
echo "::error file=.github/agent.env::Invalid RELEASE_NAME '$RELEASE_NAME'." >&2
|
|
199
|
+
exit 1
|
|
200
|
+
fi
|
|
201
|
+
{
|
|
202
|
+
echo "cd=${CD}"
|
|
203
|
+
echo "tag=${TAG}"
|
|
204
|
+
echo "image=${IMAGE_REPOSITORY}:${TAG}"
|
|
205
|
+
echo "chart_path=${CHART_PATH}"
|
|
206
|
+
echo "release=${RELEASE_NAME}"
|
|
207
|
+
echo "namespace=${NAMESPACE}"
|
|
208
|
+
echo "kube_context=${KUBE_CONTEXT}"
|
|
209
|
+
echo "graph_agents_cli_spec=${GRAPH_AGENTS_CLI_SPEC}"
|
|
210
|
+
} >> "$GITHUB_OUTPUT"
|
|
211
|
+
|
|
212
|
+
open_prod_pr:
|
|
213
|
+
needs: settings
|
|
214
|
+
if: needs.settings.outputs.cd == 'argocd'
|
|
215
|
+
runs-on: ubuntu-latest
|
|
216
|
+
environment: production
|
|
217
|
+
permissions:
|
|
218
|
+
contents: write
|
|
219
|
+
pull-requests: write
|
|
220
|
+
env:
|
|
221
|
+
# `deploy` opens the pull request through gh with this token. A pull
|
|
222
|
+
# request opened with the workflow token does not trigger pr_checks
|
|
223
|
+
# (GitHub never starts workflows from GITHUB_TOKEN events); store a
|
|
224
|
+
# fine-grained PAT or a GitHub App token as GH_PR_TOKEN to lift that limit.
|
|
225
|
+
GH_TOKEN: ${{ secrets.GH_PR_TOKEN || secrets.GITHUB_TOKEN }}
|
|
226
|
+
GRAPH_AGENTS_CLI_NO_UPDATE_CHECK: "1"
|
|
227
|
+
# The CLI's own `deploy`: no extension (committed, or installed on the
|
|
228
|
+
# runner) can replace it while it holds the PR token.
|
|
229
|
+
GRAPH_AGENTS_CLI_DISABLE_OVERRIDES: "1"
|
|
230
|
+
steps:
|
|
231
|
+
- name: Checkout code
|
|
232
|
+
uses: actions/checkout@v4
|
|
233
|
+
|
|
234
|
+
- name: Install uv
|
|
235
|
+
uses: astral-sh/setup-uv@v6
|
|
236
|
+
with:
|
|
237
|
+
python-version: "3.12"
|
|
238
|
+
|
|
239
|
+
- name: Open the production PR (merge is the gate)
|
|
240
|
+
# In argocd mode `deploy` never runs helm: it rewrites image.tag in
|
|
241
|
+
# values-prod.yaml, commits that one file on deploy/prod/<tag> from
|
|
242
|
+
# origin/main and opens (or updates) the pull request. The commit needs
|
|
243
|
+
# a git identity. --yes: no prompt (this runner has no cluster context).
|
|
244
|
+
env:
|
|
245
|
+
IMAGE: ${{ needs.settings.outputs.image }}
|
|
246
|
+
GRAPH_AGENTS_CLI_SPEC: ${{ needs.settings.outputs.graph_agents_cli_spec }}
|
|
247
|
+
run: |
|
|
248
|
+
git config user.name "github-actions[bot]"
|
|
249
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
250
|
+
uvx --from "$GRAPH_AGENTS_CLI_SPEC" graph-agents-cli deploy --env prod --image "$IMAGE" --yes
|
|
251
|
+
|
|
252
|
+
deploy_helm_push:
|
|
253
|
+
# The cluster credentials are the DEPLOY_KUBECONFIG secret of the
|
|
254
|
+
# `production` environment: an environment secret, never a repository
|
|
255
|
+
# secret, so only jobs that pass this environment's protection rules
|
|
256
|
+
# (required reviewers, main only) can read it.
|
|
257
|
+
needs: settings
|
|
258
|
+
if: needs.settings.outputs.cd == 'helm-push'
|
|
259
|
+
runs-on: self-hosted
|
|
260
|
+
environment: production
|
|
261
|
+
permissions:
|
|
262
|
+
contents: read
|
|
263
|
+
env:
|
|
264
|
+
GRAPH_AGENTS_CLI_NO_UPDATE_CHECK: "1"
|
|
265
|
+
# The CLI's own `deploy`: no extension (committed, or installed on the
|
|
266
|
+
# runner) can replace it while it holds the cluster credentials.
|
|
267
|
+
GRAPH_AGENTS_CLI_DISABLE_OVERRIDES: "1"
|
|
268
|
+
IMAGE: ${{ needs.settings.outputs.image }}
|
|
269
|
+
RELEASE: ${{ needs.settings.outputs.release }}
|
|
270
|
+
NAMESPACE: ${{ needs.settings.outputs.namespace }}
|
|
271
|
+
MANIFEST_CONTEXT: ${{ needs.settings.outputs.kube_context }}
|
|
272
|
+
GRAPH_AGENTS_CLI_SPEC: ${{ needs.settings.outputs.graph_agents_cli_spec }}
|
|
273
|
+
steps:
|
|
274
|
+
- name: Checkout code
|
|
275
|
+
uses: actions/checkout@v4
|
|
276
|
+
|
|
277
|
+
- name: Install uv
|
|
278
|
+
uses: astral-sh/setup-uv@v6
|
|
279
|
+
with:
|
|
280
|
+
python-version: "3.12"
|
|
281
|
+
|
|
282
|
+
- name: Configure kubeconfig
|
|
283
|
+
# Written to the job's temporary directory (owner-only) and removed by
|
|
284
|
+
# the last step, whatever happens: nothing is left on the runner.
|
|
285
|
+
env:
|
|
286
|
+
DEPLOY_KUBECONFIG: ${{ secrets.DEPLOY_KUBECONFIG }}
|
|
287
|
+
run: |
|
|
288
|
+
if [ -z "$DEPLOY_KUBECONFIG" ]; then
|
|
289
|
+
echo "::error::DEPLOY_KUBECONFIG is empty: store the cluster credentials as the DEPLOY_KUBECONFIG secret of the production environment (Settings > Environments > production)." >&2
|
|
290
|
+
exit 1
|
|
291
|
+
fi
|
|
292
|
+
umask 077
|
|
293
|
+
printf '%s\n' "$DEPLOY_KUBECONFIG" > "$RUNNER_TEMP/kubeconfig"
|
|
294
|
+
echo "KUBECONFIG=$RUNNER_TEMP/kubeconfig" >> "$GITHUB_ENV"
|
|
295
|
+
|
|
296
|
+
- name: Resolve the kube context
|
|
297
|
+
# One context for the deploy and the checks after it, passed to both:
|
|
298
|
+
# the manifest's environments.prod.context when set, else the current
|
|
299
|
+
# context of DEPLOY_KUBECONFIG (what `deploy` itself would pick).
|
|
300
|
+
run: |
|
|
301
|
+
if ! command -v kubectl >/dev/null 2>&1; then
|
|
302
|
+
echo "::error::kubectl is not on the runner's PATH; the deploy and its checks need it." >&2
|
|
303
|
+
exit 1
|
|
304
|
+
fi
|
|
305
|
+
context="${MANIFEST_CONTEXT:-}"
|
|
306
|
+
if [ -z "$context" ]; then
|
|
307
|
+
context="$(kubectl config current-context 2>/dev/null || true)"
|
|
308
|
+
fi
|
|
309
|
+
if [ -z "$context" ]; then
|
|
310
|
+
echo "::error::No kube context: set environments.prod.context in graph-agents-cli-manifest.yaml or a current-context in DEPLOY_KUBECONFIG." >&2
|
|
311
|
+
exit 1
|
|
312
|
+
fi
|
|
313
|
+
if ! [[ "$context" =~ ^[[:graph:]]+$ ]] || [[ "$context" == -* ]]; then
|
|
314
|
+
echo "::error::Invalid kube context name '$context'." >&2
|
|
315
|
+
exit 1
|
|
316
|
+
fi
|
|
317
|
+
if ! kubectl config get-contexts "$context" >/dev/null 2>&1; then
|
|
318
|
+
echo "::error::Kube context '$context' is not in the DEPLOY_KUBECONFIG of the production environment." >&2
|
|
319
|
+
exit 1
|
|
320
|
+
fi
|
|
321
|
+
echo "Kube context: $context"
|
|
322
|
+
echo "KUBE_CONTEXT=$context" >> "$GITHUB_ENV"
|
|
323
|
+
|
|
324
|
+
- name: Deploy to production
|
|
325
|
+
# `deploy --image` in helm-push mode runs helm only (the image is already
|
|
326
|
+
# pushed), in the context resolved above; --yes: no prompt.
|
|
327
|
+
run: |
|
|
328
|
+
uvx --from "$GRAPH_AGENTS_CLI_SPEC" graph-agents-cli deploy --env prod --image "$IMAGE" --context "$KUBE_CONTEXT" --yes
|
|
329
|
+
|
|
330
|
+
- name: Verify the rollout
|
|
331
|
+
run: |
|
|
332
|
+
: "${NAMESPACE:?the settings job resolved no namespace}" "${RELEASE:?the settings job resolved no release}"
|
|
333
|
+
: "${KUBE_CONTEXT:?no kube context was resolved}"
|
|
334
|
+
# The cluster `deploy` just used (the same context).
|
|
335
|
+
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" rollout status "deployment/$RELEASE" --timeout=300s
|
|
336
|
+
log="$RUNNER_TEMP/port-forward.log"
|
|
337
|
+
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" port-forward "service/$RELEASE" :http > "$log" 2>&1 &
|
|
338
|
+
forward=$!
|
|
339
|
+
trap 'kill "$forward" 2>/dev/null || true' EXIT
|
|
340
|
+
port=""
|
|
341
|
+
for _ in $(seq 1 30); do
|
|
342
|
+
port="$(sed -n 's/^Forwarding from 127\.0\.0\.1:\([0-9][0-9]*\) .*/\1/p' "$log" | head -n 1)"
|
|
343
|
+
if [ -n "$port" ] || ! kill -0 "$forward" 2>/dev/null; then
|
|
344
|
+
break
|
|
345
|
+
fi
|
|
346
|
+
sleep 1
|
|
347
|
+
done
|
|
348
|
+
if [ -z "$port" ]; then
|
|
349
|
+
echo "::error::kubectl port-forward to service/$RELEASE failed: $(cat "$log")" >&2
|
|
350
|
+
exit 1
|
|
351
|
+
fi
|
|
352
|
+
for path in /health /ready; do
|
|
353
|
+
ok=""
|
|
354
|
+
for _ in $(seq 1 10); do
|
|
355
|
+
if curl --fail --silent --show-error --max-time 5 "http://127.0.0.1:${port}${path}"; then
|
|
356
|
+
ok=1
|
|
357
|
+
break
|
|
358
|
+
fi
|
|
359
|
+
sleep 3
|
|
360
|
+
done
|
|
361
|
+
echo
|
|
362
|
+
if [ -z "$ok" ]; then
|
|
363
|
+
echo "::error::${path} did not answer 2xx on the production deployment ($NAMESPACE/$RELEASE)." >&2
|
|
364
|
+
exit 1
|
|
365
|
+
fi
|
|
366
|
+
done
|
|
367
|
+
echo "production runs ${IMAGE} and answers /health and /ready."
|
|
368
|
+
|
|
369
|
+
- name: Remove kubeconfig
|
|
370
|
+
if: always()
|
|
371
|
+
run: rm -f "$RUNNER_TEMP/kubeconfig" "$RUNNER_TEMP/port-forward.log"
|