From 8cabdfb9ce781de3045c48235db9e4e9669b103b Mon Sep 17 00:00:00 2001 From: Michal Dengusiak Date: Wed, 20 May 2026 19:58:52 +0200 Subject: [PATCH 1/4] build: Directory.Build.props for centralised SAMVersion stamping Mirrors SAM-BIM/SAM#7. Stage 2 of the AssemblyVersion versioning migration. --- .github/workflows/build.yml | 29 +++++++++++++-- Directory.Build.props | 36 +++++++++++++++++++ .../Kernel/AssemblyInfo.cs | 5 ++- .../Properties/AssemblyInfo.cs | 3 -- .../SAM.Analytical.Grasshopper.TMP.csproj | 1 - .../Kernel/AssemblyInfo.cs | 5 ++- .../Properties/AssemblyInfo.cs | 3 -- .../SAM.Core.Grasshopper.TMP.csproj | 1 - .../Properties/AssemblyInfo.cs | 5 ++- .../SAM.Analytical.TMP.csproj | 3 -- .../SAM.Core.TMP/Properties/AssemblyInfo.cs | 5 ++- SAM_TMP/SAM.Core.TMP/SAM.Core.TMP.csproj | 3 -- .../Properties/AssemblyInfo.cs | 5 ++- .../SAM.Geometry.TMP/SAM.Geometry.TMP.csproj | 3 -- 14 files changed, 83 insertions(+), 24 deletions(-) create mode 100644 Directory.Build.props diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 26ab09b..c92fe66 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,9 +2,9 @@ name: Build (Windows) on: push: - branches: [ "master", "main", "sow/2026-Q2" ] + branches: [ "master", "main", "sow/**" ] pull_request: - branches: [ "master", "main", "sow/2026-Q2" ] + branches: [ "master", "main", "sow/**" ] workflow_dispatch: jobs: @@ -35,6 +35,25 @@ jobs: - name: Setup MSBuild uses: microsoft/setup-msbuild@v2 + - name: Compute SAMVersion + id: ver + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $ref = if ('${{ github.event_name }}' -eq 'pull_request') { '${{ github.base_ref }}' } else { '${{ github.ref_name }}' } + # .NET AssemblyVersion components are UInt16 (max 65535). Cap to 60000 for headroom. + $run = ${{ github.run_number }} % 60000 + if ($ref -match 'sow/(\d{4})-Q(\d)') { + $v = "$($Matches[1]).$($Matches[2]).$run" + $src = "branch '$ref'" + } else { + $now = (Get-Date).ToUniversalTime() + $quarter = [int][Math]::Ceiling($now.Month / 3.0) + $v = "$($now.Year).$quarter.$run" + $src = "date $($now.ToString('yyyy-MM-dd')) (ref '$ref' not sow/yyyy-Qx)" + } + Write-Host "SAMVersion = $v (from $src)" + "samversion=$v" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8 - name: Clone dependency repos (siblings) shell: pwsh @@ -56,8 +75,13 @@ jobs: foreach ($r in $deps) { if (Test-Path $r) { continue } $headRef = '${{ github.head_ref }}' + $baseRef = '${{ github.base_ref }}' + $refName = '${{ github.ref_name }}' $candidates = @() if ($headRef) { $candidates += $headRef } + # Current sow branch: base_ref on PR events, ref_name on push events. + $sowRef = if ($baseRef -match '^sow/') { $baseRef } elseif ($refName -match '^sow/') { $refName } else { '' } + if ($sowRef -and $sowRef -ne $headRef) { $candidates += $sowRef } $candidates += 'sow/2026-Q2' $cloned = $false foreach ($cand in $candidates) { @@ -94,6 +118,7 @@ jobs: '/v:m' '/p:Configuration=Release' '/p:UseSharedCompilation=false' + '/p:SAMVersion=${{ steps.ver.outputs.samversion }}' '/p:RunPostBuildEvent=OnOutputUpdated' "/p:ReferencePath=$windowsRef" ) diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..bd157b1 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,36 @@ + + + + + 1.0.0.0 + $(SAMVersion) + $(SAMVersion) + true + + + + + + <_SAMVersionLine Include="// <auto-generated />" /> + <_SAMVersionLine Include="[assembly: System.Reflection.AssemblyVersionAttribute("$(SAMVersion)")]" /> + <_SAMVersionLine Include="[assembly: System.Reflection.AssemblyFileVersionAttribute("$(SAMVersion)")]" /> + + + + + + + + + + diff --git a/Grasshopper/SAM.Analytical.Grasshopper.TMP/Kernel/AssemblyInfo.cs b/Grasshopper/SAM.Analytical.Grasshopper.TMP/Kernel/AssemblyInfo.cs index 4d59577..e060efe 100644 --- a/Grasshopper/SAM.Analytical.Grasshopper.TMP/Kernel/AssemblyInfo.cs +++ b/Grasshopper/SAM.Analytical.Grasshopper.TMP/Kernel/AssemblyInfo.cs @@ -1,4 +1,7 @@ -using Grasshopper.Kernel; +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors + +using Grasshopper.Kernel; using System; using System.Drawing; diff --git a/Grasshopper/SAM.Analytical.Grasshopper.TMP/Properties/AssemblyInfo.cs b/Grasshopper/SAM.Analytical.Grasshopper.TMP/Properties/AssemblyInfo.cs index cd4373a..6fc7b87 100644 --- a/Grasshopper/SAM.Analytical.Grasshopper.TMP/Properties/AssemblyInfo.cs +++ b/Grasshopper/SAM.Analytical.Grasshopper.TMP/Properties/AssemblyInfo.cs @@ -55,6 +55,3 @@ // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Grasshopper/SAM.Analytical.Grasshopper.TMP/SAM.Analytical.Grasshopper.TMP.csproj b/Grasshopper/SAM.Analytical.Grasshopper.TMP/SAM.Analytical.Grasshopper.TMP.csproj index 87b8b9f..98cf142 100644 --- a/Grasshopper/SAM.Analytical.Grasshopper.TMP/SAM.Analytical.Grasshopper.TMP.csproj +++ b/Grasshopper/SAM.Analytical.Grasshopper.TMP/SAM.Analytical.Grasshopper.TMP.csproj @@ -10,7 +10,6 @@ false true true - false false false diff --git a/Grasshopper/SAM.Core.Grasshopper.TMP/Kernel/AssemblyInfo.cs b/Grasshopper/SAM.Core.Grasshopper.TMP/Kernel/AssemblyInfo.cs index d64e096..a5eecbf 100644 --- a/Grasshopper/SAM.Core.Grasshopper.TMP/Kernel/AssemblyInfo.cs +++ b/Grasshopper/SAM.Core.Grasshopper.TMP/Kernel/AssemblyInfo.cs @@ -1,4 +1,7 @@ -using Grasshopper.Kernel; +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors + +using Grasshopper.Kernel; using System; using System.Drawing; diff --git a/Grasshopper/SAM.Core.Grasshopper.TMP/Properties/AssemblyInfo.cs b/Grasshopper/SAM.Core.Grasshopper.TMP/Properties/AssemblyInfo.cs index 0c0032f..874d4fa 100644 --- a/Grasshopper/SAM.Core.Grasshopper.TMP/Properties/AssemblyInfo.cs +++ b/Grasshopper/SAM.Core.Grasshopper.TMP/Properties/AssemblyInfo.cs @@ -55,6 +55,3 @@ // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Grasshopper/SAM.Core.Grasshopper.TMP/SAM.Core.Grasshopper.TMP.csproj b/Grasshopper/SAM.Core.Grasshopper.TMP/SAM.Core.Grasshopper.TMP.csproj index 13098db..715d271 100644 --- a/Grasshopper/SAM.Core.Grasshopper.TMP/SAM.Core.Grasshopper.TMP.csproj +++ b/Grasshopper/SAM.Core.Grasshopper.TMP/SAM.Core.Grasshopper.TMP.csproj @@ -11,7 +11,6 @@ true true C:\Program Files\Rhino 8\System\Rhino.exe - false false false True diff --git a/SAM_TMP/SAM.Analytical.TMP/Properties/AssemblyInfo.cs b/SAM_TMP/SAM.Analytical.TMP/Properties/AssemblyInfo.cs index e46b4e2..c5b13db 100644 --- a/SAM_TMP/SAM.Analytical.TMP/Properties/AssemblyInfo.cs +++ b/SAM_TMP/SAM.Analytical.TMP/Properties/AssemblyInfo.cs @@ -1,4 +1,7 @@ -/* +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors + +/* * This file is part of the Sustaiable Analytical Model (SAM) * Copyright (c) 2020, the respective contributors. All rights reserved. * diff --git a/SAM_TMP/SAM.Analytical.TMP/SAM.Analytical.TMP.csproj b/SAM_TMP/SAM.Analytical.TMP/SAM.Analytical.TMP.csproj index 8720753..7de9420 100644 --- a/SAM_TMP/SAM.Analytical.TMP/SAM.Analytical.TMP.csproj +++ b/SAM_TMP/SAM.Analytical.TMP/SAM.Analytical.TMP.csproj @@ -2,13 +2,10 @@ netstandard2.0 Library - false false SAM.Analytical SAM.Analytical Copyright (c) 2020-2026 Michal Dengusiak & Jakub Ziolkowski and contributors - 1.0.0.0 - 1.0.0.0 false false diff --git a/SAM_TMP/SAM.Core.TMP/Properties/AssemblyInfo.cs b/SAM_TMP/SAM.Core.TMP/Properties/AssemblyInfo.cs index cf1e05d..b147d35 100644 --- a/SAM_TMP/SAM.Core.TMP/Properties/AssemblyInfo.cs +++ b/SAM_TMP/SAM.Core.TMP/Properties/AssemblyInfo.cs @@ -1,4 +1,7 @@ -/* +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors + +/* * This file is part of the Sustaiable Analytical Model (SAM) * Copyright (c) 2020, the respective contributors. All rights reserved. * diff --git a/SAM_TMP/SAM.Core.TMP/SAM.Core.TMP.csproj b/SAM_TMP/SAM.Core.TMP/SAM.Core.TMP.csproj index 7f5935b..53fa88d 100644 --- a/SAM_TMP/SAM.Core.TMP/SAM.Core.TMP.csproj +++ b/SAM_TMP/SAM.Core.TMP/SAM.Core.TMP.csproj @@ -2,13 +2,10 @@ netstandard2.0 Library - false false SAM SAM Copyright (c) 2020-2026 Michal Dengusiak & Jakub Ziolkowski and contributors - 1.0.0.0 - 1.0.0.0 false false diff --git a/SAM_TMP/SAM.Geometry.TMP/Properties/AssemblyInfo.cs b/SAM_TMP/SAM.Geometry.TMP/Properties/AssemblyInfo.cs index cf1e05d..b147d35 100644 --- a/SAM_TMP/SAM.Geometry.TMP/Properties/AssemblyInfo.cs +++ b/SAM_TMP/SAM.Geometry.TMP/Properties/AssemblyInfo.cs @@ -1,4 +1,7 @@ -/* +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors + +/* * This file is part of the Sustaiable Analytical Model (SAM) * Copyright (c) 2020, the respective contributors. All rights reserved. * diff --git a/SAM_TMP/SAM.Geometry.TMP/SAM.Geometry.TMP.csproj b/SAM_TMP/SAM.Geometry.TMP/SAM.Geometry.TMP.csproj index 924393f..de3eb0f 100644 --- a/SAM_TMP/SAM.Geometry.TMP/SAM.Geometry.TMP.csproj +++ b/SAM_TMP/SAM.Geometry.TMP/SAM.Geometry.TMP.csproj @@ -2,13 +2,10 @@ netstandard2.0 Library - false false SAM SAM Copyright (c) 2020-2026 Michal Dengusiak & Jakub Ziolkowski and contributors - 1.0.0.0 - 1.0.0.0 false false From d9fe1380dae709c188b2bc34db5b91874356fe07 Mon Sep 17 00:00:00 2001 From: Michal Dengusiak Date: Wed, 20 May 2026 20:11:38 +0200 Subject: [PATCH 2/4] fix: replace literal u{2013} escape with actual en-dash in SPDX header PowerShell 5.1 doesn't support backtick-u escape sequences; the apply-stage2.ps1 script leaked them as literal text in 'Copyright (c) 2020u{2013}2026'. --- .../SAM.Analytical.Grasshopper.TMP/Kernel/AssemblyInfo.cs | 2 +- Grasshopper/SAM.Core.Grasshopper.TMP/Kernel/AssemblyInfo.cs | 2 +- SAM_TMP/SAM.Analytical.TMP/Properties/AssemblyInfo.cs | 2 +- SAM_TMP/SAM.Core.TMP/Properties/AssemblyInfo.cs | 2 +- SAM_TMP/SAM.Geometry.TMP/Properties/AssemblyInfo.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Grasshopper/SAM.Analytical.Grasshopper.TMP/Kernel/AssemblyInfo.cs b/Grasshopper/SAM.Analytical.Grasshopper.TMP/Kernel/AssemblyInfo.cs index e060efe..177e4f8 100644 --- a/Grasshopper/SAM.Analytical.Grasshopper.TMP/Kernel/AssemblyInfo.cs +++ b/Grasshopper/SAM.Analytical.Grasshopper.TMP/Kernel/AssemblyInfo.cs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors +// Copyright (c) 2020–2026 Michal Dengusiak & Jakub Ziolkowski and contributors using Grasshopper.Kernel; using System; diff --git a/Grasshopper/SAM.Core.Grasshopper.TMP/Kernel/AssemblyInfo.cs b/Grasshopper/SAM.Core.Grasshopper.TMP/Kernel/AssemblyInfo.cs index a5eecbf..5cf95ac 100644 --- a/Grasshopper/SAM.Core.Grasshopper.TMP/Kernel/AssemblyInfo.cs +++ b/Grasshopper/SAM.Core.Grasshopper.TMP/Kernel/AssemblyInfo.cs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors +// Copyright (c) 2020–2026 Michal Dengusiak & Jakub Ziolkowski and contributors using Grasshopper.Kernel; using System; diff --git a/SAM_TMP/SAM.Analytical.TMP/Properties/AssemblyInfo.cs b/SAM_TMP/SAM.Analytical.TMP/Properties/AssemblyInfo.cs index c5b13db..fc1a18b 100644 --- a/SAM_TMP/SAM.Analytical.TMP/Properties/AssemblyInfo.cs +++ b/SAM_TMP/SAM.Analytical.TMP/Properties/AssemblyInfo.cs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors +// Copyright (c) 2020–2026 Michal Dengusiak & Jakub Ziolkowski and contributors /* * This file is part of the Sustaiable Analytical Model (SAM) diff --git a/SAM_TMP/SAM.Core.TMP/Properties/AssemblyInfo.cs b/SAM_TMP/SAM.Core.TMP/Properties/AssemblyInfo.cs index b147d35..2fa9aca 100644 --- a/SAM_TMP/SAM.Core.TMP/Properties/AssemblyInfo.cs +++ b/SAM_TMP/SAM.Core.TMP/Properties/AssemblyInfo.cs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors +// Copyright (c) 2020–2026 Michal Dengusiak & Jakub Ziolkowski and contributors /* * This file is part of the Sustaiable Analytical Model (SAM) diff --git a/SAM_TMP/SAM.Geometry.TMP/Properties/AssemblyInfo.cs b/SAM_TMP/SAM.Geometry.TMP/Properties/AssemblyInfo.cs index b147d35..2fa9aca 100644 --- a/SAM_TMP/SAM.Geometry.TMP/Properties/AssemblyInfo.cs +++ b/SAM_TMP/SAM.Geometry.TMP/Properties/AssemblyInfo.cs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (c) 2020u{2013}2026 Michal Dengusiak & Jakub Ziolkowski and contributors +// Copyright (c) 2020–2026 Michal Dengusiak & Jakub Ziolkowski and contributors /* * This file is part of the Sustaiable Analytical Model (SAM) From 5f5d9de942af599d31d13e5f8ebcadb6777f76f6 Mon Sep 17 00:00:00 2001 From: Michal Dengusiak Date: Wed, 20 May 2026 20:36:06 +0200 Subject: [PATCH 3/4] fix: relax SAMVersion.g.cs Target condition to != 'true' Codex P1 on SAM_LadybugTools#4: classic (non-SDK) csprojs don't set GenerateAssemblyInfo at all, so the previous '== false' condition skipped them. Switching to '!= true' catches both GenerateAssemblyInfo=false (SDK projects with legacy AssemblyInfo.cs) AND empty (classic projects). --- Directory.Build.props | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index bd157b1..9841655 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -9,13 +9,16 @@ + Condition="'$(GenerateAssemblyInfo)' != 'true'"> <_SAMVersionLine Include="// <auto-generated />" /> <_SAMVersionLine Include="[assembly: System.Reflection.AssemblyVersionAttribute("$(SAMVersion)")]" /> From c1b26e942d51cf28396b33805c0c67f57d3f566e Mon Sep 17 00:00:00 2001 From: Michal Dengusiak Date: Wed, 20 May 2026 20:39:45 +0200 Subject: [PATCH 4/4] =?UTF-8?q?ci:=20Codex=20P2=20fixes=20=E2=80=94=20four?= =?UTF-8?q?-part=20SAMVersion,=20prefer=20head=5Fref=20for=20sow=20PRs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Append .0 so SAMVersion is 4-part (AssemblyFileVersion expects 4 parts). - Prefer github.head_ref when it matches sow/yyyy-Qx (release-promotion PRs). - Mirrors SAM sow/2026-Q2 6d87d98e. --- .github/workflows/build.yml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c92fe66..d16b29a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,16 +40,27 @@ jobs: shell: pwsh run: | $ErrorActionPreference = 'Stop' - $ref = if ('${{ github.event_name }}' -eq 'pull_request') { '${{ github.base_ref }}' } else { '${{ github.ref_name }}' } + # Prefer head_ref when its a sow branch (release-promotion PRs from sow/* to main), + # else use base_ref on PR events / ref_name on push events. + $headRef = '${{ github.head_ref }}' + $baseRef = '${{ github.base_ref }}' + $refName = '${{ github.ref_name }}' + if ($headRef -match '^sow/\d{4}-Q\d$') { + $ref = $headRef + } elseif ('${{ github.event_name }}' -eq 'pull_request') { + $ref = $baseRef + } else { + $ref = $refName + } # .NET AssemblyVersion components are UInt16 (max 65535). Cap to 60000 for headroom. $run = ${{ github.run_number }} % 60000 if ($ref -match 'sow/(\d{4})-Q(\d)') { - $v = "$($Matches[1]).$($Matches[2]).$run" + $v = "$($Matches[1]).$($Matches[2]).$run.0" $src = "branch '$ref'" } else { $now = (Get-Date).ToUniversalTime() $quarter = [int][Math]::Ceiling($now.Month / 3.0) - $v = "$($now.Year).$quarter.$run" + $v = "$($now.Year).$quarter.$run.0" $src = "date $($now.ToString('yyyy-MM-dd')) (ref '$ref' not sow/yyyy-Qx)" } Write-Host "SAMVersion = $v (from $src)"