Skip to content
Merged
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
45 changes: 45 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"permissions": {
"allow": [
"Read(//C:/GitHub/**)",
"Read(//C:/Program Files/Microsoft Visual Studio/**)",

"Edit(/GeoMagGUI/**)",
"Edit(/GeoMagSharp/**)",
"Edit(/GeoMagSharp-UnitTests/**)",
"Edit(/Installer/**)",
"Edit(/docs/**)",
"Edit(/.github/**)",
"Edit(/.claude/**)",
"Edit(/*.md)",
"Edit(/*.sln)",
"Edit(/*.props)",
"Edit(/*.json)",
"Edit(/.gitignore)",

"Bash(msbuild *)",
"Bash(\"C:/Program Files/Microsoft Visual Studio/2022/Community/MSBuild/Current/Bin/MSBuild.exe\" *)",
"Bash(vstest.console.exe *)",
"Bash(\"C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TestWindow/vstest.console.exe\" *)",
"Bash(nuget *)",
"Bash(git status *)",
"Bash(git log *)",
"Bash(git diff *)",
"Bash(git branch *)",
"Bash(git checkout *)",
"Bash(git stash *)",
"Bash(git ls-tree *)",
"Bash(git remote *)",
"Bash(gh pr *)",
"Bash(gh issue *)",
"Bash(gh api *)",
"Bash(gh run *)"
],
"deny": [
"Bash(git push --force *)",
"Bash(git reset --hard *)",
"Bash(rm -rf *)",
"Bash(del /s *)"
]
}
}
165 changes: 14 additions & 151 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
name: Build and Package
name: Build and Test

on:
push:
branches: [ master, preview ]
branches: [ development, 'feature/**' ]
pull_request:
branches: [ master, preview ]
branches: [ development ]
workflow_dispatch:

env:
SOLUTION_FILE: GeoMagGUI.sln
MAIN_PROJECT: GeoMagGUI
CONFIGURATION: Release

jobs:
build:
build-and-test:
runs-on: windows-latest
outputs:
full_version: ${{ steps.version.outputs.full_version }}
artifact_suffix: ${{ steps.version.outputs.artifact_suffix }}

steps:
- name: Checkout code
Expand All @@ -29,41 +25,20 @@ jobs:
id: version
shell: pwsh
run: |
# Read base version from Version.props
[xml]$versionProps = Get-Content "Version.props"
$major = $versionProps.Project.PropertyGroup.MajorVersion
$minor = $versionProps.Project.PropertyGroup.MinorVersion
$patch = $versionProps.Project.PropertyGroup.PatchVersion

$baseVersion = "$major.$minor.$patch"

# Determine channel and build number based on branch
$branch = "${{ github.ref_name }}"
$runNumber = "${{ github.run_number }}"
$fullVersion = "$baseVersion.$runNumber"
$version = "$baseVersion-dev.$runNumber"

if ($branch -eq "master") {
$channel = "release"
$fullVersion = "$baseVersion.0"
$artifactSuffix = ""
} elseif ($branch -eq "preview") {
$channel = "preview"
$fullVersion = "$baseVersion.$runNumber"
$artifactSuffix = "-preview.$runNumber"
} else {
$channel = "dev"
$fullVersion = "$baseVersion.$runNumber"
$artifactSuffix = "-dev.$runNumber"
}

Write-Host "Branch: $branch"
Write-Host "Channel: $channel"
Write-Host "Version: $version"
Write-Host "Full Version: $fullVersion"
Write-Host "Artifact Suffix: $artifactSuffix"

echo "base_version=$baseVersion" >> $env:GITHUB_OUTPUT
echo "full_version=$fullVersion" >> $env:GITHUB_OUTPUT
echo "channel=$channel" >> $env:GITHUB_OUTPUT
echo "artifact_suffix=$artifactSuffix" >> $env:GITHUB_OUTPUT
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
echo "FULL_VERSION=$fullVersion" >> $env:GITHUB_OUTPUT

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
Expand All @@ -77,16 +52,14 @@ jobs:
- name: Update AssemblyInfo versions
shell: pwsh
run: |
$version = "${{ steps.version.outputs.full_version }}"
$version = "${{ steps.version.outputs.FULL_VERSION }}"

# Update GeoMagGUI AssemblyInfo
$guiAssemblyInfo = "GeoMagGUI\Properties\AssemblyInfo.cs"
$content = Get-Content $guiAssemblyInfo -Raw
$content = $content -replace 'AssemblyVersion\("[^"]+"\)', "AssemblyVersion(`"$version`")"
$content = $content -replace 'AssemblyFileVersion\("[^"]+"\)', "AssemblyFileVersion(`"$version`")"
Set-Content $guiAssemblyInfo $content -NoNewline

