Strip the pre-release suffix from the MSI version - #536
Conversation
MSI ProductVersion accepts only numeric major.minor.build, so the pinned windows-package action rejects the crate version 0.1.0-beta1 and every pull request's release dry-run fails at the installer step. The Windows packaging step now derives its version by stripping the pre-release identifier; every other artefact keeps the full crate version, and the workflow contract tests still pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Reviewer's guide (collapsed on small PRs)Reviewer's GuideAdjusts the Windows build-and-package workflow so that the MSI installer uses a numeric-only version (without pre-release suffix), while other artifacts keep the full semantic version, to satisfy MSI ProductVersion constraints and unblock release checks. Sequence diagram for deriving numeric MSI version in Windows workflowsequenceDiagram
participant Workflow as GitHubActionsWorkflow
participant Derive as DeriveNumericMSIVersionStep
participant WindowsPackage as WindowsPackageAction
Workflow->>Derive: inputs.version
Derive-->>Workflow: msi_version.outputs.value (version%%-*)
Workflow->>WindowsPackage: version = msi_version.outputs.value
WindowsPackage-->>Workflow: Build MSI with numeric ProductVersion
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Summary
WalkthroughUpdate the Windows packaging workflow to strip pre-release suffixes from ChangesWindows MSI packaging
Possibly related issues
Possibly related PRs
Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error, 5 warnings, 1 inconclusive)
✅ Passed checks (13 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
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 @.github/workflows/build-and-package.yml:
- Line 165: Update the workflow step around the version assignment to pass the
caller-provided version through an environment variable before Bash evaluates
it, then read it from INPUT_VERSION. Validate the value against strict SemVer
and only write GITHUB_OUTPUT after validation succeeds.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2bcd5cef-bc43-405f-9e93-dce1e4263a90
📒 Files selected for processing (1)
.github/workflows/build-and-package.yml
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
leynos/rstest-bdd(auto-detected)leynos/ortho-config(auto-detected)leynos/whitaker(auto-detected)leynos/shared-actions(auto-detected)
| # 0.1.0-beta1. The suffix is stripped for the installer alone; every | ||
| # other artefact keeps the full crate version. | ||
| run: | | ||
| version="${{ inputs.version }}" |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' 'Reusable workflow and callers:'
rg -n -C 10 \
'build-and-package\.yml|needs\.metadata\.outputs\.version|outputs:|version:|cargo metadata|semver|validate.*version|version.*validate' \
.github/workflows
printf '%s\n' 'Relevant workflow sections:'
sed -n '130,190p' .github/workflows/build-and-package.yml
sed -n '1,130p' .github/workflows/release.ymlRepository: leynos/netsuke
Length of output: 31304
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' 'Cargo version action files:'
git ls-files '.github/actions/ensure-cargo-version' '.github/actions/export-cargo-metadata'
find .github/actions -maxdepth 2 -type f \( -iname '*cargo*version*' -o -iname '*cargo*metadata*' \) -print
printf '%s\n' 'Version extraction and validation references:'
rg -n -C 8 \
'ensure-cargo-version|crate-version|export-cargo-metadata|cargo metadata|semver|version.*valid|validate.*version|check-tag' \
.github/actions .github/workflowsRepository: leynos/shared-actions
Length of output: 50379
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' 'ensure-cargo-version action:'
cat -n .github/actions/ensure-cargo-version/action.yml
printf '%s\n' 'ensure_cargo_version.py:'
cat -n .github/actions/ensure-cargo-version/scripts/ensure_cargo_version.py
printf '%s\n' 'export-cargo-metadata action:'
cat -n .github/actions/export-cargo-metadata/action.yml
printf '%s\n' 'read_manifest.py:'
cat -n .github/actions/export-cargo-metadata/scripts/read_manifest.pyRepository: leynos/shared-actions
Length of output: 22928
🏁 Script executed on selected repositories:
#!/bin/bash
set -euo pipefail
printf '%s\n' 'Release-mode decision and callers:'
rg -n -C 12 \
'determine-release-modes|should-publish|workflow_call|release\.yml|netsuke.*release|uses:.*release' \
.github/actions .github/workflows README.md 2>/dev/null || true
printf '%s\n' 'Exact release-mode action:'
find .github/actions -maxdepth 3 -type f -path '*determine-release-modes*' -print
Repositories: leynos/netsuke, leynos/shared-actions
Length of output: 63879
🏁 Script executed (no clone):
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import os
import subprocess
payload = '0.1.0"; printf "INJECTED\\n"; #'
unsafe_script = f'version="{payload}"\nprintf "version=%s\\n" "$version"\n'
safe_script = 'version="$INPUT_VERSION"\nprintf "version=%s\\n" "$version"\n'
unsafe = subprocess.run(
["bash", "-c", unsafe_script],
text=True,
capture_output=True,
check=False,
)
safe = subprocess.run(
["bash", "-c", safe_script],
env={**os.environ, "INPUT_VERSION": payload},
text=True,
capture_output=True,
check=False,
)
print("unsafe_returncode:", unsafe.returncode)
print("unsafe_stdout:", repr(unsafe.stdout))
print("safe_returncode:", safe.returncode)
print("safe_stdout:", repr(safe.stdout))
assert "INJECTED" in unsafe.stdout
assert "INJECTED" not in safe.stdout
assert payload in safe.stdout
PY
Length of output: 354
Injection (CWE-78): Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Reachability: External · Exploitability: Trivial
Pass inputs.version through an environment variable before Bash parses the script.
The reusable workflow accepts version from callers. Shell syntax in this value can execute commands on the Windows runner. Read version="$INPUT_VERSION" and validate strict SemVer before writing GITHUB_OUTPUT.
🧰 Tools
🪛 zizmor (1.29.0)
[error] 165-165: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/build-and-package.yml at line 165, Update the workflow
step around the version assignment to pass the caller-provided version through
an environment variable before Bash evaluates it, then read it from
INPUT_VERSION. Validate the value against strict SemVer and only write
GITHUB_OUTPUT after validation succeeds.
Source: Linters/SAST tools
|
@coderabbitai is this now resolved in main by the shared-actions bump? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- PR metadata ---'
gh pr view 536 --repo leynos/netsuke \
--json number,state,mergedAt,baseRefName,headRefName,url \
--jq '{number, state, mergedAt, baseRefName, headRefName, url}'
echo '--- main workflow shared-action references ---'
git show origin/main:.github/workflows/build-and-package.yml |
rg -n -C3 'shared-actions|windows-package|version'
echo '--- PR workflow diff ---'
gh pr diff 536 --repo leynos/netsuke -- .github/workflows/build-and-package.yml
echo '--- shared-actions remote refs and windows-package history ---'
git ls-remote https://github.com/leynos/shared-actions.git 'refs/heads/main'Length of output: 5777 🏁 Script executed: #!/bin/bash
set -euo pipefail
PIN='8add2d99854a5b77548eae98cca59202e68fefc8'
ACTION_PATH='.github/actions/windows-package/action.yml'
echo '--- pinned windows-package action ---'
gh api "repos/leynos/shared-actions/contents/${ACTION_PATH}?ref=${PIN}" \
--jq '.content' | base64 --decode |
rg -n -C5 'ProductVersion|pre-release|prerelease|VERSION|version'
echo '--- PR `#536` changed workflow patch ---'
gh api 'repos/leynos/netsuke/pulls/536/files?per_page=100' \
--jq '.[] | select(.filename == ".github/workflows/build-and-package.yml") | .patch'
echo '--- commit identity and ancestry ---'
gh api "repos/leynos/shared-actions/commits/${PIN}" \
--jq '{sha: .sha, message: .commit.message, date: .commit.author.date}'Length of output: 11850
Keep passing the full crate version from the workflow. The action normalizes only the MSI internal version. Other artifact versions remain unchanged. Close PR You are interacting with an AI system. |
Every pull request's
release / build-windowscheck currently fails withInvalid MSI version '0.1.0-beta1': MSI ProductVersion accepts only numericmajor.minor.build, and the pinnedwindows-packageshared action validates that before building. Main never runs the release dry-run on push, so only PRs surface it.The Windows packaging step now derives a numeric version by stripping the pre-release identifier (
0.1.0-beta1→0.1.0) for the installer alone; Linux, macOS, and archive artefacts keep the full crate version. Workflow contract tests (workflow_build_and_package,polonius_toolchain_contract,workflow_release) pass unchanged.An estate-level alternative — teaching the shared action a pre-release mapping — can supersede this, but the local derivation unblocks all open PRs now.
🤖 Generated with Claude Code
Summary by Sourcery
Build: