config

package
v0.15.3 Latest Latest
Warning

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

Go to latest
Published: Jun 15, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package config loads runtime configuration from environment variables (and optionally from a .env file in development).

All secret values use the Secret type so they cannot leak through logging.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Addr        string `env:"ADDR" envDefault:":8080"`
	LogLevel    string `env:"LOG_LEVEL" envDefault:"info"`
	LogFormat   string `env:"LOG_FORMAT" envDefault:"text"`
	DatabaseURL string `env:"DATABASE_URL" envDefault:"file:./data/notifycat.db"`

	// MappingsFile is the path to the declarative mappings.yaml file.
	// The sibling lock file lives at the same path with the .yaml/.yml
	// extension swapped for .lock (or appended when there is no such ext).
	MappingsFile string `env:"NOTIFYCAT_MAPPINGS_FILE" envDefault:"./mappings.yaml"`

	GitHubWebhookSecret Secret `env:"GITHUB_WEBHOOK_SECRET,required,notEmpty"`
	SlackBotToken       Secret `env:"SLACK_BOT_TOKEN,required,notEmpty"`

	// SlackBaseURL is operator-overridable to point the client at a test
	// double. Defaults to the real Slack API.
	SlackBaseURL string `env:"SLACK_BASE_URL" envDefault:"https://slack.com"`

	// GitHubToken is consumed only by `notifycat-mapping validate` to query the
	// repository's webhook configuration. Optional; without it the webhook
	// coverage check is skipped.
	GitHubToken Secret `env:"GITHUB_TOKEN"`

	// GitHubBaseURL is operator-overridable, paralleling SlackBaseURL.
	GitHubBaseURL string `env:"GITHUB_BASE_URL" envDefault:"https://api.github.com"`

	// MessageTTLDays is the age, in days, after which a slack_messages row
	// with no further activity becomes eligible for the scheduled cleanup.
	// Must be > 0; Load() rejects 0 or negative values.
	MessageTTLDays int `env:"NOTIFYCAT_MESSAGE_TTL_DAYS" envDefault:"30"`

	// IgnoreAIReviews, when true, suppresses Slack reaction emojis for any
	// review event whose sender.type == "Bot" (GitHub Apps, including AI
	// reviewers and scripted bots alike). Default false — current behavior.
	IgnoreAIReviews bool `env:"NOTIFYCAT_IGNORE_AI_REVIEWS" envDefault:"false"`

	// DependabotFormat, when true (the default), renders a compact Slack
	// message for PRs opened by dependabot[bot] or renovate[bot] — a routine
	// "bumped" line, or a distinct "security update" line when the PR body
	// shows a security advisory. Set false to fall back to the standard
	// "please review" format for those PRs. See internal/botpr.
	DependabotFormat bool `env:"NOTIFYCAT_DEPENDABOT_FORMAT" envDefault:"true"`

	// Domain is the public DNS name operators point at this host; the
	// docker-compose reverse proxy uses it for the virtual host and TLS. It is
	// the single source of truth for the public host: notifycat-doctor derives
	// the GitHub webhook URL (https://$DOMAIN/webhook/github) from it. Optional —
	// unset is fine for local-dev / tunnel setups, and a value exported in the
	// environment counts the same as one from .env.
	Domain string `env:"DOMAIN"`

	Reactions Reactions
}

Config is the parsed runtime configuration.

func Load

func Load() (Config, error)

Load reads .env if present (no-op when absent) and parses environment variables into Config.

type MissingVarError

type MissingVarError struct {
	Var string
}

MissingVarError is returned by Load when a required env var is unset or empty.

func (*MissingVarError) Error

func (e *MissingVarError) Error() string

type Reactions

type Reactions struct {
	Enabled       bool   `env:"SLACK_REACTIONS_ENABLED" envDefault:"true"`
	NewPR         string `env:"SLACK_REACTION_NEW_PR" envDefault:"eyes"`
	MergedPR      string `env:"SLACK_REACTION_MERGED_PR" envDefault:"twisted_rightwards_arrows"`
	ClosedPR      string `env:"SLACK_REACTION_CLOSED_PR" envDefault:"x"`
	Approved      string `env:"SLACK_REACTION_PR_APPROVED" envDefault:"white_check_mark"`
	Commented     string `env:"SLACK_REACTION_PR_COMMENTED" envDefault:"speech_balloon"`
	RequestChange string `env:"SLACK_REACTION_PR_REQUEST_CHANGE" envDefault:"exclamation"`
	// BotReview is the distinct marker added when a bot reviewer's activity is
	// NOT suppressed (NOTIFYCAT_IGNORE_AI_REVIEWS=false). Set it empty to keep
	// bot reviews indistinguishable from human ones. See internal/aireview.
	BotReview string `env:"SLACK_REACTION_BOT_REVIEW" envDefault:"robot_face"`
}

Reactions configures Slack reaction emoji names per PR lifecycle event.

type Secret

type Secret string

Secret wraps a sensitive string (API token, webhook secret, password).

Its zero value is the empty string. Stringer, formatting verbs, and slog rendering all return a redaction placeholder so the raw value never reaches logs by accident. Use Reveal when handing the value to an external system.

func (Secret) Format

func (s Secret) Format(f fmtState, _ rune)

Format intercepts every Sprintf verb (%v, %s, %q, %+v, …) so we cannot leak the raw value through an unfamiliar verb.

func (Secret) GoString

func (s Secret) GoString() string

GoString satisfies fmt's %#v verb without leaking.

func (Secret) LogValue

func (s Secret) LogValue() slog.Value

LogValue ensures slog renders Secret with the same redaction placeholder.

func (Secret) Reveal

func (s Secret) Reveal() string

Reveal returns the underlying raw value. Call this only when passing the secret to an external system that needs it (HMAC, HTTP Authorization header, …). Never log the return value.

func (Secret) String

func (s Secret) String() string

String returns a placeholder so fmt and stringer-based logging never expose the underlying value. An empty Secret renders as "" to keep absence distinguishable from presence in operator output.

Jump to

Keyboard shortcuts

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