From 886d42b5a4ef5e4aae60ba87052921a697ebd629 Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Fri, 22 May 2026 11:22:27 +1200 Subject: [PATCH 1/3] fix(nuget): move global.json aside during dotnet setversion Consumer repos often pin SDK/workload versions in global.json with rollForward: disable for deterministic builds. The automatic version bump path added in #707 invokes `dotnet setversion` with cwd=rootDir, which causes the dotnet host to read global.json and refuse to launch if the pinned SDK isn't installed on the release runner. Other dotnet invocations in this target avoid this by spawning with cwd: '/' (see #601, #614). That's not viable for `dotnet-setversion` because it operates on files in cwd. Instead, temporarily rename global.json out of the way for the duration of the call and restore it in a finally block. Fixes #819 Refs getsentry/sentry-dotnet#5250 --- src/targets/nuget.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/targets/nuget.ts b/src/targets/nuget.ts index 6cb5695a..baff1037 100644 --- a/src/targets/nuget.ts +++ b/src/targets/nuget.ts @@ -1,4 +1,10 @@ -import { existsSync, readFileSync, readdirSync, writeFileSync } from 'fs'; +import { + existsSync, + readFileSync, + readdirSync, + renameSync, + writeFileSync, +} from 'fs'; import { join } from 'path'; import { TargetConfig, TypedTargetConfig } from '../schemas/project_config'; @@ -78,6 +84,19 @@ export class NugetTarget extends BaseTarget { } if (hasExecutable(NUGET_DOTNET_BIN)) { + // `dotnet-setversion` operates on files in cwd, so we must invoke it with + // cwd=rootDir. That means the dotnet host will read any global.json in + // rootDir and may refuse to launch if the pinned SDK isn't installed on + // this runner (consumer repos often pin SDK/workload versions with + // rollForward: disable for deterministic builds — see #614, #707, and + // getsentry/sentry-dotnet#5250). Move global.json aside for the duration + // of the call so the host can pick any installed SDK. + const globalJsonPath = join(rootDir, 'global.json'); + const globalJsonBackup = `${globalJsonPath}.craft-bak`; + const globalJsonMoved = existsSync(globalJsonPath); + if (globalJsonMoved) { + renameSync(globalJsonPath, globalJsonBackup); + } try { const result = await spawnProcess( NUGET_DOTNET_BIN, @@ -99,6 +118,10 @@ export class NugetTarget extends BaseTarget { logger.debug( 'dotnet-setversion not available, falling back to manual edit', ); + } finally { + if (globalJsonMoved) { + renameSync(globalJsonBackup, globalJsonPath); + } } } From 572a4ddd15cfc60b113b027536750204607677cd Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Fri, 22 May 2026 11:43:15 +1200 Subject: [PATCH 2/3] Tweak code comment --- src/targets/nuget.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/targets/nuget.ts b/src/targets/nuget.ts index baff1037..74a95393 100644 --- a/src/targets/nuget.ts +++ b/src/targets/nuget.ts @@ -84,13 +84,9 @@ export class NugetTarget extends BaseTarget { } if (hasExecutable(NUGET_DOTNET_BIN)) { - // `dotnet-setversion` operates on files in cwd, so we must invoke it with - // cwd=rootDir. That means the dotnet host will read any global.json in - // rootDir and may refuse to launch if the pinned SDK isn't installed on - // this runner (consumer repos often pin SDK/workload versions with - // rollForward: disable for deterministic builds — see #614, #707, and - // getsentry/sentry-dotnet#5250). Move global.json aside for the duration - // of the call so the host can pick any installed SDK. + // `dotnet-setversion` operates in cwd and will pickup global.json, + // which breaks if the pinned SDK isn't installed on the craft runner. + // See: https://github.com/getsentry/craft/issues/819 const globalJsonPath = join(rootDir, 'global.json'); const globalJsonBackup = `${globalJsonPath}.craft-bak`; const globalJsonMoved = existsSync(globalJsonPath); @@ -295,9 +291,9 @@ export class NugetTarget extends BaseTarget { this.logger.info( `Uploading file "${file.filename}" via "dotnet nuget"` + - (symbolFile - ? `, including symbol file "${symbolFile.filename}"` - : ''), + (symbolFile + ? `, including symbol file "${symbolFile.filename}"` + : ''), ); return this.uploadAsset(path); }), From 2b9366d3053b0f96e1643dce717704a555339d64 Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Fri, 22 May 2026 12:34:03 +1200 Subject: [PATCH 3/3] chore: apply prettier formatting to pre-existing block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Lint workflow only runs on pull_request, so this pre-existing violation in nuget.ts never failed CI on master. Surfacing it via this PR — applying `pnpm format:check` so the workflow passes. --- src/targets/nuget.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/targets/nuget.ts b/src/targets/nuget.ts index 74a95393..ae0f7bb0 100644 --- a/src/targets/nuget.ts +++ b/src/targets/nuget.ts @@ -291,9 +291,9 @@ export class NugetTarget extends BaseTarget { this.logger.info( `Uploading file "${file.filename}" via "dotnet nuget"` + - (symbolFile - ? `, including symbol file "${symbolFile.filename}"` - : ''), + (symbolFile + ? `, including symbol file "${symbolFile.filename}"` + : ''), ); return this.uploadAsset(path); }),