Skip to content

Consume Harmony via NuGet instead of submodule#2354

Open
hahn-kev wants to merge 4 commits into
developfrom
cursor/remove-harmony-submodule
Open

Consume Harmony via NuGet instead of submodule#2354
hahn-kev wants to merge 4 commits into
developfrom
cursor/remove-harmony-submodule

Conversation

@hahn-kev

@hahn-kev hahn-kev commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Remove the backend/harmony git submodule; LexBox now depends on SIL.Harmony, SIL.Harmony.Core, and SIL.Harmony.Linq2db from NuGet (pinned in Directory.Packages.props).
  • Add MSBuild props for optional local source builds (UseHarmonySource=true, default sibling path ../harmony).
  • Simplify CI checkout and dev Dockerfiles; drop submodule init from task setup.

Test plan

  • dotnet build backend/LexBoxApi/LexBoxApi.csproj
  • dotnet build backend/FwLite/LcmCrdt/LcmCrdt.csproj
  • dotnet build backend/FwHeadless/FwHeadless.csproj
  • CI passes on this PR
  • Optional: verify UseHarmonySource=true with a local ../harmony clone

hahn-kev and others added 3 commits June 12, 2026 16:34
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Removes the backend/harmony git submodule and replaces it with pinned NuGet references (SIL.Harmony, SIL.Harmony.Core, SIL.Harmony.Linq2db at 0.2.1-rc.202). Adds MSBuild props files implementing a UseHarmonySource switch for optional local source builds. All CI workflows, Dockerfiles, solution files, developer tooling, and AI agent instructions are updated to reflect the submodule removal.

Changes

Harmony submodule → NuGet + optional local source

