Skip to content

feat: rvpm dist, package Raven apps into distributable artifacts#858

Merged
martian56 merged 4 commits into
mainfrom
feat/rvpm-dist
Jul 3, 2026
Merged

feat: rvpm dist, package Raven apps into distributable artifacts#858
martian56 merged 4 commits into
mainfrom
feat/rvpm-dist

Conversation

@martian56

@martian56 martian56 commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Fixes #857

rvpm build already produces a single static binary; this adds the step that turns it into something installable. 'rvpm dist' builds the app, stages its file tree, and produces each requested artifact.

What is in here:

  • New optional [dist] manifest section: targets, out_dir, display_name, description, license, homepage, maintainer, vendor, [[dist.assets]] source/dest pairs, [dist.linux] (depends, section, priority), [dist.windows] (icon, upgrade_code). Absent fields default from [package]; the whole section is optional. Asset paths are validated against traversal at parse time, the same containment rule as [ffi].sources.
  • 'rvpm dist [--target t1,t2] [--out-dir dir]': targets are tar, zip, deb, rpm, msi, inno. Without --target the manifest applies; without a [dist] section the host default does (zip on Windows, tar elsewhere).
  • Backends generate the packaging text (DEBIAN/control, rpm spec, WiX source, Inno Setup script) and shell out to the format's tool, the same external-tool approach pkg takes with curl and tar. A missing tool fails with an install hint. msi supports WiX 3 (candle/light, what the repo's own release uses) and the WiX 4+ CLI; zip prefers bsdtar and falls back to zip.
  • The msi upgrade GUID is derived stably from the package name when not pinned, with a printed note advising to pin it.
  • Spec: docs/v2/specs/rvpm-dist.md. CHANGELOG entry under Unreleased.

Testing:

  • 7 new manifest tests (schema, defaults, traversal and GUID rejection) and 14 dist tests (generation text per format, staging, artifact naming, targets precedence, plus integration tests that run tar/zip everywhere and dpkg-deb where present, so the ubuntu runner builds a real deb).
  • Verified end to end on a real app (rook): zip and tar artifacts contain the binary and assets in the right layout on Windows; missing-tool and bad-target diagnostics read correctly.
  • cargo fmt --check, clippy (no new warnings), and the full 657-test suite pass.

One compatibility note: an rv.toml that adds [dist] is rejected by older rvpm versions because the manifest schema denies unknown fields. Projects should adopt [dist] once they are on a release carrying this change.

Summary by CodeRabbit

  • New Features
    • Added rvpm dist to create distributable artifacts (tar, zip, deb, rpm, msi, inno).
    • Added --target and --out-dir options and support for an optional [dist] section to configure assets and platform installer settings.
  • Documentation
    • Added a new specification documenting rvpm dist, including manifest behavior and packaging rules.
  • Bug Fixes
    • Added stricter validation for distribution metadata, safe output/asset paths, upgrade GUIDs, allowed targets, and protection against control-character injection.
  • Chores
    • Bumped the workspace version to 2.20.0.

…artifacts

Adds an optional [dist] manifest section (metadata, assets, linux and
windows installer settings) and an 'rvpm dist' subcommand that builds the
application, stages its file tree, generates each format's packaging text,
and shells out to the format's tool, with install hints when a tool is
missing. Archive targets need only tar or zip; deb uses dpkg-deb, rpm uses
rpmbuild, msi uses WiX 3 or the WiX 4 CLI, inno uses ISCC. The msi upgrade
GUID is derived stably from the package name when not pinned.

Fixes #857
@martian56 martian56 self-assigned this Jul 3, 2026
@strix-security

strix-security Bot commented Jul 3, 2026

Copy link
Copy Markdown

Strix Security Review

1 open security finding on this PR:

Review summary

The new rvpm dist packaging flow is generally careful about manifest-sourced metadata and asset paths, but the CLI override path is inconsistent with those safeguards. I confirmed one issue, Path traversal via unvalidated rvpm dist --out-dir override, where a caller can direct staging cleanup and artifact writes outside the package root.

Updated for 02653b7.


Reviewed by Strix
Re-run review · Configure security review settings

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3d21b771-a753-456f-9f72-ad2b1839a947

📥 Commits

Reviewing files that changed from the base of the PR and between d76b374 and 02653b7.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • CHANGELOG.md
  • Cargo.toml
  • docs/v2/specs/rvpm-dist.md
  • src/ops/dist.rs
✅ Files skipped from review due to trivial changes (3)
  • CHANGELOG.md
  • Cargo.toml
  • docs/v2/specs/rvpm-dist.md

📝 Walkthrough

Walkthrough

Adds a new rvpm dist subcommand that builds and packages a Raven application into tar, zip, deb, rpm, msi, and inno artifacts. It also adds optional [dist] manifest validation, backend packaging logic, CLI wiring, error variants, and supporting docs/tests.

Changes

rvpm dist Feature

Layer / File(s) Summary
Dist manifest schema and validation
src/manifest/mod.rs
Adds Dist, DistAsset, DistLinux, DistWindows types, target/default constants, raw TOML structs, path-safety and GUID validation, integration into Manifest::from_toml_str, and tests.
Dist error variants
src/ops/mod.rs
Exports the dist module and adds NotPackageable, DistTool, DistFailed OpError variants with Display formatting.
Dist orchestration and staging
src/ops/dist.rs
Implements DistReport/DistOptions, dist/dist_in entrypoints, target resolution precedence, naming/version helpers, and file staging with executable marking.
Packaging backends and tool execution
src/ops/dist.rs
Implements tar/zip/deb/rpm/msi/inno backends, WiX/Inno script generation, external tool execution with error mapping, filesystem helpers, and tests.
CLI subcommand wiring
src/bin/rvpm.rs
Adds the dist dispatch branch, cmd_dist argument parsing, dist_usage help text, and usage listing update.
Specification and changelog
docs/v2/specs/rvpm-dist.md, CHANGELOG.md, Cargo.toml
Documents CLI usage, manifest schema, artifact naming/version normalization, and out-of-scope items; adds a changelog entry and bumps the workspace package version.

