Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 94 additions & 88 deletions roar/application/publish/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,112 +365,118 @@ def _run_git(path: Path, *args: str) -> str | None:

def register_lineage_target(request: RegisterLineageRequest) -> RegisterLineageResponse:
"""Run the `roar register` application workflow."""
from ...publish_auth import PublishAuthError

if not request.dry_run:
bootstrap(request.roar_dir)
logger = get_logger()
resolved_target = resolve_register_lineage_target(
request.target,
cwd=request.cwd,
roar_dir=request.roar_dir,
)
runtime = (
build_register_preview_runtime(
start_dir=str(request.cwd),
allow_public_without_binding=request.public,

try:
resolved_target = resolve_register_lineage_target(
request.target,
cwd=request.cwd,
roar_dir=request.roar_dir,
)
if request.dry_run
else build_publish_runtime(
glaas_url=get_glaas_url(),
start_dir=str(request.cwd),
allow_public_without_binding=request.public,
runtime = (
build_register_preview_runtime(
start_dir=str(request.cwd),
allow_public_without_binding=request.public,
)
if request.dry_run
else build_publish_runtime(
glaas_url=get_glaas_url(),
start_dir=str(request.cwd),
allow_public_without_binding=request.public,
)
)
)
collected_lineage, error = collect_register_lineage(
target=resolved_target,
roar_dir=request.roar_dir,
cwd=request.cwd,
lineage_collector=runtime.lineage_collector,
session_service=runtime.session_service,
logger=logger,
dry_run=request.dry_run,
)
if collected_lineage is None:
return RegisterLineageResponse(success=False, error=error)
collected_lineage, error = collect_register_lineage(
target=resolved_target,
roar_dir=request.roar_dir,
cwd=request.cwd,
lineage_collector=runtime.lineage_collector,
session_service=runtime.session_service,
logger=logger,
dry_run=request.dry_run,
)
if collected_lineage is None:
return RegisterLineageResponse(success=False, error=error)

try:
if request.dry_run:
prepared = prepare_register_preview_execution(
runtime=runtime,
roar_dir=request.roar_dir,
cwd=request.cwd,
session_id=collected_lineage.session_id,
session_hash_override=collected_lineage.session_hash_override,
logger=logger,
lineage=collected_lineage.lineage,
)
else:
prepared = prepare_register_execution(
runtime=runtime,
roar_dir=request.roar_dir,
cwd=request.cwd,
session_id=collected_lineage.session_id,
dry_run=False,
session_hash_override=collected_lineage.session_hash_override,
logger=logger,
lineage=collected_lineage.lineage,
)
except ValueError as exc:
return RegisterLineageResponse(
success=False,
artifact_hash=collected_lineage.artifact_hash,
error=str(exc),
)

try:
if request.dry_run:
prepared = prepare_register_preview_execution(
runtime=runtime,
roar_dir=request.roar_dir,
cwd=request.cwd,
session_id=collected_lineage.session_id,
session_hash_override=collected_lineage.session_hash_override,
logger=logger,
return preview_register_lineage(
lineage=collected_lineage.lineage,
)
else:
prepared = prepare_register_execution(
runtime=runtime,
roar_dir=request.roar_dir,
artifact_hash=collected_lineage.artifact_hash,
prepared=prepared,
cwd=request.cwd,
session_id=collected_lineage.session_id,
dry_run=False,
session_hash_override=collected_lineage.session_hash_override,
logger=logger,
lineage=collected_lineage.lineage,
skip_confirmation=request.skip_confirmation,
confirm_callback=request.confirm_callback,
)
except ValueError as exc:
return RegisterLineageResponse(
success=False,
artifact_hash=collected_lineage.artifact_hash,
error=str(exc),
)

if request.dry_run:
return preview_register_lineage(
service = RegisterService(
glaas_client=runtime.glaas_client,
coordinator=runtime.registration_coordinator,
)
result = service.register_prepared_lineage(
lineage=collected_lineage.lineage,
roar_dir=request.roar_dir,
artifact_hash=collected_lineage.artifact_hash,
prepared=prepared,
cwd=request.cwd,
dry_run=request.dry_run,
as_blake3=request.as_blake3,
skip_confirmation=request.skip_confirmation,
confirm_callback=request.confirm_callback,
prepared=prepared,
)

service = RegisterService(
glaas_client=runtime.glaas_client,
coordinator=runtime.registration_coordinator,
)
result = service.register_prepared_lineage(
lineage=collected_lineage.lineage,
roar_dir=request.roar_dir,
artifact_hash=collected_lineage.artifact_hash,
dry_run=request.dry_run,
as_blake3=request.as_blake3,
skip_confirmation=request.skip_confirmation,
confirm_callback=request.confirm_callback,
prepared=prepared,
)

finalize_register_git(
result_success=result.success,
dry_run=request.dry_run,
git_tag_name=prepared.git_tag_name,
git_tag_repo_root=prepared.git_tag_repo_root,
logger=logger,
)
finalize_register_git(
result_success=result.success,
dry_run=request.dry_run,
git_tag_name=prepared.git_tag_name,
git_tag_repo_root=prepared.git_tag_repo_root,
logger=logger,
)

return RegisterLineageResponse(
success=result.success,
session_hash=result.session_hash,
artifact_hash=result.artifact_hash,
jobs_registered=result.jobs_registered,
artifacts_registered=result.artifacts_registered,
links_created=result.links_created,
error=result.error,
secrets_detected=list(result.secrets_detected),
secrets_redacted=result.secrets_redacted,
aborted_by_user=result.aborted_by_user,
)
return RegisterLineageResponse(
success=result.success,
session_hash=result.session_hash,
artifact_hash=result.artifact_hash,
jobs_registered=result.jobs_registered,
artifacts_registered=result.artifacts_registered,
links_created=result.links_created,
error=result.error,
secrets_detected=list(result.secrets_detected),
secrets_redacted=result.secrets_redacted,
aborted_by_user=result.aborted_by_user,
)
except PublishAuthError as exc:
return RegisterLineageResponse(success=False, error=str(exc))


def put_artifacts(request: PutRequest) -> PutResponse:
Expand Down
8 changes: 6 additions & 2 deletions roar/publish_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
from .auth_store import load_auth_state


class PublishAuthError(RuntimeError):
"""Raised when publish auth or repo binding requirements are not satisfied."""


@dataclass(frozen=True)
class PublishAuthContext:
access_token: str | None
Expand Down Expand Up @@ -38,11 +42,11 @@ def load_publish_auth_context(

binding = _load_repo_binding(start_dir)
if binding and not access_token:
raise RuntimeError(
raise PublishAuthError(
"Repo is linked to GLaaS but no global auth state is available. Run `roar login`."
)
if not binding and not allow_public_without_binding:
raise RuntimeError(
raise PublishAuthError(
"No GLaaS repo binding found for this publish. Link the repo to a TReqs owner/project first, or rerun with --public to publish publicly."
)

Expand Down
4 changes: 3 additions & 1 deletion tests/integration/test_public_publish_intent_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,10 @@ def test_register_requires_explicit_public_flag_when_repo_has_no_binding(

assert result.returncode != 0
combined = f"{result.stdout}\n{result.stderr}"
assert "No GLaaS repo binding found" in combined
assert "Error: No GLaaS repo binding found" in combined
assert "--public" in combined
assert "Traceback (most recent call last)" not in combined
assert "RuntimeError:" not in combined
assert fake_glaas_publish_server.session_registrations == []


Expand Down
Loading