Skip to content

feat(charts): the three chart tools become embeddable, feature-gated … #30

feat(charts): the three chart tools become embeddable, feature-gated …

feat(charts): the three chart tools become embeddable, feature-gated … #30

# Proves the `dotnet new daxalgo-strategy` template scaffolds a plugin that BUILDS, TESTS, and PACKS —
# both variants (headless + --ui). Two jobs:
#
# * in-repo — installs the template from THIS checkout, checks the template's pinned SDK version
# tracks the repo's DaxAlgoSdkVersion (the anti-drift guard — a version bump that
# forgets the template fails here), then scaffolds + builds + tests + packs both
# variants and asserts the identity rule (no host DLLs in the plugin output). Every PR.
# * published — installs `DaxAlgo.Templates` from NuGet.org and scaffolds against the PUBLISHED
# packages with NO repo checkout (pure NuGet resolution). Gated behind schedule +
# manual dispatch so a version-bump PR doesn't fail here before the version is live.
name: template-smoke
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Mondays 06:00 UTC — catch a broken published chain
workflow_dispatch:
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
# ── Anti-drift: the in-repo template must scaffold + build + test + pack, both variants ────────────
in-repo:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: AI context pack + template CLAUDE/AGENTS are regenerated (no drift)
shell: pwsh
run: |
pwsh build/gen-ai-context.ps1
$generated = @(
'sdk/ai-context/daxalgo-strategy-context.md',
'templates/content/daxalgo-strategy/CLAUDE.md',
'templates/content/daxalgo-strategy/AGENTS.md'
)
$diff = git status --porcelain -- $generated
if ($diff) { git --no-pager diff -- $generated; throw "AI context is stale - run 'pwsh build/gen-ai-context.ps1' and commit." }
Write-Host "AI context pack + template CLAUDE.md/AGENTS.md are current."
- name: Template pins the current SDK version
shell: pwsh
run: |
# A fresh scaffold must reference a PUBLISHED SDK, and that version must track the repo's
# SdkInfo.Version / DaxAlgoSdkVersion — otherwise a bump silently orphans the template.
$ver = (Select-String -Path Directory.Build.props -Pattern '<DaxAlgoSdkVersion>([^<]+)</DaxAlgoSdkVersion>').Matches[0].Groups[1].Value
$csproj = 'templates/content/daxalgo-strategy/DaxNewStrategy/DaxNewStrategy.csproj'
$pinned = Select-String -Path $csproj -Pattern 'Include="DaxAlgo\.Sdk(?:\.Wpf)?" Version="([^"]+)"' -AllMatches |
ForEach-Object { $_.Matches } | ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique
if ($pinned -contains $ver -and $pinned.Count -eq 1) { Write-Host "Template pins $ver (matches DaxAlgoSdkVersion)." }
else { throw "Template SDK pin(s) [$($pinned -join ', ')] != DaxAlgoSdkVersion ($ver). Bump the template's PackageReference versions." }
- name: Install the template from source
shell: pwsh
run: dotnet new install ./templates/content/daxalgo-strategy --force
- name: Scaffold + build + test + pack (headless and --ui)
shell: pwsh
run: |
$work = "$env:RUNNER_TEMP/scaffold"
New-Item -ItemType Directory -Force $work | Out-Null
foreach ($variant in @(@{ name = 'HeadlessPlug'; ui = $false }, @{ name = 'UiPlug'; ui = $true })) {
$out = Join-Path $work $variant.name
$newArgs = @('new', 'daxalgo-strategy', '-n', $variant.name, '-o', $out)
if ($variant.ui) { $newArgs += '--ui' }
& dotnet @newArgs; if ($LASTEXITCODE -ne 0) { throw "scaffold failed: $($variant.name)" }
$sln = Get-ChildItem -Recurse $out -Filter '*.slnx' | Select-Object -First 1
dotnet build $sln.FullName -c Release; if ($LASTEXITCODE -ne 0) { throw "build failed: $($variant.name)" }
dotnet test $sln.FullName -c Release --no-build; if ($LASTEXITCODE -ne 0) { throw "test failed: $($variant.name)" }
$pack = Get-ChildItem -Recurse $out -Filter 'pack-plugin.ps1' | Select-Object -First 1
& $pack.FullName -Configuration Release; if ($LASTEXITCODE -ne 0) { throw "pack failed: $($variant.name)" }
if (-not (Get-ChildItem -Recurse $out -Filter '*.daxplugin')) { throw "no .daxplugin produced: $($variant.name)" }
# Identity rule: the plugin's build output must ship NONE of the host's contract assemblies.
$bin = Get-ChildItem -Recurse $out -Directory | Where-Object { $_.FullName -match 'bin\\Release\\net9.0-windows7.0$' } | Select-Object -First 1
$leaked = Get-ChildItem $bin.FullName -Filter *.dll | Where-Object { $_.Name -match '^(TradingTerminal|DaxAlgo|MahApps|ControlzEx|ScottPlot)' }
if ($leaked) { throw "identity rule broken - host DLLs in $($variant.name) output: $($leaked.Name -join ', ')" }
Write-Host "$($variant.name): scaffolded, built, tested, packed; bin is clean."
}
# ── CLI: the daxalgo strategy tool drives scaffold -> build -> test -> package with the fake provider ─
cli:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: Install the template from source
shell: pwsh
run: dotnet new install ./templates/content/daxalgo-strategy --force
- name: daxalgo strategy ai --provider fake (scaffold -> build -> test -> package)
shell: pwsh
run: |
$tool = 'src/windows/Tools/DaxAlgo.StrategyTool/DaxAlgo.StrategyTool.csproj'
$work = "$env:RUNNER_TEMP/cli"
New-Item -ItemType Directory -Force $work | Out-Null
Push-Location $work
try {
dotnet run --project "$env:GITHUB_WORKSPACE/$tool" -- strategy ai --name CliDemo --provider fake
if ($LASTEXITCODE -ne 0) { throw 'daxalgo strategy ai --provider fake failed' }
if (-not (Get-ChildItem -Recurse -Filter '*.daxplugin')) { throw 'no .daxplugin produced' }
Write-Host 'CLI ai --provider fake: scaffold -> build -> test -> package OK.'
} finally { Pop-Location }
# ── Published: scaffold from NuGet.org with no repo checkout (pure package resolution) ─────────────
published:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: windows-latest
steps:
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: Install the template from NuGet.org
shell: pwsh
run: dotnet new install DaxAlgo.Templates --force
- name: Scaffold + build + test against the published packages (headless and --ui)
shell: pwsh
run: |
$work = "$env:RUNNER_TEMP/scaffold"
New-Item -ItemType Directory -Force $work | Out-Null
foreach ($variant in @(@{ name = 'HeadlessPlug'; ui = $false }, @{ name = 'UiPlug'; ui = $true })) {
$out = Join-Path $work $variant.name
$newArgs = @('new', 'daxalgo-strategy', '-n', $variant.name, '-o', $out)
if ($variant.ui) { $newArgs += '--ui' }
& dotnet @newArgs; if ($LASTEXITCODE -ne 0) { throw "scaffold failed: $($variant.name)" }
$sln = Get-ChildItem -Recurse $out -Filter '*.slnx' | Select-Object -First 1
dotnet build $sln.FullName -c Release; if ($LASTEXITCODE -ne 0) { throw "build failed: $($variant.name)" }
dotnet test $sln.FullName -c Release --no-build; if ($LASTEXITCODE -ne 0) { throw "test failed: $($variant.name)" }
Write-Host "$($variant.name): built + tested against the published SDK."
}