Skip to content

#17 Upgrade Mustang-Project CLI to 2.26.0 - #21

Merged
novakklemen merged 28 commits into
mainfrom
feature/17_upgrade-mustang-project-cli-to-2.26.0
Oct 14, 2026
Merged

novakklemen merged 28 commits into
mainfrom
feature/17_upgrade-mustang-project-cli-to-2.26.0

Conversation

@novakklemen

@novakklemen novakklemen commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

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 language option 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

  • 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.
Copilot AI balanced review requested due to automatic review settings October 14, 2026 09:29

This comment was marked as outdated.

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.

This comment was marked as outdated.

Copilot AI and others added 2 commits October 14, 2026 18:29
…anup, README row

Co-authored-by: novakklemen <3392594+novakklemen@users.noreply.github.com>
Co-authored-by: novakklemen <3392594+novakklemen@users.noreply.github.com>
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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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.

2 open findings
11 resolved since last review
Previously missed (1)

In code that hasn't changed since last review

Medium severity Run warm-up as a hosted BackgroundService

src/​Server/​Program.cs:52

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.

🧠 Review effort: Balanced

Comment thread .claude/hooks/guard.mjs Outdated
Comment thread src/Server/IO/TemporaryUploadedFile.cs
… service

Co-authored-by: novakklemen <3392594+novakklemen@users.noreply.github.com>
Co-authored-by: novakklemen <3392594+novakklemen@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The guard still permits prohibited force-push forms and shell-based modifications of protected files.

3 open findings
2 resolved since last review
Files not reviewed (1)
  • src/WebUI/package-lock.json: Generated file

🧠 Review effort: Balanced

Comment thread .claude/hooks/guard.mjs
Comment thread .claude/hooks/guard.mjs
Comment thread .claude/hooks/guard.mjs
@novakklemen
novakklemen requested review from VilkoJ and removed request for VilkoJ October 14, 2026 20:17
@novakklemen
novakklemen merged commit 65d1705 into main Oct 14, 2026
6 checks passed
@novakklemen
novakklemen deleted the feature/17_upgrade-mustang-project-cli-to-2.26.0 branch October 14, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade Mustang-Project CLI to version 2.26.0

3 participants