Layer / File(s) Summary
Harmony MSBuild props infrastructure and package pinning
backend/Harmony.props, backend/Harmony.App.References.props, backend/Harmony.Core.References.props, backend/Harmony.Linq2db.References.props, backend/Directory.Packages.props, backend/Directory.Build.props, backend/Directory.Build.props.user.example, .gitignore
Introduces base properties (RepoRoot, HarmonySourcePath, UseHarmonySource) and three conditional reference props files that switch between ProjectReference and PackageReference with build-time validation targets. Pins all three SIL.Harmony packages to 0.2.1-rc.202, imports Harmony.props globally, and provides a user example file for local source opt-in.
Consumer project files wired to shared Harmony props
backend/FwHeadless/FwHeadless.csproj, backend/FwLite/LcmCrdt/LcmCrdt.csproj, backend/LexBoxApi/LexBoxApi.csproj, backend/LexData/LexData.csproj
Each project replaces its inline submodule ProjectReference with an MSBuild Import of the appropriate Harmony*.References.props file.
Git submodule removal and developer setup
.gitmodules, backend/harmony, Taskfile.yml, README.md
Removes the backend/harmony submodule entry and recorded commit pointer. Drops git submodule init/update steps from the setup task and updates README setup bullets and backend resource links.
Solution and solution filter cleanup
LexBox.sln, FwLiteOnly.slnf, LexBoxOnly.slnf
Removes SIL.Harmony and SIL.Harmony.Core project definitions, build configuration entries, and nested project folder mappings from the solution and both solution filters.
CI workflow and Dockerfile updates
.github/workflows/codeql.yml, .github/workflows/fw-lite.yaml, .github/workflows/integration-test*.yaml, .github/workflows/lexbox-*.yaml, backend/FwHeadless/dev.Dockerfile, backend/LexBoxApi/dev.Dockerfile
Removes submodules: true from all actions/checkout steps across six workflows. Updates fw-lite.yaml path triggers from backend/harmony/** to backend/Directory.Packages.props and backend/Harmony*.props. Replaces harmony-specific Dockerfile staging with a generic csproj relocation loop.
AI agent and developer docs
.claude/agents/harmony-sentinel.md, .claude/hooks/session-start.sh, .claude/skills/_shared/apply-rules.md, .claude/skills/_shared/dispatch-matrix.md, backend/AGENTS.md
Rewrites harmony-sentinel instructions for NuGet/MSBuild review instead of submodule diffs, removes submodule init from the session hook, adds a SIL.Harmony* bump guard rule, updates the dispatch matrix routing, and adds local-source build instructions to backend/AGENTS.md.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • myieye

Poem

🐇 No more submodule to clone and to track,
A NuGet package has now got our back!
With UseHarmonySource set to true,
Devs can still build from local source too.
The sentinel watches each version we pin —
Hop along, harmony, NuGet wins! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Consume Harmony via NuGet instead of submodule' accurately and concisely summarizes the primary change: migrating from git submodule to NuGet package dependencies.
Description check ✅ Passed The description clearly explains the main changes: removing the submodule, adding NuGet dependencies, introducing MSBuild props for optional local builds, and simplifying CI/dev processes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/remove-harmony-submodule

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.

@github-actions github-actions Bot added 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included labels Jun 12, 2026
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

UI unit Tests

  1 files  ±0   62 suites  ±0   30s ⏱️ ±0s
186 tests ±0  186 ✅ ±0  0 💤 ±0  0 ❌ ±0 
258 runs  ±0  258 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 058dad3. ± Comparison against base commit 248ea03.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

C# FwHeadless Unit Tests

48 tests   48 ✅  15s ⏱️
 5 suites   0 💤
 1 files     0 ❌

Results for commit 058dad3.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

C# Unit Tests

165 tests   165 ✅  21s ⏱️
 23 suites    0 💤
  1 files      0 ❌

Results for commit 058dad3.

♻️ This comment has been updated with latest results.

@argos-ci

argos-ci Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Jun 15, 2026, 2:59 AM

@hahn-kev hahn-kev requested a review from myieye June 15, 2026 02:56
@myieye myieye marked this pull request as ready for review June 17, 2026 12:40

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/Harmony.props`:
- Line 7: The HarmonySourcePath property definition uses
System.IO.Path::GetFullPath with backslash path separators which fails on
Linux/macOS platforms where backslashes are treated as literal characters.
Replace the System.IO.Path::GetFullPath call with MSBuild::NormalizePath in both
the RepoRoot property (line 6) and the HarmonySourcePath property (line 7) to
ensure cross-platform path composition compatibility with .NET 8+. This will
properly normalize path separators on all platforms without hardcoding
platform-specific backslashes.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ca966302-8f6a-4360-a75e-b6a20968c469

📥 Commits

Reviewing files that changed from the base of the PR and between 248ea03 and 058dad3.

📒 Files selected for processing (32)
  • .claude/agents/harmony-sentinel.md
  • .claude/hooks/session-start.sh
  • .claude/skills/_shared/apply-rules.md
  • .claude/skills/_shared/dispatch-matrix.md
  • .github/workflows/codeql.yml
  • .github/workflows/fw-lite.yaml
  • .github/workflows/integration-test-gha.yaml
  • .github/workflows/integration-test.yaml
  • .github/workflows/lexbox-api.yaml
  • .github/workflows/lexbox-fw-headless.yaml
  • .gitignore
  • .gitmodules
  • FwLiteOnly.slnf
  • LexBox.sln
  • LexBoxOnly.slnf
  • README.md
  • Taskfile.yml
  • backend/AGENTS.md
  • backend/Directory.Build.props
  • backend/Directory.Build.props.user.example
  • backend/Directory.Packages.props
  • backend/FwHeadless/FwHeadless.csproj
  • backend/FwHeadless/dev.Dockerfile
  • backend/FwLite/LcmCrdt/LcmCrdt.csproj
  • backend/Harmony.App.References.props
  • backend/Harmony.Core.References.props
  • backend/Harmony.Linq2db.References.props
  • backend/Harmony.props
  • backend/LexBoxApi/LexBoxApi.csproj
  • backend/LexBoxApi/dev.Dockerfile
  • backend/LexData/LexData.csproj
  • backend/harmony
💤 Files with no reviewable changes (9)
  • .gitmodules
  • .github/workflows/lexbox-fw-headless.yaml
  • .github/workflows/lexbox-api.yaml
  • .github/workflows/codeql.yml
  • backend/harmony
  • .github/workflows/integration-test.yaml
  • .github/workflows/integration-test-gha.yaml
  • Taskfile.yml
  • LexBox.sln

Comment thread backend/Harmony.props

<PropertyGroup>
<RepoRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..'))</RepoRoot>
<HarmonySourcePath Condition="'$(HarmonySourcePath)' == ''">$([System.IO.Path]::GetFullPath('$(RepoRoot)\..\harmony'))</HarmonySourcePath>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

On .NET/MSBuild running on Linux/macOS, does System.IO.Path.GetFullPath treat backslash "\" as a directory separator, and is MSBuild::NormalizePath recommended for cross-platform path construction in .props files?

💡 Result:

On.NET (starting with.NET 8), System.IO.Path.GetFullPath no longer treats the backslash character ("") as a directory separator on Linux and macOS [1]. Because backslashes are valid characters in Unix filenames, the.NET runtime now preserves them literally rather than converting them to forward slashes [1]. Previously, older versions of.NET performed this automatic conversion [1]. Regarding MSBuild property functions for cross-platform path construction, the use of [MSBuild]::NormalizePath or [MSBuild]::NormalizeDirectory is recommended for handling path normalization and ensuring consistent directory separators [2][3]. However, users should be aware that these functions may behave differently across operating systems [4]. For example, [MSBuild]::NormalizePath may not always canonicalize backslashes into forward slashes on non-Windows platforms [4]. To ensure cross-platform compatibility in.props files: 1. Prefer forward slashes ("/") as directory separators, as they are widely supported across platforms [1][3]. 2. Use MSBuild property functions like [MSBuild]::NormalizePath to combine and normalize paths, but verify that the output meets your project's specific requirements [2]. 3. For cross-platform logic, utilize helpers like [MSBuild]::IsOSUnixLike to conditionally adjust path construction if necessary [3]. 4. Avoid hardcoding backslashes in.props or.targets files, as these can lead to issues on Unix-based systems where they are interpreted as literal file name characters rather than separators [1][5].

Citations:


🏁 Script executed:

# First, let's examine the Harmony.props file to understand the context
cat -n backend/Harmony.props

Repository: sillsdev/languageforge-lexbox

Length of output: 984


🏁 Script executed:

# Check for any .csproj, .vbproj or other project files that might indicate .NET version
fd -e csproj -e vbproj -e fsproj | head -5

Repository: sillsdev/languageforge-lexbox

Length of output: 325


🏁 Script executed:

# Let's check if there are any other references to path handling in related files
rg "HarmonySourcePath|UseHarmonySource" --type xml -A 2 -B 2

Repository: sillsdev/languageforge-lexbox

Length of output: 55


🏁 Script executed:

# Check what .NET version is targeted - look at a few key project files
head -20 backend/FwHeadless/FwHeadless.csproj

Repository: sillsdev/languageforge-lexbox

Length of output: 1181


🏁 Script executed:

# Also check the root directory for any central package or version management
find . -maxdepth 2 -name "Directory.Build.props" -o -name "global.json" -o -name ".net-version" | head -5

Repository: sillsdev/languageforge-lexbox

Length of output: 119


🏁 Script executed:

# Check global.json for .NET version
cat global.json

Repository: sillsdev/languageforge-lexbox

Length of output: 152


🏁 Script executed:

# Check Directory.Build.props for target framework info
cat backend/Directory.Build.props | head -50

Repository: sillsdev/languageforge-lexbox

Length of output: 2630


Use OS-neutral path composition for RepoRoot and HarmonySourcePath.

System.IO.Path::GetFullPath with backslash separators (\..\) will not work on Linux/macOS when targeting .NET 8+. The .NET runtime now treats backslashes as literal filename characters rather than path separators on Unix platforms. This causes HarmonySourcePath to resolve incorrectly when UseHarmonySource=true, leading to "project not found" errors.

Both line 6 (RepoRoot) and line 7 (HarmonySourcePath) are affected and should use MSBuild::NormalizePath for cross-platform compatibility.

Proposed fix
-    <RepoRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..'))</RepoRoot>
-    <HarmonySourcePath Condition="'$(HarmonySourcePath)' == ''">$([System.IO.Path]::GetFullPath('$(RepoRoot)\..\harmony'))</HarmonySourcePath>
+    <RepoRoot>$([MSBuild]::NormalizePath('$(MSBuildThisFileDirectory)', '..'))</RepoRoot>
+    <HarmonySourcePath Condition="'$(HarmonySourcePath)' == ''">$([MSBuild]::NormalizePath('$(RepoRoot)', '..', 'harmony'))</HarmonySourcePath>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/Harmony.props` at line 7, The HarmonySourcePath property definition
uses System.IO.Path::GetFullPath with backslash path separators which fails on
Linux/macOS platforms where backslashes are treated as literal characters.
Replace the System.IO.Path::GetFullPath call with MSBuild::NormalizePath in both
the RepoRoot property (line 6) and the HarmonySourcePath property (line 7) to
ensure cross-platform path composition compatibility with .NET 8+. This will
properly normalize path separators on all platforms without hardcoding
platform-specific backslashes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants