keboola-cli 0.65.0__tar.gz → 0.65.1__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.
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/CLAUDE.md +5 -8
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/PKG-INFO +1 -1
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/pyproject.toml +1 -1
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/changelog.py +18 -1
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/_data_app_git.py +0 -67
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/context.py +3 -12
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/permissions.py +0 -1
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/data_apps.py +0 -35
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/data_app_service.py +20 -214
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_data_app_cli.py +0 -69
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_data_app_service.py +4 -67
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_e2e.py +5 -23
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_server_router_calls.py +0 -20
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/.gitignore +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/CONTRIBUTING.md +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/Makefile +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/README.md +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/examples/README.md +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/examples/storage_tui/README.md +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/benchmark.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/check_command_sync.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/check_error_codes.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/check_wheel_ui.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/debug_linkedby_type.sh +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/generate_changelog.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/generate_skill.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/hatch_build.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/lineage_deep.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/post-edit-quality.sh +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/pre-commit +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/sync_version.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/scripts/web-dev.sh +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/__init__.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/__main__.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/ai_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/auto_update.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/__init__.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/_helpers.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/agent.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/branch.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/changelog.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/component.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/config.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/data_app.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/doctor.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/encrypt.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/feature.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/flow.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/http_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/init.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/job.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/kai.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/lineage.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/org.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/permissions.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/project.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/repl.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/schedule.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/search.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/serve.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/sharing.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/storage.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/stream.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/sync.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/tool.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/version.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/commands/workspace.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/config_store.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/constants.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/data_science_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/dev_portal_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/errors.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/http_base.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/json_utils.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/lib.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/manage_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/metastore_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/models.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/output.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/py.typed +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/result_models.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/__init__.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/agent_runner.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/agents_store.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/app.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/auth.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/dependencies.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/pricing.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/agents.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/branches.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/components.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/configs.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/feature.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/flows.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/health.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/kai.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/mcp.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/members.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/org.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/projects.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/search.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/storage.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/stream.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/routers/workspaces.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/server/sse.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/__init__.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_encryption.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_sync_models.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_sync_push_ops.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/_sync_writeback.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/agent_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/base.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/branch_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/component_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/config_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/deep_lineage_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/doctor_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/feature_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/flow_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/flow_validation.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/job_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/kai_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/lineage_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/mcp_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/mcp_transport.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/member_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/org_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/project_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/schedule_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/search_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/sharing_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/storage_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/stream_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/sync_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/variables_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/version_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/workspace_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/stream_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/__init__.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/clone.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/config_format.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/diff_engine.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/git_utils.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/manifest.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/naming.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/secrets.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/sync/sql_split.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/__init__.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/conftest.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/helpers.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_agent_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_agent_prompt.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_agent_prompt_helper.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_agent_runner.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_agent_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_agents_store_events.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_ai_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_auto_update.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_base_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_branch_metadata_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_branch_metadata_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_branch_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_build_hook.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_changelog_check.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_changelog_render.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_check_command_sync.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_choice_enums.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_component_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_component_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_create_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_create_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_encryption.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_metadata.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_rename.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_rename_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_resolution.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_row_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_row_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_search.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_search_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_set_default_bucket.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_store.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_config_update.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_data_app_git_repo.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_data_app_plain_env_keys.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_data_app_secrets_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_data_app_secrets_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_data_app_validate_repo_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_deep_lineage_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_dev_portal_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_dev_portal_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_dev_portal_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_doctor_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_e2e_config_dir_mode.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_e2e_lineage_deep.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_encrypt_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_encrypt_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_encryption.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_errors.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_feature_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_feature_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_file_locking.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_flow_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_flow_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_flow_validation.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_helpers.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_http_base.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_http_client_cmd.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_http_forwarder_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_integration.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_job_idempotency_store.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_json_utils.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_kai_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_kai_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_lib.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_lineage_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_local_ai_chat.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_manage_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_manage_token_bulk.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_manage_token_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_mcp_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_mcp_transport.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_member_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_member_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_metastore_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_models.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_normalize_script.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_org_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_output.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_permissions.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_permissions_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_pricing.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_project_edit.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_project_edit_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_project_info_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_project_info_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_repl.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_result_models.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_run_broadcaster.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_schedule_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_schedule_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_search_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_search_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_semantic_layer_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_semantic_layer_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_serve_conversation_id.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_serve_ui.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_server_smoke.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_services.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sharing_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sql_split.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_clone.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_delete.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_describe_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_describe_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_empty_definition.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_export_filters.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_files.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_swap.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_tables.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_truncate.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_storage_write.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_stream_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_stream_client.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_stream_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_branch_mapping.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_clone.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_code_extraction.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_config_format.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_diff_engine.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_e2e.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_encrypt.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_force_pull_baseline.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_manifest.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_naming.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_plaintext_audit.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_secrets.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_storage_jobs.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_sync_version_script.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_variables_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_variables_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_version_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_workspace_cli.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_workspace_gc.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_workspace_service.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/tests/test_workspace_sql_helper.py +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/README.md +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/index.html +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/package-lock.json +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/package.json +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/postcss.config.js +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/App.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/api/client.ts +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/components/AgentRunView.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/components/Drawer.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/components/Empty.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/components/JsonView.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/components/Table.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/index.css +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/layout/Shell.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/layout/Sidebar.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/layout/StatusBar.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/layout/TopBar.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/main.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Agents.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Branches.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Changelog.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Components.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Configs.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Dashboard.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/DataApps.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Doctor.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Encrypt.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Flows.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Jobs.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Lineage.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/LocalAi.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Mcp.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Members.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Org.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Projects.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Schedules.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Search.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Sharing.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Storage.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Streams.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/pages/Workspaces.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/state.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/theme.tsx +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/src/types.ts +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/tailwind.config.ts +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/tsconfig.json +0 -0
- {keboola_cli-0.65.0 → keboola_cli-0.65.1}/web/frontend/vite.config.ts +0 -0
|
@@ -430,13 +430,11 @@ kbagent data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL
|
|
|
430
430
|
# NO parameters.dataApp.git block, and forces --no-deploy (nothing to run yet). Mutually exclusive with
|
|
431
431
|
# --git-repo and all --git-*/PAT auth flags. Full flow to a RUNNING managed-repo app (0.65.0+):
|
|
432
432
|
# (1) create --use-managed-git-repo -> (2) `git-credentials-create --type http_token --permissions
|
|
433
|
-
# readWrite` + `git push` code to the managed repo URL (from `git-repo`) -> (3) `data-app
|
|
434
|
-
#
|
|
435
|
-
#
|
|
436
|
-
#
|
|
437
|
-
#
|
|
438
|
-
# managedGitRepoId). Use `data-app runs` to debug a deploy that reverts to stopped (setup-phase
|
|
439
|
-
# failures, e.g. git-clone "could not read Username", produce no container logs).
|
|
433
|
+
# readWrite` + `git push` code to the managed repo URL (from `git-repo`) -> (3) `data-app deploy`.
|
|
434
|
+
# The platform injects the clone credentials at deploy time, so no credential wiring is needed.
|
|
435
|
+
# deploy pins the LATEST configVersion when a git block is present and omits it for a PURE managed
|
|
436
|
+
# repo (deploys from managedGitRepoId). Use `data-app runs` to debug a deploy that reverts to
|
|
437
|
+
# stopped (setup-phase failures produce no container logs).
|
|
440
438
|
kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID]
|
|
441
439
|
kbagent data-app start --project NAME --app-id ID [--wait] [--timeout SECONDS]
|
|
442
440
|
kbagent data-app stop --project NAME --app-id ID [--wait] [--timeout SECONDS]
|
|
@@ -454,7 +452,6 @@ kbagent data-app git-branches --project NAME --app-id ID
|
|
|
454
452
|
kbagent data-app git-entrypoints --project NAME --app-id ID
|
|
455
453
|
kbagent data-app git-credentials --project NAME --app-id ID
|
|
456
454
|
kbagent data-app git-credentials-create --project NAME --app-id ID --type ssh_key|http_token --permissions readOnly|readWrite [--public-key KEY | --public-key-file PATH] [--name LABEL] [--yes]
|
|
457
|
-
kbagent data-app git-bind-credential --project NAME --app-id ID [--branch-name main] [--permissions readOnly|readWrite] [--dry-run]
|
|
458
455
|
# git-repo/git-branches/git-entrypoints introspect the deployed-from git repo (sandboxes-service /apps/{id}/git-repo/*); they return 409 "no Git repository configured" until the app has been DEPLOYED at least once (git config syncs Storage->DS record at deploy). git-credentials* manage credentials for a MANAGED repo only; apps from `data-app create --git-repo` are external => git-credentials-create returns 409. http_token mints a ONE-TIME secret (shown once); credentials endpoints need an admin storage token.
|
|
459
456
|
|
|
460
457
|
kbagent component list [--project NAME] [--type TYPE] [--query QUERY]
|
|
@@ -24,6 +24,21 @@ from .constants import CHANGELOG_HEADLINE_MAX_CHARS
|
|
|
24
24
|
|
|
25
25
|
# Ordered newest-first. Each value is a list of brief one-line descriptions.
|
|
26
26
|
CHANGELOG: dict[str, list[str]] = {
|
|
27
|
+
"0.65.1": [
|
|
28
|
+
"BREAKING: Removed `data-app git-bind-credential` (and its `kbagent serve` endpoint). It shipped in "
|
|
29
|
+
"0.65.0 on a misdiagnosis: managed-repo deploys were failing and we believed the platform "
|
|
30
|
+
"did not inject the git-clone credential, so the command wired an encrypted credential into "
|
|
31
|
+
"`parameters.dataApp.git`. A clean reproduction on `data-science.us-east4.gcp` confirmed the "
|
|
32
|
+
"platform DOES inject the clone credential at deploy time (matching the sandboxes-service "
|
|
33
|
+
"`testManagedGitRepo.sh` contract) -- the command was unnecessary. The real fix was the "
|
|
34
|
+
"0.65.0 `configVersion`-omit change; pinning a managed app's no-git-block config is what made "
|
|
35
|
+
"the runtime demand `dataApp.git.repository` and revert the deploy to stopped.",
|
|
36
|
+
"Change: Corrected the managed-repo guidance everywhere: the canonical flow is `data-app create "
|
|
37
|
+
"--use-managed-git-repo` -> `git-credentials-create --type http_token --permissions readWrite` "
|
|
38
|
+
"+ `git push` your code -> `data-app deploy`. No credential wiring is needed. The earlier "
|
|
39
|
+
"'platform does not inject credentials' / `could not read Username` framing was wrong "
|
|
40
|
+
"(GitHub issue #454 closed as not-a-bug).",
|
|
41
|
+
],
|
|
27
42
|
"0.65.0": [
|
|
28
43
|
"New: deploy a data app from a Keboola-MANAGED git repository end-to-end. "
|
|
29
44
|
"`data-app create --use-managed-git-repo` provisions an EMPTY Keboola-hosted repo (POST "
|
|
@@ -39,7 +54,9 @@ CHANGELOG: dict[str, list[str]] = {
|
|
|
39
54
|
"credentials at deploy time -- without it the runtime's `git clone` of the managed repo "
|
|
40
55
|
"fails `could not read Username` and the deploy reverts to stopped. The token is encrypted "
|
|
41
56
|
"in place and never printed; `--dry-run` previews what would be wired without minting the "
|
|
42
|
-
"one-time credential or touching the config."
|
|
57
|
+
"one-time credential or touching the config. (Removed in 0.65.1 -- this was based on a "
|
|
58
|
+
"misdiagnosis; the platform does inject the clone credential, so the command was "
|
|
59
|
+
"unnecessary. See the 0.65.1 notes.)",
|
|
43
60
|
"New: `data-app runs --project P --app-id ID [--limit N]` lists a data app's recent "
|
|
44
61
|
"deployment attempts with `failure_reason` + `startup_logs`, including setup-phase failures "
|
|
45
62
|
"(e.g. a git-clone error during `app_setup`) that produce no container logs. It works on "
|
|
@@ -341,70 +341,3 @@ def register_git_commands(app: typer.Typer) -> None:
|
|
|
341
341
|
)
|
|
342
342
|
|
|
343
343
|
formatter.output(result, _human)
|
|
344
|
-
|
|
345
|
-
@app.command("git-bind-credential")
|
|
346
|
-
def data_app_git_bind_credential(
|
|
347
|
-
ctx: typer.Context,
|
|
348
|
-
project: str = typer.Option(..., "--project", help="Project alias"),
|
|
349
|
-
app_id: str = typer.Option(..., "--app-id", help="Data Science numeric app id"),
|
|
350
|
-
branch: str = typer.Option(
|
|
351
|
-
"main", "--branch-name", help="Managed-repo branch to deploy from (default main)."
|
|
352
|
-
),
|
|
353
|
-
permissions: str = typer.Option(
|
|
354
|
-
"readOnly",
|
|
355
|
-
"--permissions",
|
|
356
|
-
help="Credential access level: readOnly (default) | readWrite.",
|
|
357
|
-
),
|
|
358
|
-
dry_run: bool = typer.Option(
|
|
359
|
-
False,
|
|
360
|
-
"--dry-run",
|
|
361
|
-
help="Preview what would be wired (repo/branch/permissions) WITHOUT minting a credential or editing the config.",
|
|
362
|
-
),
|
|
363
|
-
) -> None:
|
|
364
|
-
"""Make a MANAGED-repo app deployable by wiring a credential into its config.
|
|
365
|
-
|
|
366
|
-
A `--use-managed-git-repo` app owns an empty Keboola-hosted repo but its
|
|
367
|
-
Storage config has no git block. On stacks that do NOT inject managed-repo
|
|
368
|
-
credentials at deploy time, the runtime's `git clone` of the managed repo
|
|
369
|
-
fails ("could not read Username") and the deploy reverts to stopped. This
|
|
370
|
-
command mints a fresh `http_token` ON the app, encrypts it under the
|
|
371
|
-
project KMS, and writes `parameters.dataApp.git` (repository + placeholder
|
|
372
|
-
username + encrypted `#password` + branch) so the next `data-app deploy`
|
|
373
|
-
can clone. The token is encrypted in-place and never printed.
|
|
374
|
-
|
|
375
|
-
`--dry-run` validates the app + resolves the managed repo URL but mints
|
|
376
|
-
nothing and leaves the config untouched -- the http_token is one-time, so
|
|
377
|
-
a real run that you abort would orphan it.
|
|
378
|
-
"""
|
|
379
|
-
formatter = get_formatter(ctx)
|
|
380
|
-
service = get_service(ctx, "data_app_service")
|
|
381
|
-
try:
|
|
382
|
-
result = service.bind_managed_credential(
|
|
383
|
-
project, app_id, branch=branch, permissions=permissions, dry_run=dry_run
|
|
384
|
-
)
|
|
385
|
-
except KeboolaApiError as exc:
|
|
386
|
-
formatter.error(
|
|
387
|
-
message=exc.message,
|
|
388
|
-
error_code=exc.error_code,
|
|
389
|
-
retryable=exc.retryable,
|
|
390
|
-
details=exc.details,
|
|
391
|
-
)
|
|
392
|
-
raise typer.Exit(code=map_error_to_exit_code(exc)) from None
|
|
393
|
-
except ConfigError as exc:
|
|
394
|
-
formatter.error(message=exc.message, error_code=ErrorCode.CONFIG_ERROR)
|
|
395
|
-
raise typer.Exit(code=5) from None
|
|
396
|
-
|
|
397
|
-
def _human(c: Console, d: dict) -> None:
|
|
398
|
-
if d.get("dry_run"):
|
|
399
|
-
c.print("[bold]DRY RUN -- no credential minted, config unchanged.[/bold]")
|
|
400
|
-
c.print(f" [bold]Repository:[/bold] {d.get('repository', '')}")
|
|
401
|
-
c.print(f" [bold]Branch:[/bold] {d.get('branch', '')}")
|
|
402
|
-
c.print(f" [bold]Permissions:[/bold] {d.get('permissions', '')}")
|
|
403
|
-
return
|
|
404
|
-
c.print(f"[bold green]Success:[/bold green] {d['message']}")
|
|
405
|
-
c.print(f" [bold]Repository:[/bold] {d.get('repository', '')}")
|
|
406
|
-
c.print(f" [bold]Branch:[/bold] {d.get('branch', '')}")
|
|
407
|
-
c.print(f" [bold]Permissions:[/bold] {d.get('permissions', '')}")
|
|
408
|
-
c.print(f" [bold]Config version:[/bold] {d.get('config_version', '')}")
|
|
409
|
-
|
|
410
|
-
formatter.output(result, _human)
|
|
@@ -745,9 +745,9 @@ git block, slug, runtime size, encrypted secrets) with the Data Science API
|
|
|
745
745
|
instead of cloning an external one; writes no git block, forces --no-deploy,
|
|
746
746
|
mutually exclusive with --git-repo and all --git-*/PAT flags. Managed deploy
|
|
747
747
|
works via: create --use-managed-git-repo -> git-credentials-create
|
|
748
|
-
--type http_token + push code to the managed repo
|
|
749
|
-
|
|
750
|
-
|
|
748
|
+
--type http_token --permissions readWrite + push code to the managed repo
|
|
749
|
+
URL -> deploy. The platform injects the clone credentials at deploy time,
|
|
750
|
+
so no credential wiring is needed.
|
|
751
751
|
|
|
752
752
|
kbagent data-app deploy --project NAME --app-id ID [--config-version N]
|
|
753
753
|
[--wait] [--timeout SECONDS] [--branch ID]
|
|
@@ -881,15 +881,6 @@ git block, slug, runtime size, encrypted secrets) with the Data Science API
|
|
|
881
881
|
are EXTERNAL (not managed) -> 409 "no managed Git repository".
|
|
882
882
|
Confirmation prompt unless --yes or --json.
|
|
883
883
|
|
|
884
|
-
kbagent data-app git-bind-credential --project NAME --app-id ID
|
|
885
|
-
[--branch-name main] [--permissions readOnly|readWrite] [--dry-run]
|
|
886
|
-
Mint an http_token ON the app's MANAGED repo, encrypt it under the
|
|
887
|
-
project KMS, and wire it into parameters.dataApp.git (repository +
|
|
888
|
-
placeholder username + encrypted #password + branch) so the runtime can
|
|
889
|
-
`git clone` the managed repo at deploy time. Needed on stacks that do
|
|
890
|
-
NOT inject managed-repo credentials at deploy (clone fails with "could
|
|
891
|
-
not read Username"). The token is encrypted in-place and never printed.
|
|
892
|
-
|
|
893
884
|
### Project Sync
|
|
894
885
|
|
|
895
886
|
kbagent sync init --project ALIAS [--directory DIR] [--git-branching] [--adopt-existing]
|
|
@@ -172,7 +172,6 @@ OPERATION_REGISTRY: dict[str, str] = {
|
|
|
172
172
|
"data-app.git-entrypoints": "read",
|
|
173
173
|
"data-app.git-credentials": "read",
|
|
174
174
|
"data-app.git-credentials-create": "write",
|
|
175
|
-
"data-app.git-bind-credential": "write",
|
|
176
175
|
# Developer Portal — identity sub-app leaves (composed by the
|
|
177
176
|
# identity_app callback as "dev-portal.identity.<subcommand>")
|
|
178
177
|
"dev-portal.identity.add": "write",
|
|
@@ -90,13 +90,6 @@ class GitCredentialCreate(BaseModel):
|
|
|
90
90
|
name: str | None = None
|
|
91
91
|
|
|
92
92
|
|
|
93
|
-
class GitBindCredential(BaseModel):
|
|
94
|
-
branch: str = "main"
|
|
95
|
-
permissions: str = "readOnly"
|
|
96
|
-
branch_id: int | None = None
|
|
97
|
-
dry_run: bool = False
|
|
98
|
-
|
|
99
|
-
|
|
100
93
|
@router.get("", summary="List data apps across projects")
|
|
101
94
|
def list_apps(
|
|
102
95
|
project: list[str] | None = Query(None),
|
|
@@ -410,31 +403,3 @@ def runs(
|
|
|
410
403
|
logs endpoint returns HTTP 400.
|
|
411
404
|
"""
|
|
412
405
|
return registry.data_app.list_app_runs(project, app_id, limit=limit)
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
@router.post(
|
|
416
|
-
"/{project}/{app_id}/git-repo/bind-credential",
|
|
417
|
-
summary="Wire a managed-repo credential into a data app's config",
|
|
418
|
-
)
|
|
419
|
-
def git_bind_credential(
|
|
420
|
-
project: str,
|
|
421
|
-
app_id: str,
|
|
422
|
-
body: GitBindCredential,
|
|
423
|
-
registry: ServiceRegistry = Depends(get_registry),
|
|
424
|
-
) -> dict[str, Any]:
|
|
425
|
-
"""Make a MANAGED-repo app deployable by wiring a credential into its config.
|
|
426
|
-
|
|
427
|
-
Mirrors `kbagent data-app git-bind-credential`. Mints an `http_token` on the
|
|
428
|
-
app, encrypts it under the project KMS, and writes `parameters.dataApp.git`
|
|
429
|
-
so the runtime can clone the managed repo at deploy. The token is encrypted
|
|
430
|
-
in place and never returned. Needs an admin storage token; non-managed apps
|
|
431
|
-
are rejected.
|
|
432
|
-
"""
|
|
433
|
-
return registry.data_app.bind_managed_credential(
|
|
434
|
-
project,
|
|
435
|
-
app_id,
|
|
436
|
-
branch=body.branch,
|
|
437
|
-
permissions=body.permissions,
|
|
438
|
-
branch_id=body.branch_id,
|
|
439
|
-
dry_run=body.dry_run,
|
|
440
|
-
)
|
{keboola_cli-0.65.0 → keboola_cli-0.65.1}/src/keboola_agent_cli/services/data_app_service.py
RENAMED
|
@@ -87,13 +87,6 @@ MAX_GIT_REPO_LENGTH = 1024
|
|
|
87
87
|
MAX_GIT_BRANCH_LENGTH = 255
|
|
88
88
|
MAX_GIT_USERNAME_LENGTH = 255
|
|
89
89
|
|
|
90
|
-
# Placeholder HTTPS basic-auth username written into a managed-repo git block.
|
|
91
|
-
# The Keboola git-service ignores the username and only validates the token
|
|
92
|
-
# (RFC: managed_repo_data_apps_mvp), so any non-secret value works; we never
|
|
93
|
-
# put the token itself in this plaintext field.
|
|
94
|
-
MANAGED_GIT_CREDENTIAL_USERNAME = "kbagent"
|
|
95
|
-
DEFAULT_MANAGED_GIT_BRANCH = "main"
|
|
96
|
-
|
|
97
90
|
POLL_INTERVAL_SECONDS = 5.0
|
|
98
91
|
TERMINAL_ERROR_STATE = "error"
|
|
99
92
|
RUNNING_STATE = "running"
|
|
@@ -792,18 +785,17 @@ class DataAppService(BaseService):
|
|
|
792
785
|
# configVersion resolution depends on where the app's *source*
|
|
793
786
|
# lives, which we infer from the latest Storage config:
|
|
794
787
|
#
|
|
795
|
-
# * Streamlit / external-git
|
|
796
|
-
#
|
|
797
|
-
#
|
|
798
|
-
#
|
|
799
|
-
#
|
|
800
|
-
#
|
|
801
|
-
#
|
|
802
|
-
#
|
|
803
|
-
#
|
|
804
|
-
#
|
|
805
|
-
#
|
|
806
|
-
# `data-app git-bind-credential` (see gotchas.md).
|
|
788
|
+
# * Streamlit / external-git (parameters.dataApp.git present) -> the
|
|
789
|
+
# source pointer lives IN the Storage config, so we PIN the latest
|
|
790
|
+
# version so the operator reads the current git block.
|
|
791
|
+
# * A managed repo (useManagedGitRepo, NO git block) -> the source
|
|
792
|
+
# resolves via app.managedGitRepoId and the platform injects the
|
|
793
|
+
# clone credentials at deploy time, so we OMIT configVersion
|
|
794
|
+
# (matches keboola-mcp-server / Kai and the sandboxes-service
|
|
795
|
+
# `testManagedGitRepo.sh` contract). Pinning a managed app's
|
|
796
|
+
# no-git-block config instead makes the runtime demand
|
|
797
|
+
# `dataApp.git.repository` and the deploy fails -- that was the
|
|
798
|
+
# pre-0.65.0 bug this branch fixes.
|
|
807
799
|
#
|
|
808
800
|
# An explicit --config-version always wins as an escape hatch.
|
|
809
801
|
effective_version: str | None = config_version
|
|
@@ -859,173 +851,6 @@ class DataAppService(BaseService):
|
|
|
859
851
|
if storage_client is not None:
|
|
860
852
|
storage_client.close()
|
|
861
853
|
|
|
862
|
-
def bind_managed_credential(
|
|
863
|
-
self,
|
|
864
|
-
alias: str,
|
|
865
|
-
app_id: str,
|
|
866
|
-
*,
|
|
867
|
-
branch: str = DEFAULT_MANAGED_GIT_BRANCH,
|
|
868
|
-
permissions: str = "readOnly",
|
|
869
|
-
branch_id: int | None = None,
|
|
870
|
-
dry_run: bool = False,
|
|
871
|
-
) -> dict[str, Any]:
|
|
872
|
-
"""Make a managed-repo app deployable by wiring a credential into its config.
|
|
873
|
-
|
|
874
|
-
A managed-repo (``useManagedGitRepo``) app owns an empty Keboola-hosted
|
|
875
|
-
git repo but carries no ``parameters.dataApp.git`` block. On stacks where
|
|
876
|
-
the platform injects managed-repo credentials at deploy time that is
|
|
877
|
-
enough; on stacks that do not, the data-app runtime's ``git clone`` of
|
|
878
|
-
the managed repo fails with ``could not read Username`` and the deploy
|
|
879
|
-
reverts to ``stopped``. This method closes that gap the same way Kai's
|
|
880
|
-
dev-twin flow does (RFC: managed_repo_data_apps_mvp): it
|
|
881
|
-
|
|
882
|
-
1. resolves the managed repo's HTTPS clone URL (``get_git_repo``),
|
|
883
|
-
2. mints a fresh ``http_token`` credential ON the app (``create_git_credential``),
|
|
884
|
-
3. encrypts that token under the project KMS (``_build_git_block``), and
|
|
885
|
-
4. writes ``parameters.dataApp.git = {repository, username, '#password', branch}``
|
|
886
|
-
into the Storage config.
|
|
887
|
-
|
|
888
|
-
The minted token never leaves this process in plaintext: it is encrypted
|
|
889
|
-
in-place and only the ``KBC::...`` ciphertext is persisted. ``username``
|
|
890
|
-
is a non-secret placeholder the git-service ignores. After binding, call
|
|
891
|
-
``deploy_data_app`` to start the app.
|
|
892
|
-
|
|
893
|
-
Known limitation: the credential is minted BEFORE it is encrypted and
|
|
894
|
-
written to the config. If the encryption or ``update_config`` step fails,
|
|
895
|
-
the minted credential stays registered on the managed repo but its config
|
|
896
|
-
write never lands -- the one-time secret is lost and the credential is
|
|
897
|
-
orphaned (a harmless leaked slot). There is no rollback (the credential
|
|
898
|
-
DELETE endpoint is not wired here); re-running the command simply mints a
|
|
899
|
-
fresh credential and overwrites the git block.
|
|
900
|
-
"""
|
|
901
|
-
projects = self.resolve_projects([alias])
|
|
902
|
-
project = projects[alias]
|
|
903
|
-
ds_client = self._ds_client_factory(project.stack_url, project.token)
|
|
904
|
-
storage_client: Any | None = None
|
|
905
|
-
try:
|
|
906
|
-
app = ds_client.get_app(app_id)
|
|
907
|
-
if not app.get("hasManagedGitRepo"):
|
|
908
|
-
raise KeboolaApiError(
|
|
909
|
-
message=(
|
|
910
|
-
f"Data app {app_id} has no managed git repository. "
|
|
911
|
-
"bind-managed-credential only applies to apps created with "
|
|
912
|
-
"--use-managed-git-repo; external repos already carry their "
|
|
913
|
-
"own credentials."
|
|
914
|
-
),
|
|
915
|
-
status_code=0,
|
|
916
|
-
error_code=ErrorCode.VALIDATION_ERROR,
|
|
917
|
-
retryable=False,
|
|
918
|
-
)
|
|
919
|
-
config_id = str(app.get("configId") or "")
|
|
920
|
-
if not config_id:
|
|
921
|
-
raise KeboolaApiError(
|
|
922
|
-
message=f"Data app {app_id} has no associated configId",
|
|
923
|
-
status_code=500,
|
|
924
|
-
error_code=ErrorCode.API_ERROR,
|
|
925
|
-
retryable=False,
|
|
926
|
-
)
|
|
927
|
-
|
|
928
|
-
repo = ds_client.get_git_repo(app_id)
|
|
929
|
-
https_url = str(repo.get("httpsUrl") or "")
|
|
930
|
-
if not https_url:
|
|
931
|
-
raise KeboolaApiError(
|
|
932
|
-
message=(
|
|
933
|
-
f"Managed git repo for app {app_id} returned no HTTPS clone "
|
|
934
|
-
"URL; cannot wire an HTTPS credential."
|
|
935
|
-
),
|
|
936
|
-
status_code=0,
|
|
937
|
-
error_code=ErrorCode.API_ERROR,
|
|
938
|
-
retryable=False,
|
|
939
|
-
)
|
|
940
|
-
|
|
941
|
-
if dry_run:
|
|
942
|
-
# Show exactly what WOULD be wired without minting a credential
|
|
943
|
-
# (which is one-time and would orphan if not written) or touching
|
|
944
|
-
# the Storage config. All validation above has already run.
|
|
945
|
-
return {
|
|
946
|
-
"dry_run": True,
|
|
947
|
-
"project_alias": alias,
|
|
948
|
-
"app_id": str(app_id),
|
|
949
|
-
"config_id": config_id,
|
|
950
|
-
"repository": https_url,
|
|
951
|
-
"branch": branch,
|
|
952
|
-
"permissions": permissions,
|
|
953
|
-
"username": MANAGED_GIT_CREDENTIAL_USERNAME,
|
|
954
|
-
"message": (
|
|
955
|
-
f"Dry run -- no credential minted, config unchanged. Would mint an "
|
|
956
|
-
f"http_token ({permissions}) on app {app_id} and write "
|
|
957
|
-
f"parameters.dataApp.git -> {https_url} (branch {branch})."
|
|
958
|
-
),
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
# Mint a credential ON the app's managed repo. The one-time secret is
|
|
962
|
-
# consumed immediately by the encryption step below and never returned.
|
|
963
|
-
credential = ds_client.create_git_credential(
|
|
964
|
-
app_id,
|
|
965
|
-
type_="http_token",
|
|
966
|
-
permissions=permissions,
|
|
967
|
-
name="kbagent-managed-deploy",
|
|
968
|
-
)
|
|
969
|
-
secret = str(credential.get("secret") or "")
|
|
970
|
-
if not secret:
|
|
971
|
-
raise KeboolaApiError(
|
|
972
|
-
message=(
|
|
973
|
-
"create_git_credential returned no one-time secret for the "
|
|
974
|
-
"http_token; cannot wire the managed-repo credential."
|
|
975
|
-
),
|
|
976
|
-
status_code=500,
|
|
977
|
-
error_code=ErrorCode.API_ERROR,
|
|
978
|
-
retryable=False,
|
|
979
|
-
)
|
|
980
|
-
|
|
981
|
-
git_block = self._build_git_block(
|
|
982
|
-
alias=alias,
|
|
983
|
-
git_repo=https_url,
|
|
984
|
-
git_branch=branch,
|
|
985
|
-
git_public=False,
|
|
986
|
-
git_username=MANAGED_GIT_CREDENTIAL_USERNAME,
|
|
987
|
-
git_pat_plaintext=secret,
|
|
988
|
-
git_pat_encrypted=None,
|
|
989
|
-
)
|
|
990
|
-
|
|
991
|
-
storage_client = self._client_factory(project.stack_url, project.token)
|
|
992
|
-
detail = storage_client.get_config_detail(
|
|
993
|
-
DATA_APP_COMPONENT_ID, config_id, branch_id=branch_id
|
|
994
|
-
)
|
|
995
|
-
configuration = _coerce_config_dict(detail.get("configuration"))
|
|
996
|
-
parameters = dict(configuration.get("parameters") or {})
|
|
997
|
-
data_app = dict(parameters.get("dataApp") or {})
|
|
998
|
-
data_app["git"] = git_block
|
|
999
|
-
parameters["dataApp"] = data_app
|
|
1000
|
-
configuration["parameters"] = parameters
|
|
1001
|
-
|
|
1002
|
-
updated = storage_client.update_config(
|
|
1003
|
-
component_id=DATA_APP_COMPONENT_ID,
|
|
1004
|
-
config_id=config_id,
|
|
1005
|
-
configuration=configuration,
|
|
1006
|
-
change_description="Bind managed git credential for deploy (kbagent)",
|
|
1007
|
-
branch_id=branch_id,
|
|
1008
|
-
)
|
|
1009
|
-
return {
|
|
1010
|
-
"project_alias": alias,
|
|
1011
|
-
"app_id": str(app_id),
|
|
1012
|
-
"config_id": config_id,
|
|
1013
|
-
"repository": https_url,
|
|
1014
|
-
"branch": branch,
|
|
1015
|
-
"permissions": permissions,
|
|
1016
|
-
"credential_id": str(credential.get("id") or ""),
|
|
1017
|
-
"config_version": str(updated.get("version", "") or ""),
|
|
1018
|
-
"git": _redact_git_block(git_block),
|
|
1019
|
-
"message": (
|
|
1020
|
-
f"Wired a managed-repo credential into data app {app_id}. "
|
|
1021
|
-
"Run `kbagent data-app deploy` to start it."
|
|
1022
|
-
),
|
|
1023
|
-
}
|
|
1024
|
-
finally:
|
|
1025
|
-
ds_client.close()
|
|
1026
|
-
if storage_client is not None:
|
|
1027
|
-
storage_client.close()
|
|
1028
|
-
|
|
1029
854
|
def list_app_runs(self, alias: str, app_id: str, *, limit: int = 5) -> dict[str, Any]:
|
|
1030
855
|
"""List a data app's recent deployment attempts (runs), newest first.
|
|
1031
856
|
|
|
@@ -2304,18 +2129,14 @@ class DataAppService(BaseService):
|
|
|
2304
2129
|
self,
|
|
2305
2130
|
ds_client: DataScienceClient,
|
|
2306
2131
|
app_id: str,
|
|
2307
|
-
*,
|
|
2308
|
-
is_managed: bool,
|
|
2309
2132
|
) -> tuple[str, dict[str, Any]]:
|
|
2310
2133
|
"""Best-effort: fetch the latest run's ``failureReason`` to enrich a deploy
|
|
2311
2134
|
error message. Returns ``(message_suffix, details)``; NEVER raises -- a
|
|
2312
2135
|
diagnostic fetch failure must not mask the original deploy error.
|
|
2313
2136
|
|
|
2314
|
-
Setup-phase failures (e.g. a
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
managed-repo failure (``could not read Username``) into an actionable
|
|
2318
|
-
hint pointing at ``git-bind-credential``.
|
|
2137
|
+
Setup-phase failures (e.g. a git-clone error) produce no container logs,
|
|
2138
|
+
so ``data-app logs`` cannot show them; the run record is the only place
|
|
2139
|
+
the reason surfaces.
|
|
2319
2140
|
"""
|
|
2320
2141
|
try:
|
|
2321
2142
|
runs = ds_client.list_app_runs(app_id, limit=1)
|
|
@@ -2337,14 +2158,6 @@ class DataAppService(BaseService):
|
|
|
2337
2158
|
if detail_line:
|
|
2338
2159
|
suffix += f": {detail_line}"
|
|
2339
2160
|
suffix += ". See `kbagent data-app runs` for the full startup log."
|
|
2340
|
-
lowered = raw_message.lower()
|
|
2341
|
-
if is_managed and (
|
|
2342
|
-
"could not read username" in lowered or "authentication failed" in lowered
|
|
2343
|
-
):
|
|
2344
|
-
suffix += (
|
|
2345
|
-
" This managed-repo app cannot authenticate its git clone -- wire a"
|
|
2346
|
-
" credential with `kbagent data-app git-bind-credential` and redeploy."
|
|
2347
|
-
)
|
|
2348
2161
|
details = {
|
|
2349
2162
|
"run_id": run.get("id"),
|
|
2350
2163
|
"run_state": run.get("state"),
|
|
@@ -2377,11 +2190,8 @@ class DataAppService(BaseService):
|
|
|
2377
2190
|
while True:
|
|
2378
2191
|
last_record = ds_client.get_app(app_id)
|
|
2379
2192
|
state = str(last_record.get("state", ""))
|
|
2380
|
-
is_managed = bool(last_record.get("hasManagedGitRepo"))
|
|
2381
2193
|
if state == TERMINAL_ERROR_STATE:
|
|
2382
|
-
suffix, details = self._deploy_failure_diagnostic(
|
|
2383
|
-
ds_client, app_id, is_managed=is_managed
|
|
2384
|
-
)
|
|
2194
|
+
suffix, details = self._deploy_failure_diagnostic(ds_client, app_id)
|
|
2385
2195
|
raise KeboolaApiError(
|
|
2386
2196
|
message=(
|
|
2387
2197
|
f"Data app {app_id} reached state=error during deploy.{suffix}"
|
|
@@ -2400,9 +2210,7 @@ class DataAppService(BaseService):
|
|
|
2400
2210
|
if state == target_desired_state:
|
|
2401
2211
|
return last_record
|
|
2402
2212
|
if time.monotonic() >= deadline:
|
|
2403
|
-
suffix, details = self._deploy_failure_diagnostic(
|
|
2404
|
-
ds_client, app_id, is_managed=is_managed
|
|
2405
|
-
)
|
|
2213
|
+
suffix, details = self._deploy_failure_diagnostic(ds_client, app_id)
|
|
2406
2214
|
raise KeboolaApiError(
|
|
2407
2215
|
message=(
|
|
2408
2216
|
f"Timed out after {timeout_seconds:.0f}s waiting for data app "
|
|
@@ -2457,16 +2265,14 @@ class DataAppService(BaseService):
|
|
|
2457
2265
|
if use_managed_git_repo:
|
|
2458
2266
|
# Managed repos are provisioned empty -- there is no code to deploy
|
|
2459
2267
|
# yet. Spell out the follow-up steps so the operator (human or agent)
|
|
2460
|
-
# knows the create call is only step one.
|
|
2461
|
-
#
|
|
2462
|
-
# managed-repo credentials at deploy time.
|
|
2268
|
+
# knows the create call is only step one. The platform injects the
|
|
2269
|
+
# clone credentials at deploy time, so no credential wiring is needed.
|
|
2463
2270
|
return (
|
|
2464
2271
|
f"Data app '{name}' created with an empty Keboola-managed Git "
|
|
2465
2272
|
"repository. Next: 1) `kbagent data-app git-credentials-create "
|
|
2466
2273
|
"--type http_token --permissions readWrite` + push your code to the "
|
|
2467
|
-
"managed repo (`data-app git-repo` shows the URL),
|
|
2468
|
-
"data-app
|
|
2469
|
-
"3) `kbagent data-app deploy`."
|
|
2274
|
+
"managed repo (`data-app git-repo` shows the URL), then "
|
|
2275
|
+
"2) `kbagent data-app deploy`."
|
|
2470
2276
|
)
|
|
2471
2277
|
if not deployed:
|
|
2472
2278
|
return (
|
|
@@ -761,72 +761,3 @@ class TestDataAppRuns:
|
|
|
761
761
|
body = json.loads(result.output)
|
|
762
762
|
assert body["data"]["runs"][0]["failure_reason"]["reason"] == "StartupProbeFailed"
|
|
763
763
|
mock.list_app_runs.assert_called_once_with("prod", "42", limit=3)
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
class TestDataAppGitBindCredential:
|
|
767
|
-
def test_bind_credential_json(self, tmp_path: Path) -> None:
|
|
768
|
-
config_dir = tmp_path / "config"
|
|
769
|
-
config_dir.mkdir()
|
|
770
|
-
store = _setup_config(config_dir, {"prod": {"token": TEST_TOKEN}})
|
|
771
|
-
mock = MagicMock()
|
|
772
|
-
mock.bind_managed_credential.return_value = {
|
|
773
|
-
"project_alias": "prod",
|
|
774
|
-
"app_id": "42",
|
|
775
|
-
"repository": "https://git.example.com/keboola/app-42.git",
|
|
776
|
-
"branch": "main",
|
|
777
|
-
"permissions": "readOnly",
|
|
778
|
-
"config_version": "9",
|
|
779
|
-
"git": {"#password": "<encrypted>"},
|
|
780
|
-
"message": "Wired a managed-repo credential into data app 42.",
|
|
781
|
-
}
|
|
782
|
-
result = _invoke(
|
|
783
|
-
[
|
|
784
|
-
"--json",
|
|
785
|
-
"data-app",
|
|
786
|
-
"git-bind-credential",
|
|
787
|
-
"--project",
|
|
788
|
-
"prod",
|
|
789
|
-
"--app-id",
|
|
790
|
-
"42",
|
|
791
|
-
],
|
|
792
|
-
store=store,
|
|
793
|
-
data_app_mock=mock,
|
|
794
|
-
)
|
|
795
|
-
assert result.exit_code == 0, result.output
|
|
796
|
-
body = json.loads(result.output)
|
|
797
|
-
# The one-time token is never echoed -- only the redacted ciphertext marker.
|
|
798
|
-
assert body["data"]["git"]["#password"] == "<encrypted>"
|
|
799
|
-
mock.bind_managed_credential.assert_called_once_with(
|
|
800
|
-
"prod", "42", branch="main", permissions="readOnly", dry_run=False
|
|
801
|
-
)
|
|
802
|
-
|
|
803
|
-
def test_bind_credential_dry_run_passes_flag(self, tmp_path: Path) -> None:
|
|
804
|
-
config_dir = tmp_path / "config"
|
|
805
|
-
config_dir.mkdir()
|
|
806
|
-
store = _setup_config(config_dir, {"prod": {"token": TEST_TOKEN}})
|
|
807
|
-
mock = MagicMock()
|
|
808
|
-
mock.bind_managed_credential.return_value = {
|
|
809
|
-
"dry_run": True,
|
|
810
|
-
"project_alias": "prod",
|
|
811
|
-
"app_id": "42",
|
|
812
|
-
"repository": "https://git.example.com/keboola/app-42.git",
|
|
813
|
-
"branch": "main",
|
|
814
|
-
"permissions": "readOnly",
|
|
815
|
-
"message": "Dry run -- no credential minted, config unchanged.",
|
|
816
|
-
}
|
|
817
|
-
result = _invoke(
|
|
818
|
-
[
|
|
819
|
-
"data-app",
|
|
820
|
-
"git-bind-credential",
|
|
821
|
-
"--project",
|
|
822
|
-
"prod",
|
|
823
|
-
"--app-id",
|
|
824
|
-
"42",
|
|
825
|
-
"--dry-run",
|
|
826
|
-
],
|
|
827
|
-
store=store,
|
|
828
|
-
data_app_mock=mock,
|
|
829
|
-
)
|
|
830
|
-
assert result.exit_code == 0, result.output
|
|
831
|
-
assert "DRY RUN" in result.output
|
|
832
|
-
assert mock.bind_managed_credential.call_args.kwargs["dry_run"] is True
|