From 8aba2c7c1e3f209367a68593c5483f6c48de8a32 Mon Sep 17 00:00:00 2001 From: ZeekA McZeekA <148893598+TheZeekA@users.noreply.github.com> Date: Sun, 2 Aug 2026 16:04:09 +1200 Subject: [PATCH 1/2] Replace Resource Hacker chain in Windows CI with go-winres patch Manifest and version info are now defined in src/winres/winres.json (RT_MANIFEST/RT_VERSION) alongside the existing icon entries, and patched into the built exe post-link via `go tool go-winres patch`. This drops the unversioned Resource Hacker zip download and five tool invocations separated by hardcoded Start-Sleep calls (3.5+ minutes per build), replacing them with one deterministic, checksum pinned Go tool dependency. The manifest can't be folded into the compile-time .syso like the icon is, because this project cgo-links via mingw, whose CRT auto-links its own default-manifest.o into GUI executables and conflicts with an embedded RT_MANIFEST at link time. Patching it in post-build sidesteps that. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/build-windows.yml | 23 ++-------- .github/workflows/pr-test-build-windows.yml | 23 ++-------- dist/windows/versioninfo.rc | 22 ---------- src/README.md | 14 ++++-- src/go.mod | 10 +++++ src/go.sum | 47 +++++++++++++++++++++ src/winres/winres.json | 23 ++++++++++ 7 files changed, 99 insertions(+), 63 deletions(-) delete mode 100644 dist/windows/versioninfo.rc diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 96e3cd4..08cc29d 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -43,32 +43,17 @@ jobs: CGO_ENABLED: 1 GOAMD64: v1 - - name: Add icon, manifest, and version info - shell: pwsh + - name: Add manifest and version info run: | - Invoke-WebRequest -OutFile reshacker_setup.zip https://github.com/user-attachments/files/18878075/reshacker_setup.zip - Expand-Archive -DestinationPath reshacker_setup reshacker_setup.zip - reshacker_setup/reshacker_setup.exe /SILENT - Start-Sleep -Seconds 60 - Invoke-Expression "& `"$Env:P`" -open src/1.exe -save src/2.exe -action addoverwrite -res images/lock.ico -mask `"ICONGROUP,MAINICON,`"" - Start-Sleep -Seconds 30 - Invoke-Expression "& `"$Env:P`" -open src/2.exe -save src/3.exe -action addoverwrite -res images/lock.ico -mask `"ICONGROUP,GLFW_ICON,`"" - Start-Sleep -Seconds 30 - Invoke-Expression "& `"$Env:P`" -open src/3.exe -save src/4.exe -action addoverwrite -res dist/windows/manifest.xml -mask `"MANIFEST,1,`"" - Start-Sleep -Seconds 30 - Invoke-Expression "& `"$Env:P`" -open dist/windows/versioninfo.rc -save resources.res -action compile" - Start-Sleep -Seconds 30 - Invoke-Expression "& `"$Env:P`" -open src/4.exe -save src/5.exe -action addoverwrite -res resources.res" - Start-Sleep -Seconds 30 - env: - P: "C:\\Program Files (x86)\\Resource Hacker\\ResourceHacker.exe" + cd src + go tool go-winres patch --in winres/winres.json --no-backup 1.exe - name: Compress with upx shell: pwsh run: | Invoke-WebRequest -OutFile upx.zip https://github.com/upx/upx/releases/download/v5.0.2/upx-5.0.2-win64.zip Expand-Archive -DestinationPath upx upx.zip - upx/upx-5.0.2-win64/upx.exe --lzma -o src/ZeeCrypt.exe src/5.exe + upx/upx-5.0.2-win64/upx.exe --lzma -o src/ZeeCrypt.exe src/1.exe - name: Install WiX shell: pwsh diff --git a/.github/workflows/pr-test-build-windows.yml b/.github/workflows/pr-test-build-windows.yml index a50d224..627eb8a 100644 --- a/.github/workflows/pr-test-build-windows.yml +++ b/.github/workflows/pr-test-build-windows.yml @@ -34,32 +34,17 @@ jobs: CGO_ENABLED: 1 GOAMD64: v1 - - name: Add icon, manifest, and version info - shell: pwsh + - name: Add manifest and version info run: | - Invoke-WebRequest -OutFile reshacker_setup.zip https://github.com/user-attachments/files/18878075/reshacker_setup.zip - Expand-Archive -DestinationPath reshacker_setup reshacker_setup.zip - reshacker_setup/reshacker_setup.exe /SILENT - Start-Sleep -Seconds 60 - Invoke-Expression "& `"$Env:P`" -open src/1.exe -save src/2.exe -action addoverwrite -res images/lock.ico -mask `"ICONGROUP,MAINICON,`"" - Start-Sleep -Seconds 30 - Invoke-Expression "& `"$Env:P`" -open src/2.exe -save src/3.exe -action addoverwrite -res images/lock.ico -mask `"ICONGROUP,GLFW_ICON,`"" - Start-Sleep -Seconds 30 - Invoke-Expression "& `"$Env:P`" -open src/3.exe -save src/4.exe -action addoverwrite -res dist/windows/manifest.xml -mask `"MANIFEST,1,`"" - Start-Sleep -Seconds 30 - Invoke-Expression "& `"$Env:P`" -open dist/windows/versioninfo.rc -save resources.res -action compile" - Start-Sleep -Seconds 30 - Invoke-Expression "& `"$Env:P`" -open src/4.exe -save src/5.exe -action addoverwrite -res resources.res" - Start-Sleep -Seconds 30 - env: - P: "C:\\Program Files (x86)\\Resource Hacker\\ResourceHacker.exe" + cd src + go tool go-winres patch --in winres/winres.json --no-backup 1.exe - name: Compress with upx shell: pwsh run: | Invoke-WebRequest -OutFile upx.zip https://github.com/upx/upx/releases/download/v5.0.2/upx-5.0.2-win64.zip Expand-Archive -DestinationPath upx upx.zip - upx/upx-5.0.2-win64/upx.exe --lzma -o src/ZeeCrypt.exe src/5.exe + upx/upx-5.0.2-win64/upx.exe --lzma -o src/ZeeCrypt.exe src/1.exe - name: Upload artifact uses: actions/upload-artifact@v4 diff --git a/dist/windows/versioninfo.rc b/dist/windows/versioninfo.rc deleted file mode 100644 index e728d04..0000000 --- a/dist/windows/versioninfo.rc +++ /dev/null @@ -1,22 +0,0 @@ -1 VERSIONINFO -FILEVERSION 1,51,0,0 -PRODUCTVERSION 1,51,0,0 -FILEOS 0x40004 -FILETYPE 0x1 -{ -BLOCK "StringFileInfo" -{ - BLOCK "040904B0" - { - VALUE "CompanyName", "Teddy Jones" - VALUE "FileVersion", "1.51" - VALUE "LegalCopyright", "\xA9 Evan Su & contributors, GPLv3" - VALUE "ProductName", "ZeeCrypt" - } -} - -BLOCK "VarFileInfo" -{ - VALUE "Translation", 0x0409 0x04B0 -} -} diff --git a/src/README.md b/src/README.md index 0e206ae..97d9380 100644 --- a/src/README.md +++ b/src/README.md @@ -22,8 +22,16 @@ You should now see a compiled executable (`ZeeCrypt.exe`) in your directory, wit # Updating the app icon The icon is embedded automatically via `rsrc_windows_386.syso`/`rsrc_windows_amd64.syso` in this directory, which `go build` links in without any extra flags. If you change `images/lock.ico`, regenerate these files: ``` -go install github.com/tc-hib/go-winres@latest cd src -go-winres make +go tool go-winres make ``` -This reads `src/winres/winres.json` and rewrites the `.syso` files to match the new icon. +This reads `src/winres/winres.json` (icon only — see below) and rewrites the `.syso` files to match the new icon. + +# Manifest and version info +`src/winres/winres.json` also defines the app manifest (`RT_MANIFEST`, sourced from `dist/windows/manifest.xml`) and version info (`RT_VERSION`, shown in Explorer's file Properties dialog). These are **not** compiled into the `.syso` files above — this project links with cgo (for GLFW) via mingw, whose C runtime auto-links its own `default-manifest.o` into GUI executables, which conflicts with an embedded `RT_MANIFEST` at link time (`ld: .rsrc merge failure: multiple non-default manifests`). Version info alone doesn't hit this conflict, but it's kept alongside the manifest in the same file for a single source of truth. + +Instead, CI (and release builds) patch the manifest and version info into the already-built exe as a separate step: +``` +go tool go-winres patch --in winres/winres.json --no-backup ZeeCrypt.exe +``` +When bumping `VERSION`, also update `file_version`/`product_version`/`FileVersion` in `src/winres/winres.json` to match. diff --git a/src/go.mod b/src/go.mod index e29e0a5..f826d62 100644 --- a/src/go.mod +++ b/src/go.mod @@ -17,5 +17,15 @@ require ( github.com/Picocrypt/glfw/v3.3/glfw v0.0.0-20250412234750-7b96bfdb8dd8 // indirect github.com/Picocrypt/mainthread v0.0.0-20240831004314-496f638392b3 // indirect github.com/Picocrypt/w32 v0.0.0-20240831001500-1183079d4d57 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/tc-hib/go-winres v0.3.3 // indirect + github.com/tc-hib/winres v0.2.1 // indirect + github.com/urfave/cli/v2 v2.25.7 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + golang.org/x/image v0.12.0 // indirect golang.org/x/sys v0.34.0 // indirect ) + +tool github.com/tc-hib/go-winres diff --git a/src/go.sum b/src/go.sum index b490245..84f488b 100644 --- a/src/go.sum +++ b/src/go.sum @@ -18,7 +18,54 @@ github.com/Picocrypt/w32 v0.0.0-20240831001500-1183079d4d57 h1:jusSXTp0h5wz8lxNX github.com/Picocrypt/w32 v0.0.0-20240831001500-1183079d4d57/go.mod h1:FkeZHdKlITdP34VknO8yLdRY5pCi+iWEhDSA0YsBhZc= github.com/Picocrypt/zxcvbn-go v0.0.0-20250412183938-d59695960527 h1:IqypAzv5COsByMhiSdwlgafA5SBRG7Z0binnBSo3htM= github.com/Picocrypt/zxcvbn-go v0.0.0-20250412183938-d59695960527/go.mod h1:u0rcUNEwy7st1DnPxdOJdTsh0aSRhrdMOxlIGrXR1Ls= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/tc-hib/go-winres v0.3.3 h1:DQ50qlvDVhqrDOY0svTxZFZWfKWtZtfnXXHPCw6lqh0= +github.com/tc-hib/go-winres v0.3.3/go.mod h1:5NGzOtuvjSqnpIEi2o1h48MKZzP9olvrf+PeY2t1uoA= +github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA= +github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= +golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/src/winres/winres.json b/src/winres/winres.json index b991c88..d06ebb2 100644 --- a/src/winres/winres.json +++ b/src/winres/winres.json @@ -6,5 +6,28 @@ "GLFW_ICON": { "0000": "../../images/lock.ico" } + }, + "RT_MANIFEST": { + "#1": { + "0409": "../../dist/windows/manifest.xml" + } + }, + "RT_VERSION": { + "#1": { + "0000": { + "fixed": { + "file_version": "1.51.0.0", + "product_version": "1.51.0.0" + }, + "info": { + "0409": { + "CompanyName": "Teddy Jones", + "FileVersion": "1.51", + "LegalCopyright": "© Evan Su & contributors, GPLv3", + "ProductName": "ZeeCrypt" + } + } + } + } } } From c3793c504e4128c86b898f59c8725d2413be9fcf Mon Sep 17 00:00:00 2001 From: ZeekA McZeekA <148893598+TheZeekA@users.noreply.github.com> Date: Sun, 2 Aug 2026 16:07:51 +1200 Subject: [PATCH 2/2] Add workflow_dispatch to pr-test-build-windows for manual CI validation Automatic triggers (push/pull_request) don't fire on this fork until approved in repo settings, so this workflow has never actually run. Manual dispatch lets it be validated without needing that approval or touching the release pipeline. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/pr-test-build-windows.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-test-build-windows.yml b/.github/workflows/pr-test-build-windows.yml index 627eb8a..8063ef0 100644 --- a/.github/workflows/pr-test-build-windows.yml +++ b/.github/workflows/pr-test-build-windows.yml @@ -7,6 +7,7 @@ on: pull_request: branches: - main + workflow_dispatch: jobs: pr-test-build-windows: