Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 57 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Build (Windows)

on:
push:
branches: [ "master", "main" ]
branches: [ "master", "main", "sow/**" ]
pull_request:
branches: [ "master", "main" ]
branches: [ "master", "main", "sow/**" ]
workflow_dispatch:

jobs:
Expand Down Expand Up @@ -35,6 +35,36 @@ jobs:

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Compute SAMVersion
id: ver
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
# 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 }}'
Comment on lines +45 to +47
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Escape branch refs before embedding in PowerShell literals

The Compute SAMVersion step injects ${{ github.head_ref }}, ${{ github.base_ref }}, and ${{ github.ref_name }} directly into single-quoted PowerShell strings; a valid branch name containing an apostrophe (for example feature/o'hare) will break parsing and fail the job before any build starts. This is reachable on pull_request where head_ref is contributor-controlled, so these values need escaping or should be passed through environment variables instead of inlined script literals.

Useful? React with 👍 / 👎.

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.0"
$src = "branch '$ref'"
} else {
$now = (Get-Date).ToUniversalTime()
$quarter = [int][Math]::Ceiling($now.Month / 3.0)
$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)"
"samversion=$v" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8

- name: Clone dependency repos (siblings)
shell: pwsh
Expand All @@ -55,10 +85,32 @@ jobs:
$deps = $buildOrder[0..($buildOrder.Count-2)]
foreach ($r in $deps) {
if (Test-Path $r) { continue }
Write-Host "Cloning https://github.com/$org/$r.git"
git clone --depth 1 "https://github.com/$org/$r.git" $r
$headRef = '${{ github.head_ref }}'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Escape github.head_ref before embedding in PowerShell

The new $headRef = '${{ github.head_ref }}' assignment directly injects the PR branch name into a single-quoted PowerShell literal, so a valid Git branch containing a single quote (for example feature/o'hare) will break parsing and can alter command execution in this step. This is introduced in the new branch-selection logic and affects pull_request runs where github.head_ref is user-controlled; please escape/encode the value (or pass via environment variable) before using it in script code.

Useful? React with 👍 / 👎.

$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'
Comment on lines +88 to +96
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Clone dependencies from current branch on push builds

For push events, github.head_ref is empty, so this logic always falls back to 'sow/2026-Q2' before trying the repo default branch. That means pushes to master/main will still build against the sow/2026-Q2 dependency branch whenever it exists, so CI is no longer validating the dependency set that actually corresponds to the pushed branch and can both mask real regressions and introduce unrelated failures.

Useful? React with 👍 / 👎.

$cloned = $false
Comment on lines +94 to +97
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use base/default branch for non-sow PR dependency clones

For pull_request builds into main/master, $sowRef is empty unless the base starts with sow/, so the candidate list becomes head_ref followed by hardcoded sow/2026-Q2. Because feature branch names usually do not exist in sibling repos, CI will commonly clone sow/2026-Q2 dependencies instead of the target branch/default branch, which means PR validation can run against the wrong dependency graph and miss or introduce regressions unrelated to the PR.

Useful? React with 👍 / 👎.

foreach ($cand in $candidates) {
$has = (git ls-remote --heads "https://github.com/$org/$r.git" $cand 2>$null | Out-String).Trim()
if ($has) {
Write-Host "Cloning $org/$r @ $cand"
git clone --depth 1 --branch $cand "https://github.com/$org/$r.git" $r
$cloned = $true
break
}
}
if (-not $cloned) {
Write-Host "Cloning $org/$r @ default branch"
git clone --depth 1 "https://github.com/$org/$r.git" $r
}
}


# Ensure ReferencePath exists even before SAM_Windows builds
New-Item -ItemType Directory -Force -Path "SAM_Windows\build" | Out-Null

Expand All @@ -77,6 +129,7 @@ jobs:
'/v:m'
'/p:Configuration=Release'
'/p:UseSharedCompilation=false'
'/p:SAMVersion=${{ steps.ver.outputs.samversion }}'
'/p:RunPostBuildEvent=OnOutputUpdated'
"/p:ReferencePath=$windowsRef"
)
Expand Down
57 changes: 57 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<Project>

<PropertyGroup>
<!-- Local dev builds default to 1.0.0.0. CI passes /p:SAMVersion=YYYY.Q.<run_number>.0. -->
<SAMVersion Condition="'$(SAMVersion)' == ''">1.0.0.0</SAMVersion>
<AssemblyVersion>$(SAMVersion)</AssemblyVersion>
<FileVersion>$(SAMVersion)</FileVersion>
<!--
InformationalVersion: the content-identity stamp (SemVer +build metadata).
Composed from SAMVersion + SAMSourceRevision when CI sets the latter. If CI already
set InformationalVersion directly (e.g. SAM_Deploy installer.yml does this), respect
that and don't overwrite. Local dev builds leave both empty -> no SHA attribute emitted.
-->
<InformationalVersion Condition="'$(InformationalVersion)' == '' AND '$(SAMSourceRevision)' != ''">$(SAMVersion)+$(SAMSourceRevision)</InformationalVersion>
<!--
Suppress the SDK's SourceLink auto-append behaviour. By default, when SourceLink is
configured on a project (via NuGet or repo settings), the SDK appends the project's
OWN commit SHA to InformationalVersion (e.g. '2026.2.164.0+998af06.dd02a4c2...').
We set InformationalVersion explicitly to SAM_Deploy's SHA (which encodes all 22
submodule pointers), so the SDK's extra append is noise. False = keep our value clean.
-->
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<Deterministic>true</Deterministic>
</PropertyGroup>

