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
1 change: 1 addition & 0 deletions .github/workflows/ubuntu-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
with:
submodules: recursive
fetch-depth: 0
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.head_ref }}
- name: 'Cache: .fallout/temp, ~/.nuget/packages'
uses: actions/cache@v4
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- **Retired `GitVersion.Tool`** (#81) — version is now sourced exclusively from `Nerdbank.GitVersioning` via `version.json`. `MajorMinorPatchVersion` and friends in `Build.cs` read NB.GV's `$(Version)` MSBuild output.
- **Trimmed unused / replaceable dependencies** (#75, #78, #79, #80, #82): dropped `JetBrains.ReSharper.GlobalTools`, the matkoch Spectre.Console fork (swapped for upstream `Spectre.Console`), `Microsoft.ApplicationInsights`, `Codecov.Tool`, and `xunit.runner.console`. See `docs/dependencies.md` for the current graph.
- **Bumped Scriban 7.1.0 → 7.2.0** (#84) to clear NU1903.
- **Fixed `[GitHubActions]` `CheckoutRef` breaking cross-repo / fork PRs**. The generator emitted `ref: ${{ github.head_ref }}` but didn't set `repository:`, so the default `${{ github.repository }}` was used. For PRs from a fork, the source branch only exists on the fork; checkout tried to resolve it on origin and failed with "branch or tag could not be found" (regressed in #175). Generator now also emits `repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}` whenever `CheckoutRef` is set — works for fork PRs, same-repo PRs, AND push events (the `||` fallback). Regenerate via any `dotnet fallout <target>` to pick up the fix.
- **Fixed `fallout-migrate` producing unrestorable `_build.csproj`** (closes #217). The Nuke → Fallout namespace rewrite carried the original NUKE `Version="10.1.0"` pins onto `Fallout.*` packages — but `Fallout.*` was never published at `10.1.0`, so NuGet hit NU1603 ("not found, falling back to next-higher") and `WarningsAsErrors` in the migrated project escalated to fatal. Migrate now bumps inline `Version="..."` attributes on Nuke → Fallout PackageReferences to the running migrate tool's own version in the same regex pass, and strips the stale `System.Security.Cryptography.Xml` `<PackageReference>` (NUKE-era projects often pinned an older major that conflicts with `Fallout.Common`'s transitive ≥ 10.0.6 — NU1605 downgrade). CPM-managed references (no inline Version) keep namespace-only rewrite — version stays in Directory.Packages.props.

## [10.2.0] / 2026-05-21
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ public class GitHubActionsCheckoutStep : GitHubActionsStep
/// (the merge SHA on pull_request triggers, which leaves HEAD detached). Set to
/// <c>${{ github.head_ref }}</c> on PR workflows that read <c>.git/HEAD</c> directly
/// (e.g. <see cref="Fallout.Common.Git.GitRepository.FromLocalDirectory"/>) so the branch
/// resolves correctly.
/// resolves correctly. When set, the generator also emits a <c>repository:</c> line that
/// resolves to the PR head's repo for fork PRs and falls back to the current repo for push
/// events — without it, fork PRs fail with "branch or tag could not be found" because the
/// branch only exists on the fork, not on origin.
/// </summary>
public string Ref { get; set; }

Expand All @@ -49,7 +52,16 @@ public override void Write(CustomFileWriter writer)
if (!Filter.IsNullOrWhiteSpace())
writer.WriteLine($"filter: {Filter}");
if (!Ref.IsNullOrWhiteSpace())
{
// Pin checkout to the source repo of the PR head (or the current repo on
// push events). Required when `ref:` is set to `${{ github.head_ref }}` —
// for cross-repo PRs, that branch only exists on the fork, not on origin,
// and checkout's default `repository: ${{ github.repository }}` would fail
// to resolve it. The `||` fallback handles push events where there's no
// pull_request context.
writer.WriteLine("repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}");
writer.WriteLine($"ref: {Ref}");
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ public string Filter
/// Forwarded to <c>actions/checkout</c>'s <c>ref</c> input. Set to
/// <c>${{ github.head_ref }}</c> on PR-triggered workflows that need <c>.git/HEAD</c>
/// to stay attached (e.g. ones that read the current branch via GitRepository).
/// <para/>
/// When set, the generator also emits <c>repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}</c>
/// so cross-repo PRs (from forks) resolve the branch name on the fork instead of failing
/// on origin. The fallback to <c>github.repository</c> keeps push-triggered workflows
/// (where there's no PR context) working unchanged.
/// </summary>
public string CheckoutRef
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# ------------------------------------------------------------------------------
# <auto-generated>
#
# This code was generated.
#
# - To turn off auto-generation set:
#
# [TestGitHubActions (AutoGenerate = false)]
#
# - To trigger manual generation invoke:
#
# fallout --generate-configuration GitHubActions_test --host GitHubActions
#
# </auto-generated>
# ------------------------------------------------------------------------------

name: test

on:
pull_request:
branches:
- main

jobs:
ubuntu-latest:
name: ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.head_ref }}
- name: 'Cache: .fallout/temp, ~/.nuget/packages'
uses: actions/cache@v4
with:
path: |
.fallout/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
- 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: Test'
run: dotnet fallout Test
- name: 'Publish: src'
uses: actions/upload-artifact@v5
with:
name: src
path: src
- name: 'Publish: test-results'
uses: actions/upload-artifact@v5
with:
name: test-results
path: output/test-results
- name: 'Publish: coverage-report.zip'
uses: actions/upload-artifact@v5
with:
name: coverage-report.zip
path: output/coverage-report.zip
16 changes: 16 additions & 0 deletions tests/Fallout.Common.Tests/CI/ConfigurationGenerationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,22 @@ public class TestBuild : FalloutBuild
}
);

// Regression guard: when CheckoutRef is set, the generator must also emit a
// repository: line that resolves to the PR's head repo (for cross-repo / fork PRs)
// with a fallback to the current repo (for push events). Without this, fork PRs
// fail at the checkout step because the branch only exists on the fork, not on
// origin.
yield return
(
"checkout-ref",
new TestGitHubActionsAttribute(GitHubActionsImage.UbuntuLatest)
{
InvokedTargets = new[] { nameof(Test) },
OnPullRequestBranches = new[] { "main" },
CheckoutRef = "${{ github.head_ref }}"
}
);

yield return
(
null,
Expand Down
Loading