Getting started
In this tutorial you will learn how to set up a complete build infrastructure with FAKE. This includes:
- how to install the latest FAKE version
- how to edit and run scripts
- how to automatically compile your C# or F# projects
- how to automatically run NUnit tests on your projects
If you are interested in what FAKE actually is, see our FAQ.
Install FAKE
FAKE is completely written in F# and all build scripts will also be written in F#, but this doesn't imply that you have to learn programming in F#. In fact the FAKE syntax is hopefully very easy to learn.
There are various ways to install FAKE 5:
-
Install FAKE as a local
dotnet tool
(easiest, but needs .NET Core SDK Version 3 or newer):-
First you need to create a tool manifest, which should be commited to your repository:
dotnet new tool-manifest
-
To install FAKE, run:
dotnet tool install fake-cli
Use
--version
to specify the version of FAKE. See thelocal_tool
branch offake-bootstrap
for ideas to bootstrap in your CI process.To run fake use
dotnet fake --version
. To restore/download fake on another machine usedotnet tool restore
after this commanddotnet fake
should work as expected.
-
-
Install FAKE as a global
dotnet tool
(easiest, but needs .NET Core SDK):-
To install FAKE globally, run:
dotnet tool install fake-cli -g
-
To install FAKE into
your_tool_path
, run:dotnet tool install fake-cli --tool-path yourtoolpath
Use
--version
to specify the version of FAKE. See theglobal_tool
branch offake-bootstrap
for ideas to bootstrap in your CI process. If you run into issues, see this
-
-
Bootstrap via the
fake dotnet new
template. The template bootstraps FAKE and sets up a basic build-script.-
To install the template run:
dotnet new -i "fake-template::*"
-
Then run the template with:
dotnet new fake
See the template page for more information.
-
-
Install the 'fake' or 'fake-netcore' package for your system (currenty chocolatey). Example
choco install fake
. We also provide a Debian package at the releases-page -
Download the portable zip. We distribute a dotnetcore version of FAKE without the dotnetcore runtime. This version assumes an existing dotnet sdk installation while the non-portable installation doesn't.
Just use the
-portable
version of the downloads, extract it and execute.dotnet fake.dll
The advantage of this method is that it is portable (ie. distribute the same binaries) and requires less bandwidth. The disadvantage is that you need to have a dotnet sdk installed and that you need to prefix all calls with
dotnet /full/path/to/fake.dll <args>
which is equal tofake <args>
in other installation methods. -
Download the runtime specific zip. Just use the
-<runtime>
version matching your specific platform of the downloads (for examplefake-dotnetcore-win7-x64.zip
), extract it and execute thefake
binary. Add the extracted binary to yourPATH
to just executefake
from any directory. -
Bootstrap via a shell script (fake.cmd/fake.sh), see this example project
WARNING
These scripts have no versioning story. You either need to take care of versions yourself (and lock them) or your builds might break on major releases.
now you can use
fake --help
This is basically it. You can now execute fake commands.
One note on Intellisense
This section is to clarify when and how the intellisense updates when you add new modules (short form: Delete the <script>.fsx.lock
file and re-run fake to update all files).
INFO
We recommend Visual Studio Code with the Ionide extension for best FAKE tooling support, including proper debugging.
-
Assume you have a script
myscript.fsx
with the following contents:1: 2: 3:
#r "paket: nuget Fake.Core.Target prerelease" #load "./.fake/myscript.fsx/intellisense.fsx"
Where you can add all the fake modules you need (work through the example below if you see this the first time).
-
run the script to restore your dependencies and setup the intellisense support:
fake run myscript.fsx
. This might take some seconds depending on your internet connectionINFO
The warning
FS0988: Main module of program is empty: nothing will happen when it is run
indicates that you have not written any code into the script yet. -
now open the script in VS Code with ionide-fsharp extension or Visual Studio.
INFO
If you change your dependencies you need to delete
myscript.fsx.lock
and run the script again for intellisense to update. Intellisense is shown for the full framework while the script is run asnetcoreapp20
therefore intellisense might show APIs which are not actually usable.
CLI
Buildserver support
AppVeyor: https://github.com/fsharp/FAKE/blob/master/appveyor.yml Travis: https://github.com/fsharp/FAKE/blob/master/.travis.yml
Examples
- See https://github.com/fsharp/FAKE/blob/master/build.fsx
- See https://github.com/SAFE-Stack/SAFE-template/blob/master/build.fsx
- See https://github.com/matthid/csharptofsharp/blob/master/build.fsx
Minimal example
Create a file named build.fsx
with the following contents:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: |
|
Run this file by executing
fake run build.fsx
Example - Compiling and building your .NET application
This example will guide you by adding a fake script to your existing .NET application.
Getting started
Initially we need to create a file called build.fsx
where all our build-logic will reside.
Create a new file with Visual Studio or Visual Studio Code (with ionide) and paste the following content:
1: 2: 3: |
|
This is all we need for now to declare that we need the Fake.Core.Target
module and want to enable intellisense.
Now run fake run build.fsx
to make fake prepare our environment. Now our IDE can load the dependencies and we will have intellisense enabled (you might need to reopen the script file on some editors).
Now that we have setup our basic environment to edit the script file we can add our first target:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: |
|
As you can see the code is really simple. The first few lines (nuget Fake.Core.Target
and open Fake.Core
) load the fake modules we need and this is vital for all build scripts to support creating and running targets. The #load
line is optional but a good way to make the IDE aware of all the modules (for intellisense and IDE support)
After this header the Default target is defined. A target definition contains two important parts. The first is the name of the target (here "Default") and the second is an action (here a simple trace of "Hello world").
The last line runs the "Default" target - which means it executes the defined action of the target.
Try running your new target via fake run build.fsx
or the shortcut for a file called build.fsx
: fake build
Cleaning the last build output
A typical first step in most build scenarios is to clean the output of the last build. We can achieve this in two steps:
First change your header to the following by adding the Fake.IO.FileSystem
module:
1: 2: 3: 4: |
|
Now we need to remove the build.fsx.lock
file and run fake build
in order to restore the newly added Fake.IO.FileSystem
module.
Since we now can rely on intellisense we can easily discover the various modules and functions in Fake.IO
, for example the Shell
module provides various functions you expect from regular shell scripting, we will use Shell.cleanDir
which will ensure the given directory is empty by deleting everything within or creating the directory if required:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: |
|
HINT
You can explore the APIs for example by writingFake.IO.
and waiting for intellisense (or pressing Ctrl+Space
).
You can remove Fake.IO
once you put open Fake.IO
on top.
We introduced some new concepts in this snippet. At first we defined a global property called buildDir
with the relative path of a temporary build folder.
In the Clean
target we use the Shell.cleanDir
task to clean up this build directory. As explained above this simply deletes all files in the folder or creates the directory if necessary.
In the dependencies section we say that the Default target has a dependency on the Clean target. In other words Clean is a prerequisite of Default and will run before the Default target is executed:
Compiling the application
In the next step we want to compile our C# libraries, which means we want to compile all csproj-files under /src/app with MSBuild.
Again we need a new module for this, namely Fake.DotNet.MSBuild
.
Just like before add the required module on top via nuget Fake.DotNet.MSBuild
, delete the build.fsx.lock
file and run the script.
Now edit the script so it looks like this:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: |
|
We defined a new build target named "BuildApp" which compiles all csproj-files with the MSBuild task and the build output will be copied to buildDir
.
In order to find the right project files FAKE scans the folder src/app/ and all subfolders with the given pattern (the !!
operator was imported from Fake.IO.FileSystem
via open Fake.IO.Globbing.Operators
). Therefore a similar FileSet definition like in NAnt or MSBuild (see project page for details) is used.
In addition the target dependencies are extended again. Now Default is dependent on BuildApp and BuildApp needs Clean as a prerequisite.
This means the execution order is: Clean ==> BuildApp ==> Default.
Compiling test projects
Now our main application will be built automatically and it's time to build the test project. We use the same concepts as before:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: |
|
This time we defined a new target "BuildTest" which compiles all C# projects below src/test/ in Debug mode and we put the target into our build order.
Running the tests with NUnit
Now all our projects will be compiled and we can use FAKE's NUnit task in order to let NUnit test our assembly (we have to add a new module for this: Fake.DotNet.Testing.NUnit
):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: |
|
Our new Test target scans the test directory for test assemblies and runs them with the NUnit runner. FAKE automatically tries to locate the runner in one of your subfolders. See the NUnit3 task documentation if you need to specify the tool path explicitly.
The mysterious part (fun p -> ...) simply overrides the default parameters of the NUnit task and allows to specify concrete parameters.
Runtime Assemblies in FAKE Runner
FAKE runner uses .NETSTANDARD 2.0 runtime assemblies when compiling and running a script. To switch and use .NET 6 runtime
assemblies you need to define a global.json
file and use .NET 6 as the SDK version.
What's next?
- Add more modules specific to your application and discover the Fake-APIs
- look at the FAQ for some commonly asked questions.
- look at some of the samples in FakeBuild
- look at FAKEs own build script or other examples across the F# ecosystem.
- Add fake build scripts to your projects and let us know.
- Automate stuff with FAKE and use standalone scripts.
- Write your own modules and let us know - we love to add them to the nagivation or announce them on twitter.
- Contribute :)