diff --git a/AGENTS.md b/AGENTS.md index 8dd1878..97a67ef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -52,36 +52,38 @@ input. ## Purpose -This repo is the single source of truth for linter configs across all rubykatzen repositories. The goal is identical linting everywhere — configs live here and nowhere else. - -Baseline owns linter configuration and runtime installation for CI. Consuming -repositories call `lint-shared.yml` and get runtimes, configs, and linter -execution handled automatically. Pre-commit hooks are thin wrappers that expect -tools to already be installed in the developer environment. +Baseline is the centrally managed source of development policy for repositories +across organizations and programming language stacks. Its goal is a +zero-configuration, homogeneous development experience for developers who move +between stacks. + +Baseline owns linter configuration and CI runtime installation, GitHub repository +policy, required content fragments, and reusable notification workflows. +Consumers connect only the workflows they need. Checks verify policy but do not +mutate consumer repositories; intentional differences use explicit `skip` +inputs. Pre-commit hooks are thin wrappers that expect tools to already be +installed in the developer environment. ## Repository Structure -- `config/` — canonical linter config files +- `config/` — canonical linter, GitHub policy, and Embedder configuration - `hooks/` — shell and Python script wrappers for pre-commit (`language: script`) -- `baseline.gemspec` — Ruby gem packaging RuboCop and erb_lint configs for local `bundle exec rubocop` +- `baseline.gemspec` — Ruby gem packaging RuboCop, erb_lint, and Herb tooling - `lib/` — gem code (`Baseline::VERSION`, install stubs) - `exe/baseline-install` — writes project `.rubocop.yml` and `.erb_lint.yml` stubs - `.github/actions/lint-*/` — composite actions that run installed linters with baseline configs -- `.github/actions/check-embedder/` — validates required content fragments in consumer files +- `.github/actions/check-embedder/` — validates base and named extra content fragments +- `.github/actions/check-github-config/` — validates repository settings and labels - `.github/actions/detect-linters/` — composite action that selects applicable linters from tracked files - `.github/actions/check-precommit/` — composite action: verifies pre-commit hooks match detected CI linters - `.github/actions/setup-runtimes/` — installs Python packages, Ruby, and standalone binaries for requested linters; Python is provided by the runner -- `.github/actions/prepare-telegram-pr-message/` — formats pull request and open-PR digest messages -- `.github/actions/prepare-telegram-issue-message/` — formats closed-issue messages -- `.github/actions/send-telegram-message/` — sends plain-text messages through the Telegram Bot API -- `.github/workflows/lint-shared.yml` — reusable workflow exported for consuming repos: setup + lint -- `.github/workflows/embedder-shared.yml` — reusable workflow exported for required content validation -- `.github/workflows/notify-telegram-pr-shared.yml` — reusable pull request notifications and open-PR digest -- `.github/workflows/notify-telegram-issue-shared.yml` — optional reusable issue-closure notifications +- `.github/actions/*telegram*/` — prepares and sends Telegram notifications +- `.github/workflows/*-shared.yml` — reusable workflows exported to consumers +- `.github/workflows/lint.yml`, `github.yml`, and `embedder.yml` — local self-check callers - `.github/workflows/pr.yml` — validates Baseline pull request titles against Conventional Commits -- `.github/workflows/lint.yml` — baseline self-lint (uses local `./` references, not `@vX`) - `.github/workflows/release.yml` — maintains the release PR and publishes merged releases - `.github/workflows/notify-telegram-pr.yml` — Baseline's own Telegram pull request notification caller +- `.github/workflows/test.yml` — runs the Python test suite - `.pre-commit-hooks.yaml` — hook definitions for pre-commit ## Adding a New Linter @@ -104,6 +106,15 @@ Pre-commit hooks expect tools to already be on PATH in the developer environment ## Workflows +`lint-shared.yml` auto-detects applicable linters, installs their CI runtimes, +checks pre-commit synchronization when configured, and runs the canonical +tooling. + +`github-shared.yml` verifies repository settings and labels against +`config/github.yml`. `embedder-shared.yml` verifies the base fragment set and +named configurations selected through its `extra` JSON input. Extra fragment +IDs use the `/` namespace in `skip`. + `notify-telegram-pr-shared.yml` exports pull request notifications and the open-pull-request digest. Baseline calls it locally through `notify-telegram-pr.yml`. @@ -113,19 +124,16 @@ The caller owns any label or other notification condition; the shared workflow does not modify issues. Baseline does not call it because this repository does not use issue notifications. -`lint-shared.yml` is the primary export — consuming repos call it via -`uses: rubykatzen/baseline/.github/workflows/lint-shared.yml@VERSION`. - Pre-commit hook pins in `.pre-commit-config.yaml` are updated by Dependabot (`package-ecosystem: pre-commit` in `.github/dependabot.yml`), not by a custom workflow. -## Self-linting +## Self-validation -Baseline lints itself through `.github/workflows/lint.yml`, which calls the -shared reusable workflow `.github/workflows/lint-shared.yml` using a local -`./` reference. This ensures the current commit's actions and configs are -validated, not a pinned release. +Baseline calls its lint, GitHub, and Embedder reusable workflows through local +`./` references. This validates the current commit's actions and configurations, +not a pinned release. The Embedder self-check enables the `release-please` extra +configuration. ## Cutting Releases @@ -145,7 +153,8 @@ For language-agnostic file types (YAML, Markdown, shell, etc.), always choose th Priority order: Python > TypeScript > everything else. -This avoids introducing new runtimes into repos that don't already use them. +This minimizes setup by preferring the Python runtime already present on GitHub +runners before introducing another toolchain. ## Disabled Rules diff --git a/README.md b/README.md index 9109f4b..0326493 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,18 @@ # Baseline -Baseline simplifies managing repositories across multiple organizations and -programming language stacks. It provides a homogeneous development environment -for language-agnostic developers and a centrally managed baseline for repository -owners. +Baseline gives developers who move between language stacks a zero-configuration, +homogeneous development experience across repositories and organizations. -Connect a workflow and Baseline supplies the policy, configuration, runtimes, -and implementation. Consumer repositories only declare which capabilities they -want and, when necessary, explicit exceptions. +Connect the workflows a repository needs. Baseline detects applicable linters, +supplies their CI runtimes and configurations, and verifies shared policies and +files. Repositories satisfy those policies or declare explicit exceptions. The examples use the latest [Baseline release](https://github.com/rubykatzen/baseline/releases) and are updated automatically with every release. Dependabot keeps the pin current in consumer repositories. -## Lint automatically +## ⚡ Lint automatically Create `.github/workflows/lint.yml`: @@ -41,7 +39,7 @@ linter on the next run. When the repository contains `.pre-commit-config.yaml`, Baseline also checks that its local hooks match the automatically selected CI linters. -## Check GitHub configuration +## ⚙️ Check GitHub configuration Create `.github/workflows/github.yml`: @@ -65,7 +63,7 @@ Baseline checks the repository settings and labels against automatic branch deletion, auto-merge, and the canonical label set and colors. Release Please labels are allowed but optional. -## Check shared repository files +## 📄 Check shared repository files Create `.github/workflows/embedder.yml`: @@ -107,7 +105,7 @@ Optional configurations live under [`config/embedder/`](config/embedder/). The `release-please` configuration checks the common release configuration, workflow, and pull request title policy while leaving package-specific publishing local. -## Notify Telegram about pull requests +## 🔔 Notify Telegram about pull requests Create `.github/workflows/notify-telegram-pr.yml`: @@ -140,7 +138,7 @@ workflow code from the default branch. The shared workflow does not check out or execute pull request code. Pass the two secrets explicitly rather than using `secrets: inherit`. -## Notify Telegram about closed issues +## 📬 Notify Telegram about closed issues Issue notifications are optional and can use a different Telegram channel from pull request notifications. Create `.github/workflows/notify-telegram-issue.yml`: @@ -167,7 +165,7 @@ The caller decides which closed issues should produce a notification. Change or remove the `if` condition to match the repository's policy. Baseline only formats and sends the message; it does not modify the issue or its labels. -## Explicit exceptions +## ⏭️ Explicit exceptions Automatic policy is the default. When a repository intentionally differs, pass a JSON array through `skip`: @@ -209,7 +207,7 @@ Omit `release-please` from `extra` instead when none of its policy should apply. Unknown names fail the workflow. A skipped linter must also be absent from the Baseline entry in `.pre-commit-config.yaml`, keeping local and CI linting equal. -## Local linting +## 💻 Local linting CI runtime installation is automatic. For local pre-commit use, create `.pre-commit-config.yaml` and keep only the hooks relevant to the repository: @@ -238,14 +236,14 @@ Pre-commit hooks are thin wrappers and expect their tools on `PATH`. Install the Python and standalone tools used by the repository: ```bash -python -m pip install yamllint pymarkdownlnt ruff tombi +python -m pip install pre-commit yamllint pymarkdownlnt ruff tombi brew install shellcheck actionlint ``` -### Ruby projects +### 💎 Ruby projects -Ruby projects get RuboCop and erb_lint, with Baseline's configuration, from one -gem: +Ruby projects get RuboCop, erb_lint, and Herb, with Baseline's configuration, +from one gem: ```ruby group :development, :test do @@ -264,59 +262,34 @@ the gem. Project-specific existing violations can remain in `.rubocop_todo.yml` or `.erb_lint_todo.yml`; Baseline continues to catch new violations. -## Keep Baseline current +## 🔄 Keep Baseline current -Add GitHub Actions and pre-commit ecosystems to `.github/dependabot.yml` so -Dependabot updates every Baseline pin: - -```yaml -version: 2 -updates: - - package-ecosystem: github-actions - directory: / - labels: [dependencies] - commit-message: - prefix: chore - include: scope - schedule: - interval: daily - time: "10:00" - timezone: "Europe/Berlin" - - package-ecosystem: pre-commit - directory: / - labels: [dependencies] - commit-message: - prefix: chore - include: scope - schedule: - interval: daily - time: "10:00" - timezone: "Europe/Berlin" -``` +Dependabot keeps workflow references, pre-commit hooks, Python packages, and +Ruby gems current. The Embedder workflow verifies the canonical +`.github/dependabot.yml`, so consumer repositories do not maintain that +configuration independently. Dependabot opens `chore(deps):` pull requests, which do not request a release by default. Rename a release-worthy dependency update to `fix(deps):` to request a patch release. -## Supported linters +## 🧰 Supported linters | Key | Files | Configuration | |---|---|---| | `yamllint` | `*.yml`, `*.yaml` | `config/yamllint.yml` | -| `pymarkdown` | `*.md` | `config/pymarkdown.json` | -| `ruff` | `*.py` | `config/ruff.toml` | +| `pymarkdown` | Markdown | `config/pymarkdown.json` | +| `ruff` | Python source and stubs | `config/ruff.toml` | | `tombi` | `*.toml` | consumer config or Tombi defaults | | `shellcheck` | `*.sh` | `config/shellcheck.rc` | -| `actionlint` | `.github/workflows/*.yml` | actionlint defaults | -| `rubocop` | `*.rb` | `config/rubocop.yml` | -| `erb-lint` | `*.erb` | `config/erb_lint.yml` | +| `actionlint` | GitHub Actions workflows | actionlint defaults | +| `rubocop` | Ruby source, Gemfiles, Rakefiles, and gemspecs | `config/rubocop.yml` | +| `erb-lint` | HTML ERB templates | `config/erb_lint.yml` | | `herb` | HTML and Rails template variants | Herb defaults | See [LINTERS-DEFAULTS-OVERRIDES.md](LINTERS-DEFAULTS-OVERRIDES.md) for deliberate deviations from upstream linter defaults. -## Releasing Baseline +## 📝 License -Release Please maintains a release pull request from Conventional Commits on -`main`. Merging it creates the version tag and GitHub Release, publishes the -Ruby gem, and updates the floating major and minor tags used by consumers. +Baseline is released under the [MIT License](LICENSE).