<!--
Projects where SDK assembly-attribute generation is disabled (legacy AssemblyInfo.cs
with GenerateAssemblyInfo=false) OR projects where the SDK doesn't auto-generate
attributes at all (classic-style csprojs that don't set the property — '' evaluates
as not 'true') ignore the AssemblyVersion/FileVersion MSBuild properties above.
Inject the attributes via a generated source file so those assemblies also get
stamped by CI.
-->
<Target Name="_GenerateSAMVersionFile"
BeforeTargets="CoreCompile"
Condition="'$(GenerateAssemblyInfo)' != 'true'">
<ItemGroup>
<_SAMVersionLine Include="// &lt;auto-generated /&gt;" />
<_SAMVersionLine Include="[assembly: System.Reflection.AssemblyVersionAttribute(&quot;$(SAMVersion)&quot;)]" />
<_SAMVersionLine Include="[assembly: System.Reflection.AssemblyFileVersionAttribute(&quot;$(SAMVersion)&quot;)]" />
<!-- Only emit InformationalVersion attribute when CI provided a value (SDK projects
would otherwise get it via PropertyGroup -> SDK auto-gen). -->
<_SAMVersionLine Include="[assembly: System.Reflection.AssemblyInformationalVersionAttribute(&quot;$(InformationalVersion)&quot;)]" Condition="'$(InformationalVersion)' != ''" />
</ItemGroup>
<MakeDir Directories="$(IntermediateOutputPath)" />
<WriteLinesToFile
File="$(IntermediateOutputPath)SAMVersion.g.cs"
Lines="@(_SAMVersionLine)"
Overwrite="true"
WriteOnlyWhenDifferent="true" />
<ItemGroup>
<Compile Include="$(IntermediateOutputPath)SAMVersion.g.cs" KeepDuplicates="false" />
<FileWrites Include="$(IntermediateOutputPath)SAMVersion.g.cs" />
</ItemGroup>
</Target>

</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Grasshopper.Kernel;
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2020–2026 Michal Dengusiak & Jakub Ziolkowski and contributors

using Grasshopper.Kernel;
using System;
using System.Drawing;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
<Deterministic>false</Deterministic>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
Expand Down Expand Up @@ -70,9 +69,7 @@
<Version>8.21.25188.17001</Version>
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.3</Version>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<PropertyGroup />
<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Grasshopper.Kernel;
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2020–2026 Michal Dengusiak & Jakub Ziolkowski and contributors

using Grasshopper.Kernel;
using System;
using System.Drawing;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
<Deterministic>false</Deterministic>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
Expand Down Expand Up @@ -51,9 +50,7 @@
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.3</Version>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<PropertyGroup />
<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Grasshopper.Kernel;
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2020–2026 Michal Dengusiak & Jakub Ziolkowski and contributors

using Grasshopper.Kernel;
using System;
using System.Drawing;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
<Deterministic>false</Deterministic>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
Expand Down Expand Up @@ -58,9 +57,7 @@
<Version>8.21.25188.17001</Version>
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.3</Version>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<PropertyGroup />
<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System.Reflection;
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2020–2026 Michal Dengusiak & Jakub Ziolkowski and contributors

using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<OutputType>Library</OutputType>
<Deterministic>False</Deterministic>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
Expand Down Expand Up @@ -49,15 +48,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<PropertyGroup>
<PostBuildEvent>Copy /Y "$(SolutionDir)references\TopologicCore.dll" "$(SolutionDir)build\TopologicCore.dll"
Copy /Y "$(SolutionDir)references\TK*.dll" "$(SolutionDir)build\TK*.dll"</PostBuildEvent>
<AssemblyTitle>SAM_Topologic</AssemblyTitle>
<Product>SAM_Topologic</Product>
<Copyright>Copyright © 2019</Copyright>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/*
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2020–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.
*
Expand Down
7 changes: 2 additions & 5 deletions SAM_Topologic/SAM.Core.Topologic/SAM.Core.Topologic.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<OutputType>Library</OutputType>
<Deterministic>False</Deterministic>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
Expand Down Expand Up @@ -33,16 +32,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<PropertyGroup>
<PostBuildEvent>Copy /Y "$(SolutionDir)references\TopologicCore.dll" "$(SolutionDir)build\TopologicCore.dll"
Copy /Y "$(SolutionDir)references\TK*.dll" "$(SolutionDir)build\TK*.dll"
Copy /Y "$(SolutionDir)references\tbb*.dll" "$(SolutionDir)build\tbb*.dll"</PostBuildEvent>
<AssemblyTitle>SAM_Topologic</AssemblyTitle>
<Product>SAM_Topologic</Product>
<Copyright>Copyright © 2020</Copyright>
<AssemblyVersion>1.0.%2a</AssemblyVersion>
<FileVersion>1.0.%2a</FileVersion>
<Copyright>Copyright (c) 2020-2026 Michal Dengusiak &amp; Jakub Ziolkowski and contributors</Copyright>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/*
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2020–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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<OutputType>Library</OutputType>
<Deterministic>False</Deterministic>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
Expand All @@ -28,15 +27,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<PropertyGroup>
<PostBuildEvent>Copy /Y "$(SolutionDir)references\TopologicCore.dll" "$(SolutionDir)build\TopologicCore.dll"
Copy /Y "$(SolutionDir)references\TK*.dll" "$(SolutionDir)build\TK*.dll"</PostBuildEvent>
<AssemblyTitle>SAM_Topologic</AssemblyTitle>
<Product>SAM_Topologic</Product>
<Copyright>Copyright © 2020</Copyright>
<AssemblyVersion>1.0.%2a</AssemblyVersion>
<FileVersion>1.0.%2a</FileVersion>
<Copyright>Copyright (c) 2020-2026 Michal Dengusiak &amp; Jakub Ziolkowski and contributors</Copyright>
</PropertyGroup>
</Project>