You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Upgrades the Mustang-Project CLI from 2.22.0 to 2.26.0. The CLI version is now read from the jar instead of being hardcoded. The PR also simplifies XML validation status handling, documents the language option of the XML to PDF conversion, adds a broad xUnit test suite and adds repository tooling for AI-assisted workflows.
Replace Mustang-CLI-2.22.0.jar with Mustang-CLI-2.26.0.jar.
Add MustangJarLocator, which finds Mustang-CLI-*.jar next to the application and reads the version from the embedded Maven pom.properties. Remove the hardcoded version and jar name from MustangCliService. HealthEndpoints reports the version through GetMustangCliVersion().
MustangCliService.ExecuteAsync returns a failed result when the jar is missing.
Always pass --language to the pdf action, because Mustang CLI 2.26.0 otherwise prompts on stdin and blocks.
Add JVM options -XX:TieredStopAtLevel=1 and -XX:+UseSerialGC for faster start, and a best-effort CLI warm-up on application start in Program.cs.
API behavior
POST /api/xml/convert-to-pdf: new optional language query parameter (en, fr, de, default en). An unsupported value returns InvalidRequest.
XmlEndpoints: remove the 10 s delay in the validation handler and use MustangValidationReportParser.Parse instead of manual XDocument parsing.
MustangValidationReportParser and MustangValidationStatuses parse the signature element. PdfEndpoints uses it instead of searching the report text.
Add OpenAPI summary and description to all endpoints.
TemporaryUploadedFile.CreateAsync throws ArgumentException with the request parameter name for invalid input. Add the missing System.Reflection using and a nullable FieldInfo in ErrorCode.cs.
Tests
New xUnit v3 tests for MustangJarLocator, MustangCliService, JavaService, FileTypeValidator, TemporaryUploadedFile, the health, PDF and XML endpoints, route registration and the OpenAPI document. Extend MustangValidationReportParserTests for the new signature status.
Add Microsoft.AspNetCore.Mvc.Testing and copy the sample Factur-X XML and ZuGFeRD PDF to the test output. Java dependent tests are skipped when Java is not installed.
Documentation
Update the root README.md: Mustang 2.26.0, OpenJDK 17, UBL support, endpoint table, language parameter, project structure, ports and badges.
Remove the obsolete src/WebUI/README.md.
Repository tooling (not part of the upgrade itself)
Add AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .mcp.json, .github/pull_request_template.md, Claude skills in .claude/skills/, .claude/settings.json and the .claude/hooks/guard.mjs hook.
build.yml: add non-blocking dotnet format and npm run lint steps.
Normalize line endings to CRLF (.gitattributes, .editorconfig) and remove trailing whitespace. This touches many files without changing behavior, so reviewing commit by commit is easier than reading the full diff.
Small WebUI lint fixes (command.tsx, textarea.tsx, eslint.config.js) and src/IgnoredWords.dic.
Testing
Automated: new and extended xUnit v3 tests as listed above, run with dotnet test src/Docentric.EInvoice.Validator.slnx. Tests that start Java are skipped when Java is not available.
End-to-end tests use the sample files to validate a Factur-X XML and a ZuGFeRD PDF, extract the embedded XML and convert XML to PDF with the new CLI.
Still to record before merge: manual check of the UBL flow and of the Docker image (src/docker-build.ps1, src/docker-run.ps1) with Mustang CLI 2.26.0, and the result of the CI run.
Breaking changes / notes
REST contracts and ErrorCode values are unchanged. The only API addition is the optional language query parameter.
The health endpoint now reads the Mustang CLI version from the jar. If the jar is missing, unreadable or has no valid version, no version is reported.
The Mustang CLI jar is expected next to the application in /app. The Docker workaround from the issue comment, which mounted a jar over /opt/Mustang-CLI.jar, is no longer needed, but any jar matching Mustang-CLI-*.jar in the application folder is picked up (the last one by ordinal file name).
The dotnet format and npm run lint steps in CI are non-blocking until existing violations are fixed.
Removed 10s delay from ValidateXmlHandler for faster responses. Switched to MustangValidationReportParser.Parse for status extraction, replacing manual XDocument parsing. Upgraded Mustang CLI to 2.26.0 and updated JAR. Cleaned up obsolete README.md content.
Added a detailed Copilot instructions document covering repository structure, engineering principles, branching and commit conventions, code style, documentation, testing, build and CI/CD, GitHub MCP usage, dependency/security checks, and security/performance guidelines to ensure consistency and maintainability across the project.
Added a comprehensive "Code Review" section to copilot-instructions.md, including a detailed checklist, review etiquette, and a table of reusable Copilot Chat prompts for common repository tasks. Added prompt files in .github/prompts/ for add-tests, commit-message, create-branch-and-pr, document-public-members, review-pull-request, security-check, and upgrade-dependency, each with clear instructions aligned with repository conventions.
Expanded README with UBL, endpoints, Mustang CLI 2.26.0 and OpenJDK 17 details. Added API endpoint table, clarified error handling, and updated project structure/ports. Enhanced MustangValidationReportParser and MustangValidationStatuses to parse and expose <signature> status, replacing string search in PdfEndpoints. Added and updated xUnit tests for signature parsing, whitespace, and missing/empty cases.
- Add MustangJarLocator for robust jar file discovery and version extraction from pom.properties
- Remove hardcoded MustangCliVersion and jar file from MustangCliService; locate and read version at runtime
- Expose GetMustangCliVersion in MustangCliService; update HealthEndpoints to use it
- Update ExecuteAsync to fail gracefully if jar is missing
- Add xUnit tests for MustangJarLocator covering valid, invalid, missing, and multiple jar scenarios
- Added new prompts in `.github/prompts/` for: `/create-branch-implement-and-pr`, `/create-branch`, `/implement`, `/review-implementation`, `/create-pull-request`
- Each prompt guides through standard repo workflows (branching, implementation, review, PR creation) and enforces repository conventions
- Updated `.github/copilot-instructions.md` to document the new prompts in the "Reusable Prompts" section
- Prompts require user confirmation before pushing or opening PRs, ensuring adherence to commit, branch, and PR standards
All coding, branching, commit, PR, testing, and review rules have been moved to a new AGENTS.md, now the single source of truth for all AI agents and contributors. .github/copilot-instructions.md and CLAUDE.md now reference AGENTS.md, with the former retaining only the Copilot review checklist. All .claude/skills/ SKILL.md files updated to reference AGENTS.md for repository rules. Added .mcp.json for Claude Code MCP server config. This refactor eliminates duplication, reduces maintenance, and ensures consistent, up-to-date engineering conventions across the repository.
A new "Writing Style" section defines explicit rules for all written communication, including chat, commit messages, PRs, reviews, documentation, and code comments. The section bans hype, slogans, formulaic contrasts, flattery, and dramatic or promotional language. It prescribes plain, specific, direct prose, with a preference for complete sentences and ordinary structure. Explicit rewrite rules and examples are provided to avoid corporate or motivational phrasing. Punctuation usage is clarified, and certain rhetorical devices and headings are banned. These rules override default tendencies toward punchy or dramatic copywriting.
- Reword title for clarity and consistency
- Revise release tagging to specify `v<SemVer>` format and pipeline handling
- Reformat pull request section for consistent style and clearer bullets
- Update punctuation guidelines: allow normal hyphens, disallow em/en dashes
- Improve language precision and consistency throughout
Added dotnet format and npm lint as non-blocking checks in build.yml. Updated AGENTS.md to document these checks and clarify that new violations must not be introduced. Documented recommended main branch protection rules, including required PRs, status checks, tag restrictions, and optional Copilot review.
Added .claude/hooks/guard.mjs to enforce repository rules and block unsafe tool actions (e.g., edits to generated files, secrets, force pushes, main branch changes). Introduced .claude/settings.json for shared permissions and PreToolUse hook configuration. Updated .gitignore for local settings. Revised CLAUDE.md to document new guard and settings.
Added a section detailing how to manage file size and structure, including when and how to split content, prioritization of sections to move, and instructions for keeping Claude and Copilot agents in sync. Also clarified to avoid duplicating rules enforced by tooling, supporting ongoing maintainability as conventions evolve.
- Improved SKILL.md descriptions for all skills to clarify usage, steps, and behavior.
- Refined instructions for create-branch-implement-and-pr, create-branch, and create-pull-request skills to detail workflow and confirmation points.
- Added .github/pull_request_template.md with required PR sections: Summary, Related issue, Changes, Testing, and Breaking changes/notes.
- Updated AGENTS.md to reference the new PR template and required description sections.
- No functional code changes; documentation and workflow improvements only.
Added a best-effort warm-up in Program.cs to trigger MustangCliService.CheckAvailabilityAsync at application start, preloading the JVM and Mustang CLI JAR to reduce first-request latency. Enhanced MustangCliService to use JVM options -XX:TieredStopAtLevel=1 and -XX:+UseSerialGC for faster Java process startup, prioritizing quick launch for short-lived CLI executions. Warm-up logs success or failure without affecting startup.
- Add missing System.Reflection using in ErrorCode.cs.
- Update IgnoredWords.dic with "Cli", "Mustang", "Uri".
- Make FieldInfo nullable in ErrorCodeExtensions.GetFriendlyMessage.
- Use ArgumentException (not ArgumentNullException) for file/filename in TemporaryUploadedFile.CreateAsync; align parameter names.
- Wrap Mustang CLI warm-up log in LogLevel check in Program.cs.
Added FileTypeValidatorTests and TemporaryUploadedFileTests in Docentric.EInvoice.Validator.RestServer.Tests.IO. Tests cover normal, boundary, and error cases, including content validation, file extension handling, file deletion on disposal, exception handling for invalid input, and cancellation token support.
Added JavaServiceTests and MustangCliServiceTests covering Java availability, cancellation, Mustang CLI version, file validation, and process execution. Introduced JavaTestHelper to skip tests if Java is unavailable. Updated RestServer.Tests.csproj to exclude TestResults files from compilation and embedding.
- Added xUnit v3 tests for REST endpoints, file type validation, temp file handling, Java/Mustang CLI integration, and Mustang report parsing.
- All public test classes/methods now have XML docs per guidelines.
- Endpoint tests use in-memory server factory; cover normal, edge, error, invalid input, and cancellation cases.
- File type/temp file tests verify detection, error handling, and cleanup.
- Java/Mustang CLI tests are skipped if Java is missing; cover availability, cancellation, and errors.
- Mustang report parser tests cover all status logic, malformed input, and missing sections.
- Added multipart form data helper for tests.
- Updated test dependencies to include Microsoft.AspNetCore.Mvc.Testing.
- Introduced SampleFiles helper for Factur-X XML and ZUGFeRD PDF paths; updated test project to copy sample files to output.
- Extended MultipartContentFactory with CreateFromPath for multipart/form-data from file paths.
- Added integration and service-level tests in PdfEndpointsTests, XmlEndpointsTests, and MustangCliServiceTests for validation, extraction, and conversion using real sample files.
- Tests cover successful validation, HTTP responses, embedded XML extraction, and PDF conversion scenarios.
- README and OpenAPI docs updated: `language` query param (`en`, `fr`, `de`, default `en`) for `POST /api/xml/convert-to-pdf` is now documented.
- All endpoints now have `.WithSummary` and `.WithDescription` for better OpenAPI docs; `language` param described for conversion endpoint.
- `MustangCliService` defines supported languages and always passes language to CLI, preventing prompts.
- `ConvertXmlToPdfHandler` validates `language` param, returns error for unsupported values.
- Tests: `XmlEndpointsTests` covers language validation and PDF generation; new `OpenApiDocumentTests` checks endpoint and param docs.
- Minor code style and logging improvements.
Standardized all files to use CRLF line endings and removed trailing whitespace per .editorconfig and .gitattributes. Updated .gitattributes for explicit text/binary handling. Reformatted configuration and text files for consistent indentation and style. No changes to application logic or behavior; these changes improve cross-platform compatibility and reduce future diff noise.
Added CI coverage and release badges to README for improved project status visibility. Fixed EndpointRouteBuilderExtensionsTests.cs by removing BOM and consolidating using directives.
The build workflow now generates a coverage badge SVG using ReportGenerator. On push to main, it publishes the badge to a dedicated 'badges' branch using a Git worktree, copying the SVG as 'ci-coverage.svg' and committing only if changed. This enables automated, up-to-date coverage badge publishing for the project.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
The Git-operation guard misses standard global-option invocations, and warm-up lifecycle handling and upload-cleanup regression coverage remain unresolved.
The host does not track this discarded task. Although ApplicationStopping requests cancellation, shutdown does not await the warm-up's Java-process cleanup before disposing application services. This also conflicts with the no-fire-and-forget rule in AGENTS.md:87. Move the warm-up into a registered BackgroundService so the host cancels and awaits it during shutdown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Upgrades the Mustang-Project CLI from 2.22.0 to 2.26.0. The CLI version is now read from the jar instead of being hardcoded. The PR also simplifies XML validation status handling, documents the
languageoption of the XML to PDF conversion, adds a broad xUnit test suite and adds repository tooling for AI-assisted workflows.Related issue
Closes #17
Changes
Mustang CLI upgrade
Mustang-CLI-2.22.0.jarwithMustang-CLI-2.26.0.jar.MustangJarLocator, which findsMustang-CLI-*.jarnext to the application and reads the version from the embedded Mavenpom.properties. Remove the hardcoded version and jar name fromMustangCliService.HealthEndpointsreports the version throughGetMustangCliVersion().MustangCliService.ExecuteAsyncreturns a failed result when the jar is missing.--languageto thepdfaction, because Mustang CLI 2.26.0 otherwise prompts on stdin and blocks.-XX:TieredStopAtLevel=1and-XX:+UseSerialGCfor faster start, and a best-effort CLI warm-up on application start inProgram.cs.API behavior
POST /api/xml/convert-to-pdf: new optionallanguagequery parameter (en,fr,de, defaulten). An unsupported value returnsInvalidRequest.XmlEndpoints: remove the 10 s delay in the validation handler and useMustangValidationReportParser.Parseinstead of manualXDocumentparsing.MustangValidationReportParserandMustangValidationStatusesparse thesignatureelement.PdfEndpointsuses it instead of searching the report text.TemporaryUploadedFile.CreateAsyncthrowsArgumentExceptionwith therequestparameter name for invalid input. Add the missingSystem.Reflectionusing and a nullableFieldInfoinErrorCode.cs.Tests
MustangJarLocator,MustangCliService,JavaService,FileTypeValidator,TemporaryUploadedFile, the health, PDF and XML endpoints, route registration and the OpenAPI document. ExtendMustangValidationReportParserTestsfor the new signature status.Microsoft.AspNetCore.Mvc.Testingand copy the sample Factur-X XML and ZuGFeRD PDF to the test output. Java dependent tests are skipped when Java is not installed.Documentation
README.md: Mustang 2.26.0, OpenJDK 17, UBL support, endpoint table,languageparameter, project structure, ports and badges.src/WebUI/README.md.Repository tooling (not part of the upgrade itself)
AGENTS.md,CLAUDE.md,.github/copilot-instructions.md,.mcp.json,.github/pull_request_template.md, Claude skills in.claude/skills/,.claude/settings.jsonand the.claude/hooks/guard.mjshook.build.yml: add non-blockingdotnet formatandnpm run lintsteps..gitattributes,.editorconfig) and remove trailing whitespace. This touches many files without changing behavior, so reviewing commit by commit is easier than reading the full diff.command.tsx,textarea.tsx,eslint.config.js) andsrc/IgnoredWords.dic.Testing
dotnet test src/Docentric.EInvoice.Validator.slnx. Tests that start Java are skipped when Java is not available.src/docker-build.ps1,src/docker-run.ps1) with Mustang CLI 2.26.0, and the result of the CI run.Breaking changes / notes
ErrorCodevalues are unchanged. The only API addition is the optionallanguagequery parameter./app. The Docker workaround from the issue comment, which mounted a jar over/opt/Mustang-CLI.jar, is no longer needed, but any jar matchingMustang-CLI-*.jarin the application folder is picked up (the last one by ordinal file name).dotnet formatandnpm run lintsteps in CI are non-blocking until existing violations are fixed.