githubapp

package
v0.7.19 Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package githubapp drives the GitHub App "create from manifest" flow used by the install script's step 5. It is intentionally narrow — it knows nothing about Bicep, Azure, or .env; it only produces credentials and writes them to the install state file.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func OpenBrowser

func OpenBrowser(url string) error

OpenBrowser tries to open the given URL in the user's default browser. On failure it returns an error so the caller can fall back to printing the URL for manual paste.

func RunManual

func RunManual(in io.Reader, out io.Writer, opts ManualOptions) error

RunManual reads the values install.sh used to prompt for, validates them, and writes them to the state file. It is the fallback path when the browser flow can't be used (SSH, codespaces, --manual flag).

func SaveState

func SaveState(path string, kv map[string]string) error

SaveState appends key=value lines to the install-state file in a form that `bash source` can read. Values containing whitespace, quotes, or non-ASCII are emitted using bash's $'...' ANSI-C quoting; simple values are bare.

The file is chmod'd to 0600 after every write. SaveState appends — it never rewrites existing lines, mirroring install.sh's behavior. Bash semantics mean later assignments win on `source`.

Types

type Conversion

type Conversion struct {
	ID            int64  `json:"id"`
	Slug          string `json:"slug"`
	ClientID      string `json:"client_id"`
	ClientSecret  string `json:"client_secret"`
	WebhookSecret string `json:"webhook_secret"`
	PEM           string `json:"pem"`
	Owner         struct {
		Login string `json:"login"`
	} `json:"owner"`
}

Conversion is the response from POST /app-manifests/{code}/conversions. Fields we don't use (e.g. node_id, html_url) are intentionally omitted.

type Converter

type Converter struct {
	BaseURL    string        // e.g. https://api.github.com
	HTTP       *http.Client  // injected for testing
	RetryDelay time.Duration // delay between attempts; one retry on 5xx
}

Converter exchanges a one-time manifest code for an App's full credentials. The zero value is not usable; construct via NewConverter.

func NewConverter

func NewConverter(baseURL string, hc *http.Client) *Converter

NewConverter returns a Converter pointed at baseURL using the given client. baseURL has no trailing slash.

func (*Converter) Convert

func (c *Converter) Convert(ctx context.Context, code string) (*Conversion, error)

Convert exchanges the temporary code GitHub redirected with for the App's permanent credentials. One retry on 5xx; 4xx is surfaced immediately.

type HookAttributes

type HookAttributes struct {
	URL string `json:"url"`
}

HookAttributes is the webhook block of a manifest.

type Manifest

type Manifest struct {
	Name           string            `json:"name"`
	URL            string            `json:"url"`
	HookAttributes HookAttributes    `json:"hook_attributes"`
	RedirectURL    string            `json:"redirect_url"`
	CallbackURLs   []string          `json:"callback_urls"`
	SetupURL       string            `json:"setup_url"`
	SetupOnUpdate  bool              `json:"setup_on_update"`
	Public         bool              `json:"public"`
	DefaultEvents  []string          `json:"default_events"`
	DefaultPerms   map[string]string `json:"default_permissions"`
}

Manifest is the JSON payload posted to github.com/settings/apps/new. Field tags match GitHub's documented schema: https://docs.github.com/en/apps/sharing-github-apps/registering-a-github-app-from-a-manifest

func BuildManifest

func BuildManifest(in ManifestInput) Manifest

BuildManifest renders a Manifest from the given input. Permissions and events match what CronFoundry needs: Contents R+W (read/push skill files), Issues W (file reports), Pull Requests W (open skill-repo PRs from `+ Add job` / `+ Import job` flows), Metadata R (required by GitHub for any App), Push events.

type ManifestInput

type ManifestInput struct {
	Name             string // app name, must be globally unique on GitHub
	CallbackURL      string // base URL of the local callback server, e.g. http://localhost:8765
	HomepageURL      string // production homepage URL (optional; defaults to CallbackURL)
	WebhookURL       string // production webhook URL (optional; defaults to CallbackURL+"/webhook")
	OAuthCallbackURL string // production OAuth callback URL (optional; defaults to CallbackURL+"/oauth/callback")
}

ManifestInput is the minimal user-facing data needed to render a manifest.

CallbackURL is always the *local* callback server base URL (set by server.go from s.URL()). It is required so the manifest-create handshake (RedirectURL) reaches the local helper. The other three fields are optional production URLs pointing at the deployed FQDN; when blank we fall back to CallbackURL-derived defaults so existing local-dev behavior and older callers keep working.

type ManualOptions

type ManualOptions struct {
	StateFile string
}

ManualOptions configures the legacy interactive prompts.

type Options

type Options struct {
	Port            int
	StateFile       string
	PEMDir          string
	Converter       *Converter
	ManifestInput   ManifestInput
	Timeout         time.Duration
	SkipBrowserOpen bool
}

Options configures the local callback server.

type Result

type Result struct {
	AppID          int64
	Slug           string
	ClientID       string
	WebhookSecret  string
	InstallationID int64
	PEMPath        string
}

Result is what Run produces after a successful flow.

type Server

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

Server owns the localhost HTTP server lifecycle for one manifest flow. One Server == one Run; do not reuse.

func NewServer

func NewServer(opts Options) (*Server, error)

NewServer creates the server and binds its listener but does not yet accept connections. URL() and State() are valid after this call.

func (*Server) Run

func (s *Server) Run(ctx context.Context) (*Result, error)

Run starts the HTTP server, opens the user's browser to "/", and blocks until either /installed completes successfully, the context is cancelled, or Options.Timeout elapses.

func (*Server) State

func (s *Server) State() string

func (*Server) Timeout

func (s *Server) Timeout() time.Duration

func (*Server) URL

func (s *Server) URL() string

Jump to

Keyboard shortcuts

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