Skip to content
Draft
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
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ root = true
####################################################################

[*]
end_of_line = crlf
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

Expand Down
1 change: 0 additions & 1 deletion .fallout/build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"References",
"ReportCoverage",
"Restore",
"RunTargetInDockerImageTest",
"Test",
"UpdateContributors",
"UpdateStargazers"
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Fallout welcomes contributions. As a community, we want to help each other, prov

- **Write functional commit and PR titles** — describe what the change accomplishes, not how it's categorised. Do not use conventional-commit prefixes (`feat:`, `fix:`, `chore:`, `refactor:`, etc.). Good examples: "Add retry logic to the HTTP tool wrapper", "Fix null-reference in target dependency resolution". The `!` suffix (e.g. `fix(security)!: …`) is recognised only as a breaking-change detection signal, not a general style requirement.
- Aim for qualitative, readable code that matches the surrounding style.
- There's no committed `.editorconfig` or ReSharper/`*.DotSettings` file — they were removed during the takeover. Rely on `dotnet format` defaults and review; don't reintroduce them without a maintainer-level decision.
- Style is codified in a committed `.editorconfig` (plus `fallout.slnx.DotSettings` for Rider/ReSharper). Match it and keep `dotnet format` green; don't delete or bypass it — change a rule deliberately if needed.
- Add tests when meaningful — every `Foo` project has a sibling `Foo.Tests`.
- Don't commit code generated by `./build.ps1 GenerateTools` — generated `.cs` files are regenerated manually once per release.
- **Label the PR `target/vCurrent`** for the current release line (use `target/vNext` for work held to next year's major). Legacy `support/v10` maintenance work uses `target/v10`. **Breaking changes are batched to the yearly major cut**: they land on `main` gated behind `[Experimental("FALLOUT0xx")]` (or, when they can't be gated, on a short-lived topic branch off `main`) — never on a `release/YYYY` production train — are held for next year's `YYYY+1.0.0`, and additionally get a `breaking-change` label, a `⚠️ Breaking change` callout, and a `CHANGELOG.md` entry under the next-major `[Unreleased]` heading. Surface that isn't ready to commit to can ship behind `[Experimental("FALLOUT0xx")]` instead of being held back. See the [PR-creation flow](docs/agents/release-and-versioning.md#pr-creation-flow) for the full procedure.
Expand Down
26 changes: 0 additions & 26 deletions build/Build.RunTargetInDockerTest.cs

This file was deleted.

24 changes: 15 additions & 9 deletions build/Build.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NuGet.Packaging;
using Fallout.Common;
using Fallout.Common.CI;
using Fallout.Common.CI.GitHubActions;
using Fallout.Common.Execution;
using Fallout.Common.Git;
using Fallout.Common.IO;
using Fallout.Solutions;
using Fallout.Common.Tooling;
using Fallout.Common.Tools.DotNet;
using Fallout.Common.Tools.GitHub;
using Fallout.Common.Utilities;
using Fallout.Components;
using Fallout.Solutions;
using NuGet.Packaging;
using static Fallout.Common.ControlFlow;
using static Fallout.Common.Tools.DotNet.DotNetTasks;

Expand All @@ -30,7 +30,14 @@ partial class Build
ITest,
IReportCoverage,
IPublish,
ICreateGitHubRelease
ICreateGitHubRelease,
// Build-local steps (build/Steps/) — each concern is its own component.
IGenerateTools,
IGeneratePublicApi,
IDownloadLicenses,
IHandleExternalRepositories,
IUpdateContributors,
IUpdateStargazers
{
public static int Main() => Execute<Build>(x => ((IPack)x).Pack);

Expand Down Expand Up @@ -70,9 +77,8 @@ partial class Build
string MajorMinorPatchVersion => Major
? $"{ParseMajor(ThisAssembly.AssemblyInformationalVersion) + 1}.0.0"
: ThisAssembly.AssemblyInformationalVersion.Split('+')[0];
string MilestoneTitle => $"v{MajorMinorPatchVersion}";

private static int ParseMajor(string informationalVersion)
static int ParseMajor(string informationalVersion)
=> int.Parse(informationalVersion.Split('.')[0]);

AbsolutePath IHasArtifacts.ArtifactsDirectory => RootDirectory / "output";
Expand Down Expand Up @@ -122,7 +128,7 @@ from framework in project.GetTargetFrameworks()

string DefaultDeploymentVersion => "9999.0.0";

[Parameter] [Secret] readonly string NuGetApiKey;
[Parameter][Secret] readonly string NuGetApiKey;

// Two publish channels (FALLOUT001 — see IPublish.PublishTargets). Routing replaces the
// old single-feed push + the hand-rolled `dotnet nuget push` in the workflows (#333):
Expand All @@ -131,8 +137,8 @@ from framework in project.GetTargetFrameworks()
// - nuget.org: Fallout.* ONLY, never the Nuke.* shims. Keyed by NUGET_API_KEY.
// Select per run from CI with `dotnet fallout Publish --publish-to <name>`. PublishTarget.SkipDuplicate
// (default true) keeps re-runs idempotent if a version already exists on a feed.
#pragma warning disable FALLOUT001 // opting our own build into the experimental multi-channel publish surface
IEnumerable<PublishTarget> IPublish.PublishTargets => new[]
#pragma warning disable FALLOUT001, FALLOUT005 // opting our own build into the experimental multi-channel publish surface (ADR-0009)
IEnumerable<IPublishTarget> IPublish.PublishTargets => new IPublishTarget[]
{
new PublishTarget
{
Expand All @@ -149,7 +155,7 @@ from framework in project.GetTargetFrameworks()
ExcludePackages = new[] { "Nuke.*" },
},
};
#pragma warning restore FALLOUT001
#pragma warning restore FALLOUT001, FALLOUT005

// The workflows now gate *which* channel publishes (via --publish-to); the on-branch
// requirement is gone. We keep a CI guard, though: GitHubToken binds from the
Expand Down
6 changes: 4 additions & 2 deletions build/Build.Licenses.cs → build/Steps/IDownloadLicenses.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using Fallout.Common;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Fallout.Common;
using Fallout.Common.IO;
using Fallout.Components;
using Serilog;
using static Fallout.Common.IO.HttpTasks;

partial class Build
// Step: fetch the third-party licenses bundled into the packages. Hooks into Pack via
// DependentFor<IPack> so it runs as part of the default pipeline, not just on demand.
interface IDownloadLicenses : IFalloutBuild
{
AbsolutePath LicensesDirectory => TemporaryDirectory / "licenses";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
using Fallout.Common.Utilities;
using Fallout.Common.Utilities.Collections;

partial class Build
// Step: dump the framework's public API surface to PUBLIC_API.md.
interface IGeneratePublicApi : IFalloutBuild
{
AbsolutePath PublicApiFile => RootDirectory / "PUBLIC_API.md";

Expand Down
12 changes: 9 additions & 3 deletions build/Build.CodeGeneration.cs → build/Steps/IGenerateTools.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
using System;
using System;
using Fallout.Common;
using Fallout.Common.IO;
using Fallout.Common.Tools.GitHub;
using Fallout.Common.Utilities.Collections;
using Fallout.Components;
using static Fallout.CodeGeneration.CodeGenerator;
using static Fallout.CodeGeneration.ReferenceUpdater;
using static Fallout.Common.Tools.Git.GitTasks;

partial class Build
// Step: (re)generate the tool wrappers from their JSON specs and the CLI reference docs.
interface IGenerateTools : IFalloutBuild, IHasGitRepository
{
AbsolutePath SpecificationsDirectory => RootDirectory / "src" / "Fallout.Common" / "Tools";
AbsolutePath ReferencesDirectory => RootDirectory / "docs" / "cli-tools";

// Branch that generated source links point at. Mirrors Build.MainBranch, which must
// stay a const there (it feeds a [GitHubActions] attribute and so can't be shared here).
string ToolsSourceBranch => "main";

Target References => _ => _
.Requires(() => GitHasCleanWorkingCopy())
.Executes(() =>
Expand All @@ -28,6 +34,6 @@ partial class Build
GenerateCode(
x,
namespaceProvider: x => $"Fallout.Common.Tools.{x.Name}",
sourceFileProvider: x => GitRepository.SetBranch(MainBranch).GetGitHubBrowseUrl(x.SpecificationFile)));
sourceFileProvider: x => GitRepository.SetBranch(ToolsSourceBranch).GetGitHubBrowseUrl(x.SpecificationFile)));
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,20 @@
using Fallout.Common;
using Fallout.Common.Git;
using Fallout.Common.IO;
using Fallout.Solutions;
using Fallout.Common.Tools.GitHub;
using Fallout.Common.Utilities;
using Fallout.Utilities.Text.Yaml;
using static Fallout.Common.ControlFlow;
using static Fallout.Common.Tools.Git.GitTasks;

partial class Build
// Step: check out the companion repositories declared in external/repositories.yml and
// expose their solutions. Depended on by IUpdateContributors, which mines their git log.
interface IHandleExternalRepositories : IFalloutBuild
{
[Parameter] readonly bool UseHttps;
[Parameter] bool UseHttps => TryGetValue<bool?>(() => UseHttps) ?? false;

AbsolutePath GlobalSolution => RootDirectory / "fallout-global.sln";
AbsolutePath ExternalRepositoriesDirectory => RootDirectory / "external";
AbsolutePath ExternalRepositoriesFile => ExternalRepositoriesDirectory / "repositories.yml";

IEnumerable<Fallout.Solutions.Solution> ExternalSolutions
=> ExternalRepositories
.Select(x => ExternalRepositoriesDirectory / x.GetGitHubName())
.Select(x => x.GlobFiles("*.sln").Single())
.Select(x => x.ReadSolution());

IEnumerable<GitRepository> ExternalRepositories
=> ExternalRepositoriesFile.ReadYaml<string[]>().Select(x => GitRepository.FromUrl(x));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
using Fallout.Common.Utilities.Collections;
using static Fallout.Common.Tools.Git.GitTasks;

partial class Build
// Step: append newly-seen authors from this repo (and the external companions) to
// CONTRIBUTORS.md. Inherits IHandleExternalRepositories for ExternalRepositoriesDirectory.
interface IUpdateContributors : IFalloutBuild, IHandleExternalRepositories
{
AbsolutePath ContributorsFile => RootDirectory / "CONTRIBUTORS.md";
AbsolutePath ContributorsCacheFile => TemporaryDirectory / "contributors.dat";

Target UpdateContributors => _ => _
.Executes(() =>
{
var previousContributors = ContributorsCacheFile.Existing()?.ReadAllLines() ?? new string[0];
var previousContributors = ContributorsCacheFile.Existing()?.ReadAllLines() ?? [];

var repositoryDirectories = new[] { RootDirectory / ".git" }
.Concat(ExternalRepositoriesDirectory.GlobDirectories("*/.git"));
Expand All @@ -30,7 +32,7 @@ partial class Build

foreach (var newContributor in newContributors)
{
var content = (ContributorsFile.Existing()?.ReadAllLines() ?? new string[0])
var content = (ContributorsFile.Existing()?.ReadAllLines() ?? [])
.Concat($"- {newContributor.Name}").OrderBy(x => x);
ContributorsFile.WriteAllLines(content, Encoding.Default);
Git($"add {ContributorsFile}");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System.Linq;
using System.Linq;
using System.Threading.Tasks;
using Fallout.Common;
using Fallout.Common.IO;
using Fallout.Common.Tools.GitHub;
using Fallout.Common.Utilities;
using Fallout.Components;

partial class Build
// Step: snapshot the repository's stargazers to a CSV in the temp directory.
interface IUpdateStargazers : IFalloutBuild, IHasGitRepository
{
AbsolutePath StargazersFile => TemporaryDirectory / "stargazers.csv";

Expand Down
27 changes: 0 additions & 27 deletions build/_build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,8 @@
<PropertyGroup>
<FalloutTasksEnabled Condition="'$(FalloutTasksEnabled)' == ''">False</FalloutTasksEnabled>
<FalloutTasksDirectory>$(MSBuildThisFileDirectory)\..\src\Fallout.MSBuildTasks\bin\Debug\net8.0\publish</FalloutTasksDirectory>

<!-- <PackAsTool>True</PackAsTool>-->
<!-- <ToolCommandName>build</ToolCommandName>-->

<!-- <PublishSingleFile>True</PublishSingleFile>-->
<!-- <SelfContained>True</SelfContained>-->
<!-- <RuntimeIdentifier>linux-arm64</RuntimeIdentifier>-->
<!-- <InvariantGlobalization>True</InvariantGlobalization>-->
</PropertyGroup>

<!-- Test properties for external files -->
<!-- <ItemGroup>-->
<!-- <NukeExternalFiles Include="https://github.com/nuke-build/common/tree/develop/source/Nuke.GlobalTool/templates" BasePath="..\download">-->
<!-- <TargetFramework>Bla</TargetFramework>-->
<!-- <GitVersion />-->
<!-- <NuGetSource>https://www.myget.org/F/matkoch/api/v2/package</NuGetSource>-->
<!-- <NukeVersion>9999.0.0</NukeVersion>-->
<!-- </NukeExternalFiles>-->
<!-- </ItemGroup>-->

<!-- Test properties for source generators -->
<!-- <PropertyGroup>-->
<!-- <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>-->
<!-- <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GeneratedFiles</CompilerGeneratedFilesOutputPath>-->
<!-- </PropertyGroup>-->
<!-- <ItemGroup>-->
<!-- <PackageReference Include="Fallout.SourceGenerators" Version="1.0.0-beta01" OutputItemType="Analyzer" />-->
<!-- </ItemGroup>-->

<PropertyGroup>
<DefineConstants>$(Configuration.ToUpper())</DefineConstants>
<DefineConstants Condition="'$(OS)' == 'Windows_NT'">$(DefineConstants);WIN</DefineConstants>
Expand Down
Loading
Loading