-
Notifications
You must be signed in to change notification settings - Fork 2
DSPX 2655 simplified workflow #438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
dmihalcik-virtru
wants to merge
17
commits into
main
Choose a base branch
from
DSPX-2655-simplified-workflow
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
3567fd3
feat(xtest): support platform-embedded otdfctl for migration to monorepo
dmihalcik-virtru 0ea2e5d
fixup ruff format
dmihalcik-virtru 7c20d73
fix(xtest): update remaining otdfctl references for platform monorepo…
dmihalcik-virtru cd0aec5
fixup pkg.go removes tag prefixes IIRC
dmihalcik-virtru 1f02700
refactor(xtest): consolidate .version and .module-path into single .v…
dmihalcik-virtru 9b9c9d7
feat(sdk-mgr): wire --source option through install artifact command
dmihalcik-virtru 0c1b428
fix(setup-cli-tool): avoid script injection by using env vars for inp…
dmihalcik-virtru bf739dc
Apply suggestion from @gemini-code-assist[bot]
dmihalcik-virtru edb5e3a
feat(setup-cli-tool): support multiple platform-source Go versions
dmihalcik-virtru 8f783c3
fix: address PR review findings for platform otdfctl migration
dmihalcik-virtru 1e5fc53
fix(sdk-mgr): accept "standalone" as valid Go source in go_module_path
dmihalcik-virtru 821c02c
docs(xtest): clarify auto mode resolves releases from standalone
dmihalcik-virtru 2901544
fix(setup-cli-tool): require SHA match in auto-detect platform fallback
dmihalcik-virtru 7e99e2d
fix: harden validation and error handling for platform otdfctl migration
dmihalcik-virtru 13385f5
fixup ruff format
dmihalcik-virtru bfe1119
refactor(xtest): extract composite actions from xtest.yml
dmihalcik-virtru cfc8fd9
Simplify xtest workflow with local runner
dmihalcik-virtru File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,223 @@ | ||
| """CI-specific commands for otdf-local. | ||
|
|
||
| These commands adapt the local environment management for GitHub Actions CI, | ||
| where the platform is already started by an external action and we only need | ||
| to start KAS instances as background processes. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import os | ||
| import sys | ||
| from pathlib import Path | ||
| from typing import Annotated | ||
|
|
||
| import typer | ||
|
|
||
| from otdf_local.config.ports import Ports | ||
| from otdf_local.config.settings import Settings | ||
| from otdf_local.health.waits import WaitTimeoutError, wait_for_health | ||
| from otdf_local.services import get_kas_manager | ||
| from otdf_local.utils.console import ( | ||
| print_error, | ||
| print_info, | ||
| print_success, | ||
| print_warning, | ||
| ) | ||
| from otdf_local.utils.yaml import load_yaml, save_yaml, set_nested | ||
|
|
||
| ci_app = typer.Typer( | ||
| name="ci", | ||
| help="CI-specific commands for GitHub Actions workflows.", | ||
| no_args_is_help=True, | ||
| ) | ||
|
|
||
|
|
||
| def _emit_github_output(key: str, value: str) -> None: | ||
| """Write a key=value pair to $GITHUB_OUTPUT if available, else print to stdout.""" | ||
| github_output = os.environ.get("GITHUB_OUTPUT") | ||
| if github_output: | ||
| with open(github_output, "a") as f: | ||
| f.write(f"{key}={value}\n") | ||
| else: | ||
| # Fallback for local testing | ||
| print(f"{key}={value}", file=sys.stdout) | ||
|
|
||
|
|
||
| def _prepare_kas_template( | ||
| settings: Settings, root_key: str | None, ec_tdf_enabled: bool | ||
| ) -> None: | ||
| """Ensure the KAS template config has the right root key and EC TDF settings. | ||
|
|
||
| In CI, the platform config may have a root_key that differs from what | ||
| we want for additional KAS instances. This updates the platform config | ||
| in-place so that KASService._generate_config reads the correct root_key. | ||
| """ | ||
| if root_key: | ||
| config = load_yaml(settings.platform_config) | ||
| set_nested(config, "services.kas.root_key", root_key) | ||
| if ec_tdf_enabled: | ||
| set_nested(config, "services.kas.preview.ec_tdf_enabled", True) | ||
| save_yaml(settings.platform_config, config) | ||
|
|
||
|
|
||
| @ci_app.command("start-kas") | ||
| def start_kas( | ||
| platform_dir: Annotated[ | ||
| Path, | ||
| typer.Option( | ||
| "--platform-dir", | ||
| help="Path to the platform checkout (must contain opentdf-kas-mode.yaml)", | ||
| envvar="OTDF_LOCAL_PLATFORM_DIR", | ||
| ), | ||
| ], | ||
| root_key: Annotated[ | ||
| str | None, | ||
| typer.Option( | ||
| "--root-key", | ||
| help="Root key for KAS instances (overrides platform config value)", | ||
| envvar="OT_ROOT_KEY", | ||
| ), | ||
| ] = None, | ||
| ec_tdf_enabled: Annotated[ | ||
| bool, | ||
| typer.Option( | ||
| "--ec-tdf-enabled/--no-ec-tdf", | ||
| help="Enable EC TDF support", | ||
| ), | ||
| ] = True, | ||
| key_management: Annotated[ | ||
| bool, | ||
| typer.Option( | ||
| "--key-management/--no-key-management", | ||
| help="Enable key management on km1/km2 instances", | ||
| ), | ||
| ] = False, | ||
| log_type: Annotated[ | ||
| str, | ||
| typer.Option( | ||
| "--log-type", | ||
| help="Log format type (json, text)", | ||
| ), | ||
| ] = "json", | ||
| health_timeout: Annotated[ | ||
| int, | ||
| typer.Option( | ||
| "--health-timeout", | ||
| help="Seconds to wait for each KAS instance to become healthy", | ||
| ), | ||
| ] = 60, | ||
| instances: Annotated[ | ||
| str | None, | ||
| typer.Option( | ||
| "--instances", | ||
| help="Comma-separated KAS instance names (default: all)", | ||
| ), | ||
| ] = None, | ||
| ) -> None: | ||
| """Start KAS instances for CI and emit GitHub Actions outputs. | ||
|
|
||
| Expects the platform to already be running (started by start-up-with-containers). | ||
| Starts all 6 KAS instances (alpha, beta, gamma, delta, km1, km2) as background | ||
| processes, waits for each to pass health checks, and emits log file paths as | ||
| GitHub Actions step outputs. | ||
|
|
||
| Output keys (written to $GITHUB_OUTPUT): | ||
| kas-alpha-log-file, kas-beta-log-file, kas-gamma-log-file, | ||
| kas-delta-log-file, kas-km1-log-file, kas-km2-log-file | ||
| """ | ||
| platform_dir = platform_dir.resolve() | ||
| if not platform_dir.is_dir(): | ||
| print_error(f"Platform directory does not exist: {platform_dir}") | ||
| raise typer.Exit(1) | ||
|
|
||
| # Check for required template files | ||
| kas_template = platform_dir / "opentdf-kas-mode.yaml" | ||
| platform_config = platform_dir / "opentdf-dev.yaml" | ||
| if not kas_template.exists(): | ||
| # Fall back to opentdf.yaml if opentdf-kas-mode.yaml doesn't exist | ||
| kas_template_alt = platform_dir / "opentdf.yaml" | ||
| if kas_template_alt.exists(): | ||
| print_info( | ||
| f"Using {kas_template_alt} as KAS template (opentdf-kas-mode.yaml not found)" | ||
| ) | ||
| else: | ||
| print_error( | ||
| f"Neither opentdf-kas-mode.yaml nor opentdf.yaml found in {platform_dir}" | ||
| ) | ||
| raise typer.Exit(1) | ||
|
|
||
| if not platform_config.exists(): | ||
| # Try opentdf.yaml as fallback | ||
| platform_config_alt = platform_dir / "opentdf.yaml" | ||
| if platform_config_alt.exists(): | ||
| platform_config = platform_config_alt | ||
|
|
||
| # Build settings with CI-specific overrides | ||
| # We use a fresh xtest_root derived from this package's location | ||
| settings = Settings( | ||
| platform_dir=platform_dir, | ||
| ) | ||
| settings.ensure_directories() | ||
|
|
||
| # Update root key in platform config if provided | ||
| if root_key: | ||
| _prepare_kas_template(settings, root_key, ec_tdf_enabled) | ||
|
|
||
| # Determine which instances to start | ||
| if instances: | ||
| kas_names = [n.strip() for n in instances.split(",")] | ||
| for name in kas_names: | ||
| if name not in Ports.all_kas_names(): | ||
| print_error(f"Unknown KAS instance: {name}") | ||
| raise typer.Exit(1) | ||
| else: | ||
| kas_names = Ports.all_kas_names() | ||
|
|
||
| # Start KAS instances | ||
| print_info(f"Starting KAS instances: {', '.join(kas_names)}...") | ||
| kas_manager = get_kas_manager(settings) | ||
|
|
||
| failed = [] | ||
| for name in kas_names: | ||
| kas = kas_manager.get(name) | ||
| if kas is None: | ||
| print_error(f"KAS instance {name} not found in manager") | ||
| failed.append(name) | ||
| continue | ||
| if not kas.start(): | ||
| print_error(f"Failed to start KAS {name}") | ||
| failed.append(name) | ||
|
|
||
| if failed: | ||
| print_error(f"Failed to start: {', '.join(failed)}") | ||
| raise typer.Exit(1) | ||
|
|
||
| # Wait for health | ||
| print_info("Waiting for KAS health checks...") | ||
| unhealthy = [] | ||
| for name in kas_names: | ||
| port = Ports.get_kas_port(name) | ||
| try: | ||
| wait_for_health( | ||
| f"http://localhost:{port}/healthz", | ||
| timeout=health_timeout, | ||
| service_name=f"KAS {name}", | ||
| ) | ||
| except WaitTimeoutError as e: | ||
| print_warning(str(e)) | ||
| unhealthy.append(name) | ||
|
|
||
| if unhealthy: | ||
| print_error(f"KAS instances failed health check: {', '.join(unhealthy)}") | ||
| raise typer.Exit(1) | ||
|
|
||
| print_success(f"All {len(kas_names)} KAS instances are healthy") | ||
|
|
||
| # Emit outputs | ||
| for name in kas_names: | ||
| log_path = settings.get_kas_log_path(name) | ||
| output_key = f"kas-{name}-log-file" | ||
| _emit_github_output(output_key, str(log_path)) | ||
|
|
||
| print_success("CI KAS startup complete") | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback logic for
kas_templateandplatform_configappears to be disconnected from the rest of the orchestration.kas_templatevariable (lines 135-148) is checked for existence but never used again in the function. If the intention is to use this template for KAS instances, it should be passed to theSettingsor theKASManager.platform_configvariable (lines 150-154) is updated with a fallback path, but it is not passed to theSettingsconstructor (lines 158-160). If theSettingsclass defaults toopentdf-dev.yaml, it will ignore the fallback found here, causing_prepare_kas_templateto fail or modify the wrong file.