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
148 changes: 148 additions & 0 deletions .github/workflows/nuget-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
name: Nuget-Release

# Manual, versioned release of the Auriga NuGet packages (Auriga, Auriga.Xmi, Auriga.Extensions).
# Auriga.CodeGenerator and Auriga.Reporting are IsPackable=false, so `dotnet pack` on the solution
# produces exactly the three library packages (plus their .snupkg symbol packages). Packaging metadata,
# SBOM generation (Microsoft.Sbom.Targets) and SourceLink are configured in Directory.Build.props.

on:
workflow_dispatch:
inputs:
version:
description: 'SemVer (e.g., 1.0.0 or 1.0.0-beta.1)'
required: true
type: string

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
ref: ${{ github.event.repository.default_branch }}

- name: Validate version (SemVer)
run: |
set -euo pipefail
VERSION="${{ github.event.inputs.version }}"
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
if [[ "$VERSION" == *-* ]]; then
echo "PRERELEASE=true" >> "$GITHUB_ENV"
else
echo "PRERELEASE=false" >> "$GITHUB_ENV"
fi
else
echo "Provided version '$VERSION' is not SemVer." >&2
exit 1
fi

- name: Setup .NET
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0
with:
dotnet-version: '10.0.x'

- name: Set date
run: echo "DATE=$(date +'%Y-%m-%d')" >> "$GITHUB_ENV"

- name: Update CITATION.cff (version + date)
run: |
set -euo pipefail
# Top-level
sed -i "s/^version:.*/version: \"${VERSION}\"/" CITATION.cff
sed -i "s/^date-released:.*/date-released: \"${DATE}\"/" CITATION.cff
# preferred-citation (two-space indent)
sed -i "s/^ version:.*/ version: \"${VERSION}\"/" CITATION.cff
sed -i "s/^ date-released:.*/ date-released: \"${DATE}\"/" CITATION.cff

- name: Commit CITATION.cff to default branch
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add CITATION.cff

if ! git diff --cached --quiet; then
git commit -m "chore: release ${VERSION} (update CITATION.cff)"
git push origin HEAD:${DEFAULT_BRANCH}
else
echo "No changes to CITATION.cff."
fi

- name: Install xmlstarlet (for parsing csproj)
run: |
sudo apt-get update
sudo apt-get install -y xmlstarlet

- name: Build RELEASE_NOTES.md from PackageReleaseNotes
run: |
set -euo pipefail
echo "The following items have been fixed in this release:" > RELEASE_NOTES.md
echo "" >> RELEASE_NOTES.md

mapfile -t CSPROJS < <(git ls-files '*.csproj' | sort)

for csproj in "${CSPROJS[@]}"; do
# PackageId (fallback to file name)
pkg_id="$(xmlstarlet sel -t -v '(//Project/PropertyGroup/PackageId)[1]' "$csproj" 2>/dev/null || true)"
if [ -z "$pkg_id" ]; then
pkg_id="$(basename "$csproj" .csproj)"
fi

# Version (fallback to the workflow input)
pkg_version="$(xmlstarlet sel -t -v '(//Project/PropertyGroup/Version)[1]' "$csproj" 2>/dev/null || true)"
if [ -z "$pkg_version" ]; then
pkg_version="${VERSION}"
fi

# Multiline PackageReleaseNotes
notes="$(xmlstarlet sel -t -v '(//Project/PropertyGroup/PackageReleaseNotes)[1]' "$csproj" 2>/dev/null || true)"
notes="$(printf "%s" "$notes" | sed -e 's/\r$//')"

if [ -n "$notes" ]; then
printf "**%s [%s]**\n" "$pkg_id" "$pkg_version" >> RELEASE_NOTES.md
while IFS= read -r line; do
trimmed="$(printf "%s" "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
if [ -n "$trimmed" ]; then
cleaned="$(printf "%s" "$trimmed" | sed 's/^- \{0,1\}//')"
printf " - %s\n" "$cleaned" >> RELEASE_NOTES.md
fi
done <<< "$notes"
echo "" >> RELEASE_NOTES.md
fi
done

echo "----- RELEASE_NOTES.md -----"
cat RELEASE_NOTES.md

- name: Pack
run: dotnet pack -c Release -o ReleaseBuilds Auriga.sln