# Update GeoMagSharp AssemblyInfo
$sharpAssemblyInfo = "GeoMagSharp\Properties\AssemblyInfo.cs"
$content = Get-Content $sharpAssemblyInfo -Raw
$content = $content -replace 'AssemblyVersion\("[^"]+"\)', "AssemblyVersion(`"$version`")"
Expand All @@ -99,13 +72,10 @@ jobs:
run: msbuild ${{ env.SOLUTION_FILE }} /p:Configuration=${{ env.CONFIGURATION }} /p:Platform="Mixed Platforms" /m

- name: Run tests
continue-on-error: true
shell: pwsh
run: |
# Find VSTest console
$vsTestPath = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Workload.ManagedDesktop -find Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe
if (-not $vsTestPath) {
# Fallback to common paths
$vsTestPath = Get-ChildItem -Path "${env:ProgramFiles}\Microsoft Visual Studio" -Recurse -Filter "vstest.console.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
}

Expand All @@ -115,118 +85,11 @@ jobs:
Write-Host "VSTest not found, skipping tests"
}

- name: Upload test results
- name: Upload test results (only on failure)
uses: actions/upload-artifact@v4
if: always()
if: failure()
with:
name: test-results${{ steps.version.outputs.artifact_suffix }}
name: test-results-dev-${{ steps.version.outputs.VERSION }}
path: TestResults/*.trx
if-no-files-found: ignore

# Installer steps only run on push events (not pull requests)
- name: Install WiX Toolset
if: github.event_name == 'push'
shell: pwsh
run: |
dotnet tool install --global wix --version 5.0.2

- name: Generate WiX file components
if: github.event_name == 'push'
shell: pwsh
run: |
$buildOutput = "GeoMagGUI\bin\Release"
$version = "${{ steps.version.outputs.full_version }}"

# Run the component generation script
& "Installer\Generate-FileComponents.ps1" -BuildOutputPath $buildOutput -Version $version

- name: Build MSI installer
if: github.event_name == 'push'
shell: pwsh
run: |
$version = "${{ steps.version.outputs.full_version }}"
$channel = "${{ steps.version.outputs.channel }}"

cd Installer

# Build the MSI
wix build -arch x86 `
-d Version=$version `
-d Channel=$channel `
-d BuildOutput=..\GeoMagGUI\bin\Release `
-out ..\artifacts\GeoMagGUI${{ steps.version.outputs.artifact_suffix }}.msi `
Product.wxs `
FileComponents.wxs

- name: Upload MSI artifact
if: github.event_name == 'push'
uses: actions/upload-artifact@v4
with:
name: GeoMagGUI${{ steps.version.outputs.artifact_suffix }}-msi
path: artifacts/*.msi

- name: Upload build output
if: github.event_name == 'push'
uses: actions/upload-artifact@v4
with:
name: GeoMagGUI${{ steps.version.outputs.artifact_suffix }}-bin
path: |
GeoMagGUI/bin/Release/
!GeoMagGUI/bin/Release/**/*.pdb

create-release:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master' && github.event_name == 'push'

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Download MSI artifact
uses: actions/download-artifact@v4
with:
name: GeoMagGUI-msi
path: artifacts

- name: Generate release notes
shell: bash
run: |
cat > release_notes.md << EOF
## What's New in v${{ needs.build.outputs.full_version }}

### Features & Improvements
- Added support for WMM2020+ coefficient file format (Issue #1)
- Upgraded to .NET Framework 4.8
- Added CI/CD pipeline with automated MSI installer generation
- Added comprehensive unit tests for Calculator and ModelReader classes

### Bug Fixes
- Fixed critical latitude/longitude type mismatch in DMS input (Issue #2)
- Fixed cursor management with try-finally blocks (Issue #4)
- Fixed decimal date to DateTime conversion rounding issue
- Added input validation to ModelReader with detailed error messages (Issue #5)

### Issues Resolved
- #1 - NOAA WMM2020 coefficient file support
- #2 - Type mismatch: Longitude constructor used for Latitude
- #3 - Add unit tests for Calculator class
- #4 - Add try-finally for cursor management
- #5 - Add input validation to ModelReader

---
*Full changelog available in the [commit history](https://github.com/${{ github.repository }}/commits/master)*
EOF

- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.build.outputs.full_version }}
name: GeoMag # ${{ needs.build.outputs.full_version }}
body_path: release_notes.md
draft: false
files: artifacts/*.msi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
retention-days: 3
122 changes: 122 additions & 0 deletions .github/workflows/preview-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: Preview Release

on:
push:
branches: [ preview ]
workflow_dispatch:

permissions:
contents: write

env:
SOLUTION_FILE: GeoMagGUI.sln
CONFIGURATION: Release

jobs:
build-and-release:
runs-on: windows-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Calculate version
id: version
shell: pwsh
run: |
[xml]$versionProps = Get-Content "Version.props"
$major = $versionProps.Project.PropertyGroup.MajorVersion
$minor = $versionProps.Project.PropertyGroup.MinorVersion
$patch = $versionProps.Project.PropertyGroup.PatchVersion
$baseVersion = "$major.$minor.$patch"
$runNumber = "${{ github.run_number }}"
$fullVersion = "$baseVersion.$runNumber"
$version = "$baseVersion-preview.$runNumber"
Write-Host "Version: $version"
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
echo "FULL_VERSION=$fullVersion" >> $env:GITHUB_OUTPUT

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2

- name: Setup NuGet
uses: NuGet/setup-nuget@v2

- name: Restore NuGet packages
run: nuget restore ${{ env.SOLUTION_FILE }}

- name: Update AssemblyInfo versions
shell: pwsh
run: |
$version = "${{ steps.version.outputs.FULL_VERSION }}"
foreach ($path in @("GeoMagGUI\Properties\AssemblyInfo.cs", "GeoMagSharp\Properties\AssemblyInfo.cs")) {
$content = Get-Content $path -Raw
$content = $content -replace 'AssemblyVersion\("[^"]+"\)', "AssemblyVersion(`"$version`")"
$content = $content -replace 'AssemblyFileVersion\("[^"]+"\)', "AssemblyFileVersion(`"$version`")"
Set-Content $path $content -NoNewline
}
Write-Host "Updated assembly versions to $version"

- name: Build solution
run: msbuild ${{ env.SOLUTION_FILE }} /p:Configuration=${{ env.CONFIGURATION }} /p:Platform="Mixed Platforms" /m

- name: Run tests
shell: pwsh
run: |
$vsTestPath = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Workload.ManagedDesktop -find Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe
if (-not $vsTestPath) {
$vsTestPath = Get-ChildItem -Path "${env:ProgramFiles}\Microsoft Visual Studio" -Recurse -Filter "vstest.console.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
}
if ($vsTestPath) {
& $vsTestPath "GeoMagSharp-UnitTests\bin\Release\GeoMagSharp-UnitTests.dll" --logger:trx --ResultsDirectory:TestResults
} else {
Write-Host "VSTest not found, skipping tests"
}

- name: Install WiX Toolset
shell: pwsh
run: dotnet tool install --global wix --version 5.0.2

- name: Generate WiX file components
shell: pwsh
run: |
$buildOutput = "GeoMagGUI\bin\Release"
$version = "${{ steps.version.outputs.FULL_VERSION }}"
& "Installer\Generate-FileComponents.ps1" -BuildOutputPath $buildOutput -Version $version

- name: Build MSI installer
shell: pwsh
run: |
$version = "${{ steps.version.outputs.FULL_VERSION }}"
cd Installer
wix build -arch x86 -d Version=$version -d Channel=preview -d BuildOutput=..\GeoMagGUI\bin\Release -out ..\artifacts\GeoMagGUI-${{ steps.version.outputs.VERSION }}.msi Product.wxs FileComponents.wxs

- name: Generate release notes
shell: pwsh
run: |
$lastTag = $null
try { $lastTag = git describe --tags --match "v*-preview.*" --abbrev=0 2>$null } catch { }
if ($lastTag) { $commits = git log --oneline "$lastTag..HEAD" 2>$null }
else { $commits = git log --oneline -20 2>$null }
$version = "${{ steps.version.outputs.VERSION }}"
$notes = "Preview Release $version`n`n### Changes`n"
if ($commits) { $commits -split "`n" | ForEach-Object { $l = $_.Trim(); if ($l) { $notes += "- $l`n" } } }
else { $notes += "- Build from latest preview branch`n" }
Set-Content -Path "release-notes.md" -Value $notes -Encoding UTF8

- name: Create GitHub Pre-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: pwsh
run: |
$version = "${{ steps.version.outputs.VERSION }}"
gh release create "v$version" "artifacts\GeoMagGUI-$version.msi" --title "GeoMag GUI $version" --notes-file "release-notes.md" --prerelease

- name: Upload MSI artifact
uses: actions/upload-artifact@v4
with:
name: GeoMagGUI-preview-${{ steps.version.outputs.VERSION }}-msi
path: artifacts/*.msi
retention-days: 90
Loading