Alma.Build
2.0.0
dotnet add package Alma.Build --version 2.0.0
NuGet\Install-Package Alma.Build -Version 2.0.0
<PackageReference Include="Alma.Build" Version="2.0.0" />
<PackageVersion Include="Alma.Build" Version="2.0.0" />
<PackageReference Include="Alma.Build" />
paket add Alma.Build --version 2.0.0
#r "nuget: Alma.Build, 2.0.0"
#:package Alma.Build@2.0.0
#addin nuget:?package=Alma.Build&version=2.0.0
#tool nuget:?package=Alma.Build&version=2.0.0
fbuild
fbuild is a versioned, distributable FAKE + Paket build infrastructure for F# projects.
This repository ships one deliverable: Alma.Build (src/Alma.Build/) — the build
engine library plus the support files that consuming repositories vendor alongside it.
Current engine version: 2.0.0 (Version in src/Alma.Build/Alma.Build.fsproj).
What you get
A consuming repository owns a single build file, build/Build.fs, which declares a
ProjectDefinition — project metadata plus one Spec case — and passes it to
Targets.init. The engine derives the target graph from the spec:
LibraryExecutableConsoleApplicationSAFEStackApplication
Targets are then run through the bootstrap entry point:
./build.sh <Target>
Common targets (Library spec):
Build(default when no target is provided)LintTestsReleasePublishInfo
Arguments:
no-clean: skips theCleanstep.no-lint: skips theLintstep.
./build.sh Build no-lint
Prerequisites
- .NET SDK with
net10.0support. bash.git(required by build metadata initialization).
Adoption
The engine is a normal NuGet package plus a handful of support files that live in the
consuming repo; the engine's Bootstrap target deploys those files, so only the paket
pin and the build project are written by hand.
1. Pin the engine
paket.dependencies at the repo root:
group Build
source https://api.nuget.org/v3/index.json
nuget Alma.Build 2.0.0
build/paket.references:
group Build
Alma.Build
.config/dotnet-tools.json — Paket is mandatory; dotnet-fsharplint backs the Lint
target:
{
"version": 1,
"isRoot": true,
"tools": {
"paket": { "version": "10.3.1", "commands": [ "paket" ] },
"dotnet-fsharplint": { "version": "0.26.10", "commands": [ "dotnet-fsharplint" ] }
}
}
2. Add the build project
build/build.fsproj:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<IsPackable>false</IsPackable>
<NoWarn>NU1510</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Include="Build.fs" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />
</Project>
The Paket.Restore.targets import makes a plain dotnet build/dotnet run trigger
Paket's restore.
build/Build.fs is the only build file the repository owns and edits.
3. Restore
Generate paket.lock once:
dotnet tool restore
dotnet paket install # writes paket.lock — commit it
4. Bootstrap the support files
The files are bundled inside the engine assembly; its Bootstrap target deploys them
into the repo, preserving their directory structure:
dotnet run --project ./build/build.fsproj -- Bootstrap
| File | Purpose |
|---|---|
build.sh |
entry point: restores tools + packages, runs the build |
.editorconfig |
formatting rules the engine's Lint target assumes |
fsharplint.json |
lint configuration |
build/README.md |
consumer-facing quick reference |
Bootstrap overwrites existing copies and marks build.sh executable. The files are
version-locked to the engine: rerunning Bootstrap after a version bump is how
engine-side changes to lint rules, formatting, or the entry point reach the repo.
5. Build
From here on the entry point is enough:
./build.sh
Console application runtime settings
Spec.defaultConsoleApplication defaults to portable Build, Run, and Watch
targets and publishes one self-contained single-file artifact per supplied runtime target.
Use Spec.mapConsoleApplication when the local build should target a runtime or when
the release should keep its files unbundled:
Specs =
Spec.defaultConsoleApplication [ Linux; Windows ]
|> Spec.mapConsoleApplication (fun spec ->
{ spec with
RuntimeMode = RuntimeMode.AutoDetect
PublishSingleFile = false
}
)
RuntimeMode.AutoDetect selects the RID reported by the running .NET runtime;
RuntimeMode.Specific runtimeTarget selects the given target. Both pass the resolved RID
as -r <runtimeIdentifier> to Build, Tests, Run, and Watch, including their
Mirrord variants. A Specific target must occur in RuntimeTargets; AutoDetect is
independent of the release matrix. Release always publishes every target in
RuntimeTargets; PublishSingleFile = false keeps the published files separate.
Use Custom "linux-musl-arm64" for a RID without a predefined RuntimeTarget case.
Updating
- Bump the version in
paket.dependencies. dotnet paket install../build.sh Bootstrapto redeploy the support files.- If the engine's
Spec/Targetssurface changed, adjustbuild/Build.fsper the release notes inCHANGELOG.md. - Run
./build.shand commitpaket.lockwith the rest.
Further reading
docs/specs/fbuild/spec.md— architecture and design reference.build/README.md— consumer-facing quick reference shipped with the engine.CONTRIBUTING.md— working on the engine itself.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Fake.Core.ReleaseNotes (>= 6.1.4)
- Fake.Core.Target (>= 6.1.4)
- Fake.Core.UserInput (>= 6.1.4)
- Fake.DotNet.AssemblyInfoFile (>= 6.1.4)
- Fake.DotNet.Cli (>= 6.1.4)
- Fake.IO.FileSystem (>= 6.1.4)
- Fake.IO.Zip (>= 6.1.4)
- Fake.Tools.Git (>= 6.1.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0 | 82 | 9/9/2026 |