From 05a87960d1e454e91b2349de08afb6bdc590f9b5 Mon Sep 17 00:00:00 2001 From: Duc-Tam Nguyen Date: Mon, 15 Jun 2026 00:42:53 +0700 Subject: [PATCH] Ship a GUI-subsystem Windows base and cover it in CI A second goreleaser build links a Windows binary for the GUI subsystem (-H windowsgui) and ships it as kage__windows-gui_.zip, scoped so the package managers still install the console build. Packing a viewer onto this base gives a double-click .exe with no console behind it. A CI job cross-compiles the windowsgui link so it cannot rot. --- .github/workflows/ci.yml | 19 +++++++++++++++ .goreleaser.yaml | 51 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1905f04..eacaa2e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,3 +125,22 @@ jobs: cache: true - name: build webview viewer run: CGO_ENABLED=1 go build -tags webview ./cmd/kage + + # Cross-compile the GUI-subsystem Windows base the release ships for + # double-click viewers (kage pack --base). A change that breaks the + # -H windowsgui link is caught here instead of at release time. Pure Go, so it + # cross-compiles from Linux with no extra toolchain. + windows-gui: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + check-latest: true + cache: true + - name: build windowsgui base + env: + GOOS: windows + CGO_ENABLED: "0" + run: go build -ldflags "-H=windowsgui" -o kage-windowsgui.exe ./cmd/kage diff --git a/.goreleaser.yaml b/.goreleaser.yaml index b384a4e..3028720 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -43,9 +43,35 @@ builds: - freebsd_amd64 - freebsd_arm64 + # A second Windows build linked for the GUI subsystem (-H windowsgui). It is + # the same pure-Go kage, but a viewer packed onto it shows only its window when + # double-clicked, with no console flashing behind it. Users point `kage pack + # --base` at this to build a clean double-click Windows app. The default build + # above stays console-attached so the CLI still prints clone progress. + - id: kage-gui + binary: kage + main: ./cmd/kage + env: + - CGO_ENABLED=0 + flags: + - -trimpath + ldflags: + - -s -w + - -H=windowsgui + - -X github.com/tamnd/kage/cli.Version={{ .Version }} + - -X github.com/tamnd/kage/cli.Commit={{ .ShortCommit }} + - -X github.com/tamnd/kage/cli.Date={{ .CommitDate }} + mod_timestamp: "{{ .CommitTimestamp }}" + targets: + - windows_amd64 + - windows_arm64 + archives: - # tar.gz everywhere except a zip on Windows. + # tar.gz everywhere except a zip on Windows. Scoped to the console build so + # this is the archive every package manager installs. - id: default + ids: + - kage name_template: "kage_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}" format_overrides: - goos: windows @@ -54,6 +80,18 @@ archives: - LICENSE - README.md + # A separate zip for the GUI-subsystem Windows binary, named so it cannot be + # confused with the console build. It is a base to pack against, not something + # to run directly, so no package manager points at it. + - id: windows-gui + ids: + - kage-gui + name_template: "kage_{{ .Version }}_windows-gui_{{ .Arch }}" + formats: [zip] + files: + - LICENSE + - README.md + nfpms: # One nfpm definition emits the deb, rpm, and apk for every Linux build. kage # is a user command, not a daemon, so there is no unit file and no @@ -61,6 +99,8 @@ nfpms: # dependency the user supplies (or the container image bundles). - id: linux-packages package_name: kage + ids: + - kage file_name_template: "{{ .ConventionalFileName }}" vendor: tamnd homepage: https://github.com/tamnd/kage @@ -106,6 +146,8 @@ homebrew_casks: # HOMEBREW_TAP_GITHUB_TOKEN (a PAT with write to tamnd/homebrew-tap) is set, # so a tokenless release still writes the cask into dist for inspection. - name: kage + ids: + - default repository: owner: tamnd name: homebrew-tap @@ -119,8 +161,11 @@ homebrew_casks: email: tamnd87@gmail.com scoops: - # Scoop manifest for Windows, pushed to the bucket repository. - - repository: + # Scoop manifest for Windows, pushed to the bucket repository. It installs the + # console build (the CLI), not the GUI base. + - ids: + - default + repository: owner: tamnd name: scoop-bucket token: '{{ envOrDefault "SCOOP_BUCKET_GITHUB_TOKEN" "" }}'