Estimated code review effort: 4 (Complex) | ~75 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant rvpm_cli as rvpm CLI
  participant ops_dist as ops::dist
  participant Manifest
  participant Builder as build_in

  User->>rvpm_cli: rvpm dist --target deb,tar --out-dir dist/
  rvpm_cli->>ops_dist: dist(project_dir, DistOptions)
  ops_dist->>Manifest: load and validate [dist]
  Manifest-->>ops_dist: Dist config or defaults
  ops_dist->>Builder: build_in(project_dir)
  Builder-->>ops_dist: built binary path
  ops_dist->>ops_dist: resolve_targets and stage_tree
  ops_dist-->>rvpm_cli: DistReport(outcome_lines, artifacts)
  rvpm_cli-->>User: print outcome lines
Loading

Related Issues: #857
Suggested labels: feature, packaging, cli
Suggested reviewers: martian56

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly names the new rvpm dist subcommand and its packaging purpose.
Description check ✅ Passed The description covers the change summary, key changes, testing, related issue, and reviewer note content required by the template.
Linked Issues check ✅ Passed The code and docs add rvpm dist, optional [dist] metadata, target selection, defaults, validation, artifact generation, and tests matching #857.
Out of Scope Changes check ✅ Passed The only extra changes are docs, changelog, and a version bump, all consistent with the dist release work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/rvpm-dist

Comment @coderabbitai help to get the list of available commands.

@strix-security strix-security Bot 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.

Strix flagged 2 new security findings below. See the pinned summary comment for the full PR status.

Comment thread src/ops/dist.rs
Comment thread src/manifest/mod.rs

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/v2/specs/rvpm-dist.md (1)

10-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a language to the usage fence.

Static analysis flags the rvpm dist usage block as missing a language identifier (MD040).

📝 Proposed fix
-```
+```text
 rvpm dist [--target <t1,t2>] [--out-dir <dir>]
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/v2/specs/rvpm-dist.md around lines 10 - 12, The rvpm dist usage fence
in the spec is missing a language identifier, which triggers MD040. Update the
markdown code fence around the usage text to include a text language tag so the
fenced block is properly recognized, using the rvpm dist usage example in the
docs/spec content as the target.


</details>

<!-- cr-comment:v1:6f996ed84e8b950bcff00253 -->

_Source: Linters/SAST tools_

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @src/ops/dist.rs:

  • Around line 556-600: The wix_source generator still emits WiX 3 authoring,
    but dist_msi can route to wix build, which expects WiX 4/5-compatible
    source. Update wix_source (and any related authoring in dist_msi) to
    generate WiX 4 schema and elements, or otherwise ensure the wix CLI path is
    not used with this output. Use the existing wix_source function and dist_msi
    flow to keep the authoring format aligned with the tool selected on PATH.

Nitpick comments:
In @docs/v2/specs/rvpm-dist.md:

  • Around line 10-12: The rvpm dist usage fence in the spec is missing a language
    identifier, which triggers MD040. Update the markdown code fence around the
    usage text to include a text language tag so the fenced block is properly
    recognized, using the rvpm dist usage example in the docs/spec content as the
    target.

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro Plus

**Run ID**: `fee91353-2c0b-41f2-9cf7-2e107ef590c3`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 6c23ea1523b711315c223921ebf27a0e026662b5 and f7c06f42f585642bfab6bcf67f652ee3ab5ea8b9.

</details>

<details>
<summary>📒 Files selected for processing (6)</summary>

* `CHANGELOG.md`
* `docs/v2/specs/rvpm-dist.md`
* `src/bin/rvpm.rs`
* `src/manifest/mod.rs`
* `src/ops/dist.rs`
* `src/ops/mod.rs`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread src/ops/dist.rs
martian56 added 3 commits July 3, 2026 14:02
Dist text fields and the package version are written verbatim into the
generated deb control file, rpm spec, and Inno Setup script. An embedded
newline could inject an extra field or, for rpm and inno, a section that
runs commands during packaging. Reject control characters at the manifest
boundary so no backend has to trust the metadata (CWE-94).

Addresses the strix-security findings on #858.
The generated WiX source uses the v3 schema (2006 namespace, <Product>).
WiX 4 removed that schema, so its 'wix build' would reject the source; the
code no longer tries it when the v4 CLI happens to be on PATH. candle and
light (WiX 3, what the Raven toolchain release also uses) are the msi tools,
with a hint that names them. WiX 4 support would emit the v4 schema and is
tracked separately.

Addresses the WiX compatibility finding on #858.

@strix-security strix-security Bot 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.

Strix flagged 3 new security findings below. See the pinned summary comment for the full PR status.

Comment thread src/bin/rvpm.rs
Comment thread src/ops/dist.rs
Comment thread src/ops/dist.rs
@martian56 martian56 merged commit 89465b8 into main Jul 3, 2026
7 checks passed
@martian56 martian56 deleted the feat/rvpm-dist branch July 3, 2026 10:20
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.

feat: rvpm dist, package a Raven app into deb, rpm, msi, inno, zip, and tar artifacts

1 participant