feat: add GitHub App installation token authentication for push/sync#177
Merged
Conversation
Add a --github-app-auth flag so push/sync can authenticate with a GitHub App installation token (ghs_*). App tokens have no user context, so the GET /user call is skipped and repositories are created under the owner from the destination repo name. Refs github/actions-persistence#1182
Add unit tests for getOrCreateGitHubRepo (previously untested) covering GitHub App auth and PAT regression paths: existing repo, create-under-user vs org, GHAE internal visibility (from both user and repo responses), create-failure wrapping, repo-get errors, org-already-exists fallback, and nil-login handling.
There was a problem hiding this comment.
Pull request overview
Adds first-class support for authenticating push/sync using GitHub App installation tokens (ghs_*) by avoiding /user API calls and adjusting repo-creation behavior accordingly, while keeping the PAT path intact.
Changes:
- Introduces
--github-app-authto route repo creation through org-owner derived from the destinationowner/repo, and skipsGET /userunder App auth. - Refactors repo-creation logic to support AE detection without relying on the user response, and updates git basic-auth username to
x-access-token. - Expands test coverage with shared test fakes/utilities, plus an integration test path that fails if
/useris hit withghs_*tokens.
Show a summary per file
| File | Description |
|---|---|
| test/github.go | Test server now returns 403 on /api/v3/user for ghs_* tokens to enforce the “no user API under App auth” contract. |
| src/testutils_test.go | Adds shared mocks/fakes/helpers for GitHub API and git push tests to reduce duplication. |
| src/push.go | Adds --github-app-auth, refactors repo creation to support App tokens, and switches git basic-auth username to x-access-token. |
| src/push_test.go | Adds/updates unit tests covering App-auth and PAT behaviors and moves shared test helpers out. |
| script/test-build | Adds an integration test case exercising push --github-app-auth with a ghs_* token. |
| README.md | Documents --github-app-auth and adds a GitHub App authentication section. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 6/6 changed files
- Comments generated: 2
- Error early when --github-app-auth and --actions-admin-user are both set, since App installation tokens cannot impersonate (no user/site-admin context). - Correct the README App permission name to 'Metadata: Read-only'.
danwkennedy
approved these changes
Jun 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add GitHub App installation token authentication for
push/syncMotivation
It is currently not possible to authenticate
actions-syncwith a GitHub App installation token (ghs_*); thepush/syncflow callsGET /user, which App installation tokens cannot use (they have no user context and receive403 Resource not accessible by integration). Users who want to avoid long-lived personal access tokens are therefore blocked. This revives the GitHub App authentication portion of #158.What this does
--github-app-authflag topushandsync. When set, theGET /usercall is skipped and the destination repository is created under the owner taken from the destination repo name viaPOST /orgs/{owner}/repos.x-access-tokenas the git basic-auth username for the push, matching GitHub's documented convention for App installation tokens.script/test-buildthat pushes with aghs_*token; the test server now returns403on/api/v3/userforghs_*tokens so the test fails if/useris ever hit.testutils_test.gohelper.Scope
This intentionally covers only the GitHub App authentication part of #158. The description-syncing and
keep-descriptionchanges from that PR are out of scope here.Constraints / behavior notes
POST /user/reposrequires user context that App tokens lack), so a user-account installation will not work. This was verified empirically against a real GHES instance.--actions-admin-user) rely on user/site-admin context and are not used under App auth.--github-app-auth(defaultfalse); the existing PAT code path is unchanged.Required App permissions
Administration: Read & write(create repositories),Contents: Read & write,Metadata: Read-only, andWorkflows: Read & writeif synced repositories contain workflow files.Validation
Validated end-to-end against a real GitHub Enterprise Server 3.21.1 instance:
ghs_*installation token returns403on/api/v3/user, confirming the need to skip that call.push --github-app-authcreated the repository under the target org and pushed all refs; destination branch SHAs matched the source exactly.POST /user/reposreturns403), confirming the org-owner requirement.go build,go vet,go test, andgofmtare clean.