Conversation
|
Caution Review failedThe pull request is closed. Walkthrough新增 GitHub Actions 工作流 Changes
Sequence Diagram(s)sequenceDiagram
participant User as 用户
participant GH as GitHub Actions
participant Repo as 本仓库
participant ExtRepo as ege-installer
participant BuildPS as build.ps1
participant Artifact as 制品(dist)
participant Release as GitHub Release
User->>GH: 推送 v* 标签 或 手动触发 workflow_dispatch
GH->>Repo: 检出并运行 `.github/workflows/release.yml`
Repo->>ExtRepo: 克隆或更新 ege-installer
GH->>GH: 决定版本(input > tag > version.txt > 1.0.0)
GH->>ExtRepo: 安装 NSIS 并调用 BuildPS(Version, ProductVersion)
ExtRepo->>BuildPS: 执行构建(NSIS)
BuildPS->>Artifact: 生成 `ege-installer-<version>.exe` 到 dist/
GH->>Artifact: 上传 dist 作为 action 制品
GH->>Release: 若为 tag,则创建 Release 并附加 exe(草稿/预发布,含中文正文)
Estimated code review effort🎯 3 (中等) | ⏱️ ~20 分钟 Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 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 |
🤖 Augment PR SummarySummary: Adds automated Windows installer packaging for Changes:
Technical Notes: CI runs on 🤖 Was this summary useful? React with 👍 or 👎 |
|
|
||
| - name: Clone ege-installer | ||
| run: | | ||
| git clone --depth 1 https://github.com/x-ege/ege-installer.git ege-installer |
There was a problem hiding this comment.
This clones ege-installer from the default branch at build time, which can make tagged releases non-reproducible (and increases supply-chain risk if ege-installer changes); consider pinning to a known tag/commit for release builds.
Severity: medium
Other Locations
build-installer.sh:63build-installer.sh:68
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
|
|
||
| Write-Host "Display Version: $version" | ||
| Write-Host "Product Version: $productVersion" | ||
| "VERSION=$version" >> $env:GITHUB_OUTPUT |
There was a problem hiding this comment.
Since $version is written directly to $GITHUB_OUTPUT, a version containing newlines or other special characters could corrupt outputs and break downstream steps; consider validating/normalizing it to a single safe token before exporting.
Severity: medium
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
| case "$1" in | ||
| -v | --version) | ||
| CUSTOM_VERSION="$2" | ||
| shift 2 |
There was a problem hiding this comment.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @.github/workflows/release.yml:
- Around line 57-67: The current fallback silently sets $version = "1.0.0" when
$version is empty and version.txt is missing; update the block that uses
$versionFile/Test-Path/Get-Content/Write-Host so that instead of assigning
"1.0.0" it emits a visible error and exits (e.g., use Write-Error and exit 1)
when no version can be determined—this ensures tag-triggered releases cannot
proceed with an incorrect default version; if you prefer a softer approach,
replace the silent assignment with a prominent Write-Host warning and fail the
job for tag-triggered workflows.
- Around line 70-82: The current logic leaves $productVersion unchanged when it
contains more than four segments (e.g., "1.2.3.4.5"); after splitting into
$parts (the line assigning $parts = $productVersion.Split('.')), add a
truncation step that, if $parts.Length -gt 4, reduces $parts to the first four
elements and then reassigns $productVersion by joining those four segments (so
subsequent checks and NSIS/VIProductVersion use a strict X.X.X.X format). Ensure
this uses the existing $productVersion and $parts variables so other branches
still work.
- Around line 37-55: The workflow currently injects github.event.inputs.version
and github.ref directly into the PowerShell run script (variables $inputVersion
and $ref), creating a script-injection risk; change the job to pass these values
via environment variables (e.g. set env: INPUT_VERSION: ${{
github.event.inputs.version }} and env: GITHUB_REF: ${{ github.ref }}) and in
the script read them via $env:INPUT_VERSION and $env:GITHUB_REF, then
validate/sanitize before use (for example use a strict regex to allow only
semantic version characters or extract tag with -match "^refs/tags/v(.+)$"
against $env:GITHUB_REF and assign to $version only if it passes the regex),
thereby removing direct interpolation of ${ { github.* }} into the run block and
ensuring $inputVersion, $ref and $version are derived from validated environment
variables.
🧹 Nitpick comments (4)
build-installer.sh (3)
16-17:set -e应在cd之前,确保cd失败时脚本也能退出。当前
set -e在cd之后,如果cd失败(例如脚本所在目录被删除),脚本会在错误的工作目录下继续执行。建议调整顺序
+set -e cd "$(dirname "$0")" -set -e
30-32:-v缺少参数值校验,用户误用时报错不友好。如果用户执行
./build-installer.sh -v(不带版本号),$2为空,CUSTOM_VERSION被设为空字符串,然后shift 2在只剩一个参数时会失败。虽然set -e会使脚本退出,但错误信息不直观。建议添加参数存在性检查
-v | --version) + if [[ -z "${2:-}" ]]; then + echo "Error: -v/--version requires a version argument." + exit 1 + fi CUSTOM_VERSION="$2" shift 2
131-140: 日志输出与实际执行的路径不一致。第 131 行将
BUILD_SCRIPT转为 Windows 路径存入BUILD_SCRIPT_WIN,第 133 行日志打印的是$BUILD_SCRIPT_WIN,但第 138 行实际传给powershell -File的却是未转换的$BUILD_SCRIPT(Unix 路径)。虽然 MSYS2 会自动转换传给 Windows 可执行程序的路径参数,所以实际运行可能没有问题,但日志与实际命令不一致会给排查问题带来困惑。建议统一:
使用转换后的 Windows 路径调用 PowerShell
echo "Running: powershell $BUILD_SCRIPT_WIN" echo "" powershell -NoProfile -ExecutionPolicy Bypass -File "$BUILD_SCRIPT_WIN" \ -XegeLibsPath "$XEGE_LIBS_WIN" \ -Version "$EGE_VERSION"或者如果确认依赖 MSYS 自动转换,则日志也应打印实际使用的路径:
-echo "Running: powershell $BUILD_SCRIPT_WIN" +echo "Running: powershell $BUILD_SCRIPT".github/workflows/release.yml (1)
31-32: NSIS 未固定版本,可能影响构建可复现性。
choco install nsis -y会安装最新版。如果 NSIS 更新引入了不兼容变更,可能导致构建意外失败。可考虑固定版本以提升 CI 稳定性。固定 NSIS 版本示例
- run: choco install nsis -y + run: choco install nsis --version=3.11 -y
| run: | | ||
| # Priority: workflow input > tag name > version.txt | ||
| $version = "" | ||
|
|
||
| # 1. Check workflow_dispatch input | ||
| $inputVersion = "${{ github.event.inputs.version }}" | ||
| if ($inputVersion) { | ||
| $version = $inputVersion | ||
| Write-Host "Using workflow input version: $version" | ||
| } | ||
|
|
||
| # 2. Check tag name | ||
| if (-not $version) { | ||
| $ref = "${{ github.ref }}" | ||
| if ($ref -match "^refs/tags/v(.+)$") { | ||
| $version = $matches[1] | ||
| Write-Host "Using tag version: $version" | ||
| } | ||
| } |
There was a problem hiding this comment.
脚本注入风险:github.event.inputs.version 和 github.ref 直接内插到 run 脚本中。
${{ github.event.inputs.version }}(第 42 行)和 ${{ github.ref }}(第 50 行)直接拼入 PowerShell 脚本,存在脚本注入风险。虽然 workflow_dispatch 仅限仓库协作者触发,但这是 GitHub Actions 安全最佳实践中明确反对的模式。恶意或错误的输入(如包含 " 或 ; 的版本号)可能导致任意命令执行。
推荐做法是通过环境变量传递,避免直接内插:
建议使用环境变量替代直接内插
- name: Determine version
id: version
shell: pwsh
+ env:
+ INPUT_VERSION: ${{ github.event.inputs.version }}
+ GH_REF: ${{ github.ref }}
run: |
# Priority: workflow input > tag name > version.txt
$version = ""
# 1. Check workflow_dispatch input
- $inputVersion = "${{ github.event.inputs.version }}"
+ $inputVersion = $env:INPUT_VERSION
if ($inputVersion) {
$version = $inputVersion
Write-Host "Using workflow input version: $version"
}
# 2. Check tag name
if (-not $version) {
- $ref = "${{ github.ref }}"
+ $ref = $env:GH_REF
if ($ref -match "^refs/tags/v(.+)$") {
$version = $matches[1]
Write-Host "Using tag version: $version"
}
}📝 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.
| run: | | |
| # Priority: workflow input > tag name > version.txt | |
| $version = "" | |
| # 1. Check workflow_dispatch input | |
| $inputVersion = "${{ github.event.inputs.version }}" | |
| if ($inputVersion) { | |
| $version = $inputVersion | |
| Write-Host "Using workflow input version: $version" | |
| } | |
| # 2. Check tag name | |
| if (-not $version) { | |
| $ref = "${{ github.ref }}" | |
| if ($ref -match "^refs/tags/v(.+)$") { | |
| $version = $matches[1] | |
| Write-Host "Using tag version: $version" | |
| } | |
| } | |
| - name: Determine version | |
| id: version | |
| shell: pwsh | |
| env: | |
| INPUT_VERSION: ${{ github.event.inputs.version }} | |
| GH_REF: ${{ github.ref }} | |
| run: | | |
| # Priority: workflow input > tag name > version.txt | |
| $version = "" | |
| # 1. Check workflow_dispatch input | |
| $inputVersion = $env:INPUT_VERSION | |
| if ($inputVersion) { | |
| $version = $inputVersion | |
| Write-Host "Using workflow input version: $version" | |
| } | |
| # 2. Check tag name | |
| if (-not $version) { | |
| $ref = $env:GH_REF | |
| if ($ref -match "^refs/tags/v(.+)$") { | |
| $version = $matches[1] | |
| Write-Host "Using tag version: $version" | |
| } | |
| } |
🤖 Prompt for AI Agents
In @.github/workflows/release.yml around lines 37 - 55, The workflow currently
injects github.event.inputs.version and github.ref directly into the PowerShell
run script (variables $inputVersion and $ref), creating a script-injection risk;
change the job to pass these values via environment variables (e.g. set env:
INPUT_VERSION: ${{ github.event.inputs.version }} and env: GITHUB_REF: ${{
github.ref }}) and in the script read them via $env:INPUT_VERSION and
$env:GITHUB_REF, then validate/sanitize before use (for example use a strict
regex to allow only semantic version characters or extract tag with -match
"^refs/tags/v(.+)$" against $env:GITHUB_REF and assign to $version only if it
passes the regex), thereby removing direct interpolation of ${ { github.* }}
into the run block and ensuring $inputVersion, $ref and $version are derived
from validated environment variables.
There was a problem hiding this comment.
Pull request overview
Adds automated packaging for an end-user Windows installer (ege-setup-<version>.exe) via a local build script and a tag-triggered GitHub Actions release workflow, using the external x-ege/ege-installer project.
Changes:
- Added
build-installer.shfor local installer builds (clone/updateege-installer, read version, invokebuild.ps1, copy output todist/). - Added
.github/workflows/release.ymlto build the installer onv*tags (and manual dispatch) and publish it to GitHub Releases. - Updated
.gitignoreto ignoredist/and the clonedege-installer/directory.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| build-installer.sh | New local script to build the Windows installer via ege-installer tooling. |
| .github/workflows/release.yml | New CI workflow to build/publish the installer on tags and upload artifacts. |
| .gitignore | Ignores generated installer output and the cloned installer tool repo. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (-not $version) { | ||
| $versionFile = "${{ github.workspace }}\version.txt" | ||
| if (Test-Path $versionFile) { | ||
| $version = (Get-Content $versionFile -Raw).Trim() | ||
| Write-Host "Using version.txt: $version" | ||
| } else { | ||
| $version = "1.0.0" | ||
| Write-Host "Fallback version: $version" | ||
| } |
There was a problem hiding this comment.
If neither a workflow input nor a tag is present, the workflow falls back to 1.0.0 when version.txt is missing. For a release pipeline, silently defaulting to an arbitrary version is error-prone; it should fail with a clear error so accidental releases don’t get published under the wrong version.
| -v | --version) | ||
| CUSTOM_VERSION="$2" | ||
| shift 2 | ||
| ;; |
There was a problem hiding this comment.
The -v/--version option assumes a value exists in $2; if the user passes -v as the last argument, shift 2 will fail (and with set -e the script exits) without a clear error. Add an explicit check for a missing/empty version argument and print usage before exiting.
build-installer.sh
Outdated
|
|
||
| # 注意:build.ps1 的 NSIS 输出路径被硬编码为 ege-installer/dist/ | ||
| # 不传 OutputDir,让 build.ps1 使用默认值,之后再复制到本地 dist/ | ||
| powershell -NoProfile -ExecutionPolicy Bypass -File "$BUILD_SCRIPT" \ |
There was a problem hiding this comment.
BUILD_SCRIPT_WIN is computed and logged, but the actual PowerShell invocation uses the POSIX path in $BUILD_SCRIPT. In Git Bash/MSYS, passing a /c/... path to powershell -File can be interpreted as a switch and fail. Use the Windows-converted path consistently (or otherwise ensure -File receives a PowerShell-safe path).
| powershell -NoProfile -ExecutionPolicy Bypass -File "$BUILD_SCRIPT" \ | |
| powershell -NoProfile -ExecutionPolicy Bypass -File "$BUILD_SCRIPT_WIN" \ |
|
|
||
| - name: Clone ege-installer | ||
| run: | | ||
| git clone --depth 1 https://github.com/x-ege/ege-installer.git ege-installer |
There was a problem hiding this comment.
This workflow clones and executes ege-installer from GitHub without pinning to a tag/commit. For release automation, this creates a supply-chain risk and makes releases non-reproducible if ege-installer changes. Pin the clone to a known-good ref (tag/SHA) and update it intentionally when needed.
| git clone --depth 1 https://github.com/x-ege/ege-installer.git ege-installer | |
| # NOTE: Pin to a known-good tag or commit SHA to ensure reproducible, secure builds. | |
| # Update <PINNED_EGE_INSTALLER_REF> intentionally when upgrading ege-installer. | |
| git clone --depth 1 --branch <PINNED_EGE_INSTALLER_REF> https://github.com/x-ege/ege-installer.git ege-installer |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @.github/workflows/release.yml:
- Around line 89-95: Validate and sanitize the version output in the "Determine
version" step (e.g., enforce a regex like ^\d+(\.\d+)*[-\w]*$ and fail the step
if it doesn't match) to prevent malicious values from being written to
GITHUB_OUTPUT, and stop relying on direct interpolation of
steps.version.outputs.VERSION in consumer steps; update the "Build installer
package" step (and other consumers referencing steps.version.outputs.VERSION) to
receive the version via environment variables (env: VERSION: ${{
steps.version.outputs.VERSION }}) and then reference the env variable within the
run block instead of using ${{ ... }} so untrusted workflow output cannot be
injected directly into shell commands.
- Around line 31-32: Update the GitHub Actions step that installs NSIS (the
"Install NSIS" run step) to pin the package to a specific version instead of
using `choco install nsis -y`; change it to install NSIS 3.11 (or a specific
3.11.x patch) by passing the --version argument (e.g., --version=3.11) so builds
are reproducible and use the patched release that fixes the CVE.
🧹 Nitpick comments (3)
.github/workflows/release.yml (3)
27-29: ege-installer 未固定到特定提交或标签,存在供应链与构建可重现性风险。当前
git clone --depth 1始终拉取ege-installer的默认分支最新提交。如果上游仓库被篡改或引入了破坏性变更,发布流水线将在无预警的情况下受到影响。建议固定到已知可信的提交哈希或标签:
建议固定提交哈希
- git clone --depth 1 https://github.com/x-ege/ege-installer.git ege-installer + git clone --depth 1 --branch <known-tag-or-branch> https://github.com/x-ege/ege-installer.git ege-installer + cd ege-installer + git verify-commit HEAD || true # optional: verify if signed + # Or pin to a specific commit: + # git clone https://github.com/x-ege/ege-installer.git ege-installer + # cd ege-installer && git checkout <trusted-commit-sha>
17-19: 建议添加concurrency控制和作业超时。当前工作流没有
concurrency组和timeout-minutes设定:
- 如果短时间内推送多个
v*标签,可能会并行运行多个发布作业,产生竞态。- 没有超时的作业在卡住时会一直运行到 GitHub 默认的 6 小时上限。
建议添加 concurrency 和 timeout
jobs: build-and-release: runs-on: windows-latest + timeout-minutes: 30 + concurrency: + group: release-installer + cancel-in-progress: false
22-25:fetch-depth: 0对当前用途不是必需的。工作流仅从标签名或
version.txt获取版本号,不需要完整的 git 历史。fetch-depth: 0会拉取全部提交历史,对于大型仓库会增加 checkout 时间。如果没有其他需要完整历史的原因(如生成 changelog),可以改为默认的浅克隆:
建议移除 fetch-depth: 0
- name: Checkout repository uses: actions/checkout@v4 - with: - fetch-depth: 0
Security improvements: - Pin NSIS to version 3.11 for reproducible builds - Add version format validation (X.Y.Z with optional suffix) Best practices: - Add concurrency control to prevent parallel releases - Add 30-minute timeout to prevent hanging jobs - Remove unnecessary fetch-depth: 0 (only version.txt needed) Design decisions (intentionally not changed): - Keep ege-installer on latest (not pinned): We control the upstream and want immediate bug fixes and new IDE support. This is a conscious trade-off favoring flexibility over hermetic builds.
Workflow improvements: - Fail fast for tag releases when version cannot be determined - Truncate productVersion to 4 segments if longer (NSIS requirement) - Clarify fallback 1.0.0 is for manual workflow only build-installer.sh improvements: - Move 'set -e' before 'cd' to catch directory change errors - Add parameter validation for -v/--version flag - Use BUILD_SCRIPT_WIN consistently in PowerShell invocation - Improve log message clarity
Add automated installer packaging using ege-installer to produce a single
ege-installer-<version>.exefor end users.Changes
CI/CD
.github/workflows/release.yml: GitHub Actions workflow triggered byv*tagsworkflow_dispatchwith optional version overrideBuild tooling
build-installer.sh: Local build script for developersversion.txtor accepts-voverridebuild.ps1via PowerShell to producedist/ege-installer-<version>.exe--cleanto reset cached ege-installerConfiguration
.gitignore: Addeddist/andege-installer/to ignore build artifactsDesign Decisions
Script clone vs Git submodule
Chose on-demand script clone over git submodule because:
setup.ps1 -Auto)Filename: ege-installer (not ege-setup)
Output filename is
ege-installer-*.exefor clarity:Usage
Local build (requires NSIS 3.11+):
Release via CI:
git tag v25.11.0 git push origin v25.11.0 # -> GitHub Actions builds and publishes ege-installer-25.11.0.exeSummary by CodeRabbit
发布说明
新功能
Chores