Repository navigation
chore: update the build infrastructure and adopt the latest shared agent instructions - #22
Conversation
Update `Microsoft.SourceLink.GitHub` to `10.0.401` together with the SDK it ships with. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nfig Batch files are checked out with CRLF and PowerShell scripts with LF on every platform, and `.editorconfig` states the same instead of asking for CRLF in PowerShell scripts. The inline comments of `.editorconfig` move onto their own lines: the specification does not support inline comments, so they were read as part of the value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`.editorconfig` follows the settings of Fantomas 8: - `fsharp_keep_indent_in_branch` became `fsharp_experimental_keep_indent_in_branch`; under its old name the setting was ignored. - `fsharp_semicolon_at_end_of_line` and `fsharp_max_dot_get_expression_width` no longer exist. - `end_of_line=lf` matches the line endings `.gitattributes` stores F# files with, so formatting on Windows no longer rewrites them as CRLF. The comments state the current defaults and link to the current documentation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fantomas 8 no longer puts a space between a type application and its argument list: `Create<'T> ()` becomes `Create<'T>()`. Whitespace only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`ToolRestore` ran only in design-time builds, so a command-line build relied on the FAKE `DotnetToolRestore` target, and that target was a dependency of `BuildDocs` alone: on CI `CheckFormatCode` found no Fantomas and passed without checking anything. `ToolRestore` now runs before every restore, and the FAKE target is gone. `ToolUpdate` is removed: its `Outputs` used an undefined property, so MSBuild always skipped it. Formatting is delegated to one instance of a project without a target framework, so a project is formatted once per build however many target frameworks it has, and Fantomas runs twice because one pass is not always idempotent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tCover leftovers `DotnetTest` passed `/p:AltCover*` properties although no project references AltCover, and `GenerateCoverageReport` looked for `tests/**/coverage*.xml`, which nothing produced, so `ENABLE_COVERAGE` collected no coverage. `DotnetTest` now runs `dotnet test --project` for each test project and lets the MSTest runner collect coverage with `--coverage --coverage-output-format cobertura` into `TestResults`, where `GenerateCoverageReport` reads it and writes HTML and Cobertura reports. Coverage is collected when `ENABLE_COVERAGE` is set or `GenerateCoverageReport` is among the targets. Also: - the release commit is named `release: bump version to ...`; - `quoted` is shared by the test and the documentation targets; - the workflows no longer explain `ENABLE_COVERAGE: false` with AltCover. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`src/Directory.Build.props` holds what every library project shares, next to the `tests/Directory.Build.props` the test projects already have: it marks the project as packable, generates the documentation file, publishes the repository URL, embeds untracked sources and puts the PDB into the package next to the assembly. The solution groups the projects into `src` and `tests` folders. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y has no date `GenerateAssemblyInfo` read `latestEntry.Date.Value` and failed with a `NullReferenceException` for an entry without a date. The `ReleaseDate` metadata is now written only when the entry has one. This is the case in this repository today: FAKE `6.1.4` moves the link references out of the last entry of the changelog and rebuilds that entry from its versions and changes alone, dropping its date and description (fixed in FAKE after `6.1.4`, not released yet). `1.0.0` is the only entry, so it is both the latest and the last one, and `PublishToGitHub`, which generates the assembly info, could not get past this target. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ersion The package described itself as an F# API for Azure Cosmos DB and carried the `AzureCosmosDisableNewtonsoftJsonCheck` property, both left over from the project file this one was copied from. The description is `F# bindings for System.Collections.Immutable` again. `GenerateAssemblyInfo` is switched off for the SDK because the FAKE target of the same name writes `AssemblyInfo.fs`, but the project did not compile that file, so the assembly had version `0.0.0.0`. The generated file is now the first compiled file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FsLangMCP gives agents semantic F# tools: symbol lookup, diagnostics, usages and refactoring previews. It is a local tool pinned in the tool manifest, so `dotnet tool restore` installs it, and `.mcp.json` starts it with `dotnet tool run fslangmcp`. The servers in `.mcp.json` are sorted by name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- `CLAUDE.md` imports `.github/copilot-instructions.md`, so GitHub Copilot and Claude Code share one set of instructions; `AGENTS.md` points other agents at the same file. - `.mcp.json` lists the servers for Claude Code under `mcpServers` next to `servers`. - The GitHub MCP server does not support the OAuth dynamic client registration Claude Code needs, so `.claude/scripts/github-mcp-headers.ps1` passes it the token Git Credential Manager already stores. - `ClaudeSkillsLink` links `.claude/skills` to `.github/skills` when that folder exists; the link is local and git-ignored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The generic sections are replaced with the current shared ones: - `MCP Servers` – when to prefer the F#, GitHub and Microsoft Docs servers; - `F# Coding Guidelines` – tooling, asynchrony and cancellation, values and collections (`voption`, struct tuples, `ToLookup`, pipelines kept in one module, comparing `System.Type` values), functions, lambdas and strings (explicit `StringComparison`, spans), nullable reference types, XML documentation comments and the order of `open` statements; - `Naming Conventions` – test names with spaces; - `Testing` – `StringAssert`, `Assert.Contains`, `Assert.HasCount` and running tests with `--no-build`. The project details, the solution structure, the libraries in use and the test category rules are specific to this repository and stay as they are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`TestCategories.fs` keeps its `TestCategoryBaseAttribute` descendants sorted by type name. The rule lives in `.github/instructions/test-categories.instructions.md`, which GitHub Copilot applies to that file, and `.claude/rules/test-categories.md` imports it for Claude Code under the same path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- `actions/configure-pages` `v5` -> `v6` - `actions/upload-pages-artifact` `v4` -> `v5` - `actions/deploy-pages` `v4` -> `v5` Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dev container installs the starship feature and enables it in zsh when the container is created. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e its sibling keys `target` was indented by five spaces while the other safe outputs indent their keys by four. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README: - the required SDK is the `10.0.401` pinned in `global.json`, not `8.0 or higher`; - `CONFIGURATION` defaults to `Debug`, and to `Release` only when `PublishToNuGet` runs; - `ENABLE_COVERAGE` and `DotnetTest` describe the MSTest runner instead of AltCover and the solution file; - `PublishToNuGet` pushes with `dotnet nuget push`, not `paket push`; - the release commit is named ``release: bump version to `x.y.z` ``; - the badge of the `.NET Core` workflow, which does not exist, is removed, and the NuGet badge is loaded over HTTPS. The pull request template names this project instead of the one it was copied from. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
There was a problem hiding this comment.
🟡 Changes recommended
The formatting target currently executes Fantomas twice for every format pass.
1 open finding
What changed in this PR
Modernizes build, release, coverage, formatting, and agent infrastructure while preserving library behavior.
Changes:
- Updates .NET, Fantomas, SourceLink, GitHub Actions, and coverage tooling.
- Corrects package and assembly metadata generation.
- Adds shared agent/MCP configuration and applies formatting updates.
| File | Description |
|---|---|
src/FSharp.Collections.Immutable/Stack.fs |
Applies Fantomas formatting. |
src/FSharp.Collections.Immutable/Sets.fs |
Applies Fantomas formatting. |
src/FSharp.Collections.Immutable/Queue.fs |
Applies Fantomas formatting. |
src/FSharp.Collections.Immutable/Maps.fs |
Applies Fantomas formatting. |
src/FSharp.Collections.Immutable/ImmutableList.fs |
Applies Fantomas formatting. |
src/FSharp.Collections.Immutable/FSharp.Collections.Immutable.fsproj |
Corrects package metadata and compiles assembly metadata. |
src/FSharp.Collections.Immutable/FlatList.fs |
Applies Fantomas formatting. |
src/FSharp.Collections.Immutable/AssemblyInfo.fs |
Adds generated version and assembly metadata. |
src/Directory.Build.props |
Configures library packaging and PDB inclusion. |
README.md |
Updates build, coverage, and release documentation. |
global.json |
Pins .NET SDK 10.0.401. |
FSharp.Collections.Immutable.slnx |
Organizes projects into solution folders. |
Directory.Packages.props |
Updates SourceLink. |
Directory.Build.targets |
Revises tool restoration, formatting, and skill linking. |
CLAUDE.md |
Redirects Claude Code to shared instructions. |
build/Changelog.fs |
Applies formatting. |
build/build.fs |
Migrates coverage and improves release metadata handling. |
AGENTS.md |
Directs agents to shared repository instructions. |
.mcp.json |
Configures F#, GitHub, and Microsoft Docs MCP servers. |
.gitignore |
Ignores the generated Claude skills link. |
.github/workflows/repo-assist.md |
Corrects formatting. |
.github/workflows/publish_release.yml |
Removes obsolete AltCover commentary. |
.github/workflows/publish_ci.yml |
Removes obsolete AltCover commentary. |
.github/workflows/fsdocs-gh-pages.yml |
Updates GitHub Pages actions. |
.github/PULL_REQUEST_TEMPLATE.md |
Corrects the project name. |
.github/instructions/test-categories.instructions.md |
Adds scoped test-category guidance. |
.github/copilot-instructions.md |
Expands shared coding and tooling guidance. |
.gitattributes |
Defines platform-appropriate script line endings. |
.editorconfig |
Updates Fantomas 8 and line-ending configuration. |
.devcontainer/devcontainer.json |
Adds and initializes Starship. |
.config/dotnet-tools.json |
Adds FsLangMCP and updates Fantomas. |
.claude/scripts/github-mcp-headers.ps1 |
Supplies GitHub MCP authentication headers. |
.claude/rules/test-categories.md |
Bridges Claude to scoped test guidance. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
FAKE `6.1.5` keeps the date and the description of the last entry of the changelog, which `6.1.4` dropped. `1.0.0` is the only entry here, so: - the regenerated `AssemblyInfo.fs` now carries the `ReleaseDate` metadata; - the release notes of the package start with `## [1.0.0] - 2020-02-23` and `First release` instead of a bare `## [1.0.0]`. `GenerateAssemblyInfo` still writes `ReleaseDate` only for an entry that has a date, because the date is optional in a changelog entry; its comment no longer refers to the FAKE defect. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A solution restores its projects in parallel, so `ToolRestore` ran `dotnet tool restore` in every project at the same time and all of them touched the same marker file. The `Restore dependencies` step of the Copilot setup, which restores the solution, failed on Linux after `ToolRestore` started to run on every restore. Every project now delegates to one instance of `Directory.Build.targets`, which MSBuild builds once per build, so the tools are restored once and the other projects wait for that run. The Copilot setup no longer restores the tools on its own before restoring the solution. `Format` says why it runs Fantomas twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Proposed Changes
Brings the repository infrastructure up to date; the library code changes only by a whitespace reformat with Fantomas
8.0.5. The build restores the local tools once before every restore, formats each project once per build and collects coverage with the MSTest runner (dotnet test --project … --coverage) – theAltCoverproperties it passed before did nothing, soENABLE_COVERAGEproduced no coverage. The package is described asF# bindings for System.Collections.Immutableagain instead of an Azure Cosmos DB API, and the assembly gets version1.0.0.0instead of0.0.0.0because the generatedAssemblyInfo.fsis now compiled. FAKE is updated to6.1.5:6.1.4dropped the date of the last entry ofCHANGELOG.md, which is the only one here, andGenerateAssemblyInfofailed on it, which stoppedPublishToGitHub; the target now also writesReleaseDateonly for an entry that has a date. Agents get the F# MCP server, the Claude Code configuration (CLAUDE.md,AGENTS.md,mcpServers), the latest shared coding instructions and a path-scoped rule forTestCategories.fs.Types of changes
What types of changes does your code introduce to FSharp.Collections.Immutable?
Put an
xin the boxes that applyChecklist
Put an
xin the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.build.cmdwithCI=trueandENABLE_COVERAGE=trueinDebugandRelease, plusGenerateCoverageReportandBuildDocsREADME.mdand.github/copilot-instructions.mdFurther comments
CheckFormatCodestarts to check. On CI it ran before any tool was restored, found no Fantomas and passed whatever the formatting was.Directory.Build.targetsper build. Restoring them in every project made the projects of a solution rundotnet tool restoreat the same time, and theRestore dependenciesstep of the Copilot setup failed on Linux.Formatruns Fantomas twice on purpose: one pass is not always idempotent..nupkg; the.snupkgis still produced.net8.0, so the workflows and the dev container keep installing the8.xruntime next to the SDK10.0.401.PublishToGitHuband the documentation deployment run onmainonly. Locally the build was run with the prereleaseAssemblyInfo.fsthatPublishToGitHubgenerates (1.0.1-ci): it compiles with theFS2003warning about a version that is not numeric.🤖 Generated with Claude Code