Skip to content

fix(archive): use api.github.com zipball endpoint and fix App auth#532

Open
fasher wants to merge 1 commit into
zapier:mainfrom
fasher:fix/525-github-archive-zipball-private-repos
Open

fix(archive): use api.github.com zipball endpoint and fix App auth#532
fasher wants to merge 1 commit into
zapier:mainfrom
fasher:fix/525-github-archive-zipball-private-repos

Conversation

@fasher

@fasher fasher commented May 27, 2026

Copy link
Copy Markdown

Summary

Fixes #525.

  • Switch the GitHub archive URL from the public web endpoint (github.com/{o}/{r}/archive/{sha}.zip) to the REST API zipball endpoint (api.github.com/repos/{o}/{r}/zipball/{sha}). The web URL does not honor Authorization: Bearer for fine-grained PATs or GitHub App installation tokens on private repos and returns 404; the API endpoint accepts all token types and 302s to a signed codeload URL. Go's http.Client strips the Authorization header on the cross-host redirect, so the bearer token is not leaked.
  • Fix GitHub App auth for archive downloads. GetAuthHeaders previously emitted Authorization: Bearer (empty token) in App mode because cfg.VcsToken is unset. The client now holds an installationTokenSource (satisfied by *ghinstallation.Transport) and fetches a fresh installation token per call. The vcs.Client interface signature changes to GetAuthHeaders(ctx) (map, error); GitLab + mocks updated.
  • Fix the enterprise-vs-cloud branch in DownloadArchive. The original PR draft keyed off VcsBaseUrl != "", but pkg/config/config.go defaults VcsBaseUrl to https://github.com when unset — so cloud configs were taking the enterprise branch and producing a bogus https://github.com/repos/.../zipball/... URL. Detection now requires both VcsBaseUrl and VcsUploadUrl, matching createHttpClient. (Caught by Codex review and verified with a regression test.)
  • Update extractSHAFromArchiveURL to recognize /zipball/{sha} and /tarball/{sha} (no extension) alongside the legacy /archive/{sha}.zip and GitLab ?sha= formats.

Test plan

  • go build ./...
  • go vet ./...
  • go test ./... — full suite passes
  • New unit tests:
    • TestClient_DownloadArchive_HappyPath / …_StaleMergeCommitThenReady / …_GHEnterprise updated for new URL format
    • TestClient_DownloadArchive_DefaultedVcsBaseUrl — regression test for the defaulted-VcsBaseUrl cloud case
    • TestClient_GetAuthHeaders_NoCredentials — no PAT / no App transport → error rather than empty Bearer
    • TestClient_GetAuthHeaders_GitHubApp / …_TokenFetchError — App-auth happy path and Token() failure surface correctly
    • TestDownloader_FollowsRedirect — httptest 302 → 200 with a real zip, locks in that the downloader follows redirects (the zipball flow depends on it)
    • TestExtractSHAFromArchiveURL extended for /zipball/, /tarball/, GHE API, and empty-SHA error cases
  • Smoke test against a private github.com repo with a fine-grained PAT
  • Smoke test against a private github.com repo with a GitHub App installation
  • Smoke test against a GHE instance (no local environment to validate)

Notes

  • The vcs.Client.GetAuthHeaders interface signature changed (() (map)(ctx) (map, error)). All in-tree implementations and the generated mock are updated.
  • pkg/archive/README.md updated to reflect the new signature and document the supported token sources (classic PAT, fine-grained PAT, OAuth user token, App installation token).

@fasher fasher force-pushed the fix/525-github-archive-zipball-private-repos branch 2 times, most recently from a386fd4 to 382265c Compare May 27, 2026 12:43
@fasher fasher marked this pull request as ready for review May 27, 2026 12:44
@Greyeye Greyeye requested a review from Copilot May 27, 2026 23:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes archive downloads for private GitHub.com repositories by switching from the public web /archive/{sha}.zip URL to the authenticated REST API zipball endpoint, and by correcting GitHub App archive authentication so a valid installation token is used.

Changes:

  • Switch GitHub archive URL generation to .../repos/{owner}/{repo}/zipball/{sha} (cloud + GHE) and fix cloud-vs-enterprise detection.
  • Update vcs.Client.GetAuthHeaders to accept context.Context and return (headers, error), and implement GitHub App installation-token fetching for archive downloads.
  • Extend SHA extraction to support /zipball/{sha} and /tarball/{sha} formats and add/adjust unit tests (including redirect-follow behavior for zipball).

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/vcs/types.go Update GetAuthHeaders interface to be context-aware and error-returning.
pkg/vcs/gitlab_client/client.go Adapt GitLab implementation to new GetAuthHeaders(ctx) (map, error) signature.
pkg/vcs/gitlab_client/client_test.go Update tests for the new GetAuthHeaders signature.
pkg/vcs/github_client/client.go Add GitHub App installation token source + context-aware GetAuthHeaders with error handling.
pkg/vcs/github_client/client_test.go Add coverage for GitHub App token fetching and “no credentials” errors; update archive URL expectations.
pkg/vcs/github_client/archive.go Switch archive URL generation to REST zipball endpoint; fix enterprise-vs-cloud branching.
pkg/archive/README.md Update documentation for new URL format and new GetAuthHeaders signature/token sources.
pkg/archive/manager.go Call new GetAuthHeaders(ctx) and propagate errors; extend SHA extraction for zipball/tarball.
pkg/archive/manager_sha_test.go Extend SHA extraction tests for zipball/tarball + empty-SHA cases.
pkg/archive/download_test.go Add redirect-follow test using an in-memory zip payload.
mocks/vcs/mocks/mock_MockClient.go Regenerate/update mock for new GetAuthHeaders(ctx) (map, error) signature.
Files not reviewed (1)
  • mocks/vcs/mocks/mock_MockClient.go: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/archive/manager.go
Comment thread pkg/archive/README.md Outdated
The public web archive URL (github.com/{o}/{r}/archive/{sha}.zip) does
not honor `Authorization: Bearer` for fine-grained PATs or GitHub App
installation tokens on private repos and 404s. The REST API zipball
endpoint accepts all token types and 302s to a signed codeload URL.

Also fixes GitHub App auth for archive downloads: `GetAuthHeaders`
previously returned `Bearer ` with an empty token in App mode because
`cfg.VcsToken` is unset. The client now holds an installation token
source (satisfied by `ghinstallation.Transport`) and fetches a fresh
token on each call.

GHE detection switched to require both VcsBaseUrl and VcsUploadUrl,
mirroring createHttpClient — VcsBaseUrl alone is unreliable because
config defaults it to https://github.com when unset.

Fixes zapier#525

Signed-off-by: Asher Frenkel <asher.frenkel@gmail.com>
@fasher fasher force-pushed the fix/525-github-archive-zipball-private-repos branch from 382265c to 70799f4 Compare May 28, 2026 08:01
@rouke-broersma

rouke-broersma commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

@Greyeye could you review? Kubechecks has been unusable for months for me.

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.

Archive download fails with HTTP 404 on github.com private repos: hardcoded web URL doesn't honor Bearer auth

3 participants