diff --git a/README.md b/README.md index fb0994c..b1e04f0 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,10 @@ The current workspace flow: For remote environments, the stable lane model is `testing` plus `prod`. Launchplane-managed PR previews are a separate control-plane concern rather -than a third durable runtime lane exposed through `platform runtime`. Remote release -or promotion flow is artifact-backed and belongs in `launchplane`, not -in branch-oriented `odoo-devkit` commands. +than a third durable runtime lane exposed through `platform runtime`. +`odoo-devkit` can publish artifact images for handoff, but remote ship, +promote, gate, and preview lifecycle flow belongs in `launchplane`, not in +branch-oriented `odoo-devkit` commands. ## Command surface diff --git a/odoo_devkit/artifact_inputs.py b/odoo_devkit/artifact_inputs.py index 2a5fc50..f781141 100644 --- a/odoo_devkit/artifact_inputs.py +++ b/odoo_devkit/artifact_inputs.py @@ -164,9 +164,7 @@ def _read_source_definitions( exact_ref = _read_optional_string(entry, "exact_ref", scope=entry_scope) selector = _read_optional_string(entry, "selector", scope=entry_scope) if bool(exact_ref) == bool(selector): - raise ArtifactInputsError( - f"{entry_scope} must set exactly one of exact_ref or selector." - ) + raise ArtifactInputsError(f"{entry_scope} must set exactly one of exact_ref or selector.") definitions.append( ArtifactInputSourceDefinition( repository=repository, diff --git a/odoo_devkit/dokploy_config.py b/odoo_devkit/dokploy_config.py index 760bd90..a0e8cbe 100644 --- a/odoo_devkit/dokploy_config.py +++ b/odoo_devkit/dokploy_config.py @@ -66,14 +66,10 @@ def load_dokploy_source_of_truth(repo_root: Path) -> DokploySourceOfTruth | None for target_index, raw_target in enumerate(targets_payload, start=1) ) if control_plane_root is not None: - missing_target_id_routes = [ - f"{target.context}/{target.instance}" for target in targets if not target.target_id.strip() - ] + missing_target_id_routes = [f"{target.context}/{target.instance}" for target in targets if not target.target_id.strip()] if missing_target_id_routes: missing_joined = ", ".join(missing_target_id_routes) - target_ids_display = ( - str(target_ids_file_path) if target_ids_file_path is not None else "config/dokploy-targets.toml" - ) + target_ids_display = str(target_ids_file_path) if target_ids_file_path is not None else "config/dokploy-targets.toml" raise RuntimeCommandError( "Control-plane Dokploy route catalog resolved through ODOO_CONTROL_PLANE_ROOT is missing pinned target ids for " f"{missing_joined}. Define them in {target_ids_display} or inline target_id values in {source_file_path}." @@ -154,12 +150,9 @@ def _apply_dokploy_target_id_catalog( merged_targets.append(merged_target) if remaining_routes: - unknown_routes = ", ".join( - f"{context_name}/{instance_name}" for context_name, instance_name in sorted(remaining_routes) - ) + unknown_routes = ", ".join(f"{context_name}/{instance_name}" for context_name, instance_name in sorted(remaining_routes)) raise RuntimeCommandError( - "Dokploy target-id catalog contains route(s) that are not present in the control-plane route catalog: " - f"{unknown_routes}" + f"Dokploy target-id catalog contains route(s) that are not present in the control-plane route catalog: {unknown_routes}" ) merged_payload["targets"] = merged_targets diff --git a/odoo_devkit/workspace_cockpit.py b/odoo_devkit/workspace_cockpit.py index fe5d2d6..1cb7e63 100644 --- a/odoo_devkit/workspace_cockpit.py +++ b/odoo_devkit/workspace_cockpit.py @@ -85,9 +85,7 @@ def load_workspace_cockpit_manifest(manifest_path: Path) -> WorkspaceCockpitMani _read_string_tuple(docs_table, "external_reference_boundary") or _default_docs_external_reference_lines() ), docs_working_split_lines=_read_string_tuple(docs_table, "working_split") or _default_docs_working_split_lines(), - docs_operational_note_lines=( - _read_string_tuple(docs_table, "operational_notes") or _default_docs_operational_note_lines() - ), + docs_operational_note_lines=(_read_string_tuple(docs_table, "operational_notes") or _default_docs_operational_note_lines()), session_prompt_rule_lines=( _read_string_tuple(session_prompt_table, "working_rules") or _default_session_prompt_rule_lines() ), @@ -367,9 +365,7 @@ def _default_docs_working_split_lines() -> tuple[str, ...]: def _default_docs_operational_note_lines() -> tuple[str, ...]: - return ( - "Historical plans remain available under `/Users/cbusillo/.codex/plans/` when you need rationale or prior sequencing.", - ) + return ("Historical plans remain available under `/Users/cbusillo/.codex/plans/` when you need rationale or prior sequencing.",) def _default_session_prompt_rule_lines() -> tuple[str, ...]: diff --git a/odoo_devkit/workspace_surface.py b/odoo_devkit/workspace_surface.py index 2d96052..55e11aa 100644 --- a/odoo_devkit/workspace_surface.py +++ b/odoo_devkit/workspace_surface.py @@ -253,11 +253,7 @@ def _render_workspace_session_prompt( shared_addons_repo_path: Path | None, ) -> str: shared_addons_source_path = shared_addons_repo_path.resolve() if shared_addons_repo_path is not None else None - shared_addons_line = ( - f"- sources/shared-addons -> {shared_addons_source_path}\n" - if shared_addons_source_path is not None - else "" - ) + shared_addons_line = f"- sources/shared-addons -> {shared_addons_source_path}\n" if shared_addons_source_path is not None else "" return ( "# Session Prompt Template\n\n" "Use this as a starting prompt for a new Every Code session from the generated workspace root.\n\n" diff --git a/tests/test_scaffold.py b/tests/test_scaffold.py index b745bde..dc3a5dc 100644 --- a/tests/test_scaffold.py +++ b/tests/test_scaffold.py @@ -72,7 +72,7 @@ def test_real_template_renders_current_shared_addons_contract(self) -> None: workspace_status_text = (output_directory / "scripts" / "workspace-status").read_text(encoding="utf-8") self.assertIn('name = "odoo-devkit"', manifest_text) - self.assertIn('[repos.runtime]', manifest_text) + self.assertIn("[repos.runtime]", manifest_text) self.assertIn('path = "../odoo-devkit"', manifest_text) self.assertIn('name = "odoo-shared-addons"', manifest_text) self.assertIn('path = "../odoo-shared-addons"', manifest_text) @@ -272,7 +272,9 @@ def test_sync_workspace_cockpit_rerenders_existing_root(self) -> None: self.assertIn("sources/shared-addons", agents_text) self.assertIn("AGENTS.override.md", agents_text) self.assertIn("Public base image", (output_directory / "docs" / "README.md").read_text(encoding="utf-8")) - self.assertIn("source repos as the source of truth", (output_directory / "docs" / "session-prompt.md").read_text(encoding="utf-8")) + self.assertIn( + "source repos as the source of truth", (output_directory / "docs" / "session-prompt.md").read_text(encoding="utf-8") + ) def test_workspace_cockpit_status_reports_current_missing_and_stale_files(self) -> None: with tempfile.TemporaryDirectory() as temporary_directory: @@ -317,7 +319,9 @@ def test_workspace_cockpit_status_reports_current_missing_and_stale_files(self) (output_directory / "AGENTS.md").write_text("stale\n", encoding="utf-8") stale_result = workspace_cockpit_status(manifest=manifest, output_directory=output_directory) self.assertFalse(stale_result.is_current) - stale_agents_status = next(file_status for file_status in stale_result.file_statuses if file_status.path.name == "AGENTS.md") + stale_agents_status = next( + file_status for file_status in stale_result.file_statuses if file_status.path.name == "AGENTS.md" + ) self.assertTrue(stale_agents_status.exists) self.assertFalse(stale_agents_status.matches_expected)