twinsphere.Vdi2770 0.1.0

dotnet add package twinsphere.Vdi2770 --version 0.1.0
                    
NuGet\Install-Package twinsphere.Vdi2770 -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="twinsphere.Vdi2770" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="twinsphere.Vdi2770" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="twinsphere.Vdi2770" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add twinsphere.Vdi2770 --version 0.1.0
                    
#r "nuget: twinsphere.Vdi2770, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package twinsphere.Vdi2770@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=twinsphere.Vdi2770&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=twinsphere.Vdi2770&version=0.1.0
                    
Install as a Cake Tool

twinsphere.Vdi2770

A .NET library providing utilities for working with VDI 2770 packages:

  • Conversion of VDI 2770 packages to AAS HandoverDocumentation structures
  • Validation of VDI 2770 packages for correctness

Installation

dotnet add package twinsphere.Vdi2770

Requires .NET 10 or later.

Usage

Results over Exceptions

Public APIs return FluentResults Result/Result<T> values instead of throwing exceptions. Callers must check result.IsSuccess / result.IsFailed before consuming the value. Exceptions are reserved for programming errors (precondition violations) and catastrophic/unrecoverable failures.

Validating a Package

Vdi2770Validator checks a VDI 2770 package ZIP for structural, model, and consistency errors:

using twinsphere.Vdi2770.Validation;

var validator = new Vdi2770Validator();
var result = validator.Validate(packagePath);

if (result.IsFailed)
{
    // Inspect result.Errors for details (e.g. PackageValidationError instances)
}

Vdi2770ValidationOptions.ValidationLevel controls how strictly a package is validated:

  • ValidationLevel.Vdi2770Conformance (default) checks only what the VDI 2770 standard strictly mandates.
  • ValidationLevel.Strict additionally flags unreferenced files, unresolvable document relationships, duplicate DocumentVersion languages, and orphaned RefersTo relationships.

Independently of the validation level, a nested Document Container or Documentation Container is only included in the converted/validated model if it is referenced via a RefersTo DocumentRelationship from its enclosing container's main document; unreferenced sub-containers present in the ZIP are excluded from the result (and, in Strict mode, reported as an error).

var options = new Vdi2770ValidationOptions { ValidationLevel = ValidationLevel.Strict };
var validator = new Vdi2770Validator(options);
var result = validator.Validate(packagePath);

Converting a Package

Vdi2770Converter validates a package and converts it into an AAS HandoverDocumentation payload, streaming the result into a caller-supplied IHandoverDocumentationSink and routing any digital files through a caller-supplied IDigitalFileHandler:

using twinsphere.Vdi2770.Conversion;

var converter = new Vdi2770Converter();
var result = await converter.ConvertAsync(
    packagePath,
    submodelId: "https://example.com/ids/sm/1234",
    sink: mySink,               // implements IHandoverDocumentationSink
    digitalFileHandler: myFileHandler // implements IDigitalFileHandler
);

if (result.IsFailed)
{
    // Inspect result.Errors for details
}

IHandoverDocumentationSink receives the converted payload (e.g. to serialise it to JSON), and IDigitalFileHandler decides where each digital file referenced by the package ends up (e.g. a directory, archive, or blob store), returning the URI to embed in the resulting HandoverDocumentation.

Retrieving the Code

git clone https://dev.azure.com/twinsphere/Foundation/_git/twinsphere.Vdi2770
cd twinsphere.Vdi2770

Building

Requires the .NET 10 SDK.

dotnet restore
dotnet build

Running Tests

Run the full test suite:

dotnet test

Run a single test by name:

dotnet test --filter "FullyQualifiedName~Vdi2770ConverterTests"

Run a single test project:

dotnet test tests/twinsphere.Vdi2770.Tests.Unit/twinsphere.Vdi2770.Tests.Unit.csproj

Code Style

This project uses the following tools to enforce consistent formatting:

Tool Purpose Config
CSharpier C# code formatter defaults
Biome JSON/XML formatter and linter defaults
EditorConfig IDE-level style rules .editorconfig

To format C# files manually:

dotnet tool restore
dotnet csharpier .

Pre-commit Hooks

This project uses pre-commit to automatically format code and validate commit messages before each commit.

Setup

  1. Install pre-commit:

    pip install pre-commit
    
  2. Install the hooks:

    pre-commit install --hook-type pre-commit --hook-type commit-msg
    

The hooks will now run automatically on git commit. To run them manually against all files:

pre-commit run --all-files

Configured hooks

Hook What it does
csharpier Auto-formats staged C# files
biome-check Formats and lints staged JSON/XML files
commitlint Validates commit message format (conventional commits)

Contributing

This project follows GitHub Flow:

  1. Create a feature branch from main (feat/my-feature, fix/my-fix, etc.)
  2. Commit your changes with conventional commit messages (see below)
  3. Open a pull request against main
  4. After review and CI passing, merge using squash or merge commit

Please ensure pre-commit hooks are installed and passing before opening a pull request.

Versioning

This project follows Semantic Versioning. The current version is maintained in the <VersionPrefix> property of src/twinsphere.Vdi2770/twinsphere.Vdi2770.csproj, and is kept up to date automatically by the release pipeline (see Releasing) — you normally don't need to edit it by hand.

Releasing

Releases are triggered by pushing a tag of the form:

release/vX.Y.Z
release/vX.Y.Z-SUFFIX   # pre-release, e.g. release/v1.2.0-RC1

Pushing such a tag to the Azure DevOps repository runs pipelines/build.azure-pipelines.yml, which:

  1. Parses the version (and optional pre-release suffix) directly out of the tag name.
  2. Builds, tests, and packs the NuGet package using that version, overriding whatever is currently checked into the .csproj (-p:VersionPrefix=X.Y.Z).
  3. Publishes the package to nuget.org (after manual approval).
  4. Commits the resolved X.Y.Z back into <VersionPrefix> on main (suffix dropped), so the repository's on-disk version stays in sync without a manual edit.

The sync-back commit uses the ***NO_CI*** marker so it doesn't re-trigger the pipeline.

Note: the pipeline's Build Service identity must have "Contribute" permission on the repository (and "Bypass policies when pushing" if main has branch policies) for step 4 to succeed. This is a one-time Azure DevOps project setting, not something configured in this repository.

Publishing to nuget.org requires a nuget_api_key secret (see the twinsphere.Vdi2770-cicd Library variable group in Azure DevOps). nuget.org caps API key lifetimes at 30 days, so this key must be regenerated and updated in the Library group periodically — nuget.org does not yet support OIDC-based keyless "Trusted Publishing" for Azure DevOps (only GitHub Actions and GitLab CI, as of this writing).

Commit Messages

Commit messages must follow the Conventional Commits specification. This is enforced by the commitlint pre-commit hook and the CI pipeline.

Examples:

feat: add VDI 2770 package validation
fix: handle missing metadata in converter
docs: update README with build instructions
chore: bump FluentResults to 3.17.0

License

This software is subject to copyright. See LICENSE for the full terms.

Changelog

See CHANGELOG.md for release history.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 88 9/8/2026