Documentation
¶
Overview ¶
Package ghtest is test support for the CI subsystem: a fake GitHub REST API that records every write the GitHub CI provider makes, plus a fixture that sets the GitHub Actions environment (GITHUB_*) so the real provider can be exercised end to end without network access.
This package is a regular (non-_test) package only so tests in other packages can import it. It must never be imported by production code.
Typical use ¶
s := ghtest.NewServer(t) env := ghtest.SetEnv(t, s, ghtest.WithPullRequest(42, "feature", "main")) ghtest.RegisterProvider(t, github.NewProvider()) // ... run code that calls ci.Detect() / ci.ResolveProvider() ... require.Len(t, s.Comments(), 1)
Import-cycle rules ¶
ghtest imports pkg/ci but deliberately does NOT import pkg/ci/providers/github, so both external and in-package tests of the github provider (package github) can use it. RegisterProvider therefore receives the provider as an argument.
Tests that live inside package ci (internal tests, "package ci") must not import ghtest: ghtest imports ci, which would form an import cycle. Reporter tests in pkg/ci that need ghtest must be written as "package ci_test".
Index ¶
- func ReadFile(t testing.TB, path string) string
- func RegisterProvider(t testing.TB, p ci.Provider)
- type CheckRun
- type Comment
- type Env
- type EnvOption
- func WithEvent(name string, payload map[string]any) EnvOption
- func WithForkPullRequest(number int, headRef, baseRef string) EnvOption
- func WithPullRequest(number int, headRef, baseRef string) EnvOption
- func WithRef(ref string) EnvOption
- func WithRepository(repository string) EnvOption
- func WithRunID(id string) EnvOption
- func WithSHA(sha string) EnvOption
- func WithServerURL(serverURL string) EnvOption
- func WithToken(token string) EnvOption
- type Option
- func WithCheckRuns(owner, repo, ref string, runs ...CheckRun) Option
- func WithFailure(method, pathPrefix string, status int, message string) Option
- func WithPullRequests(owner, repo string, prs ...PullRequest) Option
- func WithSeedComments(owner, repo string, n int, comments ...Comment) Option
- func WithSeedCommitComments(owner, repo, sha string, comments ...Comment) Option
- type PullRequest
- type RecordedRequest
- type SARIFUpload
- type Server
- func (s *Server) Comments() []Comment
- func (s *Server) CommentsFor(owner, repo string, n int) []Comment
- func (s *Server) CommitCommentsFor(owner, repo, sha string) []Comment
- func (s *Server) Requests() []RecordedRequest
- func (s *Server) SARIFUploads() []SARIFUpload
- func (s *Server) Statuses() []Status
- func (s *Server) URL() string
- type Status
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RegisterProvider ¶
RegisterProvider isolates the CI provider registry for the duration of the test and registers p in it (restoring the previous registry in t.Cleanup). Pass a freshly constructed github.NewProvider(): the provider caches its API client on first use, and the provider registered at init() may already hold a client built before SetEnv pointed GITHUB_API_URL at the fake server.
Call SetEnv first (or at least before the provider makes its first API call).
Types ¶
type Comment ¶
type Comment struct {
// Owner is the repository owner.
Owner string
// Repo is the repository name.
Repo string
// Number is the issue or pull request number the comment belongs to. Zero for a commit comment.
Number int
// SHA is the commit the comment belongs to. Empty for an issue or pull request comment.
SHA string
// ID is the comment ID. Zero on a seeded comment means "assign one".
ID int64
// Body is the comment markdown.
Body string
// HTMLURL is the comment permalink assigned by the server.
HTMLURL string
// Edited is true when this record was produced by an edit (PATCH) rather than a create.
Edited bool
}
Comment is an issue or pull request comment.
type Env ¶
type Env struct {
// Output is the $GITHUB_OUTPUT file.
Output string
// EnvFile is the $GITHUB_ENV file.
EnvFile string
// Path is the $GITHUB_PATH file.
Path string
// Summary is the $GITHUB_STEP_SUMMARY file.
Summary string
// EventPath is the $GITHUB_EVENT_PATH event payload JSON file.
EventPath string
}
Env holds the paths of the files SetEnv created for the GitHub Actions runner contract.
func SetEnv ¶
SetEnv points the process at s as a GitHub Actions run, using t.Setenv so the environment is restored when the test ends. It returns the paths of the runner files it created. Tests using SetEnv must not be parallel.
Variables set: GITHUB_ACTIONS, GITHUB_API_URL, GITHUB_TOKEN, GITHUB_REPOSITORY, GITHUB_SHA, GITHUB_REF, GITHUB_REF_NAME, GITHUB_HEAD_REF, GITHUB_BASE_REF, GITHUB_EVENT_NAME, GITHUB_EVENT_PATH, GITHUB_RUN_ID, GITHUB_RUN_NUMBER, GITHUB_SERVER_URL, GITHUB_ACTOR, GITHUB_WORKFLOW, GITHUB_JOB, GITHUB_OUTPUT, GITHUB_ENV, GITHUB_PATH and GITHUB_STEP_SUMMARY. Ambient overrides that could redirect the client (ATMOS_CI_GITHUB_API_URL, ATMOS_CI_GITHUB_TOKEN, ATMOS_PRO_GITHUB_TOKEN, GH_TOKEN) are blanked.
The provider resolves Context.SHA from git HEAD of the working directory before falling back to GITHUB_SHA. Tests that assert the SHA must run outside a git checkout (for example after t.Chdir(t.TempDir())).
type EnvOption ¶
type EnvOption func(*envConfig)
EnvOption customizes SetEnv.
func WithEvent ¶
WithEvent sets GITHUB_EVENT_NAME and the top-level keys of the event payload file. When combined with WithPullRequest the payload keys are overlaid on the generated pull_request payload, and the event name (for example "pull_request_target") replaces the default "pull_request".
func WithForkPullRequest ¶
WithForkPullRequest is WithPullRequest for a pull request whose head lives in a fork: the payload marks head.repo as a fork and gives it a full_name different from the base repository.
func WithPullRequest ¶
WithPullRequest makes the run a pull request: it writes a pull_request event payload, sets GITHUB_REF=refs/pull/N/merge, GITHUB_REF_NAME=N/merge, GITHUB_HEAD_REF and GITHUB_BASE_REF, and defaults the event name to "pull_request" unless WithEvent chose another. For pull_request_target and workflow_run, which GitHub runs against the base branch, GITHUB_REF is refs/heads/<base> and only the payload names the pull request (workflow_run writes a workflow_run payload instead of a pull_request one).
func WithRef ¶
WithRef sets GITHUB_REF (for example "refs/heads/feature"). GITHUB_REF_NAME is derived from it.
func WithRepository ¶
WithRepository sets GITHUB_REPOSITORY ("owner/repo").
func WithServerURL ¶
WithServerURL sets GITHUB_SERVER_URL.
type Option ¶
type Option func(*Server)
Option configures a Server.
func WithCheckRuns ¶
WithCheckRuns seeds the check runs returned for a commit ref.
func WithFailure ¶
WithFailure makes every request whose method matches and whose path starts with pathPrefix fail with the given HTTP status and a GitHub-style {"message": ...} body. An empty method or "*" matches any method. The first matching failure wins. Failed requests are still recorded by Requests.
func WithPullRequests ¶
func WithPullRequests(owner, repo string, prs ...PullRequest) Option
WithPullRequests seeds the pull requests returned by the pulls list/get endpoints.
func WithSeedComments ¶
WithSeedComments pre-populates the comments of issue or pull request n so that an upsert can find an existing marker. Seeded comments are not recorded as writes.
func WithSeedCommitComments ¶
WithSeedCommitComments pre-populates the comments of a commit so that an upsert can find an existing marker. Seeded comments are not recorded as writes.
type PullRequest ¶
type PullRequest struct {
Number int
Title string
HeadRef string
HeadSHA string
BaseRef string
HTMLURL string
}
PullRequest is a pull request returned by the pulls endpoints.
type RecordedRequest ¶
type RecordedRequest struct {
Method string
Path string
RawQuery string
Body string
// Status is the HTTP status code the server answered with. It is zero while the
// handler is still running: a request is listed as soon as it arrives.
Status int
}
RecordedRequest is a raw HTTP request the server saw, including unexpected ones.
type SARIFUpload ¶
type SARIFUpload struct {
Owner string
Repo string
CommitSHA string
Ref string
// SARIF is the decoded SARIF document (the "sarif" field is base64 of gzip).
SARIF string
// ID is the analysis ID the server returned.
ID string
}
SARIFUpload is a code-scanning upload received by POST /repos/{owner}/{repo}/code-scanning/sarifs.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is a fake GitHub REST API backed by httptest.Server that records every write the CI provider makes. It is test support; never use it in production code.
Unimplemented routes answer 404 with a JSON message, so unexpected calls are visible both as errors in the code under test and in Requests.
func (*Server) Comments ¶
Comments returns every comment write (create and edit) in the order received. Edits carry the submitted body and Edited=true.
func (*Server) CommentsFor ¶
CommentsFor returns the current comments of an issue or pull request, including seeded ones, with edits applied.
func (*Server) CommitCommentsFor ¶
CommitCommentsFor returns the current comments of a commit, including seeded ones, with edits applied.
func (*Server) Requests ¶
func (s *Server) Requests() []RecordedRequest
Requests returns every HTTP request received (including failed and unexpected ones), in order. Intended for debugging and for asserting "no unexpected calls".
func (*Server) SARIFUploads ¶
func (s *Server) SARIFUploads() []SARIFUpload
SARIFUploads returns every code-scanning upload received, decoded.