Skip to content

Guardrails / Collectors

.NET build ​

The .NET build in the project directory: the SDK it pins, every project file and the frameworks each targets, the packages they reference and which of them are pinned or supplied centrally, and the lock files beside them.

Facts keydotnet
Versionv1
Scriptdotnet.py
Timeout45 seconds

Inputs ​

InputDescriptionDefaultEnvironment
projectDirDirectory holding the project, relative to the directory the CLI runs in..GUARDRAIL_INPUT_PROJECTDIR
maxProjectsMaximum number of project files to describe. A larger solution carries the ones found first in path order.200GUARDRAIL_INPUT_MAXPROJECTS

When a guardrail declares an input with the same name, it passes its value through. That means you set these values in the guardrail's configuration in buildnote.json.

A guardrail asks for these facts by name and reads them back by the same name:

json
{
  "collect": ["dotnet"]
}
python
dotnet = guardrail.facts("dotnet")

Facts ​

These are the fields of the document dotnet collects. In a path, [] means each entry of the list before it, and [path] means a key of the object before it.

FactMeaning
directoryThe project directory set by the guardrail's projectDir input, relative to the directory the CLI runs in. Every other path this collector reports is also relative to the directory the CLI runs in, so it resolves from where you invoked the CLI, not from wherever the collector happened to run.
existsWhether that directory exists. When it doesn't, nothing else is collected.
manifestPath of the primary manifest, from the directory the CLI runs in: the solution when the checkout has one, otherwise the first project file found.
sourcesEvery project file, global.json and Directory.Packages.props that was read and understood. One the reader could not handle is in unparsed instead.
declaredThe SDK version global.json pins, or null when the checkout pins none and whatever SDK the runner has is used.
declared.versionVersion exactly as written, such as 8.0.204.
declared.sourceFile declaring it, from the directory the CLI runs in.
declared.pinnedWhether the SDK is held to that version. A rollForward other than disable lets a newer SDK take over, so it is not pinned.
rollForwardThe rollForward policy global.json declares, such as latestFeature, or null when it declares none.
targetFrameworksEvery target framework moniker any project declares, sorted, such as net8.0. A project targeting several carries all of them.
solutionPath of the solution file, from the directory the CLI runs in, or null when the checkout carries none.
centralPackageManagementWhether a Directory.Packages.props declares the versions centrally, which is what makes a PackageReference without a version correct rather than broken.
projectsEvery project file found, in path order.
projects[].pathDirectory of the project, from the directory the CLI runs in; directory itself for the project directory.
projects[].manifestThe project file, from the directory the CLI runs in.
projects[].nameAssembly name the project declares, or the project file's own stem when it declares none.
projects[].targetFrameworksTarget framework monikers that project declares.
dependenciesWhat the projects reference, split by whether the build asks for it itself.
dependencies.directEvery PackageReference any project declares, in project order.
dependencies.direct[].namePackage id, such as Serilog.
dependencies.direct[].versionVersion exactly as written, or null when the reference carries none and a central version supplies it.
dependencies.direct[].scopesdefault, or development when the reference sets PrivateAssets to all, which keeps it out of what consumers restore.
dependencies.direct[].sourceProject file declaring it, from the directory the CLI runs in.
dependencies.direct[].pinnedWhether the version names one exact release. A floating 8.0.*, a range in brackets and an unresolved $(Property) are not pinned.
dependencies.direct[].managedByDirectory.Packages.props when a central PackageVersion supplied the version, or null when the reference carried its own.
dependencies.transitiveAlways empty. What packages.lock.json resolves is not read: lockfiles says whether one is committed.
lockfilesEvery packages.lock.json committed, from the directory the CLI runs in. Restore only honours them when the build sets RestorePackagesWithLockFile.
droppedProject files left out because maxProjects was reached. Above zero, projects and dependencies describe only part of the solution.
unparsedEvery file the reader could not handle, so a guardrail can tell a build that declares nothing apart from one that could not be read.
unparsed[].pathPath of that file, from the directory the CLI runs in.
unparsed[].reasonWhy the reader could not handle it.

If a collector can't finish, it prints what it gathered so far along with an incomplete key that says why. Facts after the point where it stopped are missing, so a check that depends on them should read incomplete first.

Example facts ​

Here are the facts the dotnet collector gathers from an example project:

json
{
  "directory": ".",
  "exists": true,
  "manifest": "src/Widget/Widget.csproj",
  "sources": [
    "Directory.Packages.props",
    "global.json",
    "src/Widget/Widget.csproj"
  ],
  "declared": {
    "version": "8.0.204",
    "source": "global.json",
    "pinned": true
  },
  "rollForward": "disable",
  "targetFrameworks": [
    "net8.0"
  ],
  "solution": null,
  "centralPackageManagement": true,
  "projects": [
    {
      "path": "src/Widget",
      "manifest": "src/Widget/Widget.csproj",
      "name": "Company.Widget",
      "targetFrameworks": [
        "net8.0"
      ]
    }
  ],
  "dependencies": {
    "direct": [
      {
        "name": "Serilog",
        "version": "4.0.0",
        "scopes": [
          "default"
        ],
        "source": "src/Widget/Widget.csproj",
        "pinned": true,
        "managedBy": "Directory.Packages.props"
      },
      {
        "name": "Npgsql",
        "version": "8.0.3",
        "scopes": [
          "default"
        ],
        "source": "src/Widget/Widget.csproj",
        "pinned": true,
        "managedBy": null
      },
      {
        "name": "StyleCop.Analyzers",
        "version": "1.2.0-beta.556",
        "scopes": [
          "development"
        ],
        "source": "src/Widget/Widget.csproj",
        "pinned": true,
        "managedBy": null
      }
    ],
    "transitive": []
  },
  "lockfiles": [
    "src/Widget/packages.lock.json"
  ],
  "dropped": 0,
  "unparsed": []
}

Collected for ​

GuardrailCategoryInputs
dotnet/central-package-managementdotnetprojectDir
dotnet/dependencies-versioneddotnetprojectDir
dotnet/sdk-pinneddotnetprojectDir
dotnet/target-framework-floordotnetprojectDir

All collectors

Buildnote Limited
Registered in England and Wales, Reg: 16140412