basic BMAD setup
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# Store starter: GitHub Issues. `scripts/read_store.py` reads this file as the base layer; the project's
|
||||
# _bmad/custom/ticketing-store-config.toml names the store, fills the empty fields below, and replaces
|
||||
# any other key here, key by key.
|
||||
# It updates with the skill and holds only what is specific to this store: the rules every store shares
|
||||
# are in references/board.md. Comments and `description` are never loaded; `description` is for choosing a store.
|
||||
#
|
||||
# One tool: the gh CLI, 2.94 or later (sub-issues and dependencies). Labels carry type and status,
|
||||
# sub-issues carry hierarchy, blocked-by relations carry blocking, milestones put initiatives on the roadmap.
|
||||
# Using the defaults below: the repo needs the type, status, and hitl labels; `setup` creates them.
|
||||
|
||||
description = "GitHub Issues through the gh CLI: labels, sub-issues, blocked-by, milestones. For teams whose code and planning already live on GitHub."
|
||||
|
||||
[tickets]
|
||||
store = "github"
|
||||
key = "" # ids are the repo's issue numbers; leave empty
|
||||
repo = "" # OWNER/REPO; empty = the repo of the current checkout (origin)
|
||||
access = """
|
||||
Use the gh CLI against `repo`, passing `-R <repo>` on every call when it is set. Needs gh 2.94+; check `--help` when a flag is doubted.
|
||||
"""
|
||||
|
||||
fields = """
|
||||
risk is a label risk:<value>; severity is a label P0-P3. `setup` creates them with the other
|
||||
labels; publish and update set them like any label. estimate is a label est:<value> (`setup` creates none; add on first use). Empty field: no label.
|
||||
"""
|
||||
|
||||
reference = """
|
||||
GitHub renders urls as links; nothing more to do.
|
||||
"""
|
||||
|
||||
[verbs]
|
||||
setup = """
|
||||
Connect, unless `gh auth status` already shows a login: `gh auth login`.
|
||||
Labels must exist before they are used. List the repo's labels (`gh label list --limit 1000 --json name`)
|
||||
and run `gh label create <name>` for each of these it lacks, comparing names ignoring case: the
|
||||
[tickets.types] values except initiative (a milestone), the [tickets.status] values except done and
|
||||
dropped (closed states), `hitl`, risk:low, risk:medium, risk:high, and P0-P3. A create that fails with
|
||||
"already exists" found the label after all: leave it. Never `--force`: it recolours a label the repo
|
||||
already has.
|
||||
"""
|
||||
|
||||
write = """
|
||||
One issue per new ticket. tracker_id is the issue number and remote its url.
|
||||
Create with content only: `gh issue create --title <t> --body-file <b> --label <type>,<[tickets.status].<state>>[,hitl,risk:<r>,P<n>]
|
||||
[--milestone <initiative>]`, and mirror tracker_id and remote from the url it prints before anything else. Then add the
|
||||
relations with `gh issue edit <n> --parent <n> --add-blocked-by <n,n>`, leaving out any that `gh issue view <n> --json
|
||||
parent,blockedBy` already shows, since adding one twice fails. Keep --parent and --blocked-by off the create: gh adds them
|
||||
after the issue exists, and when that step fails it exits non-zero without printing the url, so a rerun files the ticket
|
||||
twice. A create that fails with no url may still have made the issue: before creating again, list the newest issues
|
||||
(`gh issue list --state all --limit 100 --json number,title,body,createdAt`) twice, a few seconds apart since the list can
|
||||
trail a create, and take the one whose title and body are what was sent. None matches and the list does not reach back to
|
||||
the failed create: ask before creating again. Changes go through `gh issue edit <n>` (--body-file, --add-assignee,
|
||||
--add-blocked-by, label swaps; --add-sub-issue on the parent). No parent: omit --parent; no initiative: omit --milestone.
|
||||
Status is a label swap on an open issue. done: remove the status label and `gh issue close <n>`;
|
||||
dropped: the same with `--reason "not planned"`. An initiative is a
|
||||
milestone (`gh api repos/{owner}/{repo}/milestones -f title=<name>`) holding its tree's issues.
|
||||
"""
|
||||
|
||||
query = """
|
||||
One issue: `gh issue view <n> --json
|
||||
number,title,labels,assignees,state,stateReason,milestone,parent,blockedBy,subIssuesSummary,body`.
|
||||
Type, hitl, risk, severity, and status are labels — except done and dropped, the closed states per
|
||||
[tickets.status]; after is blockedBy; the body's covers holds the source requirement ids. Children: `gh issue view <n>
|
||||
--json subIssues`. Words: `gh issue list --search "<words>" --state all`, narrowed by
|
||||
--label. An initiative's issues are the ones in its milestone; a standalone ticket has no milestone.
|
||||
"""
|
||||
|
||||
# BMad type -> this store's type.
|
||||
[tickets.types]
|
||||
initiative = "milestone" # an initiative is a milestone, not an issue; its epics carry it
|
||||
epic = "epic"
|
||||
story = "story"
|
||||
spike = "spike"
|
||||
bug = "bug"
|
||||
|
||||
# BMad state -> this store's status.
|
||||
[tickets.status]
|
||||
backlog = "backlog"
|
||||
in-progress = "in-progress"
|
||||
review = "review"
|
||||
done = "closed" # state, not a label
|
||||
dropped = "closed: not planned" # state, not a label
|
||||
Reference in New Issue
Block a user