- name: Push to NuGet
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
run: dotnet nuget push ReleaseBuilds/*.nupkg -k "$NUGET_API_KEY" -s https://api.nuget.org/v3/index.json --skip-duplicate

- name: Create annotated tag at this commit
run: |
set -euo pipefail
git tag -a "${VERSION}" -m "Release ${VERSION}"
git push origin "refs/tags/${VERSION}"

- name: Create draft GitHub release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
FLAGS=(--draft --title "Auriga ${VERSION}" --notes-file RELEASE_NOTES.md --target "${DEFAULT_BRANCH}")
if [ "${PRERELEASE}" = "true" ]; then
FLAGS+=(--prerelease)
fi
gh release create "${VERSION}" "${FLAGS[@]}"
30 changes: 30 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."

title: "Auriga: A .NET library for reading, manipulating and writing Eclipse Capella models"
abstract: "Auriga is a suite of .NET libraries for reading, manipulating and writing Eclipse Capella (Arcadia) models in XMI form, exposing the Capella semantic model as a fully resolved in-memory object graph."
version: "0.1.0"
date-released: "2026-07-10"
url: "https://github.com/stariongroup/Auriga"

authors:
- given-names: "Sam"
family-names: "Gerené"
affiliation: "Starion Group S.A."
orcid: "https://orcid.org/0009-0000-1848-550X"
- name: "Starion Group S.A."

repository-code: "https://github.com/stariongroup/Auriga"
license: "Apache-2.0"

preferred-citation:
type: software
title: "Auriga: A .NET library for reading, manipulating and writing Eclipse Capella models"
authors:
- given-names: "Sam"
family-names: "Gerené"
orcid: "https://orcid.org/0009-0000-1848-550X"
- name: "Starion Group S.A."
version: "0.1.0"
url: "https://github.com/stariongroup/Auriga"
date-released: "2026-07-10"
2 changes: 2 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<PropertyGroup Condition="!$(MSBuildProjectName.EndsWith('.Tests'))">
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageIcon>cdp4-icon.png</PackageIcon>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GenerateSBOM>true</GenerateSBOM>
</PropertyGroup>
Expand All @@ -49,6 +50,7 @@
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="\" />
<None Include="$(MSBuildThisFileDirectory)LICENSE" Pack="true" PackagePath="\" />
<None Include="$(MSBuildThisFileDirectory)NOTICE" Pack="true" PackagePath="\" />
<None Include="$(MSBuildThisFileDirectory)cdp4-icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

<!--
Expand Down
52 changes: 46 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ Auriga is a suite of dotnet libraries and tools that are used to deserialize (re

Auriga builds on [ECoreNetto](https://github.com/STARIONGROUP/EcoreNetto) for reading the Capella Ecore metamodel, and is a sibling of [uml4net](https://github.com/STARIONGROUP/uml4net) and [SysML2.NET](https://github.com/STARIONGROUP/SysML2.NET). Auriga provides a number of libraries that are described in the following sections.

> **Scope note.** Version 1 targets the Capella **semantic model** (`.capella` / `.melodymodeller` and `.capellafragment` files). The Sirius diagram/representation files (`.aird`) are out of scope for v1.

## Auriga

The core library that contains the Capella object model: the C# implementation of the Capella metamodel (the Arcadia layers — Operational Analysis, System Analysis, Logical Architecture, Physical Architecture, EPBS — and the common packages), generated from the Capella Ecore metamodel. Together with **Auriga.Xmi** it provides the capability to read and write Capella models and make them available as an in-memory object graph.
Expand All @@ -18,14 +16,56 @@ The **Auriga.Xmi** library provides an XMI reader implementation to read Capella

The **Auriga.Extensions** library provides LINQ-style query extension methods over the Auriga object graph, following the `uml4net.Extensions` pattern: containment navigation (`QueryAncestors`, `QueryRoot`, `QueryAllFunctions`, `QueryAllComponents`), component-functional allocation (`QueryAllocatedFunctions`, `IsAllocatedTo`, `QueryAllocatingBlocks`), function/component ports and functional exchanges, and cross-layer realization (`QueryRealizedFunctions`/`QueryRealizingFunctions` and the component equivalents). See [Query Extension Methods](docs/query-extensions.md).

## Auriga.CodeGenerator

The **Auriga.CodeGenerator** is an Ecore-to-C# code generator, built on [ECoreNetto](https://github.com/STARIONGROUP/EcoreNetto) and [ECoreNetto.HandleBars](https://github.com/STARIONGROUP/EcoreNetto), that emits the Auriga object model from the vendored Capella `.ecore` files. It is a development-time tool and is not published as a package.

## Auriga.Reporting

The **Auriga.Reporting** tool renders a browsable HTML report of the Capella metamodel from the vendored `.ecore` files, using the [ECoreNetto](https://github.com/STARIONGROUP/EcoreNetto) `HtmlReportGenerator` — the same report generator used by the sibling projects (uml4net, SysML2.NET). The [`docker-build-docs-local.sh`](docker-build-docs-local.sh) and [`docker-build-docs-attested.sh`](docker-build-docs-attested.sh) scripts render the report and serve it from an nginx image ([`HtmlDocs/Dockerfile`](HtmlDocs/Dockerfile)). See [Capella Metamodel HTML Report](docs/metamodel-report.md) for build and run instructions. It is a development-time tool and is not published as a package.

# Getting Started

Install the packages from NuGet (once published):

```
dotnet add package Auriga
dotnet add package Auriga.Xmi
dotnet add package Auriga.Extensions
```

Load a Capella project, navigate the Arcadia layers, query it, and write it back:

```csharp
using Auriga.Xmi;
using Auriga.Extensions;

// 1) Load a project — pass the .capella / .melodymodeller file or the project directory.
// Referenced .capellafragment files are discovered and resolved into one object graph.
var project = CapellaProject.Load("In-Flight Entertainment System/In-Flight Entertainment System.capella");

// 2) Navigate the Arcadia layers as first-class properties (null when a layer is absent).
var logical = project.LogicalArchitecture;
var physical = project.PhysicalArchitecture;

// 3) Query with LINQ and the Auriga.Extensions methods.
foreach (var component in logical!.QueryAllComponents())
{
foreach (var function in component.QueryAllocatedFunctions())
{
// function.IsAllocatedTo(component) == true
}
}

// Any element can walk its own subtree; combine with LINQ for ad-hoc queries.
var exchanges = project.Project!
.QueryAllContainedElements()
.OfType<Auriga.Fa.IFunctionalExchange>();

// 4) Write the (possibly modified) model back to disk — the fragment layout is preserved.
var writer = XmiWriterBuilder.Create().Build();
writer.Write(project.Project!, "out/In-Flight Entertainment System.capella");
```

See [ContainerList Design](docs/containment-list.md), [Query Extension Methods](docs/query-extensions.md)
and [XMI Writer](docs/xmi-writer.md) for the containment, query and write-back APIs in depth.

# Code Quality

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=STARIONGROUP_Auriga&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=STARIONGROUP_Auriga)
Expand Down
Binary file added cdp4-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading