Documentation
¶
Index ¶
- Constants
- Variables
- func BuildDepsCommitMessage(bumps []DepBump, rootCause string) string
- func CompareVersions(v1, v2 string) int
- func EnsureGHSession(runner Runner) error
- func FormatCommitMessage(message string) string
- func ValidateCommitMessage(message string) error
- func ValidateShellSafeMessage(message string) string
- func WorkTreeDirtyBeyond(git GitClient, allowed ...string) (bool, error)
- type DepBump
- type Git
- func (g *Git) Add() error
- func (g *Git) CheckRemoteAccess() error
- func (g *Git) Clone(repoURL string) (alreadyPresent bool, err error)
- func (g *Git) Commit(message string) (bool, error)
- func (g *Git) CommitPaths(message string, paths ...string) (bool, error)
- func (g *Git) CreateTag(tag string) (bool, error)
- func (g *Git) DiffShortStat() (string, error)
- func (g *Git) Fetch() error
- func (g *Git) GenerateNextTag() (string, error)
- func (g *Git) GetConfigUserEmail() (string, error)
- func (g *Git) GetConfigUserName() (string, error)
- func (g *Git) GetLatestTag() (string, error)
- func (g *Git) GitIgnoreAdd(entry string) error
- func (g *Git) HasChanges() (bool, error)
- func (g *Git) HasPendingChanges() (bool, error)
- func (g *Git) HasUpstream() (bool, error)
- func (g *Git) IncrementTag(tag string) (string, error)
- func (g *Git) InitRepo(dir string) error
- func (g *Git) IsAheadOfRemote() (bool, error)
- func (g *Git) ObjectsToPublish(_ PublishContext) (PublishAction, string)
- func (g *Git) Pull() error
- func (g *Git) Push(message, tag string) (PushResult, error)
- func (g *Git) PushWithTags(tag string) (bool, error)
- func (g *Git) PushWithoutTags() (bool, error)
- func (g *Git) SetAuthRetrier(a GitHubAuthenticator)
- func (g *Git) SetLog(fn func(...any))
- func (g *Git) SetRootDir(path string)
- func (g *Git) SetShouldWrite(f func() bool)
- func (g *Git) SetUserConfig(name, email string) error
- func (g *Git) StatusPorcelain() (string, error)
- func (g *Git) TagExists(tag string) (bool, error)
- type GitClient
- type GitHub
- func (gh *GitHub) CreateRelease(tag string, assets []string, targetRepo string) (string, error)
- func (gh *GitHub) CreateRepo(owner, name, description, visibility string) error
- func (gh *GitHub) DeleteRepo(owner, name string) error
- func (gh *GitHub) DeleteSecret(repo, name string) error
- func (gh *GitHub) GetCurrentUser() (string, error)
- func (gh *GitHub) GetHelpfulErrorMessage(err error) string
- func (gh *GitHub) IsNetworkError(err error) bool
- func (gh *GitHub) ListSecrets(repo string) ([]string, error)
- func (gh *GitHub) RepoExists(owner, name string) (bool, error)
- func (gh *GitHub) RepoInfo(repoRef string) (owner, name, visibility string, err error)
- func (gh *GitHub) SetLog(fn func(...any))
- func (gh *GitHub) SetSecret(repo, name, value string) error
- func (gh *GitHub) SetSecretWithScope(repo, name, value, org, visibility string) error
- type GitHubAuthHandler
- type GitHubAuthenticator
- type GitHubClient
- type GitHubOAuth
- type GitHubPATAuth
- type Keyring
- type MockGitHubAuth
- type PublishAction
- type PublishContext
- type PublishObjector
- type PushResult
- type RealRunner
- type Runner
- type SecretRunner
- type TestCache
- func (tc *TestCache) GetCacheKey() (string, error)
- func (tc *TestCache) GetCachePath() (string, error)
- func (tc *TestCache) GetCachedMessage() string
- func (tc *TestCache) GetGitState() (string, error)
- func (tc *TestCache) InvalidateCache() error
- func (tc *TestCache) IsCacheValid() bool
- func (tc *TestCache) SaveCache(message string) error
Constants ¶
const ( // DepsCommitPrefix is the prefix for dependency update commit messages DepsCommitPrefix = "deps: " // CauseLinePrefix is the prefix for the root cause line in commit messages CauseLinePrefix = "cause: " )
const ( ObjectionCodejobSession = "codejob session active" ObjectionOtherReplaces = "other replaces exist" ObjectionPlanPending = "docs/PLAN.md pending" ObjectionDirtyTree = "dirty tree" )
const DevflowOAuthClientID = "Ov23lijHU2vxBCpShn1Q"
DevflowOAuthClientID is the OAuth App Client ID for devflow.
IMPORTANT: This Client ID is intentionally hardcoded and is NOT a secret. OAuth Client IDs are public identifiers (like a username, not a password). The Client Secret is NEVER included in the code - Device Flow doesn't need it. This is the standard approach used by CLI tools like gh, goreleaser, hub, etc.
The OAuth App is registered under a personal GitHub account (not organization). Manage the app at: https://github.com/settings/developers -> OAuth Apps -> devflow
Variables ¶
var ErrDirtyWorkTree = errors.New("cannot pull: working tree has uncommitted changes")
ErrDirtyWorkTree is returned by Pull when the working tree has uncommitted changes.
Functions ¶
func BuildDepsCommitMessage ¶ added in v0.0.2
BuildDepsCommitMessage constructs a standard dependency update commit message. rootCause is the original commit message that triggered the cascade.
func CompareVersions ¶ added in v0.0.2
CompareVersions compares two semantic version strings (e.g., "v1.2.3"). It returns -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2. It handles "v" prefix gracefully.
func EnsureGHSession ¶ added in v0.0.2
EnsureGHSession verifies the gh session and, if expired, restores it non-interactively from the keyring PAT via `gh auth login --with-token`. No-op when the session is healthy. The probe and verification run through runner so tests can inject a double and never touch a real gh CLI; restore itself always uses the real process (only reached when the probe genuinely fails, i.e. never under an injected test Runner that reports success).
func FormatCommitMessage ¶ added in v0.0.2
FormatCommitMessage ensures the message is trimmed.
func ValidateCommitMessage ¶ added in v0.0.2
ValidateCommitMessage ensures that a commit message is provided and is valid. It trims whitespace and returns an error if the message is empty.
func ValidateShellSafeMessage ¶ added in v0.0.2
ValidateShellSafeMessage provides a warning if the message contains characters that might need escaping in certain shells (like backticks, dollar signs, or single quotes) if it were to be used in a shell script, even though exec.Command is safe.
Types ¶
type Git ¶
type Git struct {
// contains filtered or unexported fields
}
Git handler for Git operations
func (*Git) CheckRemoteAccess ¶ added in v0.0.2
CheckRemoteAccess verifies connectivity to the remote repository. If an auth error is detected and an authRetrier is configured, it triggers the Device Flow auth automatically and retries once.
func (*Git) Clone ¶ added in v0.0.2
Clone clones repoURL into the working copy. If the destination already contains a repository, it is NOT an error: it does nothing and returns alreadyPresent == true, so an unattended publisher can call Clone unconditionally at startup.
func (*Git) Commit ¶ added in v0.0.2
Commit creates a commit with the given message Returns true if a commit was created
func (*Git) CommitPaths ¶ added in v0.0.2
CommitPaths adds specific paths and creates a commit. It returns true if a commit was created, false if no changes in those paths. This is safer than Add() + Commit() as it only touches specific files.
func (*Git) DiffShortStat ¶ added in v0.0.2
DiffShortStat returns the output of git diff HEAD --shortstat
func (*Git) Fetch ¶ added in v0.0.2
Fetch fetches refs from remote without touching the working tree.
func (*Git) GenerateNextTag ¶ added in v0.0.2
GenerateNextTag calculates the next semantic version
func (*Git) GetConfigUserEmail ¶ added in v0.0.2
GetConfigUserEmail gets the git user.email
func (*Git) GetConfigUserName ¶ added in v0.0.2
GetConfigUserName gets the git user.name
func (*Git) GetLatestTag ¶ added in v0.0.2
GetLatestTag gets the latest tag
func (*Git) GitIgnoreAdd ¶ added in v0.0.2
GitIgnoreAdd adds entry to .gitignore if shouldWrite allows and entry not present. Creates .gitignore if it doesn't exist.
func (*Git) HasChanges ¶ added in v0.0.2
HasChanges checks if there are staged changes
func (*Git) HasPendingChanges ¶ added in v0.0.2
HasPendingChanges returns true if there are uncommitted or unpushed changes. Used by CodeJob to ensure the file is visible to Jules before dispatching. It ignores changes to .env and .gitignore files.
func (*Git) HasUpstream ¶ added in v0.0.2
HasUpstream checks if the branch has upstream
func (*Git) IncrementTag ¶ added in v0.0.2
IncrementTag increments a specific tag (e.g., v0.0.12 -> v0.0.13)
func (*Git) IsAheadOfRemote ¶ added in v0.0.2
IsAheadOfRemote checks if local branch is ahead of remote
func (*Git) ObjectsToPublish ¶ added in v0.0.2
func (g *Git) ObjectsToPublish(_ PublishContext) (PublishAction, string)
func (*Git) Pull ¶ added in v0.0.2
Pull updates the working copy from upstream. Returns ErrDirtyWorkTree if the working tree has uncommitted changes.
func (*Git) Push ¶ added in v0.0.2
func (g *Git) Push(message, tag string) (PushResult, error)
Push executes the complete push workflow (add, commit, tag, push) Returns a PushResult and error if any.
func (*Git) PushWithTags ¶ added in v0.0.2
PushWithTags pushes commits and tag
func (*Git) PushWithoutTags ¶ added in v0.0.2
PushWithoutTags pushes commits without pushing tags
func (*Git) SetAuthRetrier ¶ added in v0.0.2
func (g *Git) SetAuthRetrier(a GitHubAuthenticator)
SetAuthRetrier injects an authenticator to use for auto-recovery on access errors
func (*Git) SetRootDir ¶ added in v0.0.2
SetRootDir sets the root directory for git operations
func (*Git) SetShouldWrite ¶ added in v0.0.2
SetShouldWrite sets a function that determines if Git write operations (like updating .gitignore) should be allowed.
func (*Git) SetUserConfig ¶ added in v0.0.2
SetUserConfig sets git user name and email
func (*Git) StatusPorcelain ¶ added in v0.0.2
StatusPorcelain returns the output of git status --porcelain
type GitClient ¶ added in v0.0.2
type GitClient interface {
CheckRemoteAccess() error
Push(message, tag string) (PushResult, error)
GetLatestTag() (string, error)
SetLog(fn func(...any))
SetShouldWrite(fn func() bool)
SetRootDir(path string)
GitIgnoreAdd(entry string) error
GetConfigUserName() (string, error)
GetConfigUserEmail() (string, error)
InitRepo(dir string) error
Add() error
Commit(message string) (bool, error)
CommitPaths(message string, paths ...string) (bool, error)
CreateTag(tag string) (bool, error)
PushWithTags(tag string) (bool, error)
PushWithoutTags() (bool, error)
HasPendingChanges() (bool, error)
StatusPorcelain() (string, error)
DiffShortStat() (string, error)
GenerateNextTag() (string, error)
Clone(repoURL string) (alreadyPresent bool, err error)
Pull() error
Fetch() error
}
GitClient defines the interface for Git operations.
type GitHub ¶ added in v0.0.2
type GitHub struct {
SecretRunner SecretRunner
// contains filtered or unexported fields
}
GitHub handler for GitHub operations
func NewGitHub ¶ added in v0.0.2
func NewGitHub(logFn func(...any), auth ...GitHubAuthenticator) (*GitHub, error)
NewGitHub creates handler and verifies gh CLI availability. logFn is used to display authentication messages during Device Flow. If not authenticated, it initiates OAuth Device Flow automatically.
func (*GitHub) CreateRelease ¶ added in v0.0.2
CreateRelease creates a GitHub Release and uploads assets. If targetRepo is not empty, it uses the --repo flag to publish to that repository.
func (*GitHub) CreateRepo ¶ added in v0.0.2
CreateRepo creates a new empty repository on GitHub If owner is provided, creates repo under that organization
func (*GitHub) DeleteRepo ¶ added in v0.0.2
DeleteRepo deletes a repository on GitHub. WARNING: This permanently deletes the repository and cannot be undone. Use with caution, primarily for test cleanup.
func (*GitHub) DeleteSecret ¶ added in v0.0.2
DeleteSecret removes a GitHub Actions secret. gh secret delete NAME --repo=OWNER/REPO
func (*GitHub) GetCurrentUser ¶ added in v0.0.2
GetCurrentUser gets the current authenticated user
func (*GitHub) GetHelpfulErrorMessage ¶ added in v0.0.2
GetHelpfulErrorMessage returns a helpful message for common errors
func (*GitHub) IsNetworkError ¶ added in v0.0.2
IsNetworkError checks if an error is likely a network error
func (*GitHub) ListSecrets ¶ added in v0.0.2
ListSecrets returns the names of secrets registered in the repo. Values are never accessible via API — GitHub only exposes names. gh secret list --repo=OWNER/REPO --json name --jq '[.[].name]'
func (*GitHub) RepoExists ¶ added in v0.0.2
RepoExists checks if a repository exists
func (*GitHub) RepoInfo ¶ added in v0.0.3
repoInfo returns basic information about a repository. If repoRef is empty, it queries the repository in the current directory.
func (*GitHub) SetSecret ¶ added in v0.0.2
SetSecret registers a secret in GitHub Actions via gh CLI. The value is passed via stdin — gh CLI encrypts it with the repo's public key before transmitting it. It does not appear in system ps/logs.
func (*GitHub) SetSecretWithScope ¶ added in v0.0.2
SetSecretWithScope registers a secret either at the repository level or organization level.
type GitHubAuthHandler ¶ added in v0.0.2
type GitHubAuthHandler interface {
GitHubAuthenticator
Name() string
}
GitHubAuthHandler defines the interface for GitHub auth as a TUI handler.
type GitHubAuthenticator ¶ added in v0.0.2
GitHubAuthenticator defines the interface for GitHub authentication. This allows mocking authentication in tests.
type GitHubClient ¶ added in v0.0.2
type GitHubClient interface {
SetLog(fn func(...any))
GetCurrentUser() (string, error)
RepoExists(owner, name string) (bool, error)
CreateRepo(owner, name, description, visibility string) error
DeleteRepo(owner, name string) error
IsNetworkError(err error) bool
GetHelpfulErrorMessage(err error) string
CreateRelease(tag string, assets []string, targetRepo string) (string, error)
}
GitHubClient defines the interface for GitHub operations. This allows mocking the GitHub dependency in tests.
type GitHubOAuth ¶ added in v0.0.2
type GitHubOAuth struct {
// contains filtered or unexported fields
}
GitHubOAuth handles GitHub authentication and token management via Device Flow
func NewGitHubOAuth ¶ added in v0.0.2
func NewGitHubOAuth() *GitHubOAuth
NewGitHubOAuth creates a new GitHub authentication handler
func (*GitHubOAuth) DeviceFlowAuth ¶ added in v0.0.2
func (a *GitHubOAuth) DeviceFlowAuth(kr *Keyring) (string, error)
DeviceFlowAuth initiates GitHub OAuth Device Flow and returns an access token
func (*GitHubOAuth) EnsureGitHubAuth ¶ added in v0.0.2
func (a *GitHubOAuth) EnsureGitHubAuth() error
EnsureGitHubAuth checks if GitHub is authenticated via keyring, and if not, initiates Device Flow
func (*GitHubOAuth) Name ¶ added in v0.0.2
func (a *GitHubOAuth) Name() string
Name returns the handler name for TUI display.
func (*GitHubOAuth) SetLog ¶ added in v0.0.2
func (a *GitHubOAuth) SetLog(fn func(...any))
SetLog sets the logger function
type GitHubPATAuth ¶ added in v0.0.2
type GitHubPATAuth struct {
// contains filtered or unexported fields
}
GitHubPATAuth manages the GitHub PAT via the system keyring. It is used to recover the gh CLI session non-interactively.
func NewGitHubPATAuth ¶ added in v0.0.2
func NewGitHubPATAuth() (*GitHubPATAuth, error)
NewGitHubPATAuth creates a GitHubPATAuth with an initialized keyring.
func (*GitHubPATAuth) EnsureGitHubAuth ¶ added in v0.0.2
func (a *GitHubPATAuth) EnsureGitHubAuth() error
EnsureGitHubAuth fulfills the GitHubAuthenticator interface.
func (*GitHubPATAuth) EnsureToken ¶ added in v0.0.2
func (a *GitHubPATAuth) EnsureToken() (string, error)
EnsureToken returns the PAT from the environment or keyring; if absent, prompts once and persists.
func (*GitHubPATAuth) HasToken ¶ added in v0.0.2
func (a *GitHubPATAuth) HasToken() bool
HasToken returns true if the GitHub PAT is already stored in the environment or keyring.
func (*GitHubPATAuth) Reset ¶ added in v0.0.2
func (a *GitHubPATAuth) Reset() error
Reset removes the GitHub PAT from the keyring.
func (*GitHubPATAuth) SetLog ¶ added in v0.0.2
func (a *GitHubPATAuth) SetLog(fn func(...any))
SetLog sets the logging function.
type Keyring ¶ added in v0.0.2
type Keyring struct {
// contains filtered or unexported fields
}
Keyring provides secure credential storage using the system keyring
func NewKeyring ¶ added in v0.0.2
NewKeyring creates a keyring handler and ensures dependencies are installed
type MockGitHubAuth ¶ added in v0.0.2
type MockGitHubAuth struct {
EnsureAuthError error // Set this to simulate auth failure
// contains filtered or unexported fields
}
MockGitHubAuth is a mock implementation of GitHubAuthenticator for testing.
func NewMockGitHubAuth ¶ added in v0.0.2
func NewMockGitHubAuth() *MockGitHubAuth
NewMockGitHubAuth creates a new mock authenticator.
func (*MockGitHubAuth) EnsureGitHubAuth ¶ added in v0.0.2
func (m *MockGitHubAuth) EnsureGitHubAuth() error
EnsureGitHubAuth simulates the authentication process.
func (*MockGitHubAuth) Name ¶ added in v0.0.2
func (m *MockGitHubAuth) Name() string
Name returns the handler name for TUI display.
func (*MockGitHubAuth) SetLog ¶ added in v0.0.2
func (m *MockGitHubAuth) SetLog(fn func(...any))
SetLog sets the logger function.
type PublishAction ¶ added in v0.0.2
type PublishAction int
const ( ActionNone PublishAction = iota // no objection: full publication (tag + cascade) ActionDepsOnly // commit go.mod/go.sum, push without tag, no cascade ActionSkip // do not touch the repo at all )
func ResolvePublishAction ¶ added in v0.0.2
func ResolvePublishAction(objectors []PublishObjector, ctx PublishContext) (PublishAction, string)
ResolvePublishAction returns the strongest action any objector requires (Skip > DepsOnly > None) and the reason of the objector that set it.
type PublishContext ¶ added in v0.0.2
type PublishObjector ¶ added in v0.0.2
type PublishObjector interface {
ObjectsToPublish(ctx PublishContext) (PublishAction, string) // action + readable reason
}
type PushResult ¶ added in v0.0.2
type PushResult struct {
Summary string // Human-readable summary of operations performed
Tag string // The tag that was created and pushed
}
PushResult contains the results of a Git push operation
type SecretRunner ¶ added in v0.0.2
type SecretRunner interface {
Run(name string, args ...string) (string, error)
RunSilent(name string, args ...string) (string, error)
RunWithStdin(input, name string, args ...string) (string, error)
}
SecretRunner abstracts command execution for testability. Exported to be implemented in external tests.
type TestCache ¶ added in v0.0.2
TestCache provides git-based test caching to avoid re-running tests when the code hasn't changed since the last successful test run.
func NewTestCache ¶ added in v0.0.2
NewTestCache creates a new TestCache instance
func (*TestCache) GetCacheKey ¶ added in v0.0.2
GetCacheKey returns a unique key for the current module based on its path
func (*TestCache) GetCachePath ¶ added in v0.0.2
GetCachePath returns the full path to the cache file
func (*TestCache) GetCachedMessage ¶ added in v0.0.2
GetCachedMessage returns the cached test output message
func (*TestCache) GetGitState ¶ added in v0.0.2
GetGitState returns current git state: commit hash + diff hash This uniquely identifies the exact state of the code
func (*TestCache) InvalidateCache ¶ added in v0.0.2
InvalidateCache removes the cache file
func (*TestCache) IsCacheValid ¶ added in v0.0.2
IsCacheValid checks if tests were already run successfully with the current code