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
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"fsdocs-tool": {
"version": "22.0.0",
"version": "23.0.0-alpha.1",
"commands": [
"fsdocs"
],
Expand Down
30 changes: 4 additions & 26 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,17 @@ on:
- main
workflow_dispatch:

env:
FSHARP_DIR: fsharp

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Checkout fsharp main
uses: actions/checkout@v6
with:
repository: dotnet/fsharp
path: ${{ env.FSHARP_DIR }}
ref: main
- name: Setup .NET for FSharp
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
global-json-file: ${{ env.FSHARP_DIR }}/global.json
- name: Restore tools
run: dotnet tool restore
- name: Restore FSharp.Compiler.Service.fsproj
run: dotnet restore FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
- name: Build FCS
run: dotnet build FSharp.Compiler.Service.sln
working-directory: ${{ env.FSHARP_DIR }}

- name: Run fsdocs
env:
# allow roll forward to latest major version - this would happen for us if we invoked the fsdocs tool instead of invoking the binary directly
DOTNET_ROLL_FORWARD: "LatestMajor"
# need previews because .NET 8 is what's being used at runtime
DOTNET_ROLL_FORWARD_TO_PRERELEASE: "1"
run: dotnet fsdocs build --eval --sourcefolder fsharp --input fsharp/docs
dotnet-version: 10.0.x
- name: Build docs
run: dotnet fsi build.fsx
- name: Deploy
uses: peaceiris/actions-gh-pages@v4
with:
Expand Down
31 changes: 4 additions & 27 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,14 @@ on:
branches:
- '**'

env:
FSHARP_DIR: fsharp

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Checkout fsharp main
uses: actions/checkout@v6
with:
repository: dotnet/fsharp
path: ${{ env.FSHARP_DIR }}
ref: main
- name: Setup .NET for FSharp
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
global-json-file: ${{ env.FSHARP_DIR }}/global.json
- name: Restore tools
run: dotnet tool restore
- name: Restore FSharp.Compiler.Service.fsproj
run: dotnet restore FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj

- name: Build FCS
run: dotnet build FSharp.Compiler.Service.sln
working-directory: ${{ env.FSHARP_DIR }}

- name: Run fsdocs
env:
# allow roll forward to latest major version - this would happen for us if we invoked the fsdocs tool instead of invoking the binary directly
DOTNET_ROLL_FORWARD: "LatestMajor"
# need previews because .NET 8 is what's being used at runtime
DOTNET_ROLL_FORWARD_TO_PRERELEASE: "1"
run: dotnet fsdocs build --eval --sourcefolder fsharp --input fsharp/docs
dotnet-version: 10.0.x
- name: Build docs
run: dotnet fsi build.fsx
33 changes: 14 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,36 @@ signature files (`*.fsi`) in the FSharp.Compiler.Service implementation.

* Fork and clone https://github.com/dotnet/fsharp locally, see below

* Contribute to [src/fsharp directory](https://github.com/dotnet/fsharp/tree/master/docs) and [src/fsharp directory](https://github.com/dotnet/fsharp/tree/master/src/fsharp) and submit work to `main` branch of [dotnet/fsharp](https://github.com/dotnet/fsharp)
* Contribute to [docs directory](https://github.com/dotnet/fsharp/tree/main/docs) and [src/Compiler directory](https://github.com/dotnet/fsharp/tree/main/src/Compiler) and submit work to `main` branch of [dotnet/fsharp](https://github.com/dotnet/fsharp)

* Once accepted your work will be published through a rebuild here. A rebuild is triggered daily at 17:30 UTC or you can trigger it yourself by submitting a dummy change.

The docs are generated by using `fsdocs` tool from FSharp.Formatting.

## Build steps

Eventually the build will just be
Everything is driven by `build.fsx`, a [Fun.Build](https://github.com/slaveOftime/Fun.Build) script.
You need a .NET 10 SDK to run it. The default pipeline does the following:

dotnet tool restore
dotnet restore FSharp.Compiler.Service
dotnet fsdocs build
1. Clones [dotnet/fsharp](https://github.com/dotnet/fsharp) (shallow, `main` branch) into the git-ignored `fsharp` folder, unless it already exists.
2. Builds `FSharp.Compiler.Service.slnx` with the SDK that `fsharp/global.json` pins, using dotnet/fsharp's own `eng/common/dotnet.sh` bootstrap so that SDK does not need to be on your PATH.
3. Restores the `fsdocs` tool and the `FSharp.Compiler.Service` project in this repo.
4. Runs `fsdocs build` against `fsharp/docs` and writes the site to `output`.

For now, we make a fresh build of FSharp.Compiler.Service.
dotnet fsi build.fsx

(start in fsharp-compiler-docs)
dotnet restore FSharp.Compiler.Service
dotnet tool restore
To pick up new upstream changes, delete the `fsharp` folder and run the pipeline again.

(make fsharp-compiler-docs/fsharp)
git clone https://github.com/dotnet/fsharp --depth 1 -b main
Once a build has run, iterate on the docs with live reload:

(build fsharp-compiler-docs/fsharp)
pushd fsharp
dotnet build src/Compiler/FSharp.Compiler.Service.fsproj /p:BUILDING_USING_DOTNET=true
popd
dotnet fsi build.fsx -- -p Watch

Then do iterative development using:
Anything after the pipeline name is passed on to `fsdocs watch`, for example `-- -p Watch --nolaunch --port 8080`.

(from fsharp-compiler-docs)
dotnet fsdocs watch --sourcefolder fsharp --input fsharp/docs
Run `dotnet fsi build.fsx -- -h` to list the pipelines.

## CI Pipeline

This repo is published via GitHub Actions. On each push to main, the docs are built, and the outputs (which are written to the `output` directory by fsdocs) are pushed to the `gh-pages` branch. This repo is configured to host using GitHub Pages from this branch.
This repo is published via GitHub Actions. On each push to main, `build.fsx` runs, and the outputs (which are written to the `output` directory by fsdocs) are pushed to the `gh-pages` branch. This repo is configured to host using GitHub Pages from this branch.


88 changes: 88 additions & 0 deletions build.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env -S dotnet fsi --
#r "nuget: Fun.Build, 1.1.18"

open System
open System.IO
open Fun.Build

let root = __SOURCE_DIRECTORY__

/// A shallow clone of dotnet/fsharp main. It is git-ignored; the docs are generated from its
/// `docs` folder and from the FSharp.Compiler.Service it builds.
let fsharpDir = Path.Combine(root, "fsharp")

/// The SDK bootstrap script dotnet/fsharp ships. It runs its arguments with the exact SDK that
/// `fsharp/global.json` asks for, installing it under `fsharp/.dotnet` first when this machine
/// does not have it. Building through it means nobody has to keep a preview SDK on their PATH.
let upstreamDotnet =
if OperatingSystem.IsWindows() then
let script = Path.Combine(fsharpDir, "eng", "common", "dotnet.cmd")
$"cmd /c \"{script}\""
else
Path.Combine(fsharpDir, "eng", "common", "dotnet.sh")

let cloneStage =
stage "clone fsharp" {
run (fun ctx ->
async {
if Directory.Exists fsharpDir then
printfn "fsharp/ already exists, not cloning. Delete it to start from a fresh checkout."
return Ok()
else
return! ctx.RunCommand "git clone https://github.com/dotnet/fsharp --depth 1 -b main fsharp"
})
}

let buildFcsStage =
stage "build FSharp.Compiler.Service" {
workingDir fsharpDir
run $"{upstreamDotnet} build FSharp.Compiler.Service.slnx"
}

let restoreStage =
stage "restore" {
run "dotnet tool restore"
run "dotnet restore FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj"
}

/// fsdocs targets a fixed .NET runtime. Let it run on whatever newer runtime the machine has,
/// prereleases included, so the SDK dotnet/fsharp needs is also enough to run the tool.
let fsdocsEnv =
[ "DOTNET_ROLL_FORWARD", "LatestMajor"; "DOTNET_ROLL_FORWARD_TO_PRERELEASE", "1" ]

let fsdocsArgs = "--eval --sourcefolder fsharp --input fsharp/docs"

pipeline "Build" {
description "Clone dotnet/fsharp, build FSharp.Compiler.Service and generate the docs into output/."
workingDir root
cloneStage
buildFcsStage
restoreStage
stage "docs" {
envVars fsdocsEnv
run $"dotnet fsdocs build {fsdocsArgs}"
}
runIfOnlySpecified false
}

/// Everything after the pipeline name is passed on to `fsdocs watch`, for example
/// `dotnet fsi build.fsx -- -p Watch --nolaunch --port 8080`.
pipeline "Watch" {
description "Serve the docs with live reload. Expects a Build to have run first."
workingDir root
restoreStage
stage "watch" {
envVars fsdocsEnv
run (fun ctx ->
let extraArgs =
fsi.CommandLineArgs
|> Array.skipWhile (fun arg -> arg <> "Watch")
|> Array.skip 1
|> String.concat " "

ctx.RunCommand $"dotnet fsdocs watch {fsdocsArgs} {extraArgs}")
}
runIfOnlySpecified true
}

tryPrintPipelineCommandHelp ()