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
58 changes: 58 additions & 0 deletions .github/ISSUE_TEMPLATE/release-candidate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Release candidate feedback
description: Report OpenDisNet 0.9 RC interoperability, API, performance, or documentation results.
title: "[RC feedback]: "
body:
- type: markdown
attributes:
value: |
Thank you for testing the OpenDisNet release candidate. Do not attach controlled, private, or operational packet captures.
- type: input
id: version
attributes:
label: Package version
description: Enter the exact prerelease version, for example 0.9.0-rc.1.
placeholder: 0.9.0-rc.1
validations:
required: true
- type: input
id: environment
attributes:
label: Environment
description: Include the target framework, operating system, architecture, and application type.
placeholder: .NET 10, Windows 11 x64, UDP simulation gateway
validations:
required: true
- type: dropdown
id: category
attributes:
label: Feedback category
options:
- Wire interoperability
- API usability
- Performance or allocation
- Packaging or installation
- Documentation
- Successful validation
validations:
required: true
- type: textarea
id: families
attributes:
label: PDU families and workflows tested
description: Describe the representative workflows and protocol families you exercised.
validations:
required: true
- type: textarea
id: result
attributes:
label: Result
description: Explain what worked or failed, the expected behavior, and a minimal synthetic reproduction when applicable.
validations:
required: true
- type: checkboxes
id: safety
attributes:
label: Data handling
options:
- label: I confirm this report contains no controlled, private, or operational packet capture.
required: true
8 changes: 7 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ jobs:
- run: dotnet run --project tools/OpenDisNet.Generator/OpenDisNet.Generator.csproj --configuration Release --no-restore -- --verify
- run: dotnet build --configuration Release --no-restore
- run: dotnet test --configuration Release --no-build
- run: dotnet pack src/OpenDisNet/OpenDisNet.csproj --configuration Release --no-build --output artifacts/packages
- run: dotnet pack src/OpenDisNet/OpenDisNet.csproj --configuration Release --no-build --output artifacts/packages -p:PackageVersion=0.0.0-ci.${{ github.run_id }}
- name: Restore packed-package consumer
run: dotnet restore tests/OpenDisNet.PackageSmoke/OpenDisNet.PackageSmoke.csproj --source "${{ github.workspace }}/artifacts/packages" --force --no-cache -p:OpenDisNetPackageVersion=0.0.0-ci.${{ github.run_id }}
- name: Run packed-package consumer on .NET 9
run: dotnet run --project tests/OpenDisNet.PackageSmoke/OpenDisNet.PackageSmoke.csproj --configuration Release --framework net9.0 --no-restore -p:OpenDisNetPackageVersion=0.0.0-ci.${{ github.run_id }}
- name: Run packed-package consumer on .NET 10
run: dotnet run --project tests/OpenDisNet.PackageSmoke/OpenDisNet.PackageSmoke.csproj --configuration Release --framework net10.0 --no-restore -p:OpenDisNetPackageVersion=0.0.0-ci.${{ github.run_id }}
- uses: actions/upload-artifact@v7
if: matrix.os == 'ubuntu-latest'
with:
Expand Down
14 changes: 13 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ jobs:
- run: dotnet restore --locked-mode
- run: dotnet test --configuration Release --no-restore
- run: dotnet pack src/OpenDisNet/OpenDisNet.csproj --configuration Release --no-restore --output artifacts/packages -p:PackageVersion=${{ env.PACKAGE_VERSION }}
- name: Restore packed-package consumer
run: dotnet restore tests/OpenDisNet.PackageSmoke/OpenDisNet.PackageSmoke.csproj --source "${{ github.workspace }}/artifacts/packages" --force --no-cache -p:OpenDisNetPackageVersion=${{ env.PACKAGE_VERSION }}
- name: Run packed-package consumer on .NET 9
run: dotnet run --project tests/OpenDisNet.PackageSmoke/OpenDisNet.PackageSmoke.csproj --configuration Release --framework net9.0 --no-restore -p:OpenDisNetPackageVersion=${{ env.PACKAGE_VERSION }}
- name: Run packed-package consumer on .NET 10
run: dotnet run --project tests/OpenDisNet.PackageSmoke/OpenDisNet.PackageSmoke.csproj --configuration Release --framework net10.0 --no-restore -p:OpenDisNetPackageVersion=${{ env.PACKAGE_VERSION }}
- name: Authenticate to NuGet.org
uses: NuGet/login@v1
id: nuget
Expand All @@ -37,4 +43,10 @@ jobs:
- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "${{ github.ref_name }}" artifacts/packages/*.*nupkg --generate-notes --verify-tag
shell: bash
run: |
flags=(--generate-notes --verify-tag)
if [[ "${{ github.ref_name }}" == *-* ]]; then
flags+=(--prerelease)
fi
gh release create "${{ github.ref_name }}" artifacts/packages/*.*nupkg "${flags[@]}"
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ Versioning after 1.0 and uses prerelease versions while conformance is incomplet

## Unreleased

- Froze the complete public C# surface with compiler-enforced API baselines and
NuGet package compatibility validation against OpenDisNet 0.8.0.
- Added an external-style smoke consumer that installs the packed artifact and
exercises all 72 PDU factory/codec paths on .NET 9 and .NET 10.
- Added prerelease-aware publishing, an external 0.9 RC test checklist, and a
structured GitHub feedback form.
- Corrected the `RadioId` construction example discovered by the package smoke
consumer.
- Added deterministic populated conformance cases for all 72 DIS v7 PDU types,
independent byte vectors, and truncation checks at every byte boundary across
all 12 protocol families planned for versions 0.3 through 0.8.
Expand Down
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ Contributions should include specification-section provenance, known binary
vectors, round-trip tests, and malformed-input tests. Run `dotnet test
--configuration Release` before opening a pull request. Do not submit IEEE
specification text or non-public operational packet captures.

The public API is frozen during the 0.9 release-candidate cycle. Additive API
changes must update `src/OpenDisNet/PublicAPI.Unshipped.txt`, include tests, and
describe the consumer benefit in the changelog. Removals or signature changes
require explicit breaking-change review and a new release candidate.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
OpenDisNet is a high-performance, type-safe .NET codec for Distributed
Interactive Simulation (DIS) Protocol Version 7, defined by IEEE 1278.1-2012.

> **Development status:** pre-release. All 72 DIS v7 PDU identifiers have typed
> models and native C# binary codecs. Every protocol family has populated
> round-trip and boundary-truncation coverage; remaining 1.0 release gates are
> tracked in [`docs/conformance.md`](docs/conformance.md).
> **Development status:** 0.9 release-candidate hardening. All 72 DIS v7 PDU
> identifiers have typed native C# codecs, every family has populated and
> boundary-truncation coverage, and the public API is frozen for external
> validation. See the [`RC testing guide`](docs/release-candidate.md) and
> [`conformance matrix`](docs/conformance.md).

## Install

Expand Down Expand Up @@ -57,7 +58,7 @@ var signal = new SignalPdu
{
ExerciseId = 1,
Timestamp = 42,
Radio = new RadioId(new EntityId(1, 10, 42), number: 7),
Radio = new RadioId(new EntityId(1, 10, 42), 7),
EncodingScheme = SignalEncodingScheme.EncodedAudio(SignalEncodingType.Opus),
TdlType = SignalTdlType.Other,
SampleRate = 8_000,
Expand Down
13 changes: 10 additions & 3 deletions docs/api-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ untrusted network input.

## Compatibility

The package is pre-1.0 while the complete PDU surface is being reviewed. After
1.0, public names and wire behavior follow semantic versioning. Internal codec
generation may change without becoming part of the supported API.
The 0.9 release-candidate line freezes the complete public C# surface before
1.0. `PublicAPI.Shipped.txt` is the reviewable contract. Compiler analyzers
reject an unrecorded public addition or removal, and NuGet package validation
compares new artifacts with version 0.8.0 for binary compatibility.

New API belongs in `PublicAPI.Unshipped.txt` and requires tests plus a changelog
entry. Removing or changing frozen API requires explicit breaking-change review
and another release candidate. After 1.0, public names and wire behavior follow
semantic versioning. Internal codec generation may change without becoming part
of the supported API.
9 changes: 9 additions & 0 deletions docs/conformance.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ input tests, and round-trip tests.
- [x] 0.8 Live Entity
- [x] 0.8 Information Operations

## 0.9 release readiness

- [x] Frozen, compiler-enforced public C# API baseline
- [x] NuGet package compatibility validation against 0.8.0
- [x] Packed-package consumer validation on .NET 9 and .NET 10
- [x] Prerelease-aware GitHub and NuGet publishing workflow
- [x] External RC validation checklist and structured feedback form
- [ ] External RC feedback reviewed and high-impact findings resolved

Family coverage is implemented and exercised entirely in C#/.NET. Frozen bytes
from an independent implementation are test inputs only; they are not product
code or a runtime/build dependency. Two default vectors and 28 aggressively
Expand Down
53 changes: 53 additions & 0 deletions docs/release-candidate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# 0.9 external release candidate

Version 0.9 is the public API freeze and external validation stage before 1.0.
The current C# surface is recorded in `PublicAPI.Shipped.txt`; builds reject an
undocumented addition or removal, and package validation compares every new
artifact with the published 0.8.0 package.

## Install an RC

Release candidates use SemVer tags such as `v0.9.0-rc.1`. After a candidate is
published, install that exact version so test results remain reproducible:

```shell
dotnet add package OpenDisNet --version 0.9.0-rc.1
```

GitHub and NuGet identify RC builds as prereleases. Do not use an RC in a
production exercise unless your own release policy permits prerelease packages.

## External validation checklist

Test the workflows that resemble your application rather than only constructing
empty PDUs:

1. Deserialize representative, non-sensitive DIS v7 datagrams from each family
your application consumes.
2. Inspect the typed properties your application needs and reserialize the PDU.
3. Construct and transmit representative PDUs using ordinary object initializers.
4. Confirm unknown enumeration values, reserved bits, and vendor-defined bodies
survive a decode/encode round trip when applicable.
5. Exercise caller-owned buffers or sustained packet rates if allocation and
throughput matter to your application.
6. Build with nullable analysis and warnings enabled to expose API friction.

Never attach controlled, private, or operational packet captures. Reduce a
problem to synthetic bytes or property values before reporting it.

## Report results

Use the repository's **Release candidate feedback** issue form. Include the
exact package version, target framework, operating system, PDU families tested,
and whether the problem concerns API usability, wire interoperability,
performance, or documentation.

## 1.0 exit criteria

- Public API analyzer and 0.8.0 package-compatibility validation remain clean.
- The packed-package consumer passes on .NET 9 and .NET 10.
- No unresolved high-impact wire-correctness or data-loss defect remains.
- External testing covers real application workflows without relying on
sensitive captures.
- Any intentional API change after the freeze is documented, reviewed as a
breaking-change candidate, and followed by another RC.
11 changes: 11 additions & 0 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ publishes to NuGet.org, and creates a GitHub release for tags such as `v0.2.0`.
GitHub-generated notes are categorized using `.github/release.yml`, and package
plus symbol artifacts are attached to the release shown on the repository page.

Prerelease tags use SemVer identifiers such as `v0.9.0-rc.1`. The workflow
derives the package version from the tag and marks the GitHub release as a
prerelease automatically. Before publishing any tag, the workflow validates the
public API, compares the package with the 0.8.0 compatibility baseline, and runs
an external-style consumer against the packed artifact on .NET 9 and .NET 10.

The RC testing contract and feedback process are documented in
[`release-candidate.md`](release-candidate.md). Promote an RC to a stable tag
only after its exit criteria are satisfied; published NuGet versions and GitHub
releases are never rewritten.

## One-time NuGet.org setup

1. Reserve or publish the `OpenDisNet` package ID under the intended NuGet.org owner.
Expand Down
6 changes: 6 additions & 0 deletions src/OpenDisNet/OpenDisNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<EnablePackageValidation>true</EnablePackageValidation>
<PackageValidationBaselineVersion>0.8.0</PackageValidationBaselineVersion>
<EnableStrictModeForCompatibleTfms>true</EnableStrictModeForCompatibleTfms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="5.6.0" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>
Expand Down
Loading
Loading