Skip to content

Latest commit

 

History

History
211 lines (179 loc) · 10.6 KB

AGENTS.md

File metadata and controls

211 lines (179 loc) · 10.6 KB

AGENTS.md

Project instructions for AI agents working in this repository. Read this before building, cleaning, or releasing anything.

Repository layout

Every project has its own top-level folder beside the solution file — there are no src/apps/tests/samples grouping folders. The solution mirrors the disk (always keep the two in sync — a project's path in CSharp_XISOSharp.sln must match its real folder):

Folder Contents
XISOSharp/ Shipped library (NuGet: XISOSharp)
XISOSharp.Cli/ Shipped command-line executable
XISOSharp.Gui/ Shipped Avalonia desktop app
XISOSharpTester/ Windows-only WPF regression rig
XISOSharp.Sample/ Library walkthrough app
XISOSharp.Tests/ xUnit suite
XISOSharp.BattleTests/ CLI-vs-reference battle harness
XISOSharp.Benchmarks/ BenchmarkDotNet harness
XISOSharp.Fuzz/ Mutation fuzzer
XISOSharp.AotSmoke/ NativeAOT publish/run smoke check
XISOSharp.TestDataGenerator/ Deterministic TestData/ fixture generator
docs/, References/, TestData/ Docs, vendored upstream sources, gitignored fixtures — stay at the repo root
  • Directory.Build.props defines $(RepoRoot); cross-project paths (linked Compile items, ProjectReference, the strong-name key, staged CLI outputs) use it instead of ..\..\ chains. Add new cross-project references that way.
  • TestDataLocator finds the repo root by walking up to CSharp_XISOSharp.sln, so keep the solution file at the root. TestData/ stays there too.
  • References/** is never part of the solution; it holds oracle binaries and third-party sources for parity work.

Hard rule: never delete files in Release output paths

Release output trees are artifact stores, not disposable caches. They hold previously shipped bundles (e.g. XISOSharp.Gui/bin/Release/release_1.0.1_win-x64.zip) that may not be reproducible or re-downloadable. Never delete them.

  • Never delete or remove files under a project's Release output paths:
    • any */bin/Release/** (library, CLI, GUI, Tests, Tester, Benchmarks, BattleTests, TestDataGenerator)
    • publish/**, publish-gui/** (publish-script outputs)
    • any release_*.zip, *.nupkg, *.snupkg file anywhere
  • Never run destructive cleanups against them: dotnet clean -c Release, Remove-Item -Recurse on bin/obj/publish*, git clean -xdf, etc.
  • Fresh builds go through a temp staging directory (%TEMP%\xiso_bundle\<rid> — safe to wipe) and only write/overwrite the exact artifact being rebuilt in the Release path. Creating new files and overwriting the same-named artifact for the current version is fine; deleting older or unrelated artifacts is not.
  • If a clean of a Release path seems required (corrupt output, TFM/RID change), stop and ask the user first.

CI

  • .github/workflows/ci.yml builds the full solution on ubuntu/windows/macos and runs the sequential test suite on all three. The suite restores the process working directory after each test; keep that invariant when adding CWD-sensitive tests.
  • The same workflow gates on gui-smoke (CLI -v, GUI --probe-cli / --self-test), inspectcode (JetBrains InspectCode, pinned 2026.2.3.1, fails on any warning/error and uploads SARIF), dependency-audit (dotnet list package --vulnerable), aot-smoke (NativeAOT publish + run), fuzz-smoke (2-minute mutation fuzz) and battle-interop (synthetic copyright-free corpus vs the checked-in extract-xiso/xdvdfs/xboxkit oracles). Keep InspectCode at 0 warnings; the floor is enforced in CI.
  • Coverage: the Windows test job writes merged line/branch coverage to the job summary and fails below MIN_LINE_COVERAGE (70%) or MIN_BRANCH_COVERAGE (60%).
  • Formatting: dotnet format whitespace --verify-no-changes runs on the Windows runner (the CRLF working tree matches .editorconfig); run it locally before pushing.
  • The test suite runs on Ubuntu, Windows and macOS (the suite restores the process working directory); Linux/macOS also build the Windows-only Tester/GUI projects.
  • Companion workflows: codeql.yml (CodeQL C#), dependency-review.yml (PRs), scorecard.yml (OpenSSF Scorecard), release.yml (tag: six RID bundles + GitHub release), pages.yml/wiki.yml (docs).
  • Tag pushes trigger the tag-only publish-nuget job; PR/branch runs stop at pack. release.yml runs in parallel and creates the GitHub release.
  • The three TFM test hosts run in parallel and share one TestData/ tree; the fixture stamps TestData/output/fixture.stamp so only the first host rebuilds the ISO (TestDataWriter). Do not make the ISO rebuild unconditional again.
  • XISOSharp.Tests is strong-named with XISOSharp/XISOSharp.snk because the library grants it InternalsVisibleTo with the matching public key embedded in XISOSharp.csproj; keep the key file, the test SignAssembly settings, and the embedded public key in sync when touching signing.

Routine: publish a library package (NuGet)

Versioning facts

  • 1.5.0 is published (2026-11-01). Do not reuse the version or move the 1.5.0 tag again. The next release is at least 1.6.0; the old 1.6.0 notes were merged into 1.5.0 and must not be published as a separate tag.
  • Version comes from git tags via MinVer. Never add or edit a Version property in a csproj.
  • Release tags are bare semver: 1.0.0, 1.0.1, 1.0.2 (v1.0.2 also works). N commits after tag 1.0.1 report 1.0.2-alpha.0.N+<sha>.
  • NuGet versions are immutable: never reuse one. --skip-duplicate makes re-runs idempotent.
  • CI is .github/workflows/ci.yml; its tag-only publish-nuget job packs the library and pushes XISOSharp.<version>.nupkg + .snupkg using the NUGET_API_KEY secret in the nuget environment (already configured).

Steps

  1. Finalize documentation first — the package bakes it in:

    • XISOSharp/README.md is packed into the nupkg (PackageReadmeFile), and XISOSharp/XISOSharp.csproj holds the nuget.org Description.
    • Add the release section to docs/release-notes.md, refresh WhatsNew.md, and update the READMEs (root, library, CLI, Tests, Tester) plus any docs the change touched.
    • Upstream parity references use the dated build (extract-xiso build 202609111233), not v2.7.1. Never change the on-disk optimized tag in!xiso!2.7.1 (01.11.14) or Constants.ExisoVersion.
  2. Run the full suite: dotnet test XISOSharp.Tests/XISOSharp.Tests.csproj -c Release (currently 2098 passed / 1 skipped on net8.0/net9.0 and 2162 passed / 1 skipped on net10.0 — net10.0 adds the GUI-helper tests).

  3. Commit + push master (only when the user asks), then tag and push: git tag <version> && git push origin <version>.

  4. The tag push triggers CI pack + publish. If the nuget environment has protection rules, approve the deployment in GitHub Actions. Verify with gh run list --workflow=ci.yml and https://api.nuget.org/v3-flatcontainer/xisosharp/index.json (indexing can lag a few minutes).

  5. Manual fallback (CI unavailable or local verification):

    dotnet pack XISOSharp/XISOSharp.csproj -c Release -o artifacts\<version>
    dotnet nuget push "artifacts\<version>\XISOSharp.<version>.nupkg" --api-key $env:NUGET_API_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate
    dotnet nuget push "artifacts\<version>\XISOSharp.<version>.snupkg" --api-key $env:NUGET_API_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate

    Push the nupkg before the snupkg (symbols require the package to exist).

Routine: publish a GitHub release

GitHub releases carry only the six RID app bundles; the library packages stay NuGet-only (user decision). The CLI's [UPDATE] check downloads release_<version>_<rid>.zip from the latest release, so asset names and the release tag must match the version exactly.

Automated path (default): .github/workflows/release.yml runs on the tag push, builds all six bundles on ubuntu-latest with the recipe below, smoke-tests win-x64/linux-x64/MacOsX-arm64, and creates the release from the tag with the version's docs/release-notes.md section as the body. Re-runs refresh the same-named assets (gh release upload --clobber) and never delete other assets. To rehearse without tagging, dispatch the workflow with dry_run: true.

Manual fallback (CI unavailable or local verification):

  1. Build the bundles (recipe below) for: win-x64, win-arm64, linux-x64, linux-arm64, MacOsX-x64, MacOsX-arm64.

  2. Create the release from the pushed tag. The body is the version's section of docs/release-notes.md:

    gh release create <version> --title <version> --notes-file <version-notes.md>
  3. Upload all six bundles:

    gh release upload <version> XISOSharp.Gui/bin/Release/release_<version>_win-x64.zip \
      XISOSharp.Gui/bin/Release/release_<version>_win-arm64.zip \
      XISOSharp.Gui/bin/Release/release_<version>_linux-x64.zip \
      XISOSharp.Gui/bin/Release/release_<version>_linux-arm64.zip \
      XISOSharp.Gui/bin/Release/release_<version>_MacOsX-x64.zip \
      XISOSharp.Gui/bin/Release/release_<version>_MacOsX-arm64.zip
  4. Verify:

    • gh release view <version> --json assets lists exactly the six zips.
    • https://github.com/purelogiccode/XISOSharp/releases/download/<version>/release_<version>_win-x64.zip returns HTTP 200.
  5. Never attach *.nupkg/*.snupkg to the release, and never delete existing release assets unless the user asks.

Bundle build recipe (framework-dependent)

Outputs need the .NET 10 runtime (Desktop Runtime for the GUI). For each RID, stage into %TEMP% (safe to wipe) and produce the zip under XISOSharp.Gui/bin/Release/:

$stage = "$env:TEMP\xiso_bundle\<rid>"
# create/clear ONLY the temp stage
dotnet publish XISOSharp.Gui/XISOSharp.Gui.csproj -c Release -r <rid> --no-self-contained -o $stage
dotnet publish XISOSharp.Cli/XISOSharp.Cli.csproj -c Release -f net10.0 -r <rid> --no-self-contained -p:PublishTrimmed=false -o $stage
Get-ChildItem $stage -Include *.pdb,*.xml -Recurse | Remove-Item -Force
Copy-Item README.md $stage
Copy-Item LICENSE $stage
Copy-Item WhatsNew.md $stage
Compress-Archive "$stage\*" "XISOSharp.Gui\bin\Release\release_<version>_<rid>.zip" -Force

Each zip must contain exactly the GUI app, XISOSharp(.exe), README.md, LICENSE, and WhatsNew.md — no *.pdb / *.xml.

Smoke-test from an extracted zip:

  • XISOSharp.exe -v → XISOSharp v<version> for <platform> - https://github.com/purelogiccode/XISOSharp
  • XISOSharp.Gui.exe --probe-cli → XISOSharp <version>
  • XISOSharp.Gui.exe --self-test <path-to-cli> → SELF-TEST: all passed