diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000..c3cff4c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,151 @@ +# The key below is `description`, NOT `about`. +# +# GitHub requires `description` on a YAML issue form and rejects the +# template without it; Gitea wants `about` but explicitly accepts +# `description` as a compatible alias. `description` is therefore the +# only spelling that works on both the canonical repo and the mirror. +# The markdown templates beside this one still use `about`, which is +# correct for their format on both forges. +name: Bug report +description: Something in the config is broken or behaves unexpectedly +labels: + - Kind/Bug +body: + - type: markdown + attributes: + value: | + Thanks for filing a bug. + + **Title it as a plain description of the problem**, not as a + conventional-commit subject — `mv clobbers a symlink when the target + exists`, not `fix(mv): ...`. The commit format belongs on the PR that + fixes this; the `Kind/` and `Area/` labels carry type and scope here. + + Before filing, please confirm the problem survives a fresh shell + (`exec fish`) — a stale function definition in a long-lived session is + the single most common false alarm. + + - type: input + id: fish-version + attributes: + label: fish version + description: Output of `fish --version`. This config targets fish 4.x. + placeholder: fish, version 4.0.2 + validations: + required: true + + - type: input + id: os + attributes: + label: Operating system + description: Distribution and version, or macOS release. + placeholder: Arch Linux (CachyOS), kernel 6.12.4 + validations: + required: true + + - type: input + id: terminal + attributes: + label: Terminal emulator + description: >- + Only matters for rendering, key bindings, and color problems. Leave it + blank if the bug has nothing to do with those. + placeholder: kitty 0.42.1 + validations: + required: false + + - type: dropdown + id: area + attributes: + label: Area + description: >- + Which part of the config is affected? Pick the closest match — a + maintainer translates this into the matching `Area/` label at triage, + since contributors without push access can't set labels themselves. + Choose "Not sure" rather than guessing. + options: + - Not sure + - Functions (functions/) + - Completions (completions/) + - Config and startup (config.fish, conf.d/) + - Docs (docs/manual/, man page, docs site) + - Tests (tests/) + - CI (.github/workflows/) + - Integrations (integrations/) + - Prompt and theme (themes/) + - Opinionated components (C1-C6 toggles) + - Scripts (scripts/) + validations: + required: true + + - type: textarea + id: summary + attributes: + label: What's broken + description: One or two sentences. Name the function or file if you know it. + placeholder: >- + `mv` replaces an existing symlink instead of prompting, so the link + target is lost with no confirmation. + validations: + required: true + + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce + description: >- + Exact commands, starting from a fresh shell, that someone else can + paste and run. Include any setup needed to reach the broken state. + render: fish + placeholder: | + exec fish + mkdir -p /tmp/repro; cd /tmp/repro + touch real; ln -s real link + mv real link + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What you thought those commands would do. + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual behavior + description: >- + What happened instead. Paste the complete output, including any error + text and stack traces — truncated errors are the usual reason a bug + report stalls in Status/Need More Info. + render: text + validations: + required: true + + - type: checkboxes + id: preflight + attributes: + label: Pre-flight + options: + - label: I searched the existing issues and this isn't already reported. + required: true + - label: I reproduced this in a fresh shell (`exec fish`), not a long-lived session. + required: true + - label: I ran `fish tests/run-tests.fish` and noted the result below (or in the output above). + required: false + + - type: textarea + id: context + attributes: + label: Additional context + description: >- + Anything else worth knowing: a private overlay in + `~/.config/.user-dots/fish/` that may be involved, opinionated + components you've disabled, the last commit where it worked. Never + paste credentials, tokens, or machine-specific paths you'd rather not + publish. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..c041d6e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,21 @@ +# Read by both Gitea (the canonical repo) and GitHub (the mirror). +# +# The .yml extension is required: Gitea accepts config.yaml or config.yml, +# but GitHub only recognizes config.yml and silently ignores config.yaml. +# Don't "tidy" this back to .yaml — the chooser on the mirror stops working. +# +# Blank issues stay enabled deliberately: the three templates cover bugs, +# features, and docs, and anything else (a chore, a refactor, a question) +# is better served by an empty box than by a template that doesn't fit. +blank_issues_enabled: true + +contact_links: + - name: Canonical repository and issue tracker + url: https://git.rootiest.dev/rootiest/fish-config/issues + about: fish-config is developed on Gitea. If you came from the GitHub mirror, please file here instead — the mirror is read-only and issues opened there are easy to miss. + - name: Contributing guide + url: https://git.rootiest.dev/rootiest/fish-config/src/branch/main/CONTRIBUTING.md + about: Branch naming, commit conventions, coding standards, and the label taxonomy. + - name: Customization and personal overrides + url: https://git.rootiest.dev/rootiest/fish-config/src/branch/main/docs/manual/07-customization.md + about: Want to change behavior on just your machine? Use your private overlay — no issue needed. diff --git a/.github/ISSUE_TEMPLATE/docs.md b/.github/ISSUE_TEMPLATE/docs.md new file mode 100644 index 0000000..e121953 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/docs.md @@ -0,0 +1,80 @@ +--- +name: Documentation issue +about: Something in the manual, man page, config-help, or docs site is wrong, missing, or unclear +labels: + - Kind/Documentation +--- + + + +## Location + + + +## Problem + + + +## Suggested fix + + + +## Notes + + diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 0000000..7fe99ae --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,111 @@ +--- +name: Feature or enhancement request +about: Propose new functionality, or an improvement to something that already exists +labels: + - Kind/Feature +--- + + + +## Summary + + + +## Problem + + + +## Proposed behavior + + + +## Alternatives considered + + + +## Scope + + + +## Acceptance criteria + + + +- [ ] +- [ ] + +## Notes + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e36ddea..7dd34fa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,9 @@ treat it as a living document, not a final word. ## Table of Contents - [Getting Started](#getting-started) +- [Issues](#issues) - [Branching & Pull Requests](#branching--pull-requests) +- [Labels](#labels) - [Commit Conventions](#commit-conventions) - [Fish Coding Standards](#fish-coding-standards) - [Opinionated Components](#opinionated-components) @@ -34,6 +36,79 @@ If you're touching anything under `docs/manual/`, you'll also want `pandoc`, (see [Documentation Pipeline](#documentation-pipeline)) — otherwise CI will catch problems on push. +## Issues + +Issues live on the Gitea repo. Three templates cover the common cases, each +pre-applying its `Kind/` label; blank issues stay enabled for everything else +— a chore, a refactor, a question, a tracking issue. + +| Template | Format | Use it for | Applies | +|---|---|---|---| +| **Bug report** | web form | Something is broken or behaves unexpectedly | `Kind/Bug` | +| **Feature or enhancement request** | markdown | New functionality, or an improvement to what exists | `Kind/Feature` | +| **Documentation issue** | markdown | The manual, man page, `config-help`, or docs site is wrong, missing, or unclear | `Kind/Documentation` | + +They live in `.github/ISSUE_TEMPLATE/`, next to the PR template, so the +GitHub mirror offers the same set. The bug report is a Gitea *issue form* — +a real web form with required fields — because a bug report missing its +version, reproduction, or full error text can't be acted on, and a form +refuses to submit without them. The other two are markdown templates in the +same comment-guided style as `.github/PULL_REQUEST_TEMPLATE.md`, since what +they ask for is open-ended prose that structure would only get in the way of. + +GitHub reads these same files on the mirror, and its schema differs from +Gitea's in two places, so both are pinned to the spelling that works on both +and each file says so in a comment: the chooser config must be `config.yml` +(GitHub ignores `config.yaml`), and `bug.yml` declares `description:` rather +than `about:` (GitHub requires it; Gitea accepts it as an alias). The two +markdown templates keep `about:`, which is correct for their format on both. + +### Issue titles + +**Issue titles are plain descriptions of the problem, not Conventional +Commits subjects.** + +```text +mv clobbers a symlink when the target exists ← yes +fix(mv): prompt before replacing an existing symlink ← no +``` + +An issue states a problem; a commit states a change. The type and scope that +`fix(mv):` would carry are already on the issue as its `Kind/` and `Area/` +labels, and the conventional subject belongs on the PR that closes it, where +it becomes the commit message. Writing the fix into the title also presumes +one, which is the wrong end to start from for anything still being diagnosed. + +### What an issue owes + +- **A bug** needs a reproduction someone else can paste and run, starting + from a fresh shell, plus the complete error output. A stale function + definition in a long-lived session is the most common false alarm, so + confirm it survives `exec fish` first. `Status/Need More Info` is where + reports without a reproduction end up. +- **A feature** needs `## Acceptance criteria` — the checkbox list of what + must be true for the issue to close. It is the issue-side counterpart to a + PR's `## Verification`: a definition of done agreed before the work starts + rather than argued about after, and the PR's checks usually grow out of it. +- **A docs issue** needs to name the `docs/manual/**` source, not just the + page where the problem showed up. `docs/fish-config.md` and + `docs/fish-config.1` are generated, and a fix applied there is overwritten + by the next CI run — see [Documentation + Pipeline](#documentation-pipeline). + +### Triage + +Reporters aren't expected to label anything. Contributors without push access +can't, and the templates apply the `Kind/` label by themselves; the rest is +the maintainer's job when the issue is triaged — add the `Area/` label (the +bug form's **Area** dropdown is how a reporter tells you, since no forge can +map a form field to a label), set a `Priority/` if it isn't ordinary, and +apply `Reviewed/Confirmed` once a bug actually reproduces. See +[Labels](#labels). + +When a PR resolves an issue it closes it with a trailing `Closes #N` line — +see [Pull request descriptions](#pull-request-descriptions). + ## Branching & Pull Requests **If you don't have push access to this repo**, fork it and open your PR @@ -48,6 +123,9 @@ assumes you *do* have push access (maintainers, regular contributors). branching doesn't touch the working tree.) - **Merge target is `main`, via PR.** Contributors open the PR; the repo owner merges it. Don't merge your own PR. +- **Label every PR.** At minimum one `Kind/` and one `Area/`, same as an + issue — see [Labels](#labels). If you can't set labels, say what the + change is in the description and a maintainer applies them. - **Don't merge until the `## Verification` checklist is fully checked.** Unchecked boxes are outstanding manual checks, not decoration. See [Pull request descriptions](#pull-request-descriptions) below. @@ -112,6 +190,128 @@ bare `#43` is only a link and won't close anything. To point at a related issue that should stay open, drop the keyword and use `Refs #42`. Leave the line out entirely when no issue is involved. +## Labels + +**Every issue and every pull request carries exactly one `Kind/` label and at +least one `Area/` label.** Everything else is optional, and most of it is +applied by a maintainer at triage rather than by whoever opened the thing. + +Labels are scoped: the `Group/Name` form renders as a two-tone chip in Gitea, +and for the three *exclusive* groups below Gitea enforces one-at-a-time by +swapping the old label out when you apply a new one. + +### `Kind/` — what this is + +Required, and by convention exactly one. Gitea doesn't enforce one-of here, +so pick the dominant character of the change instead of stacking two. + +| Label | For | +|---|---| +| `Kind/Bug` | Something is not working | +| `Kind/Feature` | New functionality | +| `Kind/Enhancement` | Improves functionality that already exists | +| `Kind/Documentation` | Documentation changes | +| `Kind/Testing` | The test suite itself | +| `Kind/Refactor` | Restructures code without changing behavior | +| `Kind/Chore` | Tooling, dependencies, housekeeping | +| `Kind/Performance` | Makes existing behavior faster or lighter | +| `Kind/Security` | A security issue | + +These deliberately mirror the Conventional Commits types in [Commit +Conventions](#commit-conventions), so a PR's label and its title agree: +`fix` → `Kind/Bug`, `feat` → `Kind/Feature` or `Kind/Enhancement`, `docs` → +`Kind/Documentation`, `test` → `Kind/Testing`, `refactor` → +`Kind/Refactor`, `chore` → `Kind/Chore`, `perf` → `Kind/Performance`. + +### `Area/` — what it touches + +Required, and non-exclusive on purpose: a change that adds a function, its +completions, and a manual entry gets all three. + +| Label | Covers | +|---|---| +| `Area/Functions` | `functions/` | +| `Area/Completions` | `completions/` | +| `Area/Config` | `config.fish`, `conf.d/` — startup and environment | +| `Area/Docs` | `docs/manual/` and the generated manual, man page, and site | +| `Area/Tests` | `tests/` | +| `Area/CI` | `.github/workflows/` and repository automation | +| `Area/Integrations` | `integrations/` | +| `Area/Prompt & Theme` | `themes/` and prompt appearance | +| `Area/Components` | The opinionated-component system (C1-C6) | +| `Area/Scripts` | `scripts/` | + +`Area/` is what makes the tracker searchable: it answers "what's still +outstanding in the docs pipeline?" in a way `Kind/` never can. Two edges +worth naming — `Area/Docs` covers the documentation *and its pipeline*, so +`README.md` and this file count even though they sit outside `docs/`; and +`Area/Components` is for the C1-C6 machinery itself, not for every function +that happens to carry a `# COMPONENT` header. + +### `Compat/Breaking` + +Applied to **any PR whose title carries `!` before the colon**, and to any +issue proposing a change that would. It travels with the `## ⚠️ Breaking +Change` section that such a PR must already include — see [Pull request +descriptions](#pull-request-descriptions). + +### `Priority/` — exclusive, maintainer-applied + +`Priority/Critical`, `Priority/High`, `Priority/Medium`, `Priority/Low`. + +**No priority label means ordinary priority.** Labeling everything defeats +the point, so leave it off unless the item is genuinely more or less urgent +than the rest of the queue. + +### `Reviewed/` — exclusive, maintainer-applied + +`Reviewed/Confirmed` goes on a bug that has actually been reproduced — +that's the signal separating a report from a known defect. +`Reviewed/Duplicate`, `Reviewed/Invalid`, and `Reviewed/Won't Fix` accompany +closing an issue, always with a comment saying why; a close with only a +label on it is not an explanation. + +### `Status/` — exclusive, maintainer-applied + +`Status/Blocked`, `Status/Need More Info`, `Status/Abandoned`. These describe +the item's current state, so remove one as soon as it stops being true — a +stale `Status/Need More Info` on an issue that got its answer is worse than +no label, because it reads as still waiting. + +### `good first issue` and `help wanted` + +Invitations to contributors, applied by a maintainer. Both are deliberately +**unscoped**: they'd be a natural fit under `Status/`, but that group is +exclusive, and an issue is quite often both blocked on something *and* open +for someone to pick up. Keeping them outside the group lets them coexist +with a real status. + +Use `good first issue` for work that is genuinely self-contained — a clear +acceptance criterion, one or two files, no need to understand the +opinionated-component system first. + +### The GitHub mirror + +The repo is mirrored to +[github.com/rootiest/fish-config](https://github.com/rootiest/fish-config), +and **the mirror carries the same labels, by the same names**. That isn't +cosmetic: GitHub reads the same `.github/ISSUE_TEMPLATE/` files, and a +`labels:` entry naming a label that doesn't exist on that side is silently +dropped rather than reported. Mirroring copies files, not repository +settings, so **a label added here must be created on the mirror too** — no +automation does it for you. + +One behavioral difference to keep in mind: **GitHub has no exclusive +labels.** Gitea enforces one-at-a-time on `Priority/`, `Reviewed/`, and +`Status/` by swapping the old label out; on the mirror those are ordinary +labels and nothing stops two of a group coexisting, so there the one-of rule +holds by convention alone. + +Issues and pull requests belong on the canonical Gitea repo — the template +chooser links there first, on both sides. The mirror's tracker stays open so +that a report which lands there anyway isn't lost, not because it's a second +supported front door. + ## Commit Conventions Commit subjects follow [Conventional Commits](https://www.conventionalcommits.org/):