Skip to content

feat(xtest): support platform-embedded otdfctl for migration to monorepo#434

Merged
alkalescent merged 18 commits into
mainfrom
DSPX-2655-migrate-otdfctl
Apr 22, 2026
Merged

feat(xtest): support platform-embedded otdfctl for migration to monorepo#434
alkalescent merged 18 commits into
mainfrom
DSPX-2655-migrate-otdfctl

Conversation

@dmihalcik-virtru

@dmihalcik-virtru dmihalcik-virtru commented Apr 15, 2026

Copy link
Copy Markdown
Member

otdfctl is moving from opentdf/otdfctl into opentdf/platform. This change updates the test infrastructure to auto-detect when the platform checkout contains otdfctl/ and updates builds to use that path instead of the standalone repo.

  • xtest.yml workflow
    • adds otdfctl-source input {auto|standalone|platform}
    • adds a detection step that checks for otdfctl/go.mod in the platform dir
  • setup-cli-tool action
    • adds the platform-otdfctl-dir input
    • symlinks platform source into ./sdk/go/src/ for head builds instead of separate checkout
  • otdf-sdk-mgr command line tool
    • resolve.py supports go_source="platform" to resolve against the platform repo with otdfctl/ tag infix
    • installers write module path and version to the .version file
  • cli.sh,otdfctl.sh
    • read .version to use the correct module path (github.com/opentdf/platform/otdfctl) for go run fallback

Backward compatible!
Old releases still resolve from the standalone repo; .module-path absence defaults to the original module path.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

Summary by CodeRabbit

  • New Features

    • Auto-detect or explicitly select whether the Go CLI (otdfctl) is platform-embedded or standalone; CI action inputs and outputs support passing detected source and platform checkout info.
  • Refactor

    • Install/resolution flows and CI checkout logic now honor a per-release source, reuse platform checkouts via symlink, and propagate source through artifact installs.
  • Documentation

    • .version documented as module-path@version; examples show platform vs standalone module selection.
  • Bug Fix / UX

    • Invalid source values now produce clear errors; platform-detect mode fails fast if required files missing.

@dmihalcik-virtru
dmihalcik-virtru requested review from a team as code owners April 15, 2026 20:31
@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds selectable otdfctl source (auto/standalone/platform), detects platform-embedded otdfctl in CI, and threads the source through resolver, registry, installers, setup action, and CLI scripts so Go CLI resolution, installation, and generated links use the correct repository/module and version format.

Changes

Cohort / File(s) Summary
Workflow
.github/workflows/xtest.yml
Add otdfctl-source input; detect platform-embedded otdfctl; emit otdfctl-source, otdfctl-dir, otdfctl-sha; pass platform dir/sha to Go setup; adjust step conditions and generated links for platform source.
Setup Action
xtest/setup-cli-tool/action.yaml
New inputs platform-otdfctl-dir/platform-otdfctl-sha; outputs for per-slot platform usage (is-platform-*, needs-checkout-*, checkout-path-*); support reuse or checkout of opentdf/platform; add symlink steps and forward resolver source to artifact install.
Config Helpers
otdf-sdk-mgr/src/otdf_sdk_mgr/config.py
Split Go constants for standalone vs platform; add go_git_url, go_tag_infix, go_module_path with validation and explicit error on invalid source.
Resolver
otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
Add go_source param; introduce _go_platform flow using platform git URL/tag infix; annotate ResolveSuccess with optional source: "platform"; narrow exception types and handle missing main branch explicitly.
Registry
otdf-sdk-mgr/src/otdf_sdk_mgr/registry.py
Aggregate Go tags from standalone and platform repos; parse platform tag infix to bare semver; deduplicate (platform wins) and mark source="platform-git-tag"; warn on platform fetch errors.
Installers & CLI wiring
otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py, .../cli_versions.py, .../cli_install.py
Thread source/OTDFCTL_SOURCE through resolve/install flows; installers accept source, write .version as module@tag, normalize incoming version specs, adjust error behavior for platform install failures; artifact CLI gains --source.
Resolve typed dict
otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
Extend ResolveSuccess typed dict with optional source and ensure success paths carry source when applicable.
Shell scripts
xtest/sdk/go/cli.sh, xtest/sdk/go/otdfctl.sh
.version may be module-path@version or legacy tag; scripts detect @ and run go run <module>@<version> when present; retain legacy fallback; switch tests to [[ ... ]].
Docs / README
otdf-sdk-mgr/README.md
Document .version format as module-path@version and conditional module selection (github.com/opentdf/platform/otdfctl vs github.com/opentdf/otdfctl).

Sequence Diagram

sequenceDiagram
    participant WF as GitHub Workflow
    participant Detect as Detect Step
    participant Setup as Setup Action
    participant Resolve as Resolver (otdf-sdk-mgr)
    participant Install as Installer (otdf-sdk-mgr)
    participant Script as CLI Script

    WF->>Detect: probe checkout for embedded otdfctl (auto or explicit)
    Detect-->>WF: outputs {otdfctl-source, otdfctl-dir, otdfctl-sha}
    WF->>Resolve: resolve(sdk="go", go_source=otdfctl-source)
    Resolve-->>WF: ResolveSuccess {version, sha, source?}
    WF->>Install: install_go_release(version, source)
    Install-->>WF: writes .version (module@tag) / installs binary
    WF->>Setup: provide platform-otdfctl-dir/sha to action
    Setup-->>WF: checkout or symlink platform sources per outputs
    WF->>Script: run cli.sh / otdfctl.sh
    Script->>Script: read .version -> choose module@version vs legacy repo@tag
    Script-->>WF: CLI output
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • pflynn-virtru
  • elizabethhealy

