Skip to main content

Check out Port for yourself ➜ 

Ingest .NET framework versions from repositories

This guide demonstrates how to track .NET framework versions across your repositories by ingesting .csproj files into Port.
Each .csproj file becomes its own entity, allowing you to see exactly which framework versions are in use per project and per repository.

Common use cases

  • Version standardization: Identify repositories still targeting older .NET versions and drive upgrades.
  • Compliance tracking: Use scorecards to flag projects not on supported framework versions.
  • Multi-project visibility: See all .csproj files across a repository, each with its own framework version.

Prerequisites

This guide assumes the following:

  • You have a Port account and have completed the onboarding process.
  • Repositories containing .csproj files with a <TargetFramework> or <TargetFrameworks> element.

Set up data model

We will create a dedicated blueprint related back to the repository to track the .NET framework versions.

Create net_versions blueprint

  1. Go to the Builder page of your portal.

  2. Click on + Blueprint.

  3. Click on {...} Edit JSON at the top right corner.

  4. Add this JSON schema:

    net_versions blueprint (click to expand)
    {
    "identifier": "net_versions",
    "title": ".NET Version",
    "icon": "Service",
    "schema": {
    "properties": {
    "dotnet_version": {
    "type": "string",
    "title": "Target Framework",
    "description": "The .NET target framework extracted from the .csproj file"
    },
    "file_path": {
    "type": "string",
    "title": "File Path",
    "description": "Path to the .csproj file in the repository"
    }
    },
    "required": []
    },
    "relations": {
    "repository": {
    "target": "githubRepository",
    "title": "Repository",
    "required": false,
    "many": false
    }
    },
    "mirrorProperties": {},
    "calculationProperties": {},
    "aggregationProperties": {}
    }
    Relation target

    If you're using GitHub, change the relation target from "githubRepository" to "gitlabRepository" (or whichever blueprint represents your repositories).

  5. Click Save to create the blueprint.

Configure the mapping

Add the following mapping to your integration's data source configuration.
This uses the file kind with skipParsing: true (since .csproj files are XML, not JSON/YAML) and extracts the framework version via a JQ regex.

  1. Go to your data sources page.

  2. Select your Git integration.

  3. Add the mapping below:

    Integration mapping (click to expand)
    resources:
    - kind: file
    selector:
    query: "true"
    files:
    path: "*.csproj"
    # Optional: limit to specific repos (omit to search all groups)
    repos:
    - group/my-dotnet-service
    skipParsing: true
    port:
    entity:
    mappings:
    identifier: .repo.path_with_namespace + "/" + .file.file_path
    title: .file.file_name
    blueprint: '"net_versions"'
    properties:
    dotnet_version: >-
    .file.content
    | capture("<TargetFrameworks?>(?<ver>[^<]+)</TargetFrameworks?>")
    | .ver
    file_path: .file.file_path
    relations:
    repository: .repo.path_with_namespace
  4. Click on Resync and Save and wait for the entities to be ingested in your Port environment.

How the JQ extraction works

The regex <TargetFrameworks?>(?<ver>[^<]+)</TargetFrameworks?> matches both:

  • <TargetFramework>net8.0</TargetFramework> (single target)
  • <TargetFrameworks>net6.0;net8.0</TargetFrameworks> (multi-target)

The ? after s makes the plural s optional, and capture returns the named group ver containing the version string (e.g., net8.0 or net6.0;net8.0).

XML files and skipParsing

This same skipParsing: true + JQ regex approach works for any XML-based manifest file (.nuspec, .fsproj, .props, pom.xml, etc.).

Add aggregation properties

To see a summary of .NET versions at the repository level, add aggregation properties to your repository blueprint.

  1. Go to the Builder page and select your Git repository blueprint.

  2. Click ... and choose {...} Edit JSON.

  3. Add the following to the aggregationProperties object:

    Aggregation properties JSON (click to expand)
    {
    "csproj_count": {
    "title": ".csproj file count",
    "target": "net_versions",
    "calculationSpec": {
    "calculationBy": "entities",
    "func": "count"
    }
    },
    "dotnet_versions_in_use": {
    "title": ".NET versions in use",
    "target": "net_versions",
    "calculationSpec": {
    "calculationBy": "property",
    "func": "unique",
    "property": "dotnet_version"
    }
    }
    }
  4. Click Save to update the blueprint.

This gives you a per-repository view showing how many .csproj files exist and the unique set of framework versions in use (e.g., net6.0, net8.0).

Summary

After completing this guide, you will have:

  • A net_versions blueprint where each entity represents a .csproj file.
  • Automatic extraction of the target framework from XML content using JQ regex.
  • Repository-level aggregation showing all .NET versions in use.

This pattern generalizes to any XML-based manifest. You can replace the file path and regex to track Java versions from pom.xml, Rust editions from Cargo.toml, or any other framework metadata.