github

package
v0.0.0-...-0549e8b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package github fetches workflow files to audit, from a repository, from a local checkout, or from the bundled fixtures.

Index

Constants

View Source
const WorkflowsDir = ".github/workflows"

WorkflowsDir is where GitHub Actions looks for workflow definitions.

Variables

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound marks a repository or path that does not exist, or that the token cannot see. The two are indistinguishable over the API by design.

Functions

func IsWorkflowFile

func IsWorkflowFile(path string) bool

IsWorkflowFile reports whether a path names a workflow definition.

func ParseRepo

func ParseRepo(ref string) (owner, name string, err error)

ParseRepo splits an "owner/name" reference, tolerating a github.com URL.

Types

type Client

type Client struct {

	// Rate carries the limit state observed on the last call.
	Rate RateState
	// contains filtered or unexported fields
}

Client wraps the GitHub REST API for the handful of calls this tool makes.

func NewClient

func NewClient(opts ClientOptions) (*Client, error)

NewClient builds a client, falling back to GITHUB_TOKEN then GH_TOKEN.

Both names are checked because GITHUB_TOKEN is what Actions injects and GH_TOKEN is what the gh CLI exports; a user who has authenticated with gh should not have to learn a third variable.

func (*Client) Authenticated

func (c *Client) Authenticated() bool

Authenticated reports whether a token was supplied.

type ClientOptions

type ClientOptions struct {
	// Token authenticates the client. Empty means unauthenticated, which is
	// allowed but rate limited to 60 requests an hour.
	Token string
	// BaseURL points at a GitHub Enterprise instance or a test server.
	BaseURL string
	// HTTPClient overrides the transport, used by tests.
	HTTPClient *http.Client
}

ClientOptions configures a client.

type FixtureSource

type FixtureSource struct {
	// contains filtered or unexported fields
}

FixtureSource serves example workflows from a filesystem, normally the one embedded in the binary at build time.

It exists so the tool can be evaluated end to end with no token, no network, and no repository — which is how most people will first run it, and how the test suite runs it every time. Taking an fs.FS rather than embedding here keeps a single copy of the fixtures at the repository root: `go:embed` cannot reach outside its own package directory, and a second copy under internal/github would drift from the first the day someone edited one.

func NewFixtureSource

func NewFixtureSource(fsys fs.FS) *FixtureSource

NewFixtureSource builds a source over a filesystem of workflow files.

func (*FixtureSource) Name

func (s *FixtureSource) Name() string

Name describes the source.

func (*FixtureSource) Workflows

func (s *FixtureSource) Workflows(_ context.Context) ([]WorkflowFile, error)

Workflows returns every workflow in the filesystem, sorted by name so two runs report findings in the same order.

type LocalSource

type LocalSource struct {
	// contains filtered or unexported fields
}

LocalSource reads workflows from a directory on disk.

This is the source that runs inside the GitHub Action: the repository is already checked out, so re-fetching the same files over the API would spend rate limit to learn nothing.

func NewLocalSource

func NewLocalSource(root string) *LocalSource

NewLocalSource builds a source over a directory. The directory may be a repository root, a `.github/workflows` directory, or a single file.

func (*LocalSource) Name

func (s *LocalSource) Name() string

Name describes the source.

func (*LocalSource) Workflows

func (s *LocalSource) Workflows(_ context.Context) ([]WorkflowFile, error)

Workflows walks the directory and returns every workflow file, sorted by path so two runs over the same tree report findings in the same order.

type RateLimitError

type RateLimitError struct {
	Reset         time.Time
	Secondary     bool
	Authenticated bool
}

RateLimitError is returned when the API refuses further calls.

It is a distinct type because the right response differs from every other failure: waiting works, and the message should say how long and — for an unauthenticated caller stuck at 60 requests an hour — that a token raises the ceiling by more than eighty times.

func (*RateLimitError) Error

func (e *RateLimitError) Error() string

Error describes the limit and what to do about it.

func (*RateLimitError) RetryAfter

func (e *RateLimitError) RetryAfter() time.Duration

RetryAfter is how long a caller should wait before trying again.

func (*RateLimitError) Retryable

func (e *RateLimitError) Retryable() bool

Retryable tells utils.Do that waiting is worthwhile.

type RateState

type RateState struct {
	Limit     int       `json:"limit"`
	Remaining int       `json:"remaining"`
	Reset     time.Time `json:"reset"`
}

RateState is what the API last told us about the rate limit.

func (RateState) Exhausted

func (r RateState) Exhausted() bool

Exhausted reports whether the budget is spent.

func (RateState) Known

func (r RateState) Known() bool

Known returns whether any rate information has been observed yet.

func (RateState) Summary

func (r RateState) Summary() string

Summary renders the state for a report footer.

type RepoSource

type RepoSource struct {
	// contains filtered or unexported fields
}

RepoSource fetches a repository's workflows over the API.

func NewRepoSource

func NewRepoSource(client *Client, owner, repo, ref string) *RepoSource

NewRepoSource builds a source for owner/repo. An empty ref means the repository's default branch.

func (*RepoSource) Name

func (s *RepoSource) Name() string

Name describes the source.

func (*RepoSource) Workflows

func (s *RepoSource) Workflows(ctx context.Context) ([]WorkflowFile, error)

Workflows lists and downloads every workflow definition in the repository.

The listing and each download are retried independently: a secondary rate limit part-way through would otherwise throw away the files already fetched and spend the same budget again on the next run.

type Source

type Source interface {
	// Name describes the source for report headers.
	Name() string
	// Workflows returns every workflow file to audit.
	Workflows(ctx context.Context) ([]WorkflowFile, error)
}

Source produces the workflows to audit.

The interface is what lets `audit --offline`, `audit ./path`, and `audit owner/repo` run through exactly the same pipeline. That matters beyond tidiness: the offline path is the one used in tests, in CI, and by anyone evaluating the tool without a token, so it must not be a second implementation that drifts from the real one.

type WorkflowFile

type WorkflowFile struct {
	// Path is how the file is reported: `.github/workflows/ci.yml` for a
	// repository, the real path for a local directory.
	Path string
	// Repo is "owner/name" when the file came from a repository, empty for a
	// local source.
	Repo    string
	Content []byte
	// URL links to the file on github.com when one is known.
	URL string
}

WorkflowFile is one workflow definition and its contents.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL