-
-
Notifications
You must be signed in to change notification settings - Fork 157
Add Windows installation packages in .msixbundle format
#698
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
linghengqian
wants to merge
2
commits into
version-fox:main
Choose a base branch
from
linghengqian:msix
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| name: compile-msix | ||
|
|
||
| on: | ||
| release: | ||
| types: [released] | ||
|
|
||
| permissions: | ||
| contents: write | ||
| id-token: write | ||
| packages: write | ||
|
|
||
| jobs: | ||
| compile-msix: | ||
| name: Build MSIX bundle and publish | ||
| runs-on: windows-latest | ||
| defaults: | ||
| run: | ||
| working-directory: packaging/msix | ||
| steps: | ||
| - name: Checkout version-fox | ||
| uses: actions/checkout@v7 | ||
| - name: Setup Go | ||
| uses: actions/setup-go@v5 | ||
| with: | ||
| go-version: '1.24' | ||
| cache: true | ||
| - name: Decode signing certificate | ||
| env: | ||
| MSIX_PFX_BASE64: ${{ secrets.MSIX_PFX_BASE64 }} | ||
| shell: pwsh | ||
| run: | | ||
| if ([string]::IsNullOrEmpty($env:MSIX_PFX_BASE64)) { | ||
| Write-Host "MSIX_PFX_BASE64 not configured; the bundle will be published unsigned." | ||
| exit 0 | ||
| } | ||
| [IO.File]::WriteAllBytes((Join-Path (Get-Location) "signing.pfx"), [Convert]::FromBase64String($env:MSIX_PFX_BASE64)) | ||
| # No -X86/-X64/-Arm64 inputs: make-msix.ps1 builds from source itself. | ||
| - name: Build MSIX bundle | ||
| env: | ||
| TAG_NAME: ${{ github.event.release.tag_name }} | ||
| MSIX_SIGN_PFX_PASSWORD: ${{ secrets.MSIX_PFX_PASSWORD }} | ||
| shell: pwsh | ||
| run: | | ||
| $ErrorActionPreference = "Stop" | ||
| $packArgs = @{ Version = ($env:TAG_NAME -replace '^v', '') } | ||
| if (Test-Path "./signing.pfx") { | ||
| $packArgs.SignPfxPath = (Resolve-Path "./signing.pfx").Path | ||
| } | ||
| ./make-msix.ps1 @packArgs | ||
| - name: Upload MSIX Assets | ||
| uses: version-fox/vfox-release-assets@v1 | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| with: | ||
| release_id: ${{ github.event.release.id }} | ||
| assets_path: packaging/msix/Output/*.msixbundle |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| # MSIX Bundle | ||
|
|
||
| The Windows assets on the [Releases](https://github.com/version-fox/vfox/releases) page include a `.msixbundle` package in addition to the setup `.exe`. MSIX is Microsoft's current application deployment format, intended to replace `.msi`/`.exe` installers. A bundle contains builds for `x86`, `x64` and `arm64`; Windows selects the matching architecture at install time. | ||
|
|
||
| ## Requirements | ||
|
|
||
| - Windows 10 (1809+) or Windows Server 2025+ | ||
| - Optional: [App Installer](https://learn.microsoft.com/windows/msix/app-installer/installing-apps-pkg) for double-click installation | ||
|
|
||
| ## Installation | ||
|
|
||
| Download the latest `vfox_<version>_windows.msixbundle` from the [Releases](https://github.com/version-fox/vfox/releases) page and install it by double-click, or from PowerShell: | ||
|
|
||
| ```powershell | ||
| Add-AppxPackage -Path .\vfox_<version>_windows.msixbundle | ||
| ``` | ||
|
|
||
| The package registers an app execution alias for `vfox.exe`, so the `vfox` command is available on PATH after installation without further configuration. | ||
|
|
||
| ::: warning ⚠️ Release bundles are currently unsigned | ||
| Windows refuses to install unsigned packages. Re-sign the bundle with your own certificate before installing (see below). | ||
| ::: | ||
|
|
||
| ### Signing an unsigned bundle | ||
|
|
||
| The build cannot perform signing on behalf of users. At install time Windows verifies the signer against certificates trusted on the target machine, so a certificate generated during packaging is treated the same as no signature at all. In addition, MSIX requires an upgrade package to be signed with the same certificate as the installed one; per-build certificates would therefore break upgrades. Signing with a long-lived certificate of your own is a one-time operation: once the certificate is trusted, subsequent versions install without extra steps. | ||
|
|
||
| First create a self-signed code-signing certificate whose subject matches the package publisher (`CN=VersionFox`) and import it into the trusted store. Importing into `Cert:\LocalMachine\TrustedPeople` requires an elevated (administrator) PowerShell session: | ||
|
|
||
| ```powershell | ||
| $cert = New-SelfSignedCertificate -Type Custom -Subject "CN=VersionFox" ` | ||
| -KeyUsage DigitalSignature -CertStoreLocation "Cert:\CurrentUser\My" ` | ||
| -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") | ||
| $password = ConvertTo-SecureString -String "pick-a-password" -Force -AsPlainText | ||
| Export-PfxCertificate -Cert $cert -FilePath vfox.pfx -Password $password | Out-Null | ||
| Import-PfxCertificate -FilePath vfox.pfx -CertStoreLocation Cert:\LocalMachine\TrustedPeople -Password $password | ||
| ``` | ||
|
|
||
| Then sign the bundle and install it ([signtool](https://learn.microsoft.com/windows/win32/seccrypto/signtool) comes with the Windows SDK): | ||
|
|
||
| ```powershell | ||
| signtool sign /fd SHA256 /f vfox.pfx /p pick-a-password .\vfox_<version>_windows.msixbundle | ||
| Add-AppxPackage -Path .\vfox_<version>_windows.msixbundle | ||
| ``` | ||
|
|
||
| ## Uninstallation | ||
|
|
||
| ```powershell | ||
| Get-AppxPackage *vfox* | Remove-AppxPackage | ||
| ``` | ||
|
|
||
| Alternatively open **Settings** > **Apps** > **Installed apps**, select **vfox** and click **Uninstall**. Uninstalling removes the execution alias together with the package; the `~/.vfox` data directory is kept. | ||
|
|
||
| ## Notes for maintainers | ||
|
|
||
| Release bundles are built by the `compile-msix` workflow on every release. Signing is optional; two options: | ||
|
|
||
| - **Self-signed certificate (no external account needed).** Generate one PFX and keep it stable across releases, then configure the repository secrets `MSIX_PFX_BASE64` (Base64-encoded certificate) and `MSIX_PFX_PASSWORD`; the subject must match the manifest publisher (`CN=VersionFox`). Releases are signed automatically from then on. Publish the public `.cer` file alongside the releases so users only need to import it once — because the signature stays identical across versions, upgrades are unaffected. | ||
| - **Publicly trusted certificate.** Packages signed by a CA-issued code-signing certificate or through [Azure Trusted Signing](https://learn.microsoft.com/azure/trusted-signing/overview) install without any user-side trust configuration. Obtaining one involves identity verification, and OV/EV certificates mandate hardware-protected private keys, which cannot be placed in CI secrets. | ||
|
|
||
| All packaging files reside in the [`packaging/msix/`](https://github.com/version-fox/vfox/tree/main/packaging/msix) directory: | ||
|
|
||
| | File | Purpose | | ||
| |------|---------| | ||
| | `AppxManifest.xml` | Manifest template; `@@VERSION@@`, `@@ARCHITECTURE@@` and `@@PUBLISHER@@` are substituted at build time. | | ||
| | `gen-assets.ps1` | Generates the tile icons from the repository logo (`logo.png`) via System.Drawing: transparent margins are cropped and the artwork is scaled onto a transparent canvas. PNG is required by AppX deployment (SVG is rejected), so these binaries are generated at build time instead of being committed. | | ||
| | `make-msix.ps1` | Builds `vfox` from source with Go, renders the manifest for each architecture, packs them with `MakeAppx.exe`, combines the packages into a `.msixbundle` and optionally signs it with `SignTool.exe`. | | ||
|
|
||
| Local packaging requires Windows, the [Windows SDK](https://developer.microsoft.com/windows/downloads/windows-sdk/) (provides `MakeAppx.exe` / `SignTool.exe`) and [Go](https://go.dev/dl/): | ||
|
|
||
| ```powershell | ||
| ./packaging/msix/make-msix.ps1 -Version 1.2.3 | ||
| ``` | ||
|
|
||
| Artifacts are written to `packaging/msix/Output/`; `assets/`, `staging/` and `build/` are scratch directories and gitignored. Only stable versions without prerelease or build metadata are supported; they are normalized to four-part versions (`1.2.3` → `1.2.3.0`). | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| # MSIX 安装包 | ||
|
|
||
| [Releases](https://github.com/version-fox/vfox/releases) 页面的 Windows 资产中,除 setup `.exe` 安装器外还提供 `.msixbundle` 安装包。MSIX 是微软当前的应用部署格式,用于取代 `.msi`/`.exe` 安装器。一个 bundle 内含 `x86`、`x64`、`arm64` 三种架构的构建,安装时由 Windows 自动选择匹配的架构。 | ||
|
|
||
| ## 环境要求 | ||
|
|
||
| - Windows 10(1809+)或 Windows Server 2025+ | ||
| - 可选:[应用安装程序](https://learn.microsoft.com/windows/msix/app-installer/installing-apps-pkg)(用于双击安装) | ||
|
|
||
| ## 安装 | ||
|
|
||
| 从 [Releases](https://github.com/version-fox/vfox/releases) 页面下载最新版本的 `vfox_<version>_windows.msixbundle`,双击安装,或在 PowerShell 中执行: | ||
|
|
||
| ```powershell | ||
| Add-AppxPackage -Path .\vfox_<version>_windows.msixbundle | ||
| ``` | ||
|
|
||
| 安装包会注册 `vfox.exe` 的应用执行别名,因此安装完成后 `vfox` 命令即可直接使用,无需手动配置 PATH。 | ||
|
|
||
| ::: warning ⚠️ 当前发布的安装包未签名 | ||
| Windows 会拒绝安装未签名包。安装前请先使用自己的证书对安装包重新签名(方法见下文)。 | ||
| ::: | ||
|
|
||
| ### 为未签名安装包签名 | ||
|
|
||
| 构建过程无法代替用户完成签名。Windows 在安装时校验签名证书是否属于目标机器信任的证书,打包阶段生成的临时证书与不签名效果相同;此外 MSIX 要求升级包与已安装包使用同一证书签名,每次构建使用不同证书会导致无法覆盖升级。因此应使用一张长期持有的证书完成签名:证书受信任后,后续版本均可直接安装。 | ||
|
|
||
| 首次操作需创建一张主题与包发布者(`CN=VersionFox`)一致的自签名代码签名证书,并导入本机受信任存储。导入 `Cert:\LocalMachine\TrustedPeople` 需要以管理员身份运行 PowerShell: | ||
|
|
||
| ```powershell | ||
| $cert = New-SelfSignedCertificate -Type Custom -Subject "CN=VersionFox" ` | ||
| -KeyUsage DigitalSignature -CertStoreLocation "Cert:\CurrentUser\My" ` | ||
| -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") | ||
| $password = ConvertTo-SecureString -String "pick-a-password" -Force -AsPlainText | ||
| Export-PfxCertificate -Cert $cert -FilePath vfox.pfx -Password $password | Out-Null | ||
| Import-PfxCertificate -FilePath vfox.pfx -CertStoreLocation Cert:\LocalMachine\TrustedPeople -Password $password | ||
| ``` | ||
|
|
||
| 随后对安装包签名并安装([signtool](https://learn.microsoft.com/windows/win32/seccrypto/signtool) 随 Windows SDK 提供): | ||
|
|
||
| ```powershell | ||
| signtool sign /fd SHA256 /f vfox.pfx /p pick-a-password .\vfox_<version>_windows.msixbundle | ||
| Add-AppxPackage -Path .\vfox_<version>_windows.msixbundle | ||
| ``` | ||
|
|
||
| ## 卸载 | ||
|
|
||
| ```powershell | ||
| Get-AppxPackage *vfox* | Remove-AppxPackage | ||
| ``` | ||
|
|
||
| 也可以在 **设置** > **应用** > **已安装的应用** 中选择 **vfox** 并点击 **卸载**。卸载会同时移除应用执行别名;`~/.vfox` 数据目录会被保留。 | ||
|
|
||
| ## 维护者须知 | ||
|
|
||
| 发布版 bundle 由 `compile-msix` 工作流在每次 release 时构建。签名可选,有两种方式: | ||
|
|
||
| - **自签证书(无需外部账号)**:生成一张 PFX 证书并在各次发布间保持不变,然后配置仓库 secrets:`MSIX_PFX_BASE64`(Base64 编码的证书文件)与 `MSIX_PFX_PASSWORD`;证书主题必须与清单中的发布者一致(`CN=VersionFox`)。此后每次发布都会自动签名。同时将公开证书(`.cer` 文件)随 release 一并分发,用户只需导入一次;由于各版本签名保持一致,覆盖升级不受影响。 | ||
| - **受信 CA 证书**:由公共 CA 签发的代码签名证书或 [Azure Trusted Signing](https://learn.microsoft.com/azure/trusted-signing/overview) 服务签名的包,用户机器默认信任,安装时无需任何额外配置。但证书申请需要实名验证,OV/EV 证书的私钥按规定必须保存在硬件介质中,无法放入 CI secrets。 | ||
|
|
||
| 打包相关文件位于仓库的 [`packaging/msix/`](https://github.com/version-fox/vfox/tree/main/packaging/msix) 目录: | ||
|
|
||
| | 文件 | 用途 | | ||
| |------|------| | ||
| | `AppxManifest.xml` | 清单模板;`@@VERSION@@`、`@@ARCHITECTURE@@`、`@@PUBLISHER@@` 在构建时替换。 | | ||
| | `gen-assets.ps1` | 通过 System.Drawing 从仓库 logo(`logo.png`)生成磁贴图标:裁剪透明边距并将图案缩放至透明画布。PNG 是 AppX 部署的强制要求(不支持 SVG),因此这些二进制文件不入库,在每次构建时重新生成。 | | ||
| | `make-msix.ps1` | 使用 Go 从源码构建 `vfox`,为每种架构渲染清单,经 `MakeAppx.exe` 打包后合并为 `.msixbundle`,并可选通过 `SignTool.exe` 签名。 | | ||
|
|
||
| 本地打包需要 Windows、[Windows SDK](https://developer.microsoft.com/windows/downloads/windows-sdk/)(提供 `MakeAppx.exe` / `SignTool.exe`)与 [Go](https://go.dev/dl/): | ||
|
|
||
| ```powershell | ||
| ./packaging/msix/make-msix.ps1 -Version 1.2.3 | ||
| ``` | ||
|
|
||
| 产物输出到 `packaging/msix/Output/`;`assets/`、`staging/`、`build/` 为临时目录,均已 gitignore。仅支持不含预发布或构建元数据后缀的正式版本,并会归一化为四段版本号(`1.2.3` → `1.2.3.0`)。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is the best way to write the documentation, but surely the signature shouldn't be provided by me, right?