Skip to content

fix(ci): use HTTP basic auth for git token push - #43

Merged
mrwogu merged 1 commit into
mainfrom
fix/ci-git-auth-scheme
Sep 22, 2026
Merged

mrwogu merged 1 commit into
mainfrom
fix/ci-git-auth-scheme

Conversation

@mrwogu

@mrwogu mrwogu commented Sep 22, 2026

Copy link
Copy Markdown
Member

Summary

The v1.4.0 release run failed. Goreleaser published the release fine, then the new action major tag step could not push tag v1:

fatal: could not read Username for 'https://github.com': No such device or address

Reason: the step sends the token as AUTHORIZATION: bearer in http.extraheader. GitHub git endpoints accept HTTP basic auth only, so the push gets 401 and git falls back to a credential prompt that cannot work on a runner. Bearer works on api.github.com, which is why goreleaser uploads with the same token succeeded.

I checked this live against this repo: ls-remote with bearer fails, with AUTHORIZATION: basic $(printf 'x-access-token:%s' "$TOKEN" | base64) works.

Re-running the failed job then made it worse: goreleaser release --clean only wipes local dist, so every asset upload hit 422 already_exists. Release v1.4.0 is published and complete, but tag v1 was never moved.

Fix: send the token as x-access-token over HTTP basic, the same scheme actions/checkout uses, in the release tag step, the forge notes workflow (template plus committed copy), and the composite action. Also pin the scheme in the template security contract so it cannot slip back.

Tag v1 still points nowhere. After this merges I will push it at 155848f manually; re-running the release workflow would just hit the same 422 on assets.

