GitHub¶
Package: pkg/vcs/github
Provides the GitHub Enterprise API client (GHClient) and a release.Provider implementation backed by the GitHub Releases API.
Constructor¶
cfg should be a props.Config.Sub("github") subtree. Reads url.api, url.upload, and authentication via vcs.ResolveToken.
Token is optional — public repositories work without one. Private repositories will receive a 401 from the API if no token is set.
Configuration keys (under the github subtree):
| Key | Default | Description |
|---|---|---|
url.api |
"" |
GitHub Enterprise API base URL. Empty string uses https://api.github.com. |
url.upload |
"" |
GitHub Enterprise upload URL. When url.api is set (or host-derived) and this is left empty, the upload URL is derived from the API host as https://<api-host>/api/uploads/. |
auth.env |
— | Name of the environment variable holding the token |
auth.value |
— | Literal token value (use auth.env in preference) |
If neither auth.env nor auth.value is present, NewGitHubClient falls back to the GITHUB_TOKEN environment variable.
Token Helper¶
Returns the resolved token or an error if none is found. Use this where a token is strictly required (e.g. authenticated git operations). For release/update operations on public repos, vcs.ResolveToken directly is sufficient.
GitHubClient Interface¶
All operations are available through the GitHubClient interface. Use the interface type in function signatures for testability:
[!NOTE] See pkg.go.dev/gitlab.com/phpboyscout/go-tool-base/pkg/vcs for the full API definition.
Sentinel errors:
| Error | Condition |
|---|---|
ErrNoPullRequestFound |
GetPullRequestByBranch finds no matching PR |
ErrRepoExists |
CreateRepo target already exists |
Usage Examples¶
Pull Request Workflow¶
client, err := github.NewGitHubClient(props.Config.Sub("github"))
if err != nil {
return err
}
pr, err := client.CreatePullRequest(ctx, "my-org", "my-repo", &gogithub.NewPullRequest{
Title: gogithub.Ptr("feat: add new command"),
Head: gogithub.Ptr("feature/my-branch"),
Base: gogithub.Ptr("main"),
Body: gogithub.Ptr("Automated PR from my-tool"),
})
if err != nil {
return err
}
_ = client.AddLabelsToPullRequest(ctx, "my-org", "my-repo", pr.GetNumber(), []string{"automated"})
File Contents¶
Asset Download (low-level)¶
assetID, err := client.GetReleaseAssetID(ctx, "my-org", "my-repo", "v1.2.0", "mytool_linux_amd64.tar.gz")
if err != nil {
return err
}
err = client.DownloadAssetTo(ctx, props.FS, "my-org", "my-repo", assetID, "/tmp/mytool.tar.gz")
For release workflows (auto-update, version checking), prefer the higher-level release.Provider — see below.
Release Provider¶
Wraps a GitHubClient and returns a release.Provider. This is the preferred way to work with releases — it keeps consuming code (e.g. the auto-update command) decoupled from GitHub specifics.
client, err := github.NewGitHubClient(props.Config.Sub("github"))
if err != nil {
return err
}
provider := github.NewReleaseProvider(client)
latest, err := provider.GetLatestRelease(ctx, "my-org", "my-repo")
fmt.Println(latest.GetTagName())
rc, _, err := provider.DownloadReleaseAsset(ctx, "my-org", "my-repo", latest.GetAssets()[0])
See Release Provider for the full interface reference.
Testing¶
The GitHubClient mock is generated by mockery:
import mock_github "gitlab.com/phpboyscout/go-tool-base/mocks/pkg/vcs/github"
mockClient := mock_github.NewMockGitHubClient(t)
mockClient.EXPECT().
ListReleases(mock.Anything, "my-org", "my-repo").
Return([]string{"v2.0.0", "v1.0.0"}, nil)
For HTTP-level tests, use net/http/httptest to stand up a mock server and pass its URL as url.api in the test config. See pkg/vcs/github/client_coverage_test.go for the established pattern.
Related Documentation¶
- GitLab — GitLab release provider (same
release.Providerinterface) - Release Provider — interface reference for
Provider,Release,ReleaseAsset - VCS index —
ResolveTokenand package overview