Skip to content

Persist HTTP basic auth credentials for git operations after clone - #7144

Open
pujitha24 wants to merge 2 commits into
pipe-cd:masterfrom
pujitha24:auto/issue-6453
Open

Persist HTTP basic auth credentials for git operations after clone#7144
pujitha24 wants to merge 2 commits into
pipe-cd:masterfrom
pujitha24:auto/issue-6453

Conversation

@pujitha24

Copy link
Copy Markdown

What this PR does:

Persists the HTTP Basic-Auth header (built from the piped git username/password config) into the checked-out repository's git config, so that git operations run after the initial clone (pull, fetch, push, etc.) keep using the configured credentials.

Why we need it:

When a piped git repository is configured with username/password (a PAT) for HTTPS auth, pkg/git/client.go's Client.Clone() only passed the Authorization header as a one-off -c http.extraHeader=... flag to the git clone --mirror / git fetch commands used to populate its internal cache. That flag is never persisted, and the Repo object handed back to callers (a worktree checked out from the cache, with origin rewritten to the real HTTPS remote URL) carries no credentials at all. Components such as the event watcher (pkg/app/piped/eventwatcher) call repo.Pull() repeatedly on that same object over time; Pull/Push/MergeRemoteBranch/CheckoutPullRequest in pkg/git/repo.go issue git commands straight at the remote with no auth, so every one of them fails with fatal: could not read Username for 'https://github.com': No such device or address — reproducing exactly the error reported in the issue.

Which issue(s) this PR fixes:

Fixes #

Does this PR introduce a user-facing change?:

  • How are users affected by this change: Piped deployments configured with HTTPS username/password git auth (a common CI/CD PAT pattern) now keep working after the initial clone — previously, background git operations like the event watcher's periodic pull and re-clone would fail indefinitely with a credential error. Deployments using SSH auth are unaffected.
  • Is this breaking change: No
  • How to migrate (if breaking change): N/A

AI assistance: this change was drafted with Claude Code.

Fixes #6453

@pujitha24
pujitha24 requested a review from a team as a code owner August 10, 2026 00:11
@pujitha24

Copy link
Copy Markdown
Author

Just checking in on this — it's still green and rebased, happy to make any changes if something would help move review along.

Copilot AI lite review requested due to automatic review settings August 22, 2026 10:23
@netlify

netlify Bot commented Aug 22, 2026

Copy link
Copy Markdown

Deploy Preview for pipecd-site canceled.

Name Link
🔨 Latest commit dab9546
🔍 Latest deploy log https://app.netlify.com/projects/pipecd-site/deploys/6a8f60afc928610008cfddd4

@codecov

codecov Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 46.21%. Comparing base (9e89f95) to head (51a87c5).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##           master    #7144       +/-   ##
===========================================
+ Coverage   29.67%   46.21%   +16.53%     
===========================================
  Files         601       76      -525     
  Lines       64392     7543    -56849     
===========================================
- Hits        19109     3486    -15623     
+ Misses      43789     3780    -40009     
+ Partials     1494      277     -1217     
Flag Coverage Δ
. ?
.-pkg-app-pipedv1-plugin-analysis 32.43% <ø> (ø)
.-pkg-app-pipedv1-plugin-ecs ?
.-pkg-app-pipedv1-plugin-kubernetes ?
.-pkg-app-pipedv1-plugin-kubernetes_multicluster 59.62% <ø> (ø)
.-pkg-app-pipedv1-plugin-scriptrun ?
.-pkg-app-pipedv1-plugin-terraform 38.46% <ø> (ø)
.-pkg-app-pipedv1-plugin-wait ?
.-pkg-app-pipedv1-plugin-waitapproval ?
.-pkg-plugin-sdk ?
.-tool-actions-gh-release 19.23% <ø> (ø)
.-tool-actions-plan-preview ?
.-tool-codegen-protoc-gen-auth ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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 updates PipeCD’s internal Git client/worktree implementation to persist HTTP Basic Auth credentials (derived from configured username/password) into the checked-out repository config so that subsequent Git operations (pull/fetch/push) continue to authenticate after the initial clone.

Changes:

  • Add repo.setHTTPAuthHeader to persist http.extraHeader into the repo’s git config and carry it across CopyToModify.
  • Refactor Basic Auth header construction into a helper (basicAuthHeader) and persist it during Client.Clone.
  • Add unit tests to verify http.extraHeader persistence and propagation.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
pkg/git/repo.go Adds persistent HTTP auth header support and propagates it across CopyToModify.
pkg/git/repo_test.go Adds tests for setHTTPAuthHeader and for propagation in CopyToModify.
pkg/git/client.go Introduces basicAuthHeader helper and persists HTTP auth config after worktree clone.
pkg/git/client_test.go Adds coverage to ensure Clone persists http.extraHeader into the checked-out repo.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/git/repo.go
Comment on lines +482 to +488
func (r *repo) setHTTPAuthHeader(ctx context.Context, header string) error {
if out, err := r.runGitCommand(ctx, "config", "http.extraHeader", header); err != nil {
return formatCommandError(err, out)
}
r.httpAuthHeader = header
return nil
}

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.

@pujitha24 please check and update your change 👀

@vanshika2720

Copy link
Copy Markdown
Contributor

@pujitha24 The required Go checks are currently failing due to Test_reporter_flush, which appears unrelated to this PR and is already fixed on current master by #7221. Could you please rebase onto the latest master and rerun the checks ?

Motivation:
When a piped git repository is configured with HTTPS username/password
(PAT) authentication, pkg/git/client.go's Client.Clone() only passed
the Authorization header as a one-off `-c http.extraHeader=...` flag
to the `git clone --mirror` / `git fetch` commands used to populate
its internal repo cache. That flag is never persisted, so the Repo
object handed back to callers (a worktree checked out from the cache,
with origin rewritten to the real HTTPS remote URL) carries no
credentials at all. Components such as the event watcher call
repo.Pull() repeatedly on that same object over time, and Pull/Push/
MergeRemoteBranch/CheckoutPullRequest in pkg/git/repo.go issue git
commands straight at the remote with no auth args, so every one of
them fails with "fatal: could not read Username for
'https://github.com': No such device or address" -- reproducing
exactly the error from the report.

Approach:
After Client.Clone() checks out the destination repo, persist the
basic-auth header into that repo's git config via a new
repo.setHTTPAuthHeader method (`git config http.extraHeader <value>`),
so every later git command run in that directory picks up the
credentials automatically instead of relying on a one-off CLI flag.
repo.CopyToModify (used to make a scratch copy for committing and
pushing changes) does a plain local `git clone`, which doesn't carry
over custom config keys, so the header is propagated there too before
CopyToModify's initial fetch.

Validation:
Ran `go build ./...` (whole main module, passes) and
`go test ./pkg/git/...` (passes, including three new/extended tests:
TestClonePersistsHTTPAuthHeader, Test_setHTTPAuthHeader, and an
extended TestCopyToModify). Confirmed TestClonePersistsHTTPAuthHeader
fails against the pre-fix code: with the new persistence call
temporarily removed from Clone(), the test fails because
`git config --get http.extraHeader` finds nothing in the checked-out
repo; restoring the fix makes it pass again. This is a local git-config
assertion, not a live HTTPS clone against a real PAT-protected remote,
but it directly demonstrates the exact defect: credentials silently
dropped after the initial clone.

Report: pipe-cd#6453
Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot clone GitHub repository with username/PAT

4 participants