Skip to content
Closed
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
46 changes: 4 additions & 42 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,52 +1,14 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"statusLine": {
"type": "command",
"command": "pwsh -NoProfile -Command '$input | & (Get-ChildItem $HOME/.claude/plugins/cache/myfoodbag/mfb-statusline/*/statusline-command.ps1 | Select-Object -Last 1)'"
},
"enabledPlugins": {
"mfb-statusline@myfoodbag": true
},
"permissions": {
"allow": [
"Bash(dotnet build:*)",
"Bash(dotnet test:*)",
"Bash(dotnet restore:*)",
"Bash(dotnet pack:*)",
"Bash(dotnet --info)",
"Bash(dotnet --version)",
"Bash(dotnet list:*)",
"Bash(dotnet:*)",
"Bash(./build.ps1:*)",
"Bash(./build.sh:*)",
"Bash(./build.cmd:*)",
"Bash(pwsh ./build.ps1:*)",
"Bash(pwsh -NoProfile ./build.ps1:*)",
"Bash(git status)",
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(git show:*)",
"Bash(git branch:*)",
"Bash(git remote -v)",
"Bash(git rev-parse:*)",
"Bash(git ls-files:*)",
"Bash(git config --get:*)",
"Bash(gh pr list:*)",
"Bash(gh pr view:*)",
"Bash(gh pr diff:*)",
"Bash(gh issue list:*)",
"Bash(gh issue view:*)",
"Bash(gh run list:*)",
"Bash(gh run view:*)",
"Bash(gh workflow list:*)",
"Bash(gh api:*)"
],
"deny": [
"Bash(git push --force:*)",
"Bash(git push -f:*)",
"Bash(git reset --hard:*)",
"Bash(git clean -f:*)",
"Bash(rm -rf:*)"
"Bash(pwsh:*)",
"Bash(git:*)",
"Bash(gh:*)"
]
}
}
4 changes: 2 additions & 2 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
# changelogs, etc.) have no code owner and are gated only by the required CI
# status check.

/src/** @ChrisonSimtian
/tests/** @ChrisonSimtian
/src/** @Fallout-build/maintainers
/tests/** @Fallout-build/maintainers
19 changes: 15 additions & 4 deletions .github/workflows/experimental.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ on:
- '.assets/**'
- '**/*.md'

# Cancel a superseded alpha build when a newer commit lands (#322). Never on release.yml.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

Expand All @@ -44,22 +49,28 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # Nerdbank.GitVersioning needs full history
submodules: recursive
- name: 'Cache: .fallout/temp, ~/.nuget/packages'
uses: actions/cache@v4
with:
path: |
.fallout/temp
~/.nuget/packages
key: ${{ runner.os }}-experimental-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props', 'version.json') }}
restore-keys: |
${{ runner.os }}-experimental-
- name: 'Setup: .NET SDK'
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: 'Restore: dotnet tools'
run: dotnet tool restore
- name: 'Run: Pack'
run: dotnet fallout Pack
# build + unit-test before publishing alpha (#324). One invocation: NUKE runs
# this as discrete internal stages (Restore → Compile → Test → Pack) and fails
# at the breaking stage — separate `dotnet fallout` steps would re-run the
# dependency graph (double-compile), so we keep it a single invocation.
# If Test fails, the job stops here and nothing is published.
- name: 'Run: Test + Pack'
run: dotnet fallout Test Pack
- name: 'Push: all *.nupkg to GitHub Packages (alpha)'
run: |
set -euo pipefail
Expand All @@ -72,7 +83,7 @@ jobs:
for pkg in "${packages[@]}"; do
echo "Pushing $pkg to GitHub Packages (alpha)..."
dotnet nuget push "$pkg" \
--source "https://nuget.pkg.github.com/ChrisonSimtian/index.json" \
--source "https://nuget.pkg.github.com/Fallout-build/index.json" \
--api-key "${{ secrets.GITHUB_TOKEN }}" \
--skip-duplicate
done
14 changes: 11 additions & 3 deletions .github/workflows/macos-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,20 @@ name: macos-latest