Poem

🐰 I nibble .version with a curious hop,
Platform or solo — which path to stop?
Symlinks hum and tags align,
Module@version now in line,
I hop away with a carrot top. 🍽️

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding support for platform-embedded otdfctl within the xtest workflow for migration to the monorepo.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch DSPX-2655-migrate-otdfctl

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for resolving and installing the Go otdfctl CLI from the platform monorepo in addition to the standalone repository. Key changes include adding a source parameter to resolution and installation logic, updating shell wrappers to support dynamic module paths, and modifying the GitHub Action to allow symlinking local platform-embedded source code. Feedback highlights a missing propagation of the source parameter during installation, a potential IndexError when resolving the main branch, and security risks associated with direct shell interpolation of JSON outputs in the GitHub Action.

Comment thread otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py Outdated
Comment thread otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py Outdated
Comment thread xtest/setup-cli-tool/action.yaml Outdated
@github-actions

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
xtest/sdk/go/otdfctl.sh (1)

20-28: Use [[ instead of [ for conditional tests.

The SonarCloud analysis correctly flags this. Since the script uses #!/usr/bin/env bash, using [[ provides safer string comparisons (no word splitting or glob expansion issues).

♻️ Proposed fix
 if [ ! -f "$SCRIPT_DIR"/otdfctl ]; then
   MODULE_PATH="github.com/opentdf/otdfctl"
-  if [ -f "$SCRIPT_DIR/.module-path" ]; then
+  if [[ -f "$SCRIPT_DIR/.module-path" ]]; then
     MODULE_PATH=$(tr -d '[:space:]' <"$SCRIPT_DIR/.module-path")
   fi
-  if [ -f "$SCRIPT_DIR/.version" ]; then
+  if [[ -f "$SCRIPT_DIR/.version" ]]; then
     OTDFCTL_VERSION=$(tr -d '[:space:]' <"$SCRIPT_DIR/.version")
     cmd=(go run "${MODULE_PATH}@${OTDFCTL_VERSION}")
   else
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@xtest/sdk/go/otdfctl.sh` around lines 20 - 28, Replace the POSIX [ tests with
Bash [[ tests in the otfdctl script to avoid word-splitting and globbing issues:
change each if [ -f "$SCRIPT_DIR/.module-path" ] and if [ -f
"$SCRIPT_DIR/.version" ] to if [[ -f "$SCRIPT_DIR/.module-path" ]] and if [[ -f
"$SCRIPT_DIR/.version" ]], keeping the same bodies that read into MODULE_PATH
and OTDFCTL_VERSION and assign cmd (MODULE_PATH, SCRIPT_DIR, OTDFCTL_VERSION,
cmd are the identifiers to locate).
otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py (1)

44-45: Consider using go_module_path(source) for consistency.

Line 49 uses go_install_prefix(source) to dynamically select the module prefix, but line 45 directly references the GO_MODULE_PATH_PLATFORM constant. Using go_module_path(source) here would be more consistent and encapsulate the platform/standalone selection logic in one place.

♻️ Suggested consistency improvement
-from otdf_sdk_mgr.config import (
-    GO_MODULE_PATH_PLATFORM,
-    LTS_VERSIONS,
-    get_sdk_dir,
-    get_sdk_dirs,
-    go_install_prefix,
-)
+from otdf_sdk_mgr.config import (
+    LTS_VERSIONS,
+    get_sdk_dir,
+    get_sdk_dirs,
+    go_install_prefix,
+    go_module_path,
+)
     if source == "platform":
-        (dist_dir / ".module-path").write_text(f"{GO_MODULE_PATH_PLATFORM}\n")
+        (dist_dir / ".module-path").write_text(f"{go_module_path(source)}\n")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py` around lines 44 - 45, The code
writes GO_MODULE_PATH_PLATFORM directly when source == "platform", which
duplicates selection logic; replace the direct constant with a call to
go_module_path(source) so the module path selection is centralized (match the
existing pattern used by go_install_prefix(source)), i.e., use
go_module_path(source) when writing to the ".module-path" file and preserve the
trailing newline.
xtest/sdk/go/cli.sh (1)

25-33: Use [[ instead of [ for conditional tests.

Same as otdfctl.sh - the SonarCloud analysis flags this. Since the script uses Bash, [[ is the safer choice.

♻️ Proposed fix
 if [ ! -f "$SCRIPT_DIR"/otdfctl ]; then
   MODULE_PATH="github.com/opentdf/otdfctl"
-  if [ -f "$SCRIPT_DIR/.module-path" ]; then
+  if [[ -f "$SCRIPT_DIR/.module-path" ]]; then
     MODULE_PATH=$(tr -d '[:space:]' <"$SCRIPT_DIR/.module-path")
   fi
-  if [ -f "$SCRIPT_DIR/.version" ]; then
+  if [[ -f "$SCRIPT_DIR/.version" ]]; then
     OTDFCTL_VERSION=$(tr -d '[:space:]' <"$SCRIPT_DIR/.version")
     cmd=(go run "${MODULE_PATH}@${OTDFCTL_VERSION}")
   else
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@xtest/sdk/go/cli.sh` around lines 25 - 33, The conditional file-existence
tests use the POSIX single-bracket form; change them to Bash's safer
double-bracket tests: replace instances of [ -f "$SCRIPT_DIR/.module-path" ] and
[ -f "$SCRIPT_DIR/.version" ] with [[ -f "$SCRIPT_DIR/.module-path" ]] and [[ -f
"$SCRIPT_DIR/.version" ]] respectively in the code that assigns MODULE_PATH,
OTDFCTL_VERSION and builds the cmd array so the checks are executed with Bash's
[[ ... ]] semantics.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@xtest/setup-cli-tool/action.yaml`:
- Around line 150-173: The run block uses interpolated inputs (${ { inputs.path
}} and ${ { inputs.sdk }}) directly causing script-injection risk; move those
into environment variables (e.g., INPUT_PATH and INPUT_SDK) in the step's env
and reference them inside the bash script (use "$INPUT_PATH" and "$INPUT_SDK")
when constructing src_dir and mkdir/ln operations (symbols to update: the step
named "symlink platform-embedded otdfctl for head versions", variables
version_json/needs_source/tag/src_dir, and the ln -sfn invocation), and ensure
all expansions are quoted to prevent word-splitting.

---

Nitpick comments:
In `@otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py`:
- Around line 44-45: The code writes GO_MODULE_PATH_PLATFORM directly when
source == "platform", which duplicates selection logic; replace the direct
constant with a call to go_module_path(source) so the module path selection is
centralized (match the existing pattern used by go_install_prefix(source)),
i.e., use go_module_path(source) when writing to the ".module-path" file and
preserve the trailing newline.

In `@xtest/sdk/go/cli.sh`:
- Around line 25-33: The conditional file-existence tests use the POSIX
single-bracket form; change them to Bash's safer double-bracket tests: replace
instances of [ -f "$SCRIPT_DIR/.module-path" ] and [ -f "$SCRIPT_DIR/.version" ]
with [[ -f "$SCRIPT_DIR/.module-path" ]] and [[ -f "$SCRIPT_DIR/.version" ]]
respectively in the code that assigns MODULE_PATH, OTDFCTL_VERSION and builds
the cmd array so the checks are executed with Bash's [[ ... ]] semantics.

In `@xtest/sdk/go/otdfctl.sh`:
- Around line 20-28: Replace the POSIX [ tests with Bash [[ tests in the otfdctl
script to avoid word-splitting and globbing issues: change each if [ -f
"$SCRIPT_DIR/.module-path" ] and if [ -f "$SCRIPT_DIR/.version" ] to if [[ -f
"$SCRIPT_DIR/.module-path" ]] and if [[ -f "$SCRIPT_DIR/.version" ]], keeping
the same bodies that read into MODULE_PATH and OTDFCTL_VERSION and assign cmd
(MODULE_PATH, SCRIPT_DIR, OTDFCTL_VERSION, cmd are the identifiers to locate).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 20c9d9d4-32c8-4359-a320-f53c627cf8a4

📥 Commits

Reviewing files that changed from the base of the PR and between cf8debf and 0ea2e5d.

📒 Files selected for processing (8)
  • .github/workflows/xtest.yml
  • otdf-sdk-mgr/src/otdf_sdk_mgr/cli_versions.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/config.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
  • xtest/sdk/go/cli.sh
  • xtest/sdk/go/otdfctl.sh
  • xtest/setup-cli-tool/action.yaml

Comment thread xtest/setup-cli-tool/action.yaml Outdated
@github-actions

Copy link
Copy Markdown

X-Test Failure Report

3 similar comments
@github-actions

Copy link
Copy Markdown

X-Test Failure Report

@github-actions

Copy link
Copy Markdown

X-Test Failure Report

@github-actions

Copy link
Copy Markdown

X-Test Failure Report

@dmihalcik-virtru
dmihalcik-virtru force-pushed the DSPX-2655-migrate-otdfctl branch from 60373eb to bf739dc Compare April 16, 2026 13:19
@github-actions

Copy link
Copy Markdown

X-Test Failure Report

@github-actions

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py (1)

148-159: Consider using exact match for main branch detection.

The condition "refs/heads/main" in tag is a substring match that could unintentionally match branches like refs/heads/main-feature or refs/heads/main2. An exact match would be safer:

sha, _ = next(tag for tag in all_heads if tag[1] == "refs/heads/main")

However, since the tuple is (sha, ref), the current logic checks if the ref string contains the substring which should work for the exact ref refs/heads/main. If all_heads contains ["sha", "refs/heads/main"] tuples, then tag[1] would be the ref. The current "refs/heads/main" in tag checks if the substring exists anywhere in the tuple (including the sha), which is less precise.

♻️ Proposed fix for exact match
             all_heads = [r.split("\t") for r in repo.ls_remote(sdk_url, heads=True).split("\n")]
-            sha, _ = next(tag for tag in all_heads if "refs/heads/main" in tag)
+            sha, _ = next((s, r) for s, r in all_heads if r == "refs/heads/main")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py` around lines 148 - 159, The branch
detection uses a substring search against the tuple (all_heads) which can
mis-match names like refs/heads/main-feature; update the generator in the
resolve.py block (where version == "main" or "refs/heads/main", all_heads,
repo.ls_remote, and the next(...) call) to unpack each tuple into (sha, ref) and
match ref exactly (e.g., next((sha for sha, ref in all_heads if ref ==
"refs/heads/main"))), then use that sha and ref to construct the returned dict
with "tag": "main" as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py`:
- Around line 148-159: The branch detection uses a substring search against the
tuple (all_heads) which can mis-match names like refs/heads/main-feature; update
the generator in the resolve.py block (where version == "main" or
"refs/heads/main", all_heads, repo.ls_remote, and the next(...) call) to unpack
each tuple into (sha, ref) and match ref exactly (e.g., next((sha for sha, ref
in all_heads if ref == "refs/heads/main"))), then use that sha and ref to
construct the returned dict with "tag": "main" as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 54ee9642-05f8-4986-a32c-5e0d698b8236

📥 Commits

Reviewing files that changed from the base of the PR and between 0ea2e5d and edb5e3a.

📒 Files selected for processing (10)
  • .github/workflows/xtest.yml
  • otdf-sdk-mgr/README.md
  • otdf-sdk-mgr/src/otdf_sdk_mgr/cli_install.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/config.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/registry.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
  • xtest/sdk/go/cli.sh
  • xtest/sdk/go/otdfctl.sh
  • xtest/setup-cli-tool/action.yaml
✅ Files skipped from review due to trivial changes (1)
  • otdf-sdk-mgr/README.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • xtest/sdk/go/cli.sh
  • .github/workflows/xtest.yml
  • otdf-sdk-mgr/src/otdf_sdk_mgr/config.py
  • xtest/sdk/go/otdfctl.sh
  • otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py

@github-actions

Copy link
Copy Markdown

X-Test Failure Report

3 similar comments
@github-actions

Copy link
Copy Markdown

X-Test Failure Report

@github-actions

Copy link
Copy Markdown

X-Test Failure Report

@github-actions

Copy link
Copy Markdown

X-Test Failure Report

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
xtest/setup-cli-tool/action.yaml (1)

338-348: ⚠️ Potential issue | 🔴 Critical

Fix .env file path: write to SDK root, not to src/ subdirectory.

The save env from version-info step writes .env files to src/${tag}.env, but the Java Makefile expects them at the SDK root directory (MAKEFILE_DIR). This causes version-specific environment variables like PLATFORM_BRANCH to be ignored during builds. Go and JS Makefiles do not consume version-specific .env files.

Change the path from ${{ inputs.path }}/${{ inputs.sdk }}/src/${tag}.env to ${{ inputs.path }}/${{ inputs.sdk }}/${tag}.env.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@xtest/setup-cli-tool/action.yaml` around lines 338 - 348, The "save env from
version-info" step currently writes per-version .env files to "${{ inputs.path
}}/${{ inputs.sdk }}/src/${tag}.env" which is wrong for the Java Makefile;
update the run loop so it writes to the SDK root instead by changing the target
path to "${{ inputs.path }}/${{ inputs.sdk }}/${tag}.env" (keep the loop,
tag/env extraction and the conditional intact, only replace the "/src/" segment
in the echo output path).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@xtest/setup-cli-tool/action.yaml`:
- Around line 338-348: The "save env from version-info" step currently writes
per-version .env files to "${{ inputs.path }}/${{ inputs.sdk }}/src/${tag}.env"
which is wrong for the Java Makefile; update the run loop so it writes to the
SDK root instead by changing the target path to "${{ inputs.path }}/${{
inputs.sdk }}/${tag}.env" (keep the loop, tag/env extraction and the conditional
intact, only replace the "/src/" segment in the echo output path).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fb9ecb89-5294-4f93-960b-ad80764c535e

📥 Commits

Reviewing files that changed from the base of the PR and between edb5e3a and 13385f5.

📒 Files selected for processing (8)
  • .github/workflows/xtest.yml
  • otdf-sdk-mgr/README.md
  • otdf-sdk-mgr/src/otdf_sdk_mgr/cli_versions.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/config.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/registry.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
  • xtest/setup-cli-tool/action.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
  • otdf-sdk-mgr/src/otdf_sdk_mgr/cli_versions.py
  • otdf-sdk-mgr/README.md
  • otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown


- name: Replace otdfctl go.mod packages, but only at head version of platform
if: fromJson(steps.configure-go.outputs.heads)[0] != null && env.FOCUS_SDK == 'go' && contains(fromJSON(needs.resolve-versions.outputs.heads), matrix.platform-tag)
if: >-

@alkalescent alkalescent Apr 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in default auto mode, detect-otdfctl reports platform if the otdfctl dir exists. However, resolve-versions still pulls the Go head from the standalone repo (which skips the replace step and the build ends with the published platform modules). Should this condition be on the per-version source from resolve-versions instead?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, it will check out a new copy of the platform repo at that tag so the go.work should be correct. I could be wrong; there are a lot of moving parts

Comment on lines 183 to 211

@alkalescent alkalescent Apr 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

latest_stable_version returns just the version string, so cmd_stable calls install_release with no source. I believe this will fail once the latest stable only exists in opentdf/platform/otdfctl bc go install github.com/opentdf/otdfctl@... will not point to anything. Should we use source here?

Comment thread xtest/setup-cli-tool/action.yaml
dmihalcik-virtru and others added 4 commits April 20, 2026 13:18
otdfctl is moving from opentdf/otdfctl into opentdf/platform. This
updates the test infrastructure to auto-detect when the platform
checkout contains otdfctl/ and build from there instead of the
standalone repo.

Key changes:
- xtest.yml: new otdfctl-source input (auto/standalone/platform) and
  detection step that checks for otdfctl/go.mod in the platform dir
- setup-cli-tool: new platform-otdfctl-dir input; symlinks platform
  source into sdk/go/src/ for head builds instead of separate checkout
- otdf-sdk-mgr: resolve.py supports go_source="platform" to resolve
  against the platform repo with otdfctl/ tag infix; installers write
  .module-path file for the new Go module path
- cli.sh/otdfctl.sh: read .module-path to use the correct module path
  (github.com/opentdf/platform/otdfctl) for go run fallback

Backward compatible: old releases still resolve from the standalone
repo; .module-path absence defaults to the original module path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… migration

- artifactLink in xtest.yml now uses the correct pkg.go.dev module path
  based on the source field (platform vs standalone)
- registry.py list_go_versions() queries both the standalone otdfctl
  repo and the platform repo (otdfctl/ prefixed tags), deduplicating
  with platform entries taking precedence
- README.md documents both module paths for Go release installs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dmihalcik-virtru and others added 12 commits April 20, 2026 13:18
…ersion file

The Go SDK version config now uses a single .version file with format
`module-path@version` (e.g., `github.com/opentdf/otdfctl@v0.24.0`)
instead of separate .version and .module-path files. Shell wrappers
fall back to the standalone module path for legacy bare-version files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allows specifying the source repo for Go CLI installs (e.g., --source platform)
to support the otdfctl migration from standalone repo to the platform monorepo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…uts and step outputs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Replace global sdk_source/sdk_repo with per-version checkout decisions
so that multiple Go head versions from opentdf/platform at different
SHAs can be tested against each other (e.g. a platform PR vs main).

- Add platform-otdfctl-sha input for SHA-based matching of the existing
  platform checkout; versions with a different SHA get a fresh checkout
  of opentdf/platform into platform-src/{tag}/ with a symlink from
  otdfctl/ into src/{tag}/
- Wire OTDFCTL_SOURCE to the resolve-versions job when otdfctl-source
  is explicitly 'platform', so the resolver returns platform SHAs
- Preserve backward-compatible auto-detect behavior: when platform-
  otdfctl-dir is set but version-info lacks source:"platform", all
  head Go versions still symlink to the existing dir

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Pass --source flag through artifact install step so platform-sourced
  Go versions get the correct module path in .version files
- Strip tag infix (e.g., otdfctl/v0.24.0 → v0.24.0) before normalizing
  in install_go_release to avoid producing invalid version strings
- Move step output expansion to env: block in detect-otdfctl to prevent
  script injection (consistent with 0c1b428)
- Narrow except Exception to GitCommandError in registry.py platform
  tag query so programming bugs propagate instead of being swallowed
- Handle StopIteration explicitly in resolve.py with a clear
  "main branch not found" error message
- Validate source parameter in go_module_path() to reject typos
- Add symlink target existence checks after ln -sfn in action.yaml
- Add ::warning:: annotation when auto-detect fallback skips SHA
  verification
- Fix typo and minor comment/doc improvements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The workflow input and CLI advertise "standalone" as a valid source, but
go_module_path rejected it with a ValueError. Add "standalone" to the
valid set so it maps to the default standalone module path, consistent
with go_git_url, go_tag_infix, and go_install_prefix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The otdfctl-source description implied auto detects from the platform
checkout, but release resolution runs before that checkout exists. Update
the input description and inline comment to accurately reflect the
two-phase behavior: releases resolve from standalone, platform detection
applies only to head builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
In auto mode, setup-cli-tool previously symlinked all head Go versions
to the platform checkout without verifying the commit SHA. This meant
otdfctl-ref=my-feature could silently test the platform-embedded otdfctl
instead of opentdf/otdfctl@my-feature. Now the fallback only reuses the
platform checkout when the resolved SHA matches; otherwise it falls
through to a standalone checkout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Validate PLATFORM_DIR before using it in detect-otdfctl to prevent
wrong-repo SHA when the directory is missing. Remove dead cross-repo SHA
comparison in auto-detect fallback (standalone and platform repos have
different commit histories). Add input validation to all go_* config
helpers and the OTDFCTL_SOURCE env var. Treat pre-warm failure as a hard
error for the platform module path. Use array pattern for source_args
to prevent shell word-splitting. Improve observability with ::warning::
annotations and version-override logging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Narrow except Exception in resolve() to (GitCommandError, ValueError);
  move config validation before try block so programming errors propagate
- Make unrecognized OTDFCTL_SOURCE a hard error (exit 2) instead of
  silent fallback to standalone
- Fix install_method display for platform versions (use stripped version,
  not prefixed tag)
- Propagate source through latest_stable_version/cmd_stable so platform
  Go releases use the correct module path
- Fix script injection: move inputs.path/sdk from run blocks to env vars
  in all action.yaml steps (SonarCloud/CodeRabbit finding)
- Make freshly checked-out symlink target absolute (alkalescent review)
- Check git rev-parse exit code in detect-otdfctl step
- Use [[ instead of [ for bash file tests in cli.sh/otdfctl.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dmihalcik-virtru
dmihalcik-virtru force-pushed the DSPX-2655-migrate-otdfctl branch from 2c9bfeb to 7c4db05 Compare April 20, 2026 18:55

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py (1)

245-252: ⚠️ Potential issue | 🟡 Minor

cmd_release cannot target platform source.

cmd_release parses sdk:version specs and calls install_release without source, so there's no path for a user invoking install release go:v0.24.0 to select the platform module. With the migration, once a version only exists on platform, this command will silently resolve to the standalone module path and (per install_go_release) warn-and-continue rather than fail, leaving a .version pointing at a nonexistent module.

Consider extending the spec syntax (e.g., go@platform:v0.24.0) or auto-detecting from list_go_versions() which source owns the requested version. This is the same class of concern raised on latest_stable_version in a prior review and is still reachable via cmd_release.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py` around lines 245 - 252,
cmd_release currently splits specs as sdk:version and calls install_release(sdk,
version) without specifying source, so platform-only versions can be
misresolved; update cmd_release to accept an optional source token (syntax like
sdk@source:version) or auto-detect the correct source before calling
install_release: parse specs for an '@' (e.g., split into sdk, source, version)
and if no source is provided, query the per-SDK version list function (e.g.,
list_go_versions or similar list_*_versions) to determine whether the requested
version lives on 'platform' vs 'standalone', then call install_release(sdk,
version, source=...) (or pass the resolved source through to install_go_release
where applicable) so the installer targets the proper module and avoids creating
.version entries pointing at nonexistent modules.
🧹 Nitpick comments (4)
otdf-sdk-mgr/src/otdf_sdk_mgr/cli_install.py (1)

77-86: Consider validating source at the CLI boundary.

Unlike resolve_versions in cli_versions.py (which validates OTDFCTL_SOURCE against {"standalone", "platform"} and exits 2 on unknown), this command forwards source verbatim into cmd_install. A typo (e.g., --source platfrm) will silently fall through to go_module_path(...)'s default behavior. Consider validating here for a consistent UX, or relying on go_module_path to raise on unknown values.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/cli_install.py` around lines 77 - 86, The CLI
handler for the install command accepts the source parameter but doesn't
validate it before calling cmd_install, so typos (e.g., "--source platfrm")
silently propagate to go_module_path; add explicit validation in the CLI
boundary (mirroring resolve_versions) to check that source is either
"standalone" or "platform" and exit with status 2 on unknown values, and only
call cmd_install(sdk, version, dist_name=dist_name, source=source) if validation
passes; reference the cli_install.py handler's source parameter, the
resolve_versions validation logic, and go_module_path/cmd_install as the places
to align behavior.
otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py (2)

45-50: Infix stripping is unconditional and source-agnostic.

if "/" in version: version = version.rsplit("/", 1)[-1] strips any prefix before /, regardless of whether it matches the expected infix for the chosen source. In practice this is fine today since callers pass already-bare semvers for platform (see registry.py line 112), but if a caller ever forwards otdfctl/v0.24.0 with source=None, the .version file will record github.com/opentdf/otdfctl@v0.24.0 — which happens to work but silently hides a source/tag mismatch. Consider validating that the stripped prefix matches the expected infix for the selected source, or logging when stripping occurs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py` around lines 45 - 50, The
current unconditional infix strip in the installer (the block that checks if "/"
in version and does version.rsplit("/",1)[-1] before calling normalize_version
and go_module_path and writing dist_dir / ".version") can hide mismatches
between the provided source and the version prefix; update this logic to detect
and validate the prefix when a slash is present: extract the prefix and compare
it against the expected infix for the given source (or the canonical module path
produced by go_module_path) and only strip when they match, otherwise either
leave the version as-is and/or emit a warning log indicating a source/tag
mismatch; ensure normalize_version is still called on the final version and that
the .version file continues to be written using module and tag only after
validation.

60-66: Asymmetric pre-warm failure handling — confirm intent.

Platform pre-warm failures raise InstallError, while standalone failures only warn and defer to runtime retry. This is defensible (platform module path is new and a miss likely means "not published yet"), but it means a transient network/proxy blip during a platform install aborts the whole install, whereas the same blip on standalone is tolerated. If that asymmetry is intentional for the migration window, consider a code comment noting it; otherwise consider distinguishing "module not found" (fail fast) from transient errors (warn + retry) by inspecting result.stderr.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py` around lines 60 - 66, Current
code treats go install failures for GO_MODULE_PATH_PLATFORM by raising
InstallError while other modules only warn and defer, which is asymmetric;
either document the intentional behavior or change logic to distinguish "module
not found" vs transient errors by inspecting result.stderr. Update the block
around the go install check (use variables result, msg, GO_MODULE_PATH_PLATFORM,
and InstallError) to: if the platform-special-case behavior is intentional, add
a brief inline comment explaining the migration/publishing rationale; otherwise
parse result.stderr (or result.returncode) to detect a not-found/publish-related
message and raise InstallError only for that case while treating other transient
errors like the non-platform path (print warning and retry at runtime). Ensure
the message includes the module and tag context as currently constructed.
otdf-sdk-mgr/src/otdf_sdk_mgr/registry.py (1)

115-122: Overlap notice may be noisy during migration window.

Once platform starts publishing the same versions as standalone, this note will print for every shared tag on every list/resolve call. Consider gating it behind a verbose/debug flag, or emitting a single summary line at the end.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/registry.py` around lines 115 - 122, The
overlap notice printing for every shared version is noisy; modify the logic
around the "if version in seen" branch (the print to sys.stderr) to either: a)
respect a verbosity/debug flag (e.g., check an existing verbose/debug parameter
or add one to the surrounding function and only emit the message when verbose is
true, or switch to using a logger and call logger.debug instead of print), or b)
collect overlapping versions into a list (e.g., overlaps or duplicated_versions)
during the loop and, after the loop completes, emit a single summary line to
stderr/log (e.g., "Note: versions X found in both...") if that list is
non-empty. Update the surrounding function signature and callers if you add a
verbose flag, or switch to the module logger for debug-level output so callers
can control noise.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py`:
- Around line 245-252: cmd_release currently splits specs as sdk:version and
calls install_release(sdk, version) without specifying source, so platform-only
versions can be misresolved; update cmd_release to accept an optional source
token (syntax like sdk@source:version) or auto-detect the correct source before
calling install_release: parse specs for an '@' (e.g., split into sdk, source,
version) and if no source is provided, query the per-SDK version list function
(e.g., list_go_versions or similar list_*_versions) to determine whether the
requested version lives on 'platform' vs 'standalone', then call
install_release(sdk, version, source=...) (or pass the resolved source through
to install_go_release where applicable) so the installer targets the proper
module and avoids creating .version entries pointing at nonexistent modules.

---

Nitpick comments:
In `@otdf-sdk-mgr/src/otdf_sdk_mgr/cli_install.py`:
- Around line 77-86: The CLI handler for the install command accepts the source
parameter but doesn't validate it before calling cmd_install, so typos (e.g.,
"--source platfrm") silently propagate to go_module_path; add explicit
validation in the CLI boundary (mirroring resolve_versions) to check that source
is either "standalone" or "platform" and exit with status 2 on unknown values,
and only call cmd_install(sdk, version, dist_name=dist_name, source=source) if
validation passes; reference the cli_install.py handler's source parameter, the
resolve_versions validation logic, and go_module_path/cmd_install as the places
to align behavior.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py`:
- Around line 45-50: The current unconditional infix strip in the installer (the
block that checks if "/" in version and does version.rsplit("/",1)[-1] before
calling normalize_version and go_module_path and writing dist_dir / ".version")
can hide mismatches between the provided source and the version prefix; update
this logic to detect and validate the prefix when a slash is present: extract
the prefix and compare it against the expected infix for the given source (or
the canonical module path produced by go_module_path) and only strip when they
match, otherwise either leave the version as-is and/or emit a warning log
indicating a source/tag mismatch; ensure normalize_version is still called on
the final version and that the .version file continues to be written using
module and tag only after validation.
- Around line 60-66: Current code treats go install failures for
GO_MODULE_PATH_PLATFORM by raising InstallError while other modules only warn
and defer, which is asymmetric; either document the intentional behavior or
change logic to distinguish "module not found" vs transient errors by inspecting
result.stderr. Update the block around the go install check (use variables
result, msg, GO_MODULE_PATH_PLATFORM, and InstallError) to: if the
platform-special-case behavior is intentional, add a brief inline comment
explaining the migration/publishing rationale; otherwise parse result.stderr (or
result.returncode) to detect a not-found/publish-related message and raise
InstallError only for that case while treating other transient errors like the
non-platform path (print warning and retry at runtime). Ensure the message
includes the module and tag context as currently constructed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/registry.py`:
- Around line 115-122: The overlap notice printing for every shared version is
noisy; modify the logic around the "if version in seen" branch (the print to
sys.stderr) to either: a) respect a verbosity/debug flag (e.g., check an
existing verbose/debug parameter or add one to the surrounding function and only
emit the message when verbose is true, or switch to using a logger and call
logger.debug instead of print), or b) collect overlapping versions into a list
(e.g., overlaps or duplicated_versions) during the loop and, after the loop
completes, emit a single summary line to stderr/log (e.g., "Note: versions X
found in both...") if that list is non-empty. Update the surrounding function
signature and callers if you add a verbose flag, or switch to the module logger
for debug-level output so callers can control noise.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 346508b2-a96f-4ce8-8a8d-e8e18536d4e2

📥 Commits

Reviewing files that changed from the base of the PR and between 13385f5 and 7c4db05.

📒 Files selected for processing (11)
  • .github/workflows/xtest.yml
  • otdf-sdk-mgr/README.md
  • otdf-sdk-mgr/src/otdf_sdk_mgr/cli_install.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/cli_versions.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/config.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/installers.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/registry.py
  • otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
  • xtest/sdk/go/cli.sh
  • xtest/sdk/go/otdfctl.sh
  • xtest/setup-cli-tool/action.yaml
🚧 Files skipped from review as they are similar to previous changes (7)
  • otdf-sdk-mgr/README.md
  • xtest/sdk/go/cli.sh
  • xtest/setup-cli-tool/action.yaml
  • otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
  • .github/workflows/xtest.yml
  • otdf-sdk-mgr/src/otdf_sdk_mgr/config.py
  • xtest/sdk/go/otdfctl.sh

@github-actions

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py (1)

333-337: ⚠️ Potential issue | 🟠 Major

Narrowed exception clause may swallow previously-handled errors from list_java_github_releases().

The switch from except Exception to except (git.exc.GitCommandError, ValueError) is generally good for specificity, but the Java "latest" branch at line 337 calls list_java_github_releases() within the try block. That function internally catches only urllib.error.URLError, allowing other exceptions to escape:

  • json.JSONDecodeError (if GitHub API returns invalid JSON)
  • UnicodeDecodeError (if response encoding fails)
  • socket.timeout (from the 30-second timeout)

These exceptions are not in the narrowed except tuple and will propagate out of resolve() instead of being converted to a ResolveError dict, breaking the previous behavior.

Consider either:

  • Adding exception types to the except tuple (e.g., json.JSONDecodeError, socket.timeout, OSError), or
  • Having list_java_github_releases() catch and normalize these errors to ValueError before they escape.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py` around lines 333 - 337, The
narrowed except clause in resolve() around the Java branch can let exceptions
from list_java_github_releases() escape (e.g., json.JSONDecodeError,
UnicodeDecodeError, socket.timeout, OSError), so update the exception tuple in
the try/except that surrounds list_java_github_releases() to also catch
json.JSONDecodeError, UnicodeDecodeError, socket.timeout and OSError (or
alternatively have list_java_github_releases() normalize those into ValueError),
ensuring resolve() converts those failures into the existing ResolveError dict
instead of letting them propagate.
🧹 Nitpick comments (1)
otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py (1)

134-155: go_source is only validated on the platform path.

_go_platform is only true when sdk == "go" and go_source == "platform". For any other combination (e.g. sdk == "go" with a typo like go_source="standaloen", or sdk != "go" with go_source="platform"), the value is silently ignored and the code falls through to SDK_GIT_URLS[sdk]. Since config._validate_go_source already exists and raises on unknown values, calling it unconditionally (or at least whenever go_source is not None) would catch caller mistakes instead of resolving from the wrong repo.

Suggested tweak
+    from otdf_sdk_mgr.config import _validate_go_source
+    _validate_go_source(go_source)
     _go_platform = sdk == "go" and go_source == "platform"

(or expose a public validator rather than importing the underscore-prefixed helper)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py` around lines 134 - 155, The code
only validates go_source when _go_platform is true; instead call the existing
validator (config._validate_go_source) whenever go_source is not None (or
otherwise expose/use a public validator) before computing _go_platform so typos
like go_source="standaloen" are rejected; then compute _go_platform = (sdk ==
"go" and go_source == "platform") and proceed to use go_git_url/go_tag_infix for
the platform path or SDK_GIT_URLS[sdk] for others, returning the same
unknown-SDK error on KeyError.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py`:
- Around line 333-337: The narrowed except clause in resolve() around the Java
branch can let exceptions from list_java_github_releases() escape (e.g.,
json.JSONDecodeError, UnicodeDecodeError, socket.timeout, OSError), so update
the exception tuple in the try/except that surrounds list_java_github_releases()
to also catch json.JSONDecodeError, UnicodeDecodeError, socket.timeout and
OSError (or alternatively have list_java_github_releases() normalize those into
ValueError), ensuring resolve() converts those failures into the existing
ResolveError dict instead of letting them propagate.

---

Nitpick comments:
In `@otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py`:
- Around line 134-155: The code only validates go_source when _go_platform is
true; instead call the existing validator (config._validate_go_source) whenever
go_source is not None (or otherwise expose/use a public validator) before
computing _go_platform so typos like go_source="standaloen" are rejected; then
compute _go_platform = (sdk == "go" and go_source == "platform") and proceed to
use go_git_url/go_tag_infix for the platform path or SDK_GIT_URLS[sdk] for
others, returning the same unknown-SDK error on KeyError.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6c6c70e9-4ca8-455c-aabf-7b4cf956a121

📥 Commits

Reviewing files that changed from the base of the PR and between 7c4db05 and 91953e8.

📒 Files selected for processing (2)
  • otdf-sdk-mgr/README.md
  • otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • otdf-sdk-mgr/README.md

@github-actions

Copy link
Copy Markdown

@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

@alkalescent
alkalescent merged commit 5ab9a0f into main Apr 22, 2026
15 checks passed
@alkalescent
alkalescent deleted the DSPX-2655-migrate-otdfctl branch April 22, 2026 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants