Skip to content

Fix Windows CLI download: missing CDN fallback + missing .exe extension - #98

Merged
kdacosta0 merged 2 commits into
mainfrom
fix/windows-download-fallback
Aug 26, 2026
Merged

Fix Windows CLI download: missing CDN fallback + missing .exe extension#98
kdacosta0 merged 2 commits into
mainfrom
fix/windows-download-fallback

Conversation

@kdacosta0

@kdacosta0 kdacosta0 commented Aug 25, 2026

Copy link
Copy Markdown
Member

What changed & why

Two bugs were stacked on top of each other, both Windows-only, both in how CLI binaries (rekor-cli, gitsign, ec, etc.) get downloaded/resolved for tests:

  1. No CDN fallback for .zip downloads. The fallback-to-last-stable-version logic only ran for .tar.gz links. Windows binaries are .zip, so they skipped it entirely and just hard-failed when the primary download 400'd.
  2. FindBinary stripped the .exe extension. Once (1) was fixed and the zip download succeeded, the code that locates the binary inside the extracted archive always created a shortcut (symlink) named without .exe on Windows, so the binary couldn't actually be executed.

Before / after

Bug 1 — download:

  • Before: .zip link fails 5 times (400) → no fallback → test fails immediately.
  • After: .zip link fails 5 times → falls back to last stable version via CDN, same as .tar.gz already did on macOS/Linux → download succeeds.

Bug 2 — execution (only visible once bug 1 was fixed):

  • Before: real file is rekor_cli_windows_amd64.exe, but FindBinary links it to a bare rekor-cli (no extension) and returns that path. Running C:\...\rekor-cli directly fails with executable file not found in %PATH%, because Windows won't guess the extension when given a full path.
  • After: FindBinary links it to rekor-cli.exe instead, so the returned path is a valid, correctly-named executable and runs normally.

Test plan

  • go build ./...
  • go vet ./...
  • go test ./pkg/support/... ./pkg/strategy/... — includes TestStrategyContentGatewayZip (exercises the previously-broken .zip download+fallback path end-to-end) and TestFindBinaryWindowsPreservesExeExtension (regression test for the .exe-stripping bug)

Made with Cursor

@qodo-for-securesign

Copy link
Copy Markdown

PR Summary by Qodo

Support Windows ZIP binaries with CDN download fallback

🐞 Bug fix ✨ Enhancement 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Adds ZIP download and secure extraction for Windows CLI archives.
• Applies stable CDN fallback consistently to ZIP and tarball OpenShift downloads.
• Selects platform-correct archive formats in the Content Gateway strategy.
Diagram

graph TD
  OS["Runtime platform"] --> CGW["CGW strategy"] --> DL["Archive download"] --> EX["Secure extraction"] --> BIN["Binary lookup"]
  OPEN["OpenShift strategy"] --> DL
  OPEN --> CDN["Stable CDN fallback"] --> DL
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Shared archive dispatcher
  • ➕ Centralizes format detection and extraction for every strategy.
  • ➕ Reduces duplicate ZIP and tarball branching as formats expand.
  • ➖ Broadens this targeted fix into a cross-strategy refactor.
  • ➖ Requires defining behavior for legacy gzip and direct binary links.

Recommendation: Keep the PR's localized format dispatch and shared ZIP extraction helper. It fixes both affected strategies without destabilizing legacy download paths; a generic archive dispatcher is worthwhile only if more strategies or archive formats need support.

Files changed (6) +287 / -16

Enhancement (1) +76 / -0
testSupport.goAdd secure ZIP download and extraction support +76/-0

Add secure ZIP download and extraction support

• Adds temporary-file-backed ZIP downloads and recursive extraction with executable output permissions. ZIP entries containing absolute or parent-traversal paths are rejected.

pkg/support/testSupport.go

Bug fix (2) +70 / -16
cgw.goSelect and extract platform-specific Content Gateway archives +16/-3

Select and extract platform-specific Content Gateway archives

• Builds '.zip' archive names on Windows and '.tar.gz' names elsewhere. Direct and CDN fallback downloads now use matching extraction logic for both formats.

pkg/strategy/cgw/cgw.go

openshift.goRoute ZIP downloads through stable CDN fallback +54/-13

Route ZIP downloads through stable CDN fallback

• Dispatches tarball and ZIP links to format-specific extractors behind a shared fallback flow. Production failures retry the last stable release through the CDN using the original archive format.

pkg/strategy/openshift/openshift.go

Tests (3) +141 / -0
openshift_test.goCover ZIP-based Console CLI downloads end to end +37/-0

Cover ZIP-based Console CLI downloads end to end

• Adds a Content Gateway ZIP scenario that selects the runtime-specific link, downloads the archive, and verifies the extracted binary.

pkg/strategy/openshift/openshift_test.go

testutil.goAdd ZIP archive fixtures for strategy tests +20/-0

Add ZIP archive fixtures for strategy tests

• Introduces a helper that builds in-memory ZIP archives from named test files.

pkg/strategy/testutil/testutil.go

testSupport_test.goVerify ZIP extraction and traversal rejection +84/-0

Verify ZIP extraction and traversal rejection

• Tests binary and nested-file extraction, executable permissions, and rejection of malicious parent-directory entries.

pkg/support/testSupport_test.go

@qodo-for-securesign

qodo-for-securesign Bot commented Aug 25, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. CGW tests fail on Windows 🐞 Bug ☼ Reliability
Description
The new runtime-dependent extension makes download request and unzip .zip files on Windows,
while the existing successful CGW tests still serve only .tar.gz URLs and payloads. Those tests
therefore fail on the platform this change is intended to support, preventing a green Windows test
run.
Code

pkg/strategy/cgw/cgw.go[R39-42]

+	ext := "tar.gz"
+	if runtime.GOOS == "windows" {
+		ext = "zip"
+	}
Relevance

●●● Strong

Windows-specific archive tests must match the new .zip request; accepted reliability fixes in PR #76
support platform coverage.

PR-#76

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed downloader selects .zip on Windows, but both CGW success tests hardcode .tar.gz
archive names and TAR.GZ payloads, so their server path cannot match the Windows request.

pkg/strategy/cgw/cgw.go[39-44]
pkg/strategy/cgw/cgw_test.go[44-52]
pkg/strategy/cgw/cgw_test.go[63-73]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The CGW downloader now requests ZIP archives on Windows, but its success-path tests still construct and serve TAR.GZ archives unconditionally. On Windows, the expected request URL does not match and the tests fail before validating the new behavior.

## Issue Context
`download` selects the archive extension and extractor from `runtime.GOOS`. Update the CGW tests to mirror that selection, including ZIP payload creation and Windows-compatible binary names.

## Fix Focus Areas
- pkg/strategy/cgw/cgw.go[39-43]
- pkg/strategy/cgw/cgw_test.go[44-80]
- pkg/strategy/testutil/testutil.go[73-90]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. ZIP test omits executable suffix 🐞 Bug ☼ Reliability
Description
TestStrategyContentGatewayZip always stores the binary as testcli, but on Windows FindBinary
searches only .exe candidate names. The newly added ZIP test consequently fails on Windows after
extraction instead of exercising the intended successful Windows path.
Code

pkg/strategy/openshift/openshift_test.go[R102-104]

+	binaryContent := []byte("#!/bin/sh\necho testcli\n")
+	zipArchive := testutil.BuildZip(t, map[string][]byte{"testcli": binaryContent})
+	expectedPath := "/RHTAS/1.4.1/testcli_" + runtime.GOOS + "_" + runtime.GOARCH + ".zip"
Relevance

●●● Strong

The Windows test archive must include .exe for FindBinary; this is a deterministic test-fixture
correction aligned with accepted PR #76 fixes.

PR-#76

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The test archive contains only testcli, while FindBinary rewrites every Windows candidate to end
in .exe; therefore none of its candidates can match that entry on Windows.

pkg/strategy/openshift/openshift_test.go[101-104]
pkg/support/cgw.go[23-43]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new OpenShift ZIP test creates an archive containing `testcli` on every platform. On Windows, binary discovery appends `.exe` to every candidate, so the test cannot find the extracted file and fails.

## Issue Context
Choose the archived binary name according to `runtime.GOOS` (for example, append `.exe` on Windows), while retaining the current name elsewhere. This allows the test to validate the ZIP path on the target platform.

## Fix Focus Areas
- pkg/strategy/openshift/openshift_test.go[101-135]
- pkg/support/cgw.go[23-54]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can start a comment with 'qodo' or '@qodo' to chat about any finding

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@kdacosta0 kdacosta0 changed the title Fix missing download fallback for Windows .zip binaries Fix Windows CLI download: missing CDN fallback + missing .exe extension Aug 25, 2026
@osmman

osmman commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

@kdacosta0 maybe it will require rebase or other fix to enable e2e CI

@kdacosta0

kdacosta0 commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

@osmman #99 should fix ci, after it lands will rebase this

kdacosta0 and others added 2 commits August 26, 2026 10:32
The CDN fallback logic in the openshift strategy only triggered for
.tar.gz links, so Windows binaries (distributed as .zip) fell through
to a code path with no retry/fallback and no zip extraction support,
causing hard failures when the primary content-gateway download
returned a 400. Add zip extraction support and wire the same
stable-version CDN fallback used for .tar.gz into the .zip path, and
fix the same hardcoded .tar.gz assumption in the cgw strategy.

Co-authored-by: Cursor <cursoragent@cursor.com>
FindBinary always symlinked the extracted binary to a bare cliName
(no extension) on Windows, because it compared the .exe-suffixed
candidate names against the never-suffixed cliName, which are never
equal. This made the symlink branch (and its extension-less link)
unconditional on Windows for every content-gateway archive tool
(rekor-cli, gitsign, ec, createtree, updatetree, ...), causing
"executable file not found in %PATH%" once the binary was actually
invoked via a full path. Compare against a Windows-aware linkName
instead so the returned/symlinked path keeps its .exe suffix.

Co-authored-by: Cursor <cursoragent@cursor.com>
@kdacosta0
kdacosta0 force-pushed the fix/windows-download-fallback branch from 10e1b1d to 6188b94 Compare August 26, 2026 08:32
@kdacosta0
kdacosta0 requested review from osmman and sampras343 and removed request for sampras343 August 26, 2026 08:35

@sampras343 sampras343 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm.

@kdacosta0
kdacosta0 merged commit 9a08354 into main Aug 26, 2026
6 checks passed
@kdacosta0
kdacosta0 deleted the fix/windows-download-fallback branch August 26, 2026 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants