-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathDirectory.Build.targets
More file actions
264 lines (219 loc) · 13.4 KB
/
Copy pathDirectory.Build.targets
File metadata and controls
264 lines (219 loc) · 13.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
<Project>
<!-- Generate SDK version from git state -->
<PropertyGroup>
<GeneratedVersionFile>$(IntermediateOutputPath)BraintrustVersion.txt</GeneratedVersionFile>
</PropertyGroup>
<!-- Target to compute version from git -->
<Target Name="ComputeBraintrustVersion" BeforeTargets="GetAssemblyVersion;GenerateNuspec;BeforeCompile;PrepareResourceNames">
<!-- Check if workspace is clean -->
<Exec Command="git status --porcelain" ConsoleToMSBuild="true" IgnoreExitCode="true">
<Output TaskParameter="ConsoleOutput" PropertyName="GitStatus" />
<Output TaskParameter="ExitCode" PropertyName="GitStatusExitCode" />
</Exec>
<!-- Get current commit SHA (short version) -->
<Exec Command="git rev-parse --short HEAD" ConsoleToMSBuild="true" IgnoreExitCode="true">
<Output TaskParameter="ConsoleOutput" PropertyName="GitSha" />
<Output TaskParameter="ExitCode" PropertyName="GitShaExitCode" />
</Exec>
<!-- Check if we're currently on a tag -->
<Exec Command="git describe --exact-match --tags HEAD" ConsoleToMSBuild="true" IgnoreExitCode="true">
<Output TaskParameter="ConsoleOutput" PropertyName="CurrentTag" />
<Output TaskParameter="ExitCode" PropertyName="CurrentTagExitCode" />
</Exec>
<!-- Get most recent tag if not on a tag -->
<Exec Command="git describe --tags --abbrev=0" ConsoleToMSBuild="true" IgnoreExitCode="true" Condition="'$(CurrentTagExitCode)' != '0'">
<Output TaskParameter="ConsoleOutput" PropertyName="MostRecentTag" />
<Output TaskParameter="ExitCode" PropertyName="MostRecentTagExitCode" />
</Exec>
<!-- Compute the version -->
<PropertyGroup>
<!-- Check if workspace is dirty -->
<IsDirty Condition="'$(GitStatus)' != ''">true</IsDirty>
<IsDirty Condition="'$(GitStatus)' == ''">false</IsDirty>
<!-- Strip 'v' prefix from tags -->
<CleanCurrentTag Condition="'$(CurrentTagExitCode)' == '0' and $(CurrentTag.StartsWith('v'))">$(CurrentTag.Substring(1))</CleanCurrentTag>
<CleanCurrentTag Condition="'$(CurrentTagExitCode)' == '0' and !$(CurrentTag.StartsWith('v'))">$(CurrentTag)</CleanCurrentTag>
<CleanMostRecentTag Condition="'$(MostRecentTagExitCode)' == '0' and $(MostRecentTag.StartsWith('v'))">$(MostRecentTag.Substring(1))</CleanMostRecentTag>
<CleanMostRecentTag Condition="'$(MostRecentTagExitCode)' == '0' and !$(MostRecentTag.StartsWith('v'))">$(MostRecentTag)</CleanMostRecentTag>
<!-- Build version string -->
<!-- If on a tag, use the tag -->
<BraintrustSdkVersion Condition="'$(CurrentTagExitCode)' == '0'">$(CleanCurrentTag)</BraintrustSdkVersion>
<!-- If not on a tag but have a recent tag, use tag-sha (already semver compatible) -->
<BraintrustSdkVersion Condition="'$(CurrentTagExitCode)' != '0' and '$(MostRecentTagExitCode)' == '0'">$(CleanMostRecentTag)-$(GitSha)</BraintrustSdkVersion>
<!-- If no tags at all, use 0.0.0-dev-sha format for NuGet compatibility -->
<BraintrustSdkVersion Condition="'$(CurrentTagExitCode)' != '0' and '$(MostRecentTagExitCode)' != '0'">0.0.0-dev-$(GitSha)</BraintrustSdkVersion>
<!-- Append -dirty if workspace is not clean -->
<BraintrustSdkVersion Condition="'$(IsDirty)' == 'true'">$(BraintrustSdkVersion)-dirty</BraintrustSdkVersion>
<!-- Fallback to "0.0.0-unknown" if git is not available -->
<BraintrustSdkVersion Condition="'$(GitShaExitCode)' != '0'">0.0.0-unknown</BraintrustSdkVersion>
</PropertyGroup>
<!-- Create intermediate directory if it doesn't exist -->
<MakeDir Directories="$(IntermediateOutputPath)" Condition="!Exists('$(IntermediateOutputPath)')" />
<!-- Write version to file -->
<WriteLinesToFile File="$(GeneratedVersionFile)" Lines="$(BraintrustSdkVersion)" Overwrite="true" />
<!-- Add the generated version file as an embedded resource dynamically -->
<ItemGroup>
<EmbeddedResource Include="$(GeneratedVersionFile)">
<LogicalName>BraintrustVersion.txt</LogicalName>
<Visible>false</Visible>
</EmbeddedResource>
</ItemGroup>
<Message Text="Generated Braintrust SDK version: $(BraintrustSdkVersion)" Importance="high" />
<!-- Set the Version property for NuGet packaging for all src/ projects.
Uses name-prefix detection so new Braintrust.Sdk.* projects are automatically included,
while test projects and temporary verifier projects in obj/ are excluded. -->
<PropertyGroup Condition="$(MSBuildProjectName.StartsWith('Braintrust.Sdk')) and '$(IsPackable)' != 'false'">
<Version>$(BraintrustSdkVersion)</Version>
<PackageVersion>$(BraintrustSdkVersion)</PackageVersion>
</PropertyGroup>
</Target>
<!-- Ensure version is generated before embedding resources -->
<PropertyGroup>
<PrepareResourceNamesDependsOn>
ComputeBraintrustVersion;
$(PrepareResourceNamesDependsOn)
</PrepareResourceNamesDependsOn>
<CoreCompileDependsOn>
ComputeBraintrustVersion;
$(CoreCompileDependsOn)
</CoreCompileDependsOn>
</PropertyGroup>
<!-- Target to verify the version in the built assembly matches the expected git version.
Runs for all packable Braintrust.Sdk.* projects so new packages are automatically covered. -->
<Target Name="VerifyAssemblyVersion" AfterTargets="Build" Condition="$(MSBuildProjectName.StartsWith('Braintrust.Sdk')) and '$(IsPackable)' != 'false'">
<Message Text="Verifying SDK version in built assembly..." Importance="high" />
<!-- Get the expected version (recompute it to ensure consistency) -->
<Exec Command="git status --porcelain" ConsoleToMSBuild="true" IgnoreExitCode="true">
<Output TaskParameter="ConsoleOutput" PropertyName="VerifyGitStatus" />
</Exec>
<Exec Command="git rev-parse --short HEAD" ConsoleToMSBuild="true" IgnoreExitCode="true">
<Output TaskParameter="ConsoleOutput" PropertyName="VerifyGitSha" />
</Exec>
<Exec Command="git describe --exact-match --tags HEAD" ConsoleToMSBuild="true" IgnoreExitCode="true">
<Output TaskParameter="ConsoleOutput" PropertyName="VerifyCurrentTag" />
<Output TaskParameter="ExitCode" PropertyName="VerifyCurrentTagExitCode" />
</Exec>
<Exec Command="git describe --tags --abbrev=0" ConsoleToMSBuild="true" IgnoreExitCode="true" Condition="'$(VerifyCurrentTagExitCode)' != '0'">
<Output TaskParameter="ConsoleOutput" PropertyName="VerifyMostRecentTag" />
<Output TaskParameter="ExitCode" PropertyName="VerifyMostRecentTagExitCode" />
</Exec>
<!-- Recompute version using same logic -->
<PropertyGroup>
<VerifyIsDirty Condition="'$(VerifyGitStatus)' != ''">true</VerifyIsDirty>
<VerifyIsDirty Condition="'$(VerifyGitStatus)' == ''">false</VerifyIsDirty>
<VerifyCleanCurrentTag Condition="'$(VerifyCurrentTagExitCode)' == '0' and $(VerifyCurrentTag.StartsWith('v'))">$(VerifyCurrentTag.Substring(1))</VerifyCleanCurrentTag>
<VerifyCleanCurrentTag Condition="'$(VerifyCurrentTagExitCode)' == '0' and !$(VerifyCurrentTag.StartsWith('v'))">$(VerifyCurrentTag)</VerifyCleanCurrentTag>
<VerifyCleanMostRecentTag Condition="'$(VerifyMostRecentTagExitCode)' == '0' and $(VerifyMostRecentTag.StartsWith('v'))">$(VerifyMostRecentTag.Substring(1))</VerifyCleanMostRecentTag>
<VerifyCleanMostRecentTag Condition="'$(VerifyMostRecentTagExitCode)' == '0' and !$(VerifyMostRecentTag.StartsWith('v'))">$(VerifyMostRecentTag)</VerifyCleanMostRecentTag>
<ExpectedSdkVersion Condition="'$(VerifyCurrentTagExitCode)' == '0'">$(VerifyCleanCurrentTag)</ExpectedSdkVersion>
<ExpectedSdkVersion Condition="'$(VerifyCurrentTagExitCode)' != '0' and '$(VerifyMostRecentTagExitCode)' == '0'">$(VerifyCleanMostRecentTag)-$(VerifyGitSha)</ExpectedSdkVersion>
<ExpectedSdkVersion Condition="'$(VerifyCurrentTagExitCode)' != '0' and '$(VerifyMostRecentTagExitCode)' != '0'">0.0.0-dev-$(VerifyGitSha)</ExpectedSdkVersion>
<ExpectedSdkVersion Condition="'$(VerifyIsDirty)' == 'true'">$(ExpectedSdkVersion)-dirty</ExpectedSdkVersion>
</PropertyGroup>
<!-- Create a small verification script -->
<PropertyGroup>
<VersionVerifierScript>
using System;
using System.Reflection;
using System.IO;
var assemblyPath = "$(TargetPath)";
var assembly = Assembly.LoadFrom(assemblyPath);
// Access the internal SdkVersion class via reflection
var sdkVersionType = assembly.GetType("Braintrust.Sdk.SdkVersion");
if (sdkVersionType == null) {
Console.Error.WriteLine("ERROR: SdkVersion type not found");
Environment.Exit(1);
}
var versionProperty = sdkVersionType.GetProperty("Version", BindingFlags.Public | BindingFlags.Static);
if (versionProperty == null) {
Console.Error.WriteLine("ERROR: Version property not found");
Environment.Exit(1);
}
var version = versionProperty.GetValue(null) as string;
if (string.IsNullOrEmpty(version)) {
Console.Error.WriteLine("ERROR: Version is null or empty");
Environment.Exit(1);
}
Console.WriteLine(version);
</VersionVerifierScript>
<VersionVerifierScriptFile>$(IntermediateOutputPath)VerifyVersion.csx</VersionVerifierScriptFile>
</PropertyGroup>
<!-- Write the verification script to a file -->
<WriteLinesToFile File="$(VersionVerifierScriptFile)" Lines="$(VersionVerifierScript)" Overwrite="true" />
<!-- Execute the verification script using dotnet-script or inline -->
<!-- For simplicity, we'll use a PowerShell/bash script to run dotnet exec with the script -->
<Exec Command="dotnet exec $(TargetPath) || dotnet exec --runtimeconfig $(TargetDir)$(TargetName).runtimeconfig.json $(TargetPath)"
IgnoreExitCode="true"
ConsoleToMSBuild="true"
ContinueOnError="true">
<Output TaskParameter="ConsoleOutput" PropertyName="DotnetExecOutput" />
<Output TaskParameter="ExitCode" PropertyName="DotnetExecExitCode" />
</Exec>
<!-- If dotnet exec doesn't work (expected for libraries), use a custom approach -->
<!-- We'll compile and run the verification script -->
<Exec Command="dotnet exec --runtimeconfig $(TargetDir)$(TargetName).runtimeconfig.json --depsfile $(TargetDir)$(TargetName).deps.json $(TargetPath)"
IgnoreExitCode="true"
ConsoleToMSBuild="true"
ContinueOnError="true"
Condition="'$(DotnetExecExitCode)' != '0'">
<Output TaskParameter="ConsoleOutput" PropertyName="FallbackExecOutput" />
<Output TaskParameter="ExitCode" PropertyName="FallbackExecExitCode" />
</Exec>
<!-- Since we can't directly exec a library, we'll use a different approach:
Create a temporary console app that loads the assembly and prints the version -->
<PropertyGroup>
<TempVerifierDir>$(IntermediateOutputPath)verifier</TempVerifierDir>
<TempVerifierCode>$(TempVerifierDir)/Program.cs</TempVerifierCode>
<TempVerifierProject>$(TempVerifierDir)/verifier.csproj</TempVerifierProject>
</PropertyGroup>
<MakeDir Directories="$(TempVerifierDir)" />
<!-- Create temporary verifier program -->
<WriteLinesToFile File="$(TempVerifierCode)" Overwrite="true" Lines="
using System%3B
using System.IO%3B
using System.Reflection%3B
var assemblyPath = @"$(TargetPath)"%3B
var assembly = Assembly.LoadFrom(assemblyPath)%3B
var sdkVersionType = assembly.GetType("Braintrust.Sdk.SdkVersion")%3B
if (sdkVersionType == null)
{
var sdkPath = Path.Combine(Path.GetDirectoryName(assemblyPath)!, "Braintrust.Sdk.dll")%3B
if (!File.Exists(sdkPath)) { Console.Error.WriteLine("ERROR: Braintrust.Sdk.dll not found in output directory")%3B Environment.Exit(1)%3B }
var sdkAssembly = Assembly.LoadFrom(sdkPath)%3B
sdkVersionType = sdkAssembly.GetType("Braintrust.Sdk.SdkVersion")%3B
}
if (sdkVersionType == null) { Console.Error.WriteLine("ERROR: SdkVersion type not found")%3B Environment.Exit(1)%3B }
var versionProperty = sdkVersionType.GetProperty("Version", BindingFlags.Public | BindingFlags.Static)%3B
var version = versionProperty.GetValue(null) as string%3B
Console.WriteLine(version)%3B
" />
<!-- Create temporary project file -->
<WriteLinesToFile File="$(TempVerifierProject)" Overwrite="true" Lines="
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(TargetFramework)</TargetFramework>
<EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
</ItemGroup>
</Project>
" />
<!-- Build and run the verifier -->
<Exec Command="dotnet run --project "$(TempVerifierProject)"" ConsoleToMSBuild="true">
<Output TaskParameter="ConsoleOutput" PropertyName="ActualSdkVersion" />
</Exec>
<!-- Trim whitespace from actual version -->
<PropertyGroup>
<ActualSdkVersion>$([System.String]::Copy('$(ActualSdkVersion)').Trim())</ActualSdkVersion>
</PropertyGroup>
<!-- Compare versions -->
<Message Text="Expected version: $(ExpectedSdkVersion)" Importance="high" />
<Message Text="Actual version: $(ActualSdkVersion)" Importance="high" />
<Error Text="Version mismatch! Assembly contains version '$(ActualSdkVersion)' but expected '$(ExpectedSdkVersion)' from git state."
Condition="'$(ActualSdkVersion)' != '$(ExpectedSdkVersion)'" />
<Message Text="✓ Version validation passed: $(ActualSdkVersion)" Importance="high"
Condition="'$(ActualSdkVersion)' == '$(ExpectedSdkVersion)'" />
</Target>
</Project>