podman-client-dotnet/CONTRIBUTING.md
2026-07-28 22:30:11 +02:00

5.2 KiB

Contributing to PodmanClient.DotNet

Thank you for contributing. This repo follows MaksIT conventions (see AGENTS.md and homelab common/csharp / common/maksit-repo-maintenance skills).

Development setup

Prerequisites

  • .NET 10 SDK
  • Git
  • PowerShell 7 hosted on .NET 10 (for the PowerShell module and E2E)
  • Optional: reachable Podman REST API for live E2E (PODMAN_TEST_URL)

Build

dotnet build src/PodmanClientDotNet.slnx

Unit tests

RepoUtils test engine (coverage + badges):

utils/Invoke-TestEngine.bat

Direct:

dotnet test src/PodmanClientDotNet.Tests/PodmanClientDotNet.Tests.csproj

Coverage badges in README.md are rewritten by the test engine (CoverageBadges with badgeFormat: shields and readmePath in utils/engines/test/scriptSettings.json) using img.shields.io URLs. Commit the updated README when coverage changes.

Integration / E2E tests (Podman API VM)

Live API coverage is PowerShell E2E under src/e2e-tests/ (not part of Invoke-TestEngine). It builds and imports MaksIT.PodmanClientDotNet.PowerShell, then runs domain scenarios against a real Podman API.

Validated target: Podman 5.4.0 (libpod path default ApiVersion = v5.4.0). Older engines that expose at least API 4.0.0 may work; Docker-compat path v1.41 is not used (network endpoints reject it).

1. Expose Podman on a Linux VM (e.g. Alma)

podman version   # expect 5.4.x for this repo's E2E baseline

# Bind all interfaces (not only 127.0.0.1)
podman system service --time=0 tcp://0.0.0.0:8080

On the VM:

curl -s http://127.0.0.1:8080/v5.4.0/_ping   # expect OK
ss -tlnp | grep 8080                        # expect 0.0.0.0:8080 (or LAN IP)
sudo firewall-cmd --add-port=8080/tcp --permanent && sudo firewall-cmd --reload
podman pull alpine:latest                   # scenarios need registry access

Optional systemd unit (lab):

[Unit]
Description=Podman API service
After=network.target

[Service]
ExecStart=/usr/bin/podman system service --time=0 tcp://0.0.0.0:8080
Restart=on-failure

[Install]
WantedBy=multi-user.target

Unauthenticated TCP API is lab-only — restrict firewall to your developer machine when possible.

2. Run E2E from Windows

Invoke-WebRequest http://<vm-ip>:8080/v5.4.0/_ping   # expect 200 / OK
$env:PODMAN_TEST_URL = "http://<vm-ip>:8080"        # must include http:// or https://
.\src\e2e-tests\Test-PodmanE2E.bat
# or:
pwsh -File .\src\e2e-tests\Test-PodmanE2E.ps1 -Scenario 'System','Images'

PODMAN_TEST_URL must be an absolute URI. Bare host:port causes UriFormatException in the .NET client.

Scenarios cover system, images, containers, exec, volumes, networks, pods, build, manifests, and generate (full PowerShell cmdlet surface). Filter with -Scenario.

Troubleshooting

  1. Pull fails — VM cannot reach a registry; pre-pull alpine:latest on the VM.
  2. Container create/start fails — confirm podman run --rm alpine:latest echo ok as the same user running system service.
  3. Attach/exec session failures — hijack opens a second TCP connection to the same host:port; allow it in the firewall; do not put the API behind a proxy that strips Upgrade: tcp.
  4. pwsh / .NET 10 — binary module requires PowerShell hosted on .NET 10.
  5. version is not supported on networks — use libpod path v4.0.0+ (default v5.4.0), not Docker-compat v1.41.

PowerShell module

dotnet build src/PodmanClient.PowerShell/PodmanClient.PowerShell.csproj
Import-Module .\src\PodmanClient.PowerShell\bin\Debug\net10.0\MaksIT.PodmanClientDotNet.PowerShell.psd1 -Force
Connect-Podman -BaseAddress $env:PODMAN_TEST_URL

See src/PodmanClient.PowerShell/README.md.

Commit message format

(type): description

Types: (feature):, (bugfix):, (refactor):, (perf):, (test):, (docs):, (build):, (ci):, (style):, (revert):, (chore):.

  • Lowercase description; no trailing period.

Code style

  • .NET 10, nullable reference types, implicit usings.
  • Root namespace: MaksIT.$(MSBuildProjectName) in PodmanClientDotNet.csproj; omit namespace when it matches the root (client partials, abstractions).
  • MaksIT.Results for API outcomes; System.Text.Json source generation via PodmanJsonContext for JSON serialization (AOT/trim-safe).
  • File-scoped namespaces and same-line braces; Models/ use nullable reference types (string?, List<T>?, …) for optional JSON fields.
  • XML documentation on public types (DTOs, interfaces, entry types). Method-level docs on large interfaces are optional (CS1591 suppressed).

Pull requests

  1. Build and unit tests pass; run E2E when changing the client or PowerShell surface if a Podman API is available.
  2. Update README.md / CHANGELOG.md when behavior or public API changes.
  3. If coverage changed: ensure README.md shields.io badge lines were updated by the test engine.
  4. Keep diffs scoped.

Versioning

Semantic Versioning: bump Version in src/PodmanClient/PodmanClientDotNet.csproj with CHANGELOG.md for releases. Use utils\Invoke-ReleasePackage-Single.bat when releasing.