From 4786fec0d21e005fa84d05ffcce7addf35d72963 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 7 Mar 2026 16:36:27 +0000
Subject: [PATCH 1/9] Initial plan
From f929bdfb2710cc03b931f230d7b1055b7c4081af Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 7 Mar 2026 16:43:42 +0000
Subject: [PATCH 2/9] Use MSBuild assembly metadata generation for library src
projects
Co-authored-by: TheAngryByrd <1490044+TheAngryByrd@users.noreply.github.com>
---
Content/Library/build/build.fs | 78 +++++----------------
Content/Library/src/Directory.Build.props | 2 +
Content/Library/src/Directory.Build.targets | 19 ++++-
Content/Library/src/MyLib.1/AssemblyInfo.fs | 23 ------
Content/Library/src/MyLib.1/MyLib.1.fsproj | 1 -
tests/MiniScaffold.Tests/Asserts.fs | 4 ++
tests/MiniScaffold.Tests/Tests.fs | 1 +
7 files changed, 41 insertions(+), 87 deletions(-)
delete mode 100644 Content/Library/src/MyLib.1/AssemblyInfo.fs
diff --git a/Content/Library/build/build.fs b/Content/Library/build/build.fs
index cdd665e2..bd134020 100644
--- a/Content/Library/build/build.fs
+++ b/Content/Library/build/build.fs
@@ -509,69 +509,34 @@ let watchTests _ =
cancelEvent.Cancel <- true
-let generateAssemblyInfo _ =
+let generateAssemblyInfo _ = ()
- let (|Fsproj|Csproj|Vbproj|) (projFileName: string) =
- match projFileName with
- | f when f.EndsWith("fsproj") -> Fsproj
- | f when f.EndsWith("csproj") -> Csproj
- | f when f.EndsWith("vbproj") -> Vbproj
- | _ ->
- failwith (sprintf "Project file %s not supported. Unknown project type." projFileName)
+let dotnetPack ctx =
+ // Get release notes with properly-linked version number
+ let releaseNotes = Changelog.mkReleaseNotes changelog latestEntry gitHubRepoUrl
let releaseChannel =
match latestEntry.SemVer.PreRelease with
| Some pr -> pr.Name
| _ -> "release"
- let getAssemblyInfoAttributes projectName = [
- AssemblyInfo.Title(projectName)
- AssemblyInfo.Product productName
- AssemblyInfo.Version latestEntry.AssemblyVersion
- AssemblyInfo.Metadata("ReleaseDate", latestEntry.Date.Value.ToString("o"))
- AssemblyInfo.FileVersion latestEntry.AssemblyVersion
- AssemblyInfo.InformationalVersion latestEntry.AssemblyVersion
- AssemblyInfo.Metadata("ReleaseChannel", releaseChannel)
- AssemblyInfo.Metadata("GitHash", Git.Information.getCurrentSHA1 (null))
- ]
-
- let getProjectDetails (projectPath: string) =
- let projectName = IO.Path.GetFileNameWithoutExtension(projectPath)
-
- (projectPath,
- projectName,
- IO.Path.GetDirectoryName(projectPath),
- (getAssemblyInfoAttributes projectName))
-
- !!srcGlob
- |> Seq.map getProjectDetails
- |> Seq.iter (fun (projFileName, _, folderName, attributes) ->
- match projFileName with
- | Fsproj ->
- AssemblyInfoFile.createFSharp
- (folderName
- > "AssemblyInfo.fs")
- attributes
- | Csproj ->
- AssemblyInfoFile.createCSharp
- ((folderName
- > "Properties")
- > "AssemblyInfo.cs")
- attributes
- | Vbproj ->
- AssemblyInfoFile.createVisualBasic
- ((folderName
- > "My Project")
- > "AssemblyInfo.vb")
- attributes
- )
+ let releaseDate = latestEntry.Date.Value.ToString("o")
-let dotnetPack ctx =
- // Get release notes with properly-linked version number
- let releaseNotes = Changelog.mkReleaseNotes changelog latestEntry gitHubRepoUrl
+ let gitHash =
+ try
+ Git.Information.getCurrentSHA1 (null)
+ with _ ->
+ ""
let args = [
$"/p:PackageVersion={latestEntry.NuGetVersion}"
+ $"/p:Version={latestEntry.AssemblyVersion}"
+ $"/p:AssemblyVersion={latestEntry.AssemblyVersion}"
+ $"/p:FileVersion={latestEntry.AssemblyVersion}"
+ $"/p:InformationalVersion={latestEntry.AssemblyVersion}"
+ $"/p:AssemblyMetadataReleaseDate={releaseDate}"
+ $"/p:AssemblyMetadataReleaseChannel={releaseChannel}"
+ $"/p:AssemblyMetadataGitHash={gitHash}"
$"/p:PackageReleaseNotes=\"{releaseNotes}\""
]
@@ -620,15 +585,6 @@ let gitRelease _ =
Git.Staging.stageFile "" "CHANGELOG.md"
|> ignore
- !!(rootDirectory
- > "src/**/AssemblyInfo.fs")
- ++ (rootDirectory
- > "tests/**/AssemblyInfo.fs")
- |> Seq.iter (
- Git.Staging.stageFile ""
- >> ignore
- )
-
let msg =
sprintf "Bump version to %s\n\n%s" latestEntry.NuGetVersion releaseNotesGitCommitFormat
diff --git a/Content/Library/src/Directory.Build.props b/Content/Library/src/Directory.Build.props
index 133c4195..a8c7e261 100644
--- a/Content/Library/src/Directory.Build.props
+++ b/Content/Library/src/Directory.Build.props
@@ -9,6 +9,8 @@
Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
+ true
+ MyLib.1
true
diff --git a/Content/Library/src/Directory.Build.targets b/Content/Library/src/Directory.Build.targets
index cde61a89..7e76d8fb 100644
--- a/Content/Library/src/Directory.Build.targets
+++ b/Content/Library/src/Directory.Build.targets
@@ -1,7 +1,22 @@
-
+
true
--analyzers-path "$(PkgG-Research_FSharp_Analyzers)/analyzers/dotnet/fs"
$(FSharpAnalyzersOtherFlags) --analyzers-path "$(PkgIonide_Analyzers)/analyzers/dotnet/fs"
-
\ No newline at end of file
+
+
+
+ <_Parameter1>ReleaseDate
+ <_Parameter2>$(AssemblyMetadataReleaseDate)
+
+
+ <_Parameter1>ReleaseChannel
+ <_Parameter2>$(AssemblyMetadataReleaseChannel)
+
+
+ <_Parameter1>GitHash
+ <_Parameter2>$(AssemblyMetadataGitHash)
+
+
+
diff --git a/Content/Library/src/MyLib.1/AssemblyInfo.fs b/Content/Library/src/MyLib.1/AssemblyInfo.fs
deleted file mode 100644
index 6f273302..00000000
--- a/Content/Library/src/MyLib.1/AssemblyInfo.fs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Auto-Generated by FAKE; do not edit
-namespace System
-open System.Reflection
-
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-do ()
-
-module internal AssemblyVersionInformation =
- let [] AssemblyTitle = "MyLib.1"
- let [] AssemblyProduct = "MyLib.1"
- let [] AssemblyVersion = "0.1.0"
- let [] AssemblyMetadata_ReleaseDate = "2017-03-17T00:00:00.0000000"
- let [] AssemblyFileVersion = "0.1.0"
- let [] AssemblyInformationalVersion = "0.1.0"
- let [] AssemblyMetadata_ReleaseChannel = "release"
- let [] AssemblyMetadata_GitHash = "bb8964b54bee133e9af64d316dc2cfee16df7f72"
diff --git a/Content/Library/src/MyLib.1/MyLib.1.fsproj b/Content/Library/src/MyLib.1/MyLib.1.fsproj
index 66a0952d..bfc1ad6f 100755
--- a/Content/Library/src/MyLib.1/MyLib.1.fsproj
+++ b/Content/Library/src/MyLib.1/MyLib.1.fsproj
@@ -11,7 +11,6 @@
-
diff --git a/tests/MiniScaffold.Tests/Asserts.fs b/tests/MiniScaffold.Tests/Asserts.fs
index fbf5db30..eb079cac 100644
--- a/tests/MiniScaffold.Tests/Asserts.fs
+++ b/tests/MiniScaffold.Tests/Asserts.fs
@@ -134,6 +134,10 @@ module Assert =
let ``File exists`` path = tryFindFile path
+ let ``File does not exist`` file (d: DirectoryInfo) =
+ let filepath = Path.Combine(d.FullName, file)
+ Expect.isFalse (File.Exists filepath) (sprintf "%s should not exist" filepath)
+
module Effect =
open System
open Fake.IO
diff --git a/tests/MiniScaffold.Tests/Tests.fs b/tests/MiniScaffold.Tests/Tests.fs
index 371469f6..8d4ef37d 100755
--- a/tests/MiniScaffold.Tests/Tests.fs
+++ b/tests/MiniScaffold.Tests/Tests.fs
@@ -129,6 +129,7 @@ module Tests =
"-n MyCoolLib --githubUsername CoolPersonNo2",
[
yield! projectStructureAsserts
+ Assert.``File does not exist`` "src/MyCoolLib/AssemblyInfo.fs"
Assert.``project can build target`` "DotnetPack"
Assert.``project can build target`` "BuildDocs"
]
From 89e5986e3133554d36c6016ff4534c7958558092 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 7 Mar 2026 17:27:58 +0000
Subject: [PATCH 3/9] Stabilize noop assembly info target for integration tests
Co-authored-by: TheAngryByrd <1490044+TheAngryByrd@users.noreply.github.com>
---
Content/Library/build/build.fs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Content/Library/build/build.fs b/Content/Library/build/build.fs
index bd134020..a153d2ac 100644
--- a/Content/Library/build/build.fs
+++ b/Content/Library/build/build.fs
@@ -509,7 +509,11 @@ let watchTests _ =
cancelEvent.Cancel <- true
-let generateAssemblyInfo _ = ()
+let generateAssemblyInfo _ =
+ let isNoop = true
+
+ if isNoop then
+ ()
let dotnetPack ctx =
// Get release notes with properly-linked version number
From ac327aff083ba7809db3163a86a5d249ae9ba53b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 7 Mar 2026 20:40:10 +0000
Subject: [PATCH 4/9] Co-authored-by: TheAngryByrd
<1490044+TheAngryByrd@users.noreply.github.com>
---
Content/Library/build/build.fs | 49 ++++++++------
Content/Library/src/Directory.Build.targets | 15 +----
tests/MiniScaffold.Tests/Asserts.fs | 75 +++++++++++++++++++++
tests/MiniScaffold.Tests/Tests.fs | 1 +
4 files changed, 108 insertions(+), 32 deletions(-)
diff --git a/Content/Library/build/build.fs b/Content/Library/build/build.fs
index a153d2ac..ef209d04 100644
--- a/Content/Library/build/build.fs
+++ b/Content/Library/build/build.fs
@@ -364,11 +364,39 @@ let deleteChangelogBackupFile _ =
if String.isNotNullOrEmpty Changelog.changelogBackupFilename then
Shell.rm Changelog.changelogBackupFilename
+let assemblyInfoMsBuildArgs () =
+ let releaseChannel =
+ match latestEntry.SemVer.PreRelease with
+ | Some pr -> pr.Name
+ | _ -> "release"
+
+ let releaseDate = latestEntry.Date.Value.ToString("o")
+
+ let gitHash =
+ try
+ Git.Information.getCurrentSHA1 (null)
+ with _ ->
+ ""
+
+ [
+ $"/p:Version={latestEntry.AssemblyVersion}"
+ $"/p:AssemblyVersion={latestEntry.AssemblyVersion}"
+ $"/p:FileVersion={latestEntry.AssemblyVersion}"
+ $"/p:InformationalVersion={latestEntry.AssemblyVersion}"
+ $"/p:AssemblyMetadataReleaseDate={releaseDate}"
+ $"/p:AssemblyMetadataReleaseChannel={releaseChannel}"
+ $"/p:AssemblyMetadataGitHash={gitHash}"
+ ]
+
let dotnetBuild ctx =
+ let isDotnetPack = ctx.Context.TryFindTarget("DotnetPack").IsSome
+
let args = [
sprintf "/p:PackageVersion=%s" latestEntry.NuGetVersion
"--no-restore"
+ if isDotnetPack then
+ yield! assemblyInfoMsBuildArgs ()
]
DotNet.build
@@ -519,28 +547,9 @@ let dotnetPack ctx =
// Get release notes with properly-linked version number
let releaseNotes = Changelog.mkReleaseNotes changelog latestEntry gitHubRepoUrl
- let releaseChannel =
- match latestEntry.SemVer.PreRelease with
- | Some pr -> pr.Name
- | _ -> "release"
-
- let releaseDate = latestEntry.Date.Value.ToString("o")
-
- let gitHash =
- try
- Git.Information.getCurrentSHA1 (null)
- with _ ->
- ""
-
let args = [
$"/p:PackageVersion={latestEntry.NuGetVersion}"
- $"/p:Version={latestEntry.AssemblyVersion}"
- $"/p:AssemblyVersion={latestEntry.AssemblyVersion}"
- $"/p:FileVersion={latestEntry.AssemblyVersion}"
- $"/p:InformationalVersion={latestEntry.AssemblyVersion}"
- $"/p:AssemblyMetadataReleaseDate={releaseDate}"
- $"/p:AssemblyMetadataReleaseChannel={releaseChannel}"
- $"/p:AssemblyMetadataGitHash={gitHash}"
+ yield! assemblyInfoMsBuildArgs ()
$"/p:PackageReleaseNotes=\"{releaseNotes}\""
]
diff --git a/Content/Library/src/Directory.Build.targets b/Content/Library/src/Directory.Build.targets
index 7e76d8fb..4fc8e4ef 100644
--- a/Content/Library/src/Directory.Build.targets
+++ b/Content/Library/src/Directory.Build.targets
@@ -6,17 +6,8 @@
-
- <_Parameter1>ReleaseDate
- <_Parameter2>$(AssemblyMetadataReleaseDate)
-
-
- <_Parameter1>ReleaseChannel
- <_Parameter2>$(AssemblyMetadataReleaseChannel)
-
-
- <_Parameter1>GitHash
- <_Parameter2>$(AssemblyMetadataGitHash)
-
+
+
+
diff --git a/tests/MiniScaffold.Tests/Asserts.fs b/tests/MiniScaffold.Tests/Asserts.fs
index eb079cac..94d613c2 100644
--- a/tests/MiniScaffold.Tests/Asserts.fs
+++ b/tests/MiniScaffold.Tests/Asserts.fs
@@ -1,6 +1,9 @@
namespace MiniScaffold.Tests
open System.IO
+open System.Diagnostics
+open System.Reflection
+open System.Runtime.Loader
open Expecto
open Infrastructure
open Fake.IO.FileSystemOperators
@@ -138,6 +141,78 @@ module Assert =
let filepath = Path.Combine(d.FullName, file)
Expect.isFalse (File.Exists filepath) (sprintf "%s should not exist" filepath)
+ let ``assembly info values are set after pack`` projectName (d: DirectoryInfo) =
+ let dllPath =
+ Path.Combine(
+ d.FullName,
+ "src",
+ projectName,
+ "bin",
+ "Debug",
+ "net8.0",
+ $"{projectName}.dll"
+ )
+
+ Expect.isTrue (File.Exists dllPath) (sprintf "%s should exist" dllPath)
+
+ let assemblyName = AssemblyName.GetAssemblyName(dllPath)
+ Expect.equal assemblyName.Version (Version "0.1.0.0") "AssemblyVersion should be 0.1.0.0"
+
+ let fileVersionInfo = FileVersionInfo.GetVersionInfo(dllPath)
+
+ Expect.equal fileVersionInfo.FileVersion "0.1.0" "FileVersion should be 0.1.0"
+
+ let assemblyContext =
+ new AssemblyLoadContext($"metadata-{projectName}-{Guid.NewGuid():N}", true)
+
+ let assembly = assemblyContext.LoadFromAssemblyPath(dllPath)
+
+ let title =
+ assembly.GetCustomAttribute()
+ |> Option.ofObj
+ |> Option.map _.Title
+
+ Expect.equal title (Some projectName) "AssemblyTitle should match project name"
+
+ let product =
+ assembly.GetCustomAttribute()
+ |> Option.ofObj
+ |> Option.map _.Product
+
+ Expect.equal product (Some projectName) "AssemblyProduct should match project name"
+
+ let informationalVersion =
+ assembly.GetCustomAttribute()
+ |> Option.ofObj
+ |> Option.map _.InformationalVersion
+
+ Expect.equal informationalVersion (Some "0.1.0") "InformationalVersion should be 0.1.0"
+
+ let metadata =
+ assembly.GetCustomAttributes()
+ |> Seq.map (fun x -> x.Key, x.Value)
+ |> Map.ofSeq
+
+ Expect.equal
+ (metadata
+ |> Map.tryFind "ReleaseChannel")
+ (Some "release")
+ "ReleaseChannel should be release"
+
+ let releaseDate =
+ metadata
+ |> Map.tryFind "ReleaseDate"
+
+ Expect.isTrue
+ (releaseDate
+ |> Option.exists (
+ String.IsNullOrWhiteSpace
+ >> not
+ ))
+ "ReleaseDate should be set"
+
+ assemblyContext.Unload()
+
module Effect =
open System
open Fake.IO
diff --git a/tests/MiniScaffold.Tests/Tests.fs b/tests/MiniScaffold.Tests/Tests.fs
index 8d4ef37d..b72d22ca 100755
--- a/tests/MiniScaffold.Tests/Tests.fs
+++ b/tests/MiniScaffold.Tests/Tests.fs
@@ -131,6 +131,7 @@ module Tests =
yield! projectStructureAsserts
Assert.``File does not exist`` "src/MyCoolLib/AssemblyInfo.fs"
Assert.``project can build target`` "DotnetPack"
+ Assert.``assembly info values are set after pack`` "MyCoolLib"
Assert.``project can build target`` "BuildDocs"
]
From 1364acbecf4cb18c0d1caac92b71e6e9c950c627 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 7 Mar 2026 23:53:29 +0000
Subject: [PATCH 5/9] Address PR review comments on assembly metadata and test
robustness
Co-authored-by: TheAngryByrd <1490044+TheAngryByrd@users.noreply.github.com>
---
Content/Library/build/build.fs | 4 -
Content/Library/src/Directory.Build.props | 2 +-
Content/Library/src/Directory.Build.targets | 17 ++-
tests/MiniScaffold.Tests/Asserts.fs | 138 ++++++++++++--------
4 files changed, 96 insertions(+), 65 deletions(-)
diff --git a/Content/Library/build/build.fs b/Content/Library/build/build.fs
index ef209d04..93baac56 100644
--- a/Content/Library/build/build.fs
+++ b/Content/Library/build/build.fs
@@ -390,13 +390,9 @@ let assemblyInfoMsBuildArgs () =
let dotnetBuild ctx =
- let isDotnetPack = ctx.Context.TryFindTarget("DotnetPack").IsSome
-
let args = [
sprintf "/p:PackageVersion=%s" latestEntry.NuGetVersion
"--no-restore"
- if isDotnetPack then
- yield! assemblyInfoMsBuildArgs ()
]
DotNet.build
diff --git a/Content/Library/src/Directory.Build.props b/Content/Library/src/Directory.Build.props
index a8c7e261..de83db80 100644
--- a/Content/Library/src/Directory.Build.props
+++ b/Content/Library/src/Directory.Build.props
@@ -10,7 +10,7 @@
true
- MyLib.1
+ $(MSBuildProjectName)
true
diff --git a/Content/Library/src/Directory.Build.targets b/Content/Library/src/Directory.Build.targets
index 4fc8e4ef..388db2ad 100644
--- a/Content/Library/src/Directory.Build.targets
+++ b/Content/Library/src/Directory.Build.targets
@@ -5,9 +5,18 @@
$(FSharpAnalyzersOtherFlags) --analyzers-path "$(PkgIonide_Analyzers)/analyzers/dotnet/fs"
-
-
-
-
+
+
+ <_Parameter1>ReleaseDate
+ <_Parameter2>$(AssemblyMetadataReleaseDate)
+
+
+ <_Parameter1>ReleaseChannel
+ <_Parameter2>$(AssemblyMetadataReleaseChannel)
+
+
+ <_Parameter1>GitHash
+ <_Parameter2>$(AssemblyMetadataGitHash)
+
diff --git a/tests/MiniScaffold.Tests/Asserts.fs b/tests/MiniScaffold.Tests/Asserts.fs
index 94d613c2..81074057 100644
--- a/tests/MiniScaffold.Tests/Asserts.fs
+++ b/tests/MiniScaffold.Tests/Asserts.fs
@@ -1,6 +1,7 @@
namespace MiniScaffold.Tests
open System.IO
+open System.IO.Compression
open System.Diagnostics
open System.Reflection
open System.Runtime.Loader
@@ -142,76 +143,101 @@ module Assert =
Expect.isFalse (File.Exists filepath) (sprintf "%s should not exist" filepath)
let ``assembly info values are set after pack`` projectName (d: DirectoryInfo) =
- let dllPath =
- Path.Combine(
- d.FullName,
- "src",
- projectName,
- "bin",
- "Debug",
- "net8.0",
- $"{projectName}.dll"
- )
-
- Expect.isTrue (File.Exists dllPath) (sprintf "%s should exist" dllPath)
-
- let assemblyName = AssemblyName.GetAssemblyName(dllPath)
- Expect.equal assemblyName.Version (Version "0.1.0.0") "AssemblyVersion should be 0.1.0.0"
+ let mutable extractedDllDir: string option = None
- let fileVersionInfo = FileVersionInfo.GetVersionInfo(dllPath)
+ let nupkgPath = Path.Combine(d.FullName, "dist", $"{projectName}.0.1.0.nupkg")
- Expect.equal fileVersionInfo.FileVersion "0.1.0" "FileVersion should be 0.1.0"
+ Expect.isTrue (File.Exists nupkgPath) (sprintf "%s should exist" nupkgPath)
- let assemblyContext =
- new AssemblyLoadContext($"metadata-{projectName}-{Guid.NewGuid():N}", true)
+ use archive = ZipFile.OpenRead(nupkgPath)
- let assembly = assemblyContext.LoadFromAssemblyPath(dllPath)
+ let entry =
+ archive.Entries
+ |> Seq.tryFind (fun x ->
+ x.FullName.StartsWith("lib/net8.0/")
+ && x.FullName.EndsWith($"/{projectName}.dll")
+ )
- let title =
- assembly.GetCustomAttribute()
- |> Option.ofObj
- |> Option.map _.Title
+ let dllPath =
+ match entry with
+ | Some e ->
+ let tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"))
- Expect.equal title (Some projectName) "AssemblyTitle should match project name"
+ let tempPath = Path.Combine(tempDir, $"{projectName}.dll")
- let product =
- assembly.GetCustomAttribute()
- |> Option.ofObj
- |> Option.map _.Product
+ Directory.CreateDirectory(tempDir)
+ |> ignore
- Expect.equal product (Some projectName) "AssemblyProduct should match project name"
+ e.ExtractToFile(tempPath, true)
+ extractedDllDir <- Some tempDir
- let informationalVersion =
- assembly.GetCustomAttribute()
- |> Option.ofObj
- |> Option.map _.InformationalVersion
+ tempPath
+ | None -> failtestf "Could not find lib/net8.0/%s.dll in %s" projectName nupkgPath
- Expect.equal informationalVersion (Some "0.1.0") "InformationalVersion should be 0.1.0"
+ let assemblyName = AssemblyName.GetAssemblyName(dllPath)
+ Expect.equal assemblyName.Version (Version "0.1.0.0") "AssemblyVersion should be 0.1.0.0"
- let metadata =
- assembly.GetCustomAttributes()
- |> Seq.map (fun x -> x.Key, x.Value)
- |> Map.ofSeq
+ let fileVersionInfo = FileVersionInfo.GetVersionInfo(dllPath)
- Expect.equal
- (metadata
- |> Map.tryFind "ReleaseChannel")
- (Some "release")
- "ReleaseChannel should be release"
+ Expect.equal fileVersionInfo.FileVersion "0.1.0" "FileVersion should be 0.1.0"
- let releaseDate =
- metadata
- |> Map.tryFind "ReleaseDate"
+ let assemblyContext =
+ new AssemblyLoadContext($"metadata-{projectName}-{Guid.NewGuid():N}", true)
- Expect.isTrue
- (releaseDate
- |> Option.exists (
- String.IsNullOrWhiteSpace
- >> not
- ))
- "ReleaseDate should be set"
-
- assemblyContext.Unload()
+ try
+ let assembly = assemblyContext.LoadFromAssemblyPath(dllPath)
+
+ let title =
+ assembly.GetCustomAttribute()
+ |> Option.ofObj
+ |> Option.map _.Title
+
+ Expect.equal title (Some projectName) "AssemblyTitle should match project name"
+
+ let product =
+ assembly.GetCustomAttribute()
+ |> Option.ofObj
+ |> Option.map _.Product
+
+ Expect.equal product (Some projectName) "AssemblyProduct should match project name"
+
+ let informationalVersion =
+ assembly.GetCustomAttribute()
+ |> Option.ofObj
+ |> Option.map _.InformationalVersion
+
+ Expect.equal informationalVersion (Some "0.1.0") "InformationalVersion should be 0.1.0"
+
+ let metadata =
+ assembly.GetCustomAttributes()
+ |> Seq.map (fun x -> x.Key, x.Value)
+ |> Map.ofSeq
+
+ Expect.equal
+ (metadata
+ |> Map.tryFind "ReleaseChannel")
+ (Some "release")
+ "ReleaseChannel should be release"
+
+ let releaseDate =
+ metadata
+ |> Map.tryFind "ReleaseDate"
+
+ Expect.isTrue
+ (releaseDate
+ |> Option.exists (
+ String.IsNullOrWhiteSpace
+ >> not
+ ))
+ "ReleaseDate should be set"
+ finally
+ assemblyContext.Unload()
+
+ extractedDllDir
+ |> Option.iter (fun path ->
+ if Directory.Exists path then
+ Directory.Delete(path, true)
+ )
module Effect =
open System
From c6c3c1ae5f38dd01907abac7f5201e43507182f2 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 8 Mar 2026 02:50:43 +0000
Subject: [PATCH 6/9] Remove no-op GenerateAssemblyInfo target from library
template build graph
Co-authored-by: TheAngryByrd <1490044+TheAngryByrd@users.noreply.github.com>
---
Content/Library/README.md | 1 -
Content/Library/build/build.fs | 19 -------------------
2 files changed, 20 deletions(-)
diff --git a/Content/Library/README.md b/Content/Library/README.md
index 14a85166..4887fcf8 100644
--- a/Content/Library/README.md
+++ b/Content/Library/README.md
@@ -98,7 +98,6 @@ src/MyLib.1/bin/
- `GenerateCoverageReport` - Code coverage is run during `DotnetTest` and this generates a report via [ReportGenerator](https://github.com/danielpalme/ReportGenerator).
- `ShowCoverageReport` - Shows the report generated in `GenerateCoverageReport`.
- `WatchTests` - Runs [dotnet watch](https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-3.0) with the test projects. Useful for rapid feedback loops.
-- `GenerateAssemblyInfo` - Generates [AssemblyInfo](https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.applicationservices.assemblyinfo?view=netframework-4.8) for libraries.
- `DotnetPack` - Runs [dotnet pack](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-pack). This includes running [Source Link](https://github.com/dotnet/sourcelink).
- `SourceLinkTest` - Runs a Source Link test tool to verify Source Links were properly generated.
- `PublishToNuGet` - Publishes the NuGet packages generated in `DotnetPack` to NuGet via [nuget push](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-nuget-push). Runs only from `Github Actions`.
diff --git a/Content/Library/build/build.fs b/Content/Library/build/build.fs
index 93baac56..a0028174 100644
--- a/Content/Library/build/build.fs
+++ b/Content/Library/build/build.fs
@@ -533,12 +533,6 @@ let watchTests _ =
cancelEvent.Cancel <- true
-let generateAssemblyInfo _ =
- let isNoop = true
-
- if isNoop then
- ()
-
let dotnetPack ctx =
// Get release notes with properly-linked version number
let releaseNotes = Changelog.mkReleaseNotes changelog latestEntry gitHubRepoUrl
@@ -696,7 +690,6 @@ let initTargets () =
Target.create "GenerateCoverageReport" generateCoverageReport
Target.create "ShowCoverageReport" showCoverageReport
Target.create "WatchTests" watchTests
- Target.create "GenerateAssemblyInfo" generateAssemblyInfo
Target.create "DotnetPack" dotnetPack
Target.create "SourceLinkTest" sourceLinkTest
Target.create "PublishToNuGet" publishToNuget
@@ -723,21 +716,10 @@ let initTargets () =
"Clean"
==>! "DotnetPack"
- // Only call GenerateAssemblyInfo if GitRelease was in the call chain
- // Ensure GenerateAssemblyInfo is called after DotnetRestore and before DotnetBuild
- "DotnetRestore"
- ?=>! "GenerateAssemblyInfo"
-
- "GenerateAssemblyInfo"
- ?=>! "DotnetBuild"
-
// Ensure UpdateChangelog is called after DotnetRestore
"DotnetRestore"
?=>! "UpdateChangelog"
- "UpdateChangelog"
- ?=>! "GenerateAssemblyInfo"
-
"CleanDocsCache"
==>! "BuildDocs"
@@ -756,7 +738,6 @@ let initTargets () =
==>! "ShowCoverageReport"
"UpdateChangelog"
- ==> "GenerateAssemblyInfo"
==> "GitRelease"
==>! "Release"
From a37a01c6023c7c485790d4662150c6e6a3208de3 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 8 Mar 2026 02:59:40 +0000
Subject: [PATCH 7/9] Apply assemblyinfo migration to console and project
templates
Co-authored-by: TheAngryByrd <1490044+TheAngryByrd@users.noreply.github.com>
---
Content/Console/.fantomasignore | 2 -
Content/Console/Directory.Packages.props | 3 +-
Content/Console/README.md | 1 -
Content/Console/build/build.fs | 103 +++++---------------
Content/Console/build/build.fsproj | 1 -
Content/Console/src/Directory.Build.props | 2 +
Content/Console/src/Directory.Build.targets | 19 +++-
Content/Console/src/MyLib.1/AssemblyInfo.fs | 23 -----
Content/Console/src/MyLib.1/MyLib.1.fsproj | 1 -
Content/ProjConsole/AssemblyInfo.fs | 23 -----
Content/ProjConsole/MyLib.1.fsproj | 1 -
Content/ProjLib/AssemblyInfo.fs | 23 -----
Content/ProjLib/MyLib.1.fsproj | 1 -
tests/MiniScaffold.Tests/Tests.fs | 7 +-
14 files changed, 49 insertions(+), 161 deletions(-)
delete mode 100644 Content/Console/.fantomasignore
delete mode 100644 Content/Console/src/MyLib.1/AssemblyInfo.fs
delete mode 100644 Content/ProjConsole/AssemblyInfo.fs
delete mode 100644 Content/ProjLib/AssemblyInfo.fs
diff --git a/Content/Console/.fantomasignore b/Content/Console/.fantomasignore
deleted file mode 100644
index d9f2aa7f..00000000
--- a/Content/Console/.fantomasignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# Ignore AssemblyInfo files
-AssemblyInfo.fs
diff --git a/Content/Console/Directory.Packages.props b/Content/Console/Directory.Packages.props
index 57cd3447..e623a592 100644
--- a/Content/Console/Directory.Packages.props
+++ b/Content/Console/Directory.Packages.props
@@ -34,7 +34,6 @@
-
@@ -47,4 +46,4 @@
-
\ No newline at end of file
+
diff --git a/Content/Console/README.md b/Content/Console/README.md
index 5be67f1a..8e0f8188 100644
--- a/Content/Console/README.md
+++ b/Content/Console/README.md
@@ -78,7 +78,6 @@ $ ./build.sh // on unix
- `GenerateCoverageReport` - Code coverage is run during `DotnetTest` and this generates a report via [ReportGenerator](https://github.com/danielpalme/ReportGenerator).
- `WatchApp` - Runs [dotnet watch](https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-3.0) on the application. Useful for rapid feedback loops.
- `WatchTests` - Runs [dotnet watch](https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-3.0) with the test projects. Useful for rapid feedback loops.
-- `GenerateAssemblyInfo` - Generates [AssemblyInfo](https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.applicationservices.assemblyinfo?view=netframework-4.8) for libraries.
- `CreatePackages` - Runs the packaging task from [dotnet-packaging](https://github.com/qmfrederik/dotnet-packaging). This creates applications for `win-x64`, `osx-x64` and `linux-x64` - [Runtime Identifiers](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog).
- Bundles the `win-x64` application in a .zip file.
- Bundles the `osx-x64` application in a .tar.gz file.
diff --git a/Content/Console/build/build.fs b/Content/Console/build/build.fs
index 31b29aad..4169c6f1 100644
--- a/Content/Console/build/build.fs
+++ b/Content/Console/build/build.fs
@@ -182,6 +182,28 @@ let failOnBadExitAndPrint (p: ProcessResult) =
failwithf "failed with exitcode %d" p.ExitCode
+let assemblyInfoMsBuildArgs () =
+ let releaseChannel =
+ match latestEntry.SemVer.PreRelease with
+ | Some pr -> pr.Name
+ | _ -> "release"
+
+ let gitHash =
+ try
+ Git.Information.getCurrentSHA1 (null)
+ with _ ->
+ ""
+
+ [
+ sprintf "/p:Version=%s" latestEntry.AssemblyVersion
+ sprintf "/p:AssemblyVersion=%s" latestEntry.AssemblyVersion
+ sprintf "/p:FileVersion=%s" latestEntry.AssemblyVersion
+ sprintf "/p:InformationalVersion=%s" latestEntry.AssemblyVersion
+ sprintf "/p:AssemblyMetadataReleaseDate=%s" (latestEntry.Date.Value.ToString("o"))
+ sprintf "/p:AssemblyMetadataReleaseChannel=%s" releaseChannel
+ sprintf "/p:AssemblyMetadataGitHash=%s" gitHash
+ ]
+
let rec retryIfInCI times fn =
if isCI.Value then
if times > 1 then
@@ -423,63 +445,6 @@ let watchTests _ =
cancelEvent.Cancel <- true
-let generateAssemblyInfo _ =
-
- let (|Fsproj|Csproj|Vbproj|) (projFileName: string) =
- match projFileName with
- | f when f.EndsWith("fsproj") -> Fsproj
- | f when f.EndsWith("csproj") -> Csproj
- | f when f.EndsWith("vbproj") -> Vbproj
- | _ ->
- failwith (sprintf "Project file %s not supported. Unknown project type." projFileName)
-
- let releaseChannel =
- match latestEntry.SemVer.PreRelease with
- | Some pr -> pr.Name
- | _ -> "release"
-
- let getAssemblyInfoAttributes projectName = [
- AssemblyInfo.Title(projectName)
- AssemblyInfo.Product productName
- AssemblyInfo.Version latestEntry.AssemblyVersion
- AssemblyInfo.Metadata("ReleaseDate", latestEntry.Date.Value.ToString("o"))
- AssemblyInfo.FileVersion latestEntry.AssemblyVersion
- AssemblyInfo.InformationalVersion latestEntry.AssemblyVersion
- AssemblyInfo.Metadata("ReleaseChannel", releaseChannel)
- AssemblyInfo.Metadata("GitHash", Git.Information.getCurrentSHA1 (null))
- ]
-
- let getProjectDetails (projectPath: string) =
- let projectName = IO.Path.GetFileNameWithoutExtension(projectPath)
-
- (projectPath,
- projectName,
- IO.Path.GetDirectoryName(projectPath),
- (getAssemblyInfoAttributes projectName))
-
- !!srcGlob
- |> Seq.map getProjectDetails
- |> Seq.iter (fun (projFileName, _, folderName, attributes) ->
- match projFileName with
- | Fsproj ->
- AssemblyInfoFile.createFSharp
- (folderName
- @@ "AssemblyInfo.fs")
- attributes
- | Csproj ->
- AssemblyInfoFile.createCSharp
- ((folderName
- @@ "Properties")
- @@ "AssemblyInfo.cs")
- attributes
- | Vbproj ->
- AssemblyInfoFile.createVisualBasic
- ((folderName
- @@ "My Project")
- @@ "AssemblyInfo.vb")
- attributes
- )
-
let createPackages _ =
runtimes
|> Seq.iter (fun (runtime, packageType) ->
@@ -491,6 +456,7 @@ let createPackages _ =
sprintf "/p:RuntimeIdentifier=%s" runtime
sprintf "/p:Configuration=%s" "Release"
sprintf "/p:PackageVersion=%s" latestEntry.NuGetVersion
+ yield! assemblyInfoMsBuildArgs ()
sprintf
"/p:PackagePath=\"%s\""
(distDir
@@ -510,12 +476,6 @@ let gitRelease _ =
Git.Staging.stageFile "" "CHANGELOG.md"
|> ignore
- !!"src/**/AssemblyInfo.fs"
- |> Seq.iter (
- Git.Staging.stageFile ""
- >> ignore
- )
-
Git.Commit.exec
""
(sprintf "Bump version to %s\n\n%s" latestEntry.NuGetVersion releaseNotesGitCommitFormat)
@@ -606,7 +566,6 @@ let initTargets () =
Target.create "GenerateCoverageReport" generateCoverageReport
Target.create "WatchApp" watchApp
Target.create "WatchTests" watchTests
- Target.create "AssemblyInfo" generateAssemblyInfo
Target.create "CreatePackages" createPackages
Target.create "GitRelease" gitRelease
Target.create "GitHubRelease" githubRelease
@@ -626,25 +585,11 @@ let initTargets () =
"Clean"
==>! "CreatePackages"
- // Only call AssemblyInfo if there is a release target in the call chain
- // Ensure AssemblyInfo is called after DotnetRestore and before DotnetBuild
- "DotnetRestore"
- ?=>! "AssemblyInfo"
-
- "AssemblyInfo"
- ?=>! "DotnetBuild"
-
- "AssemblyInfo"
- ==>! "GitRelease"
-
// Only call UpdateChangelog if there is a release target in the call chain
- // Ensure UpdateChangelog is called after DotnetRestore and before AssemblyInfo
+ // Ensure UpdateChangelog is called after DotnetRestore
"DotnetRestore"
?=>! "UpdateChangelog"
- "UpdateChangelog"
- ?=>! "AssemblyInfo"
-
"UpdateChangelog"
==>! "GitRelease"
diff --git a/Content/Console/build/build.fsproj b/Content/Console/build/build.fsproj
index 8a404997..267795e7 100644
--- a/Content/Console/build/build.fsproj
+++ b/Content/Console/build/build.fsproj
@@ -18,7 +18,6 @@
-
diff --git a/Content/Console/src/Directory.Build.props b/Content/Console/src/Directory.Build.props
index e67ecfec..b55c8189 100644
--- a/Content/Console/src/Directory.Build.props
+++ b/Content/Console/src/Directory.Build.props
@@ -9,6 +9,8 @@
Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
+ true
+ $(MSBuildProjectName)
false
diff --git a/Content/Console/src/Directory.Build.targets b/Content/Console/src/Directory.Build.targets
index cde61a89..388db2ad 100644
--- a/Content/Console/src/Directory.Build.targets
+++ b/Content/Console/src/Directory.Build.targets
@@ -1,7 +1,22 @@
-
+
true
--analyzers-path "$(PkgG-Research_FSharp_Analyzers)/analyzers/dotnet/fs"
$(FSharpAnalyzersOtherFlags) --analyzers-path "$(PkgIonide_Analyzers)/analyzers/dotnet/fs"
-
\ No newline at end of file
+
+
+
+ <_Parameter1>ReleaseDate
+ <_Parameter2>$(AssemblyMetadataReleaseDate)
+
+
+ <_Parameter1>ReleaseChannel
+ <_Parameter2>$(AssemblyMetadataReleaseChannel)
+
+
+ <_Parameter1>GitHash
+ <_Parameter2>$(AssemblyMetadataGitHash)
+
+
+
diff --git a/Content/Console/src/MyLib.1/AssemblyInfo.fs b/Content/Console/src/MyLib.1/AssemblyInfo.fs
deleted file mode 100644
index d1613d7d..00000000
--- a/Content/Console/src/MyLib.1/AssemblyInfo.fs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Auto-Generated by FAKE; do not edit
-namespace System
-open System.Reflection
-
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-do ()
-
-module internal AssemblyVersionInformation =
- let [] AssemblyTitle = "MyLib.1"
- let [] AssemblyProduct = "MyLib.1"
- let [] AssemblyVersion = "0.1.0"
- let [] AssemblyMetadata_ReleaseDate = "2017-03-17T00:00:00.0000000"
- let [] AssemblyFileVersion = "0.1.0"
- let [] AssemblyInformationalVersion = "0.1.0"
- let [] AssemblyMetadata_ReleaseChannel = "release"
- let [] AssemblyMetadata_GitHash = "b385af579477bb585016a6b5204121de4a485dac"
diff --git a/Content/Console/src/MyLib.1/MyLib.1.fsproj b/Content/Console/src/MyLib.1/MyLib.1.fsproj
index f177d838..bf3394f3 100755
--- a/Content/Console/src/MyLib.1/MyLib.1.fsproj
+++ b/Content/Console/src/MyLib.1/MyLib.1.fsproj
@@ -19,7 +19,6 @@
-
diff --git a/Content/ProjConsole/AssemblyInfo.fs b/Content/ProjConsole/AssemblyInfo.fs
deleted file mode 100644
index d1613d7d..00000000
--- a/Content/ProjConsole/AssemblyInfo.fs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Auto-Generated by FAKE; do not edit
-namespace System
-open System.Reflection
-
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-do ()
-
-module internal AssemblyVersionInformation =
- let [] AssemblyTitle = "MyLib.1"
- let [] AssemblyProduct = "MyLib.1"
- let [] AssemblyVersion = "0.1.0"
- let [] AssemblyMetadata_ReleaseDate = "2017-03-17T00:00:00.0000000"
- let [] AssemblyFileVersion = "0.1.0"
- let [] AssemblyInformationalVersion = "0.1.0"
- let [] AssemblyMetadata_ReleaseChannel = "release"
- let [] AssemblyMetadata_GitHash = "b385af579477bb585016a6b5204121de4a485dac"
diff --git a/Content/ProjConsole/MyLib.1.fsproj b/Content/ProjConsole/MyLib.1.fsproj
index 6c0387e0..2e5e4a7b 100644
--- a/Content/ProjConsole/MyLib.1.fsproj
+++ b/Content/ProjConsole/MyLib.1.fsproj
@@ -10,7 +10,6 @@
-
diff --git a/Content/ProjLib/AssemblyInfo.fs b/Content/ProjLib/AssemblyInfo.fs
deleted file mode 100644
index 6f273302..00000000
--- a/Content/ProjLib/AssemblyInfo.fs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Auto-Generated by FAKE; do not edit
-namespace System
-open System.Reflection
-
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-do ()
-
-module internal AssemblyVersionInformation =
- let [] AssemblyTitle = "MyLib.1"
- let [] AssemblyProduct = "MyLib.1"
- let [] AssemblyVersion = "0.1.0"
- let [] AssemblyMetadata_ReleaseDate = "2017-03-17T00:00:00.0000000"
- let [] AssemblyFileVersion = "0.1.0"
- let [] AssemblyInformationalVersion = "0.1.0"
- let [] AssemblyMetadata_ReleaseChannel = "release"
- let [] AssemblyMetadata_GitHash = "bb8964b54bee133e9af64d316dc2cfee16df7f72"
diff --git a/Content/ProjLib/MyLib.1.fsproj b/Content/ProjLib/MyLib.1.fsproj
index 35c00fcc..504c1f0d 100644
--- a/Content/ProjLib/MyLib.1.fsproj
+++ b/Content/ProjLib/MyLib.1.fsproj
@@ -14,7 +14,6 @@
-
diff --git a/tests/MiniScaffold.Tests/Tests.fs b/tests/MiniScaffold.Tests/Tests.fs
index b72d22ca..4005158a 100755
--- a/tests/MiniScaffold.Tests/Tests.fs
+++ b/tests/MiniScaffold.Tests/Tests.fs
@@ -146,6 +146,7 @@ module Tests =
"src"
Effect.``dotnet sln add`` "src/MyCoolLib3/MyCoolLib3.fsproj"
Assert.``File exists`` "src/MyCoolLib3/MyCoolLib3.fsproj"
+ Assert.``File does not exist`` "src/MyCoolLib3/AssemblyInfo.fs"
Assert.``project can build target`` "DotnetPack"
]
@@ -159,6 +160,7 @@ module Tests =
"src"
Effect.``dotnet sln add`` "src/MyCoolConsole/MyCoolConsole.fsproj"
Assert.``File exists`` "src/MyCoolConsole/MyCoolConsole.fsproj"
+ Assert.``File does not exist`` "src/MyCoolConsole/AssemblyInfo.fs"
Assert.``project can build target`` "DotnetPack"
Effect.``dotnet run`` "" "src/MyCoolConsole/"
]
@@ -181,6 +183,7 @@ module Tests =
"../../src/MyCoolLib3/MyCoolLib3.fsproj"
"tests/MyCoolLib3.Tests/"
Assert.``File exists`` "tests/MyCoolLib3.Tests/MyCoolLib3.Tests.fsproj"
+ Assert.``File does not exist`` "tests/MyCoolLib3.Tests/AssemblyInfo.fs"
Assert.``project can build target`` "DotnetPack"
]
@@ -204,7 +207,7 @@ module Tests =
"-n AssemblyInfoFail --githubUsername TestAccount",
[
Effect.``setup for release tests``
- Effect.``make build function fail`` "let generateAssemblyInfo"
+ Effect.``make build function fail`` "let updateChangelog"
Assert.``CHANGELOG contains Unreleased section``
Assert.``build target with failure expected`` "Release"
Assert.``CHANGELOG contains Unreleased section``
@@ -307,7 +310,7 @@ module Tests =
"-n AssemblyInfoFail --githubUsername TestAccount --outputType Console",
[
Effect.``setup for release tests``
- Effect.``make build function fail`` "let generateAssemblyInfo"
+ Effect.``make build function fail`` "let updateChangelog"
Assert.``CHANGELOG contains Unreleased section``
Assert.``build target with failure expected`` "Release"
Assert.``CHANGELOG contains Unreleased section``
From ce5cc1fdcd5dc7ec982d412805cd91a025b304c1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 8 Mar 2026 16:02:45 +0000
Subject: [PATCH 8/9] Fix CI flakiness in packed assembly metadata test
Co-authored-by: TheAngryByrd <1490044+TheAngryByrd@users.noreply.github.com>
---
tests/MiniScaffold.Tests/Asserts.fs | 33 +++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/tests/MiniScaffold.Tests/Asserts.fs b/tests/MiniScaffold.Tests/Asserts.fs
index 81074057..f7ef6f60 100644
--- a/tests/MiniScaffold.Tests/Asserts.fs
+++ b/tests/MiniScaffold.Tests/Asserts.fs
@@ -44,6 +44,9 @@ module Array =
newArray
module Assert =
+ let private deleteRetryDelayMs = 100
+ let private maxDeleteRetries = 5
+
open System
let private failIfNoneWithMsg msg opt =
@@ -179,13 +182,17 @@ module Assert =
let fileVersionInfo = FileVersionInfo.GetVersionInfo(dllPath)
- Expect.equal fileVersionInfo.FileVersion "0.1.0" "FileVersion should be 0.1.0"
+ Expect.isTrue
+ (fileVersionInfo.FileVersion = "0.1.0"
+ || fileVersionInfo.FileVersion = "0.1.0.0")
+ "FileVersion should be 0.1.0 or 0.1.0.0"
let assemblyContext =
new AssemblyLoadContext($"metadata-{projectName}-{Guid.NewGuid():N}", true)
try
- let assembly = assemblyContext.LoadFromAssemblyPath(dllPath)
+ use assemblyStream = new MemoryStream(File.ReadAllBytes dllPath)
+ let assembly = assemblyContext.LoadFromStream(assemblyStream)
let title =
assembly.GetCustomAttribute()
@@ -232,11 +239,29 @@ module Assert =
"ReleaseDate should be set"
finally
assemblyContext.Unload()
+ GC.Collect()
+ GC.WaitForPendingFinalizers()
+ GC.Collect()
extractedDllDir
|> Option.iter (fun path ->
- if Directory.Exists path then
- Directory.Delete(path, true)
+ let rec deleteWithRetry attempts =
+ try
+ if Directory.Exists path then
+ Directory.Delete(path, true)
+ with
+ | :? IOException
+ | :? UnauthorizedAccessException when attempts > 0 ->
+ GC.Collect()
+ GC.WaitForPendingFinalizers()
+ System.Threading.Thread.Sleep deleteRetryDelayMs
+
+ deleteWithRetry (
+ attempts
+ - 1
+ )
+
+ deleteWithRetry maxDeleteRetries
)
module Effect =
From 0e24dd8d8bd7d5d515bcbf453bed7421b21f5ae6 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 9 Mar 2026 14:06:45 +0000
Subject: [PATCH 9/9] Stabilize macOS debug test setup by retrying fantomas on
exit 137
Co-authored-by: TheAngryByrd <1490044+TheAngryByrd@users.noreply.github.com>
---
tests/MiniScaffold.Tests/Infrastructure.fs | 38 +++++++++++++++++-----
1 file changed, 30 insertions(+), 8 deletions(-)
diff --git a/tests/MiniScaffold.Tests/Infrastructure.fs b/tests/MiniScaffold.Tests/Infrastructure.fs
index cf489172..79451799 100644
--- a/tests/MiniScaffold.Tests/Infrastructure.fs
+++ b/tests/MiniScaffold.Tests/Infrastructure.fs
@@ -4,6 +4,10 @@ namespace Infrastructure
module Dotnet =
open Fake.Core
open Fake.DotNet
+ open System.Threading
+
+ let private fantomasRetryDelayMs = 250
+ let private fantomasMaxRetries = 2
let failOnBadExitAndPrint (p: ProcessResult) =
if
@@ -16,14 +20,32 @@ module Dotnet =
failwithf "failed with exitcode %d" p.ExitCode
let fantomas workingDir args =
- DotNet.exec
- (fun opt -> {
- opt with
- WorkingDirectory = workingDir
- })
- "fantomas"
- args
- |> failOnBadExitAndPrint
+ let rec run attempts =
+ let result =
+ DotNet.exec
+ (fun opt -> {
+ opt with
+ WorkingDirectory = workingDir
+ })
+ "fantomas"
+ args
+
+ if
+ // Exit code 137 can occur when Fantomas is transiently terminated by the OS.
+ result.ExitCode = 137
+ && attempts > 0
+ then
+ Thread.Sleep fantomasRetryDelayMs
+
+ run (
+ attempts
+ - 1
+ )
+ else
+ result
+ |> failOnBadExitAndPrint
+
+ run fantomasMaxRetries
module New =
let cmd (opt: DotNet.Options -> DotNet.Options) args =