on:
push:
tags:
- 'v*'
pull_request:
branches:
- experimental
- main
- 'release/*'
- 'support/*'
paths-ignore:
- 'docs/**'
- '.assets/**'
- '**/*.md'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
macos-latest:
Expand All @@ -31,7 +40,6 @@ jobs:
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
fetch-depth: 0
- name: 'Cache: .fallout/temp, ~/.nuget/packages'
uses: actions/cache@v4
Expand Down
19 changes: 15 additions & 4 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ on:
- '.assets/**'
- '**/*.md'

# Cancel a superseded preview build when a newer commit lands (#322). Never on release.yml.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

Expand All @@ -44,22 +49,28 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # Nerdbank.GitVersioning needs full history
submodules: recursive
- name: 'Cache: .fallout/temp, ~/.nuget/packages'
uses: actions/cache@v4
with:
path: |
.fallout/temp
~/.nuget/packages
key: ${{ runner.os }}-preview-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props', 'version.json') }}
restore-keys: |
${{ runner.os }}-preview-
- name: 'Setup: .NET SDK'
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: 'Restore: dotnet tools'
run: dotnet tool restore
- name: 'Run: Pack'
run: dotnet fallout Pack
# build + unit-test before publishing preview (#324). One invocation: NUKE runs
# this as discrete internal stages (Restore → Compile → Test → Pack) and fails
# at the breaking stage — separate `dotnet fallout` steps would re-run the
# dependency graph (double-compile), so we keep it a single invocation.
# If Test fails, the job stops here and nothing is published.
- name: 'Run: Test + Pack'
run: dotnet fallout Test Pack
- name: 'Push: all *.nupkg to GitHub Packages (preview)'
run: |
set -euo pipefail
Expand All @@ -72,7 +83,7 @@ jobs:
for pkg in "${packages[@]}"; do
echo "Pushing $pkg to GitHub Packages (preview)..."
dotnet nuget push "$pkg" \
--source "https://nuget.pkg.github.com/ChrisonSimtian/index.json" \
--source "https://nuget.pkg.github.com/Fallout-build/index.json" \
--api-key "${{ secrets.GITHUB_TOKEN }}" \
--skip-duplicate
done
5 changes: 3 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,15 @@ jobs:
with:
ref: ${{ inputs.tag || github.ref }}
fetch-depth: 0 # Nerdbank.GitVersioning needs full history
submodules: recursive # vendor/vs-solutionpersistence
- name: 'Cache: .fallout/temp, ~/.nuget/packages'
uses: actions/cache@v4
with:
path: |
.fallout/temp
~/.nuget/packages
key: ${{ runner.os }}-release-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props', 'version.json') }}
restore-keys: |
${{ runner.os }}-release-
- name: 'Setup: .NET SDK'
uses: actions/setup-dotnet@v4
with:
Expand Down Expand Up @@ -198,7 +199,7 @@ jobs:
for pkg in "${packages[@]}"; do
echo "Pushing $pkg to GitHub Packages..."
dotnet nuget push "$pkg" \
--source "https://nuget.pkg.github.com/ChrisonSimtian/index.json" \
--source "https://nuget.pkg.github.com/Fallout-build/index.json" \
--api-key "${{ secrets.GITHUB_TOKEN }}" \
--skip-duplicate
done
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/ubuntu-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ on:
- '.assets/**'
- '**/*.md'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
ubuntu-latest:
name: ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
fetch-depth: 0
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.head_ref }}
Expand Down
14 changes: 11 additions & 3 deletions .github/workflows/windows-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,20 @@ name: windows-latest

