Skip to content

feat: [CI-16621]: detect all .csproj/.vbproj/.fsproj in multi-project .NET repos#178

Open
hemanthmantri wants to merge 1 commit into
drone-plugins:masterfrom
hemanthmantri:CI-16621
Open

feat: [CI-16621]: detect all .csproj/.vbproj/.fsproj in multi-project .NET repos#178
hemanthmantri wants to merge 1 commit into
drone-plugins:masterfrom
hemanthmantri:CI-16621

Conversation

@hemanthmantri

@hemanthmantri hemanthmantri commented Apr 30, 2026

Copy link
Copy Markdown

Problem

Cache Intelligence auto-detect for .NET only hashes the root-most .csproj file and prepares a single NuGet cache at that project's directory. In repos with multiple projects (several .csproj / .vbproj / .fsproj files across nested directories), this causes two issues:

  1. The cache key ignores every project file except the shallowest one, so dependency changes in sibling projects do not invalidate the cache.
  2. Only that single project's .nuget/packages path is mounted, so other projects' restores miss the cache entirely.

Jira: https://harness.atlassian.net/browse/CI-16621

Root Cause

  • auto_detect_util.go relied on filepath.Glob("*.csproj") and filepath.Glob("**/*.csproj"). Go's filepath.Glob does not recurse — ** matches exactly one path component, so deeply nested projects were never discovered.
  • Inside calculateMd5FromFiles, shortestPath selected the single root-most match and hashed only that file.
  • The three dotnet entries (csproj/vbproj/fsproj) shared tool: "dotnet", so once the first matched, the others were skipped.

Solution

Add an extsToDetect field on buildToolInfo. When present, detection uses a recursive filepath.Walk that:

  • collects every file with one of the configured extensions,
  • skips well-known build-output, VCS and dependency directories (bin/, obj/, .vs/, .nuget/, .git/, .hg/, .svn/, node_modules/),
  • sorts matches so the digest is deterministic across filesystems,
  • hashes all matching files into a single MD5 digest that becomes the cache key contribution,
  • returns CWD as the preparer directory so a single nuget.config + .nuget/packages covers every project in the repo.

The three separate dotnet entries are consolidated into one that carries extsToDetect: {".csproj", ".vbproj", ".fsproj"}. Non-.NET tools continue to use the existing single-file glob path — behaviour unchanged for maven/gradle/bazel/node/yarn/go.

Changes Made

  • internal/plugin/autodetect/auto_detect_util.go: add extsToDetect; consolidate dotnet entries; implement hashAllFilesByExtensions + findFilesByExtensions.
  • internal/plugin/autodetect/auto_detect_util_test.go: add TestDetectDirectoriesToCacheDotnetMultiProject covering nested .csproj, deeply nested .fsproj, and confirming files under bin/ are ignored.

Testing

  • go build ./... — pass.
  • go vet ./... — pass.
  • go test ./internal/plugin/... ./key/... -count=1 — pass (including the new multi-project test).

Manual verification of detection behaviour in the new test:

  • Root .csproj, nested src/Lib/Lib.csproj, deep src/F/Sharp/Fs.fsproj are all detected.
  • bin/Artifact.csproj is excluded from the hash.
  • A single .nuget/packages directory under CWD is returned for caching.
  • Aggregate hash differs from the single-file hash, proving all project files contribute.

Related Issues/Logs


🚢 Shipped via Ship

… .NET repos

Walk the repo recursively and hash every .NET project file so the cache
key reflects all projects, not just the root-most .csproj. Cache is
prepared once at CWD so a single nuget.config / .nuget/packages covers
every detected project.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

AI-Session-Id: 2334fb1b-84e4-49ed-be44-3a482234e63b
AI-Tool: claude-code
AI-Model: unknown
@hemanthmantri

Copy link
Copy Markdown
Author

@smjt-h @satyakota04 - Please review.

@satyakota04 satyakota04 requested review from satyakota04 and smjt-h May 20, 2026 05:04
@satyakota04

Copy link
Copy Markdown
Collaborator

@hemanthmantri, I have tested the changes, and it is detecting all the projects but caching only one. IMO, it should cache all the directories.
repo link: https://github.com/satyakota04/multi-dot-net
pipeline-url: https://app.harness.io/ng/account/9UuUfLwaQ-6ZowvbG7qtLQ/module/ci/orgs/default/projects/Intel_Features/pipelines/dotnet_multi/deployments/ul1TKkyQRZ-6DNViYK41Fw/pipeline?storeType=INLINE

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