Contributing to EncDotNet.S100
Thanks for your interest in contributing! EncDotNet.S100 is a managed, cross-platform implementation of the IHO S-100 Universal Hydrographic Data Model for .NET. This guide covers everything you need to build, test, and submit changes.
Prerequisites
- .NET 10 SDK or later.
- A git client.
- No native dependencies are required — HDF5 (PureHDF) and Lua (MoonSharp) are fully managed, so everything runs on macOS, Windows, and Linux.
Getting started
git clone https://github.com/philliphoff/EncDotNet.S100.git
cd EncDotNet.S100
dotnet build
Building
dotnet build
The solution targets .NET 10 with <Nullable>enable</Nullable> and
<ImplicitUsings>enable</ImplicitUsings> throughout. CI builds on
ubuntu-latest, so avoid platform-specific APIs unless they are gated to the
appropriate runtime identifier.
Testing
dotnet test --configuration Release
Test conventions:
- Every new public API or bug fix must be accompanied by an xunit test in the
appropriate project under
tests/. - Tests that require optional external data files (real HDF5, S-101 datasets,
etc.) must use
Xunit.SkippableFactviaSkip.If(...)so CI does not fail when those files are absent. - Never commit real ENC data files to the repository. Use small synthetic
test fixtures, or skip tests that require live data. Synthetic GML fixtures
live under
tests/datasets/<SXXX>/.
Package management
All NuGet versions are managed centrally via Central Package Management in
Directory.Packages.props:
- Do not add
Versionattributes to individual.csprojfiles. - Add or update versions in
Directory.Packages.propsinstead. - Before introducing any new dependency, run the
gh-advisory-databasesecurity check and confirm the package is free of known advisories.
Spec routing (skills & instructions)
This repository is organized around individual IHO S-100 product
specifications. Per-spec skills live under .github/skills/<spec>/SKILL.md
and matching instructions under .github/instructions/. Before designing
or implementing any non-trivial change that touches a spec's semantics
(encoding, attribute names, feature-catalogue rules, portrayal pipelines),
consult the matching skill/instruction file:
| Area | Skill / instruction |
|---|---|
| S-100 framework, exchange sets, portrayal engine | s100-framework |
| S-101 ENC, ISO 8211, Lua portrayal | s101-enc |
| S-102 bathymetry | s102-bathymetry |
| S-104 water level | s104-water-level |
| S-111 surface currents | s111-surface-currents |
| S-122 marine protected areas | s122-marine-protected-areas |
| S-124 navigational warnings | s124-nav-warnings |
| S-125 marine aids to navigation | s125-aton |
| S-127 marine resources and services | s127-marine-services |
| S-128 catalogue of nautical products | s128-catalogue |
| S-129 under keel clearance | s129-ukc |
| S-131 marine harbour infrastructure | s131-marine-harbour |
| S-201 IALA aids to navigation information | s201-aton-information |
| S-411 sea ice | s411-sea-ice |
| S-421 route plans | s421-route-plans |
For cross-spec changes (e.g. a change to CoveragePipeline affecting
S-102/S-104/S-111), reconcile the guidance from all affected specs before
writing code. Cite the relevant spec section number(s) in PR descriptions and
in XML doc comments for spec-derived constants, enums, attribute names, and
group paths.
Coding style
The normative style rules live in the C# coding style guide — read it before submitting code. In brief:
PascalCasefor types/methods/properties,camelCasefor locals and parameters,_camelCasefor private fields.- File-scoped namespaces, 4-space indents, Allman braces.
- Nullable reference types are enabled everywhere — avoid
!suppression; prefer null-checks orArgumentNullException.ThrowIfNull. - All public APIs must carry XML doc comments (
<summary>,<param>,<returns>). - Only comment code that genuinely needs clarification.
For API-shape conventions (collection return types, class vs record,
quantity types) see API design conventions.
The formatting rules are encoded in .editorconfig and
enforced in CI (the Format check job). Before pushing, apply and verify
formatting locally:
# Auto-fix whitespace/formatting across the solution
dotnet format whitespace EncDotNet.S100.slnx
# Auto-fix using directives (System-first ordering + remove unused)
dotnet format style EncDotNet.S100.slnx --diagnostics IDE0005
# Verify whitespace, usings, and naming with no changes (what CI runs)
dotnet format EncDotNet.S100.slnx --diagnostics IDE0005 IDE1006 --severity warn --verify-no-changes
CI gates whitespace/formatting, using directives (ordering + unused-directive removal), and naming.
dotnet formatcannot Fix-All IDE1006 naming violations, so fix those manually. Other style diagnostics are not machine-enforced solution-wide because style fix-all is unreliable on the multi-targeted (net8.0;net10.0) projects; follow those rules by hand (the.editorconfigstill flags them in your IDE).
Documentation
- Each library has a
README.mdin itssrc/<project>/directory. Update it when adding types, removing APIs, or changing behaviour. - Conceptual guides live under
docs/in DocFX Markdown. Add or update pages there for user-facing features. - Every public type and member in a packable library needs an XML doc comment; the build fails on a missing one (CS1591).
- The docs site (
docfx.json) publishesdocs/, the per-project READMEs (listed insrc/toc.yml) and the generated API reference. The Docs workflow builds it on every pull request withdocfx docfx.json --warningsAsErrors, so a broken link or#anchorfails the check. Link to repository files that aren't pages (source files,LICENSE, folders) with an absolute GitHub URL. When adding a library, add its README tosrc/toc.yml. - When editing the viewer (
src/EncDotNet.S100.Viewer/**), follow the localization and UI rules in.github/instructions/viewer.instructions.md(every user-facing string lives inResources/Strings.resx).
Release signing
The publish job in .github/workflows/ci.yml
code-signs the desktop viewer and the standalone s100 CLI for macOS and
Windows. Both are gated to non-PR runs (pushes to main and v* tags) and
are skipped automatically when the required secrets are absent, so forks and
pull requests build unsigned artifacts without failing.
macOS (Developer ID + notarization)
Signing/notarization runs when APPLE_DEVELOPER_CERTIFICATE_P12 is present.
Required repository secrets: APPLE_DEVELOPER_CERTIFICATE_P12,
APPLE_DEVELOPER_CERTIFICATE_PASSWORD, APPLE_SIGNING_IDENTITY, APPLE_ID,
APPLE_TEAM_ID, APPLE_APP_PASSWORD.
Windows (Azure Trusted Signing)
The Windows .exes are Authenticode-signed with
Azure Trusted Signing
via the azure/trusted-signing-action.
Signing runs when AZURE_CLIENT_ID is present.
One-time Azure setup:
- Create a Trusted Signing Account and a Public Trust certificate profile, and complete Microsoft identity validation. ("Private Trust" profiles do not clear SmartScreen warnings.)
- Register a single-tenant App registration (its service principal is the CI identity) and add a client secret.
- On the Trusted Signing Account's Access control (IAM), assign the app
the Trusted Signing Certificate Profile Signer role. Without this the
signing step fails with
403 Forbidden.
Required repository secrets (from the app registration):
| Secret | Source |
|---|---|
AZURE_TENANT_ID |
App registration → Overview → Directory (tenant) ID |
AZURE_CLIENT_ID |
App registration → Overview → Application (client) ID |
AZURE_CLIENT_SECRET |
App registration → Certificates & secrets → secret Value |
Required repository variables (non-secret, account-specific, case-sensitive):
| Variable | Source |
|---|---|
AZURE_SIGNING_ENDPOINT |
Trusted Signing Account → Overview → Account URI (e.g. https://wus2.codesigning.azure.net/) |
AZURE_SIGNING_ACCOUNT_NAME |
Trusted Signing Account name |
AZURE_SIGNING_PROFILE_NAME |
Certificate profile name |
The workflow signs every .exe under the viewer publish folder (covering both
the viewer and the bundled cli/s100.exe) before archiving, then a "Verify
Windows signatures" step asserts Get-AuthenticodeSignature returns Valid.
The identity is OV-level, so SmartScreen reputation accrues over downloads
rather than instantly.
Branch & pull-request workflow
- Create a topic branch off
main(e.g.fix-s104-trend-flagorfeature/s127-pilot-boarding). - Make focused, surgical changes that fully address one concern.
- Ensure
dotnet buildanddotnet test --configuration Releasepass locally. - Open a pull request against
main. The pull request template includes a checklist for spec alignment, tests, documentation, dependencies, and breaking changes — please fill it out. - CI must pass before review. Keep PRs small and well-scoped where possible.
Reporting bugs & requesting features
Use the issue templates under
.github/ISSUE_TEMPLATE/. For questions and
general discussion, see SUPPORT.md. To report a security
vulnerability, follow SECURITY.md — please do not open a
public issue for security problems.
License
By contributing, you agree that your contributions will be licensed under the MIT License that covers this project.