on:
push:
tags:
- 'v*'
pull_request:
branches:
- experimental
- main
- 'release/*'
- 'support/*'
paths-ignore:
- 'docs/**'
- '.assets/**'
- '**/*.md'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
windows-latest:
Expand All @@ -31,7 +40,6 @@ jobs:
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
fetch-depth: 0
- name: 'Cache: .fallout/temp, ~/.nuget/packages'
uses: actions/cache@v4
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ The NUKE → Fallout hard fork. Originally NUKE by [@matkoch](https://github.com
### Backwards-compat: Nuke.* transition shims
- **`Nuke.Common` MVP shim package** (#70): thin wrapper assembly in the `Nuke.*` namespace whose types inherit from the corresponding `Fallout.*` types — lets pre-rename consumers compile against the new packages without source changes. Lives at `src/Shims/Nuke.Common/`.
- **`TransitionShimGenerator` source generator** (#69): emits shim type wrappers per-target, covering the Nuke.Common "Easy tier" surface (plain types, interfaces, enums) and static-class method delegation. Hard-tier types (sealed structs, delegates, etc.) raise `SHIM001` warnings with a pointer to `fallout-migrate`.
- **Shim packages publish to GitHub Packages** (#47): `Nuke.*` package IDs belong to matkoch on nuget.org, so the transition shim feed lives at GH Packages (`https://nuget.pkg.github.com/ChrisonSimtian/index.json`). Production-build feed is nuget.org with `Fallout.*` only.
- **Shim packages publish to GitHub Packages** (#47): `Nuke.*` package IDs belong to matkoch on nuget.org, so the transition shim feed lives at GH Packages (`https://nuget.pkg.github.com/Fallout-build/index.json`). Production-build feed is nuget.org with `Fallout.*` only.

### Vendored fork of `Microsoft.VisualStudio.SolutionPersistence`
- **Replaced `matkoch.Microsoft.VisualStudio.SolutionPersistence` with a vendored fork** (#86). The upstream Microsoft package only ships `net472` + `net8.0`; our source generators need `netstandard2.0`. Matt's fork had the netstandard2.0 patches — we forked his repo at [`ChrisonSimtian/vs-solutionpersistence`](https://github.com/ChrisonSimtian/vs-solutionpersistence) (preserves the MIT license + upstream Microsoft history + attribution chain). Sources are a submodule at `vendor/vs-solutionpersistence/`; wrapper csproj at `src/Fallout.VisualStudio.SolutionPersistence/` compiles them with the TFMs we need. Assembly name stays `Microsoft.VisualStudio.SolutionPersistence` so type identity is preserved. (Note: in 10.2 the wrapper packed as `IsPackable=false` and caused the restore bug fixed in 10.3.0 above — known issue, fix-forward.)
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<PackageVersion Include="Azure.Security.KeyVault.Keys" Version="4.8.0" />
<PackageVersion Include="Azure.Security.KeyVault.Secrets" Version="4.8.0" />
<PackageVersion Include="Basic.Reference.Assemblies.NetStandard20" Version="1.7.9" />
<PackageVersion Include="FluentFTP" Version="54.2.0" />
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
<PackageVersion Include="Glob" Version="1.1.9" />
<PackageVersion Include="HtmlAgilityPack" Version="1.11.71" />
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ Generated by [Repobeats](https://repobeats.axiom.co).

### Stars over time

[![Star History Chart](https://api.star-history.com/svg?repos=ChrisonSimtian/Fallout&type=Date)](https://star-history.com/#ChrisonSimtian/Fallout&Date)
[![RepoStars](https://repostars.dev/api/embed?repo=Fallout-build%2FFallout&theme=terminal)](https://repostars.dev/?repos=Fallout-build%2FFallout&theme=terminal)

Generated by [star-history.com](https://star-history.com). Auto-updates as new stargazers arrive.
Generated by [repostars.dev](https://www.repostars.dev/). Auto-updates as new stargazers arrive.

## Sponsorship

Expand Down
44 changes: 29 additions & 15 deletions build/Build.CI.GitHubActions.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
using Fallout.Common.CI.GitHubActions;
using Fallout.Components;

// macOS and Windows runs are reserved for post-merge validation on the
// long-lived branches (experimental, main, release/YYYY, support/*). PRs and
// feature-branch pushes get Linux-only for fast, cheap feedback. Cross-platform
// regressions on those branches surface as a red commit — same fail-fast model.
// Cross-platform (macOS/Windows) full Test+Pack is gated to RELEASE INTENT
// (#318/#326): it runs only on a PR into a production branch (release/YYYY,
// support/*) and on a release tag push (v*) — never on routine pushes to
// main/experimental, never on a per-merge basis. On main/experimental "we've
// got our edge": the ubuntu-latest PR gate + the alpha/preview pipelines.
// (workflow_dispatch as a manual cross-platform trigger isn't emitted here —
// the generator only writes workflow_dispatch when it has inputs; GitHub's
// built-in run re-run covers the on-demand case.)
//
// concurrency cancel-in-progress (#322): superseded runs are cancelled rather
// than stacked. Never applied to release.yml (a publish must not be cancelled).
[GitHubActions(
"macos-latest",
GitHubActionsImage.MacOsLatest,
FetchDepth = 0,
Submodules = GitHubActionsSubmodules.Recursive,
OnPushBranches = new[] { ExperimentalBranch, MainBranch, ReleaseBranchPattern, SupportBranchPattern },
ConcurrencyGroup = "${{ github.workflow }}-${{ github.ref }}",
ConcurrencyCancelInProgress = true,
OnPushTags = new[] { "v*" },
OnPullRequestBranches = new[] { ReleaseBranchPattern, SupportBranchPattern },
OnPullRequestExcludePaths = new[] { "docs/**", ".assets/**", "**/*.md" },
InvokedTargets = new[] { nameof(ITest.Test), nameof(IPack.Pack) },
PublishArtifacts = false)]
[GitHubActions(
"windows-latest",
GitHubActionsImage.WindowsLatest,
FetchDepth = 0,
Submodules = GitHubActionsSubmodules.Recursive,
OnPushBranches = new[] { ExperimentalBranch, MainBranch, ReleaseBranchPattern, SupportBranchPattern },
ConcurrencyGroup = "${{ github.workflow }}-${{ github.ref }}",
ConcurrencyCancelInProgress = true,
OnPushTags = new[] { "v*" },
OnPullRequestBranches = new[] { ReleaseBranchPattern, SupportBranchPattern },
OnPullRequestExcludePaths = new[] { "docs/**", ".assets/**", "**/*.md" },
InvokedTargets = new[] { nameof(ITest.Test), nameof(IPack.Pack) },
PublishArtifacts = false)]
// pull_request only — same-repo branches would otherwise fire both push and
// pull_request events on every push, double-running the validation.
//
// CheckoutRef = github.head_ref pins checkout to the PR source branch instead of the merge SHA,
// keeping HEAD attached so GitHubTasksTest.GitHubRepositoryFromLocalDirectoryTest (which reads
// .git/HEAD via GitRepository.FromLocalDirectory) resolves a non-null branch.
// The Linux PR gate — the only required status check. pull_request only:
// feature-branch pushes run zero CI until a PR is opened against a long-lived
// branch (#327). CheckoutRef = github.head_ref pins checkout to the PR source
// branch instead of the merge SHA, keeping HEAD attached so
// GitHubTasksTest.GitHubRepositoryFromLocalDirectoryTest (which reads .git/HEAD
// via GitRepository.FromLocalDirectory) resolves a non-null branch.
[GitHubActions(
"ubuntu-latest",
GitHubActionsImage.UbuntuLatest,
FetchDepth = 0,
Submodules = GitHubActionsSubmodules.Recursive,
ConcurrencyGroup = "${{ github.workflow }}-${{ github.ref }}",
ConcurrencyCancelInProgress = true,
CheckoutRef = "${{ github.head_ref }}",
// Trigger for PRs targeting experimental, main, or any release/YYYY / support/*
// branch — all are long-lived and protected; all require the ubuntu-latest check.
Expand Down
Loading