Scope

  • User-visible behavior: release tag move and notes push now authenticate correctly
  • Interfaces or compatibility: none, the header scheme is an implementation detail
  • Documentation: comment in each file explains why basic and not bearer
  • Generated artifacts: .github/workflows/git-byline.yml is the committed copy of internal/ci/templates/github.yml, updated in lockstep (the go-version 1.27.1 bump from chore(ci): update dependency go to v1.27.1 #41 stays)
  • Security and privacy: no token handling change, same env var, header is computed at runtime and unset after use in the action

Related issue

N/A

Validation

CGO_ENABLED=0 GOPROXY=off go test ./internal/ci/          ok
CGO_ENABLED=0 GOPROXY=off go test ./tools/validate/       ok
CGO_ENABLED=0 GOPROXY=off go run ./tools/validate         all 10 stages passed
python3 yaml.safe_load on all 4 edited yaml files          ok
bash -n on every changed shell block                      ok
manual ls-remote bearer vs basic against this repo        bearer 401, basic ok

Checklist

  • Focused change with unrelated refactors excluded
  • Tests added or updated
  • Documentation updated when behavior changed
  • Generated artifacts regenerated and reviewed
  • PromptScript sources updated instead of generated files
  • No secrets, private data, or unsafe fixtures included
  • Security impact considered
  • Breaking changes documented
  • Release impact understood

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Warning

Review limit reached

Next included review available in 34 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: comarch/git-byline/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 1512a7b0-f24b-445d-8bf8-74dbc408febf

📥 Commits

Reviewing files that changed from the base of the PR and between e4e5b98 and 620cc6e.

📒 Files selected for processing (6)
  • .github/workflows/git-byline.yml
  • .github/workflows/release.yml
  • action.yml
  • action/action.yml
  • internal/ci/ci_test.go
  • internal/ci/templates/github.yml

Summary by CodeRabbit

  • Bug Fixes

    • Updated GitHub integrations and automated workflows to use HTTP Basic authentication for repository fetches, attribution operations, and tag pushes.
    • Improved compatibility with GitHub’s Git endpoints, helping prevent authentication failures during automated releases and attribution updates.
    • Updated generated GitHub workflow templates to apply the revised authentication behavior consistently.
  • Tests

    • Added validation to ensure generated templates use the supported authentication method and do not use bearer authorization.

Walkthrough

Changes

GitHub Git fetch, notes, push, and release tag operations now use Basic authentication with an x-access-token username. Workflow templates and actions use git_byline, clear authentication variables, and reject Bearer authentication in CI checks.

GitHub Basic authentication

Layer / File(s) Summary
Template fetch and push authentication
.github/workflows/..., internal/ci/templates/github.yml
Workflow fetch, notes lookup, and notes push operations now build Basic authorization headers and run through git_byline.
Action and workflow authentication wiring
action.yml, action/action.yml, .github/workflows/git-byline.yml
Composite actions and workflow steps pass the Basic header to Git configuration and clear authentication variables after use.
Release authentication and security contract
.github/workflows/release.yml, internal/ci/ci_test.go
Release tag pushes use Basic authorization. CI assertions require Basic authorization and reject Bearer authorization.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Merge Risk: 🟠 High · up to e4e5b

Attribution-note pushes can fail whenever notes exist, and workflow regeneration may reintroduce an outdated Go version. Fix both before merging.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (5 skipped: 5 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: replacing bearer authentication with HTTP Basic authentication for Git token pushes.
Description check ✅ Passed The description explains the authentication failure, the affected workflows and action, the fix, scope, and validation results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (5 skipped: 5 unsupported.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: comarch/git-byline/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 6b703b65-efb7-4c86-8598-5aa5015b9aa1

📥 Commits

Reviewing files that changed from the base of the PR and between 155848f and e4e5b98.

📒 Files selected for processing (6)
  • .github/workflows/git-byline.yml
  • .github/workflows/release.yml
  • action.yml
  • action/action.yml
  • internal/ci/ci_test.go
  • internal/ci/templates/github.yml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

Comment thread action.yml Outdated
Comment thread internal/ci/ci_test.go Outdated
GitHub git endpoints reject Authorization: bearer with 401. The v1.4.0
release run published all artifacts, then the new action major tag step
failed with 'could not read Username' and re-runs died on 422
already_exists. The forge notes push had the same latent scheme bug.

Send the token as x-access-token over HTTP basic, matching how
actions/checkout authenticates git traffic.
@mrwogu
mrwogu force-pushed the fix/ci-git-auth-scheme branch from e4e5b98 to 620cc6e Compare September 22, 2026 14:00
@sonarqubecloud

Copy link
Copy Markdown

@mrwogu
mrwogu merged commit 4ce59b7 into main Sep 22, 2026
19 checks passed
@mrwogu
mrwogu deleted the fix/ci-git-auth-scheme branch September 22, 2026 14:15
mrwogu added a commit that referenced this pull request Sep 24, 2026
* fix(ci): install pinned release binary in forge workflows

Both templates ran go run ./cmd/git-byline, which works only in this
repo. In any other project the reconstruct job failed on this step.

Now the workflow downloads the release pinned on the GIT_BYLINE_VERSION
line, checks the archive against checksums.txt and the binary version,
same like action.yml and install.sh, and runs that binary. Release
Please bumps the pin in both templates, and validate fails when the pin
and the manifest drift.

A workflow that differs from the template only in the pinned tag still
counts as managed, so an upgrade does not make install-hooks warn or
uninstall skip the file.

The GitLab job runs in buildpack-deps:trixie-scm now, it does not need
Go anymore. GIT_BYLINE_VERSION and GIT_BYLINE_RELEASES_URL can be set
as CI/CD variables, for example for an internal mirror. The GitHub
workflow triggers on the default branch instead of hardcoded main.

Fixes #50

* fix(ci): use HTTP basic auth in GitLab forge job

The job put GITLAB_TOKEN into http.extraHeader as PRIVATE-TOKEN. This
header is for REST calls, Git over HTTPS takes HTTP basic auth. With
credential.helper empty Git had no other way to log in, so the first
authenticated fetch or the notes push got 401.

Now the header is basic auth with user oauth2 and the token as
password, same idea like #43 for GitHub. I checked in the runner image
that Git sends it on the first request and that it decodes to
oauth2:<token>. A run against live GitLab is still to verify in the
pilot.

A missing GITLAB_TOKEN also fails with a message now, not a bare test.

Fixes #51

* fix(ci): reconstruct GitLab squash merges from merge request head

After a squash merge the MR commits, and their notes, stay only on
refs/merge-requests/<iid>/head. The job took the source from commit
parents, so a squash with fast-forward had an empty source range and a
squash with merge commit pointed at the squash commit, which has no
notes. In both cases the lines stayed untracked.

Now the job reads the <project path>!<iid> reference from the merged
commit message, fetches the MR head and uses it as the source, but only
when its diff has the same stable patch ID as the diff the target
commit brings. Without the reference it keeps the parents like before.
When the diff differs it keeps them too and prints a warning.

The default merge commit template has the reference. The default
squash template is only the title, so with the fast-forward merge
method the project has to add %{reference} there, README says it now.

I checked seven merge setups in the runner image with sh and bash.
Live GitLab is still to verify in the pilot.

Fixes #52

* test(validate): cover CI template version check in scans

checkCITemplateVersions had a provider lookup that can not fail for the
two fixed templates, so its error return was never hit. Read the two
template files directly. Also test the checkScans branch when the pin
does not match the release manifest.

* fix(ci): clean up GitLab download when the job fails

The job runs under set -eu, so a failed checksum, version check, tar, or
ci run exits before the rm and the archive stays in CI_BUILDS_DIR. An
EXIT trap removes it on every path.
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.

1 participant