Create release.yml - #269
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR adds a GitHub Actions workflow that automates the release process for WheelWizard. The workflow triggers on version tags, validates the build with tests, publishes self-contained executables for three target platforms (Windows x64, Linux x64, and Linux ARM64), and creates a GitHub release with the binaries attached. ChangesRelease Automation Workflow
Sequence DiagramsequenceDiagram
participant GitHub as GitHub (Tag Push)
participant Runner as CI Runner
participant DotNet as dotnet CLI
participant GH as gh CLI
GitHub->>Runner: Trigger on v* tag
Runner->>DotNet: Checkout and restore
Runner->>DotNet: Run Release tests
DotNet-->>Runner: Tests pass
Runner->>DotNet: Publish Windows x64
DotNet-->>Runner: WheelWizard.exe
Runner->>DotNet: Publish Linux x64
DotNet-->>Runner: WheelWizard (linux-x64)
Runner->>DotNet: Publish Linux ARM64
DotNet-->>Runner: WheelWizard (linux-arm64)
Runner->>Runner: Stage artifacts
Runner->>GH: Create release with binaries
GH-->>GitHub: Release published
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 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/release.yml:
- Around line 31-72: The workflow is missing a macOS publish step; add a new job
step similar to "Publish Linux ARM64" named e.g. "Publish macOS ARM64" that runs
dotnet publish WheelWizard/WheelWizard.csproj with --runtime osx-arm64,
--configuration Release, --output publish/osx-arm64, --self-contained true and
the same /p: flags (set /p:AssemblyName=WheelWizard_macOS, /p:UseAppHost=true,
/p:PublishSingleFile=true, /p:IncludeAllContentForSelfExtract=true,
/p:IncludeNativeLibrariesForSelfExtract=true,
/p:EnableCompressionInSingleFile=true) and then ensure the new publish/osx-arm64
artifact is included in whichever staging/release artifact upload steps
reference the other publish/* outputs.
- Around line 3-6: Add a top-level GitHub Actions concurrency policy to the
release workflow to prevent overlapping runs: insert a concurrency block (with a
stable group key such as "release-${{ github.ref }}" or "release-${{
github.ref_name }}" and set cancel-in-progress: true) at the top level of the
release.yml so any in-flight release run for the same tag is cancelled when a
new tag-triggered push occurs; update the workflow that currently declares on:
push: tags: - "v*" to include this concurrency configuration.
- Around line 17-18: Replace the unpinned checkout action and default credential
behavior: pin the actions/checkout@v4 reference to a specific commit SHA
(instead of the tag) and add the checkout input persist-credentials: false so
the workflow does not leak GitHub tokens; update the uses field for the checkout
step to the chosen commit SHA and add the persist-credentials setting to that
step (refer to the actions/checkout@v4 usage and persist-credentials input).
- Around line 20-23: The workflow step named "Setup .NET" currently uses the
mutable tag actions/setup-dotnet@v4; replace that with a pinned commit SHA (the
specific commit SHA for the desired actions/setup-dotnet release) in the uses
field so the step always references an immutable release; update the uses line
for the "Setup .NET" step to actions/setup-dotnet@<commit-sha> and commit the
change.
- Around line 8-9: Move the top-level "permissions: contents: write" out of the
global workflow scope and instead add it under the specific job that performs
releases (e.g., the job that runs the release/publish steps), and add a short
explanatory comment above that job-level permission explaining why write access
to contents is required (for example: "Grant write access to contents for
creating/updating GitHub releases and uploading artifacts"). Update any
references to "permissions" in the workflow so only the release job has
contents: write while other jobs inherit default (read) permissions.
- Around line 85-90: The gh release create invocation is using github.ref_name
directly (used in gh release create and --title) which allows shell/template
injection; fix by validating and sanitizing the tag first (ensure it matches an
allowed pattern like a v-semver regex) and derive a safe variable (e.g.,
safe_tag) that replaces any disallowed characters (or rejects non-matching tags)
before using it in gh release create and --title; update the workflow to use
that sanitized safe_tag variable in place of github.ref_name and ensure all uses
(gh release create, --title) reference safe_tag only.
- Line 38: The Windows selector currently picks the first asset whose
BrowserDownloadUrl ends with ".exe" in WindowsUpdatePlatform (the code that
checks asset.BrowserDownloadUrl.EndsWith(".exe")); tighten it to match the exact
filename uploaded by the workflow (WheelWizardWindows.exe) by changing the check
to compare the asset filename (e.g., Path.GetFileName(new
Uri(asset.BrowserDownloadUrl).LocalPath) == "WheelWizardWindows.exe" or
EndsWith("/WheelWizardWindows.exe")) so the updater consistently picks the
intended artifact.
🪄 Autofix (Beta)
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
Run ID: c996f6ce-4342-41d2-9c00-ff26326ff773
📒 Files selected for processing (1)
.github/workflows/release.yml
| on: | ||
| push: | ||
| tags: | ||
| - "v*" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
Add concurrency control to prevent overlapping releases.
Multiple version tags pushed in quick succession could trigger concurrent release workflows, potentially causing conflicts or race conditions when creating releases.
⚙️ Proposed fix
on:
push:
tags:
- "v*"
+
+concurrency:
+ group: release-${{ github.ref }}
+ cancel-in-progress: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 3-6: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 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/release.yml around lines 3 - 6, Add a top-level GitHub
Actions concurrency policy to the release workflow to prevent overlapping runs:
insert a concurrency block (with a stable group key such as "release-${{
github.ref }}" or "release-${{ github.ref_name }}" and set cancel-in-progress:
true) at the top level of the release.yml so any in-flight release run for the
same tag is cancelled when a new tag-triggered push occurs; update the workflow
that currently declares on: push: tags: - "v*" to include this concurrency
configuration.
| permissions: | ||
| contents: write |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
Scope permissions to job level and add explanatory comment.
The contents: write permission is currently at workflow level, which grants it to all jobs. For better security posture, scope it to the specific job that needs it. Also add a comment explaining why the permission is required.
🔒 Proposed fix to scope permissions
-permissions:
- contents: write
-
jobs:
release:
name: Build and Publish Release
runs-on: ubuntu-latest
+ # Requires write access to create GitHub releases
+ permissions:
+ contents: write📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| permissions: | |
| contents: write | |
| name: Release Wheel Wizard | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| jobs: | |
| release: | |
| name: Build and Publish Release | |
| runs-on: ubuntu-latest | |
| # Requires write access to create GitHub releases | |
| permissions: | |
| contents: write |
🧰 Tools
🪛 zizmor (1.25.2)
[error] 9-9: overly broad permissions (excessive-permissions): contents: write is overly broad at the workflow level
(excessive-permissions)
[warning] 9-9: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
🤖 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/release.yml around lines 8 - 9, Move the top-level
"permissions: contents: write" out of the global workflow scope and instead add
it under the specific job that performs releases (e.g., the job that runs the
release/publish steps), and add a short explanatory comment above that job-level
permission explaining why write access to contents is required (for example:
"Grant write access to contents for creating/updating GitHub releases and
uploading artifacts"). Update any references to "permissions" in the workflow so
only the release job has contents: write while other jobs inherit default (read)
permissions.
| - name: Checkout repository | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
Harden checkout action security.
The checkout action has two security concerns:
- Not pinned to a commit SHA, making it vulnerable to tag manipulation
persist-credentialsdefaults totrue, which can leak GitHub tokens through artifacts
🔒 Proposed fix
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ persist-credentials: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Checkout repository | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 17-18: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 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/release.yml around lines 17 - 18, Replace the unpinned
checkout action and default credential behavior: pin the actions/checkout@v4
reference to a specific commit SHA (instead of the tag) and add the checkout
input persist-credentials: false so the workflow does not leak GitHub tokens;
update the uses field for the checkout step to the chosen commit SHA and add the
persist-credentials setting to that step (refer to the actions/checkout@v4 usage
and persist-credentials input).
| - name: Setup .NET | ||
| uses: actions/setup-dotnet@v4 | ||
| with: | ||
| dotnet-version: "8.0.x" |
There was a problem hiding this comment.
Pin setup-dotnet action to commit SHA.
The action reference uses a mutable tag instead of a commit SHA, which introduces supply-chain risk.
🔒 Proposed fix
- name: Setup .NET
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@3e891f423b7c8c1080ef611d6b0c5c4c6a2e40f7 # v4.2.0
with:
dotnet-version: "8.0.x"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: "8.0.x" | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@3e891f423b7c8c1080ef611d6b0c5c4c6a2e40f7 # v4.2.0 | |
| with: | |
| dotnet-version: "8.0.x" |
🧰 Tools
🪛 zizmor (1.25.2)
[error] 21-21: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 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/release.yml around lines 20 - 23, The workflow step named
"Setup .NET" currently uses the mutable tag actions/setup-dotnet@v4; replace
that with a pinned commit SHA (the specific commit SHA for the desired
actions/setup-dotnet release) in the uses field so the step always references an
immutable release; update the uses line for the "Setup .NET" step to
actions/setup-dotnet@<commit-sha> and commit the change.
| - name: Publish Windows x64 | ||
| run: > | ||
| dotnet publish WheelWizard/WheelWizard.csproj | ||
| --runtime win-x64 | ||
| --configuration Release | ||
| --output publish/win-x64 | ||
| --self-contained true | ||
| /p:AssemblyName=WheelWizardWindows | ||
| /p:UseAppHost=true | ||
| /p:PublishSingleFile=true | ||
| /p:IncludeAllContentForSelfExtract=true | ||
| /p:IncludeNativeLibrariesForSelfExtract=true | ||
| /p:EnableCompressionInSingleFile=true | ||
|
|
||
| - name: Publish Linux x64 | ||
| run: > | ||
| dotnet publish WheelWizard/WheelWizard.csproj | ||
| --runtime linux-x64 | ||
| --configuration Release | ||
| --output publish/linux-x64 | ||
| --self-contained true | ||
| /p:AssemblyName=WheelWizard_Linux | ||
| /p:UseAppHost=true | ||
| /p:PublishSingleFile=true | ||
| /p:IncludeAllContentForSelfExtract=true | ||
| /p:IncludeNativeLibrariesForSelfExtract=true | ||
| /p:EnableCompressionInSingleFile=true | ||
|
|
||
| - name: Publish Linux ARM64 | ||
| run: > | ||
| dotnet publish WheelWizard/WheelWizard.csproj | ||
| --runtime linux-arm64 | ||
| --configuration Release | ||
| --output publish/linux-arm64 | ||
| --self-contained true | ||
| /p:AssemblyName=WheelWizard_arm64_Linux | ||
| /p:UseAppHost=true | ||
| /p:PublishSingleFile=true | ||
| /p:IncludeAllContentForSelfExtract=true | ||
| /p:IncludeNativeLibrariesForSelfExtract=true | ||
| /p:EnableCompressionInSingleFile=true | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider adding macOS build.
The Directory.Build.props file defines a Release-macOS configuration for osx-arm64, but this workflow doesn't publish a macOS build. Is macOS support planned for a future release, or was this omission intentional?
If macOS support is intended, you can add it alongside the other platforms:
🍎 Proposed macOS build step
- name: Publish macOS ARM64
run: >
dotnet publish WheelWizard/WheelWizard.csproj
--runtime osx-arm64
--configuration Release
--output publish/osx-arm64
--self-contained true
/p:AssemblyName=WheelWizard_macOS
/p:UseAppHost=true
/p:PublishSingleFile=true
/p:IncludeAllContentForSelfExtract=true
/p:IncludeNativeLibrariesForSelfExtract=true
/p:EnableCompressionInSingleFile=trueAnd update staging/release steps to include the macOS artifact.
🤖 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/release.yml around lines 31 - 72, The workflow is missing
a macOS publish step; add a new job step similar to "Publish Linux ARM64" named
e.g. "Publish macOS ARM64" that runs dotnet publish
WheelWizard/WheelWizard.csproj with --runtime osx-arm64, --configuration
Release, --output publish/osx-arm64, --self-contained true and the same /p:
flags (set /p:AssemblyName=WheelWizard_macOS, /p:UseAppHost=true,
/p:PublishSingleFile=true, /p:IncludeAllContentForSelfExtract=true,
/p:IncludeNativeLibrariesForSelfExtract=true,
/p:EnableCompressionInSingleFile=true) and then ensure the new publish/osx-arm64
artifact is included in whichever staging/release artifact upload steps
reference the other publish/* outputs.
| --configuration Release | ||
| --output publish/win-x64 | ||
| --self-contained true | ||
| /p:AssemblyName=WheelWizardWindows |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for Windows update platform to verify expected asset name
# Look for Windows updater implementation
ast-grep --pattern 'class $_ : $$$UpdatePlatform {
$$$
}'
# Search for asset name references in auto-update code
rg -nP --type=cs -A5 -B5 'WheelWizard.*Windows' -g '*Update*'Repository: TeamWheelWizard/WheelWizard
Length of output: 53
🏁 Script executed:
#!/bin/bash
# 1) Inspect the release workflow around the AssemblyName line.
sed -n '1,140p' .github/workflows/release.yml | nl -ba | sed -n '20,70p'
# 2) Find updater/platform code locations and names (C#).
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' \
-S --type=cs '(LinuxUpdatePlatform|UpdatePlatform|AutoUpdate|auto[-_ ]?update|Updater)' .
# 3) Find any references to the current/expected assembly names.
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' \
-S --type=cs '(WheelWizardWindows|WheelWizard_Windows|WheelWizard_Linux|WheelWizard_arm64_Linux)' .
# 4) Search for release-asset naming logic that might depend on those strings.
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' \
-S --type=cs '(asset|artifact|name|AssemblyName|runtime|win-x64|win|x64|arm64)' .Repository: TeamWheelWizard/WheelWizard
Length of output: 50443
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Check release workflow around AssemblyName line
echo "---- .github/workflows/release.yml (around AssemblyName) ----"
sed -n '25,60p' .github/workflows/release.yml | nl -ba | sed -n '1,60p' || true
# 2) Avoid huge output: search exact naming strings in C# only
echo "---- Search for Windows assembly name strings ----"
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' --type=cs \
'(WheelWizardWindows|WheelWizard_Windows)' .
# 3) Inspect the Windows updater implementation and its identifier
echo "---- WindowsUpdatePlatform.cs ----"
sed -n '1,200p' WheelWizard/Features/AutoUpdating/Platforms/WindowsUpdatePlatform.cs | nl -ba | sed -n '1,160p'
# 4) Inspect LinuxUpdatePlatform.cs identifier for comparison
echo "---- LinuxUpdatePlatform.cs ----"
sed -n '1,120p' WheelWizard/Features/AutoUpdating/Platforms/LinuxUpdatePlatform.cs | nl -ba | sed -n '1,120p'
# 5) Inspect AutoUpdaterSingletonService for asset selection logic
echo "---- AutoUpdaterSingletonService.cs (relevant parts) ----"
sed -n '1,220p' WheelWizard/Features/AutoUpdating/AutoUpdaterSingletonService.cs | nl -ba | sed -n '1,220p'
# 6) Find where GitHub assets are matched by identifier/name/tag
echo "---- Search for 'identifier' usage in AutoUpdating feature ----"
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' --type=cs \
'identifier\s*=' WheelWizard/Features/AutoUpdating .
echo "---- Search for 'identifier' usage outside platforms (AutoUpdating/GitHub) ----"
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' --type=cs \
'identifier' WheelWizard/Features/AutoUpdating WheelWizard/Features/GitHub .Repository: TeamWheelWizard/WheelWizard
Length of output: 243
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "---- release.yml (around line 38) ----"
# use sed directly; line numbers are approximate but should cover the AssemblyName assignment
sed -n '30,50p' .github/workflows/release.yml | cat
echo "---- search for WheelWizardWindows / WheelWizard_Windows (all files) ----"
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' \
'(WheelWizardWindows|WheelWizard_Windows)' .
echo "---- search for updater identifiers ----"
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' \
'identifier\s*=' WheelWizard/Features/AutoUpdating
echo "---- WindowsUpdatePlatform.cs (full-ish first 200 lines) ----"
sed -n '1,220p' WheelWizard/Features/AutoUpdating/Platforms/WindowsUpdatePlatform.cs | cat
echo "---- LinuxUpdatePlatform.cs (first 120 lines, for comparison) ----"
sed -n '1,140p' WheelWizard/Features/AutoUpdating/Platforms/LinuxUpdatePlatform.cs | cat
echo "---- AutoUpdaterSingletonService.cs (first 260 lines) ----"
sed -n '1,260p' WheelWizard/Features/AutoUpdating/AutoUpdaterSingletonService.cs | cat
echo "---- search for GitHub asset matching by identifier/name ----"
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' \
'(asset|artifact|download|browser_download_url|name).*(identifier|WheelWizard_)|identifier.*(asset|artifact|name|tag)' \
WheelWizard/Features/AutoUpdating WheelWizard/Features/GitHubRepository: TeamWheelWizard/WheelWizard
Length of output: 18207
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the workflow section that uploads release artifacts/assets
sed -n '60,130p' .github/workflows/release.yml | cat
# Also show any other "artifacts/*.exe" or upload-artifact steps to check for multiple EXEs
rg -n --hidden --glob='!**/bin/**' --glob='!**/obj/**' \
'\.exe' .github/workflows/release.ymlRepository: TeamWheelWizard/WheelWizard
Length of output: 1448
Windows auto-updater doesn’t rely on the assembly name—WheelWizardWindows.exe will be selected.
WheelWizard/Features/AutoUpdating/Platforms/WindowsUpdatePlatform.cs picks the first GitHub release asset whose BrowserDownloadUrl ends with .exe (no identifier/name matching like Linux). Since the workflow stages and uploads only artifacts/WheelWizardWindows.exe for Windows, WheelWizardWindows naming is compatible; the Linux identifier strings are only used by LinuxUpdatePlatform.
Optional: if you ever upload multiple .exe assets to the same release, this “first .exe” selection could update the wrong file—tighten the match (e.g., by exact filename) if that becomes a risk.
🤖 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/release.yml at line 38, The Windows selector currently
picks the first asset whose BrowserDownloadUrl ends with ".exe" in
WindowsUpdatePlatform (the code that checks
asset.BrowserDownloadUrl.EndsWith(".exe")); tighten it to match the exact
filename uploaded by the workflow (WheelWizardWindows.exe) by changing the check
to compare the asset filename (e.g., Path.GetFileName(new
Uri(asset.BrowserDownloadUrl).LocalPath) == "WheelWizardWindows.exe" or
EndsWith("/WheelWizardWindows.exe")) so the updater consistently picks the
intended artifact.
Summary by CodeRabbit