From c7d3ac7470888fc2607654e0006a204cf9feea7b Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah Date: Thu, 9 Jul 2026 12:18:52 -0700 Subject: [PATCH] Add GitHub issue readiness check --- .ai-context/COMMANDS.md | 4 + CHANGELOG.md | 3 + cli/bash/commands/basectl/subcommands/gh.sh | 229 +++++++++++++++++- .../commands/basectl/tests/completions.bats | 12 +- cli/bash/commands/basectl/tests/gh.bats | 152 ++++++++++++ docs/command-reference.md | 1 + docs/github-workflow.md | 14 ++ lib/shell/completions/basectl_completion.sh | 4 +- lib/shell/completions/basectl_completion.zsh | 3 +- lib/shell/completions/tests/completions.bats | 2 + 10 files changed, 420 insertions(+), 4 deletions(-) diff --git a/.ai-context/COMMANDS.md b/.ai-context/COMMANDS.md index 4c1dc4aa..c1007fda 100644 --- a/.ai-context/COMMANDS.md +++ b/.ai-context/COMMANDS.md @@ -81,6 +81,10 @@ options. repo-local default. Pass `--no-assignee` to ignore that default for one issue. Pass `--size ` when the issue scope is clear; otherwise Project metadata defaults to `Size=S`. + - `basectl gh issue readiness ` checks required implementation issue + body sections and reports labels and assignees. Pass `--project-owner` and + `--project-number` with `--repo` to validate Base Project fields; without + Project coordinates it reports a partial result. - `basectl gh pr create` auto-injects `Fixes #` from Base branch names; pass `--no-fixes` to suppress that body injection. When `base_manifest.yaml` declares `github.pr`, it renders the PR body from diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d5ba935..a5f81dcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,9 @@ and Base versions are tracked in the repo-root `VERSION` file. alongside the standard repo baseline. - Added `basectl repo check --agent-ready` to verify the agent-ready repo guidance contract without changing default baseline checks. +- Added `basectl gh issue readiness` to check issue body sections, labels, + assignees, and optional GitHub Project fields before assigning agentic + implementation work. ### Changed diff --git a/cli/bash/commands/basectl/subcommands/gh.sh b/cli/bash/commands/basectl/subcommands/gh.sh index 33cdca4a..18777e00 100644 --- a/cli/bash/commands/basectl/subcommands/gh.sh +++ b/cli/bash/commands/basectl/subcommands/gh.sh @@ -14,6 +14,7 @@ base_gh_usage() { Usage: basectl gh issue list [gh options...] basectl gh issue create [--category ] --title [--body <body>] [--repo <owner/name>] [--assignee <login>|--no-assignee] [--size <T|S|M|L>] [project options...] + basectl gh issue readiness <number> [--repo <owner/name>] [--project-owner <login> --project-number <number>] basectl gh issue start <number> [--category <bug|enhancement|documentation|ci|security>] [--title <title>] basectl gh pr create [--no-fixes] [gh options...] basectl gh pr status [gh options...] @@ -67,10 +68,11 @@ base_gh_issue_usage() { Usage: basectl gh issue list [gh options...] basectl gh issue create [--category <bug|enhancement|documentation|ci|security>] --title <title> [--body <body>] [--repo <owner/name>] [--assignee <login>|--no-assignee] [--size <T|S|M|L>] [project options...] + basectl gh issue readiness <number> [--repo <owner/name>] [--project-owner <login> --project-number <number>] basectl gh issue start <number> [--category <bug|enhancement|documentation|ci|security>] [--title <title>] Purpose: - List, create, and start GitHub issues using Base's issue-first workflow. + List, create, validate, and start GitHub issues using Base's issue-first workflow. Branch naming: <category>/<issue>-<YYYYMMDD>-<slug> @@ -85,6 +87,11 @@ Issue create project options: --size <T|S|M|L> Project Size value. Defaults to .github/base-project.yml or S. --no-project Skip Project metadata updates. +Issue readiness options: + --repo <owner/name> Repository containing the issue. Defaults to the origin remote. + --project-owner <login> Project owner for Project field validation. + --project-number <number> Project number for Project field validation. + Default category: enhancement. Default assignee: none unless project.issue_defaults.assignee is set in .github/base-project.yml. Categories: bug, enhancement, documentation, ci, security. @@ -348,6 +355,223 @@ base_gh_issue_labels() { gh issue view "$issue" --json labels --jq '.labels[].name' 2>/dev/null || true } +base_gh_issue_readiness_required_sections() { + printf '%s\n' \ + "Goal" \ + "Background" \ + "Scope" \ + "Acceptance Criteria" \ + "Validation" \ + "Non-Goals" \ + "Project Fields" \ + "Agent Assignment" +} + +base_gh_issue_readiness_required_project_fields() { + printf '%s\n' Status Priority Size Area Initiative +} + +base_gh_issue_readiness_has_section() { + local section="$1" + + awk -v section="$section" ' + /^##[[:space:]]+/ { + heading = $0 + sub(/^##[[:space:]]+/, "", heading) + sub(/[[:space:]]+$/, "", heading) + in_section = (heading == section) + next + } + in_section && $0 !~ /^[[:space:]]*$/ { + found = 1 + } + END { + exit(found ? 0 : 1) + } + ' +} + +base_gh_lines_to_csv() { + local line + local values=() + + while IFS= read -r line || [[ -n "$line" ]]; do + [[ -n "$line" ]] && values+=("$line") + done + + if ((${#values[@]})); then + base_gh_join_csv "${values[@]}" + else + printf 'none\n' + fi +} + +base_gh_jq_string_literal() { + local value="$1" + + value="${value//\\/\\\\}" + value="${value//\"/\\\"}" + printf '"%s"\n' "$value" +} + +base_gh_issue_readiness_project_row() { + local issue="$1" repo="$2" project_owner="$3" project_number="$4" + local repo_literal query + + repo_literal="$(base_gh_jq_string_literal "$repo")" + query=".items[] | select((.content.number == $issue) and (.content.repository == $repo_literal)) | [.status // \"\", .priority // \"\", .size // \"\", .area // \"\", .initiative // \"\"] | join(\"\u001f\")" + base_gh_run project item-list "$project_number" --owner "$project_owner" --format json --limit 1000 --jq "$query" +} + +base_gh_issue_readiness() { + local issue="${1:-}" + local assignees_output="" assignees_summary="" + local body="" labels_output="" labels_summary="" + local github_repo="" + local issue_ready_state="ready" + local project_number="" project_owner="" + local project_row="" project_status="" project_priority="" project_size="" project_area="" project_initiative="" + local project_validation_requested=0 + local section field + local missing_project_fields=() + local missing_sections=() + + [[ -n "$issue" ]] || { + base_gh_usage_error base_gh_issue_usage "Missing issue number." + return $? + } + if [[ "$issue" == "help" || "$issue" == "-h" || "$issue" == "--help" ]]; then + base_gh_issue_usage + return 0 + fi + [[ "$issue" =~ ^[0-9]+$ ]] || { + base_gh_usage_error base_gh_issue_usage "Invalid issue number '$issue'." + return $? + } + shift + + while (($#)); do + case "$1" in + --repo) + github_repo="${2:-}" + [[ -n "$github_repo" ]] || { + base_gh_usage_error base_gh_issue_usage "Option '--repo' requires an argument." + return $? + } + shift + ;; + --project-owner) + project_owner="${2:-}" + [[ -n "$project_owner" ]] || { + base_gh_usage_error base_gh_issue_usage "Option '--project-owner' requires an argument." + return $? + } + project_validation_requested=1 + shift + ;; + --project-number) + project_number="${2:-}" + [[ -n "$project_number" ]] || { + base_gh_usage_error base_gh_issue_usage "Option '--project-number' requires an argument." + return $? + } + [[ "$project_number" =~ ^[0-9]+$ ]] || { + base_gh_usage_error base_gh_issue_usage "Invalid project number '$project_number'." + return $? + } + project_validation_requested=1 + shift + ;; + -h|--help) + base_gh_issue_usage + return 0 + ;; + *) + base_gh_usage_error base_gh_issue_usage "Unknown option '$1'." + return $? + ;; + esac + shift + done + + if ((project_validation_requested)) && { [[ -z "$project_owner" ]] || [[ -z "$project_number" ]]; }; then + base_gh_usage_error base_gh_issue_usage "Options '--project-owner' and '--project-number' must be used together." + return $? + fi + + [[ -n "$github_repo" ]] || github_repo="$(base_gh_infer_github_repo || true)" + [[ -n "$github_repo" ]] || { + base_gh_usage_error base_gh_issue_usage "Unable to infer GitHub repository. Pass --repo <owner/name>." + return $? + } + + body="$(base_gh_run issue view "$issue" --repo "$github_repo" --json body --jq .body)" || return $? + labels_output="$(base_gh_run issue view "$issue" --repo "$github_repo" --json labels --jq '.labels[].name')" || return $? + assignees_output="$(base_gh_run issue view "$issue" --repo "$github_repo" --json assignees --jq '.assignees[].login')" || return $? + + while IFS= read -r section || [[ -n "$section" ]]; do + [[ -n "$section" ]] || continue + if ! base_gh_issue_readiness_has_section "$section" <<<"$body"; then + missing_sections+=("$section") + fi + done < <(base_gh_issue_readiness_required_sections) + + if ((project_validation_requested)); then + project_row="$(base_gh_issue_readiness_project_row "$issue" "$github_repo" "$project_owner" "$project_number")" || return $? + if [[ -z "$project_row" ]]; then + missing_project_fields=("Project item") + while IFS= read -r field || [[ -n "$field" ]]; do + [[ -n "$field" ]] && missing_project_fields+=("$field") + done < <(base_gh_issue_readiness_required_project_fields) + else + IFS=$'\037' read -r project_status project_priority project_size project_area project_initiative <<<"$project_row" + [[ -n "$project_status" ]] || missing_project_fields+=("Status") + [[ -n "$project_priority" ]] || missing_project_fields+=("Priority") + [[ -n "$project_size" ]] || missing_project_fields+=("Size") + [[ -n "$project_area" ]] || missing_project_fields+=("Area") + [[ -n "$project_initiative" ]] || missing_project_fields+=("Initiative") + fi + fi + + labels_summary="$(base_gh_lines_to_csv <<<"$labels_output")" + assignees_summary="$(base_gh_lines_to_csv <<<"$assignees_output")" + + if ((${#missing_sections[@]} || ${#missing_project_fields[@]})); then + issue_ready_state="not ready" + elif ((!project_validation_requested)); then + issue_ready_state="partial" + fi + + printf 'Issue #%s readiness: %s\n' "$issue" "$issue_ready_state" + printf 'Repository: %s\n' "$github_repo" + if ((${#missing_sections[@]})); then + printf 'Body sections: missing %s\n' "$(base_gh_join_csv "${missing_sections[@]}")" + else + printf 'Body sections: ok\n' + fi + if ((project_validation_requested)); then + if ((${#missing_project_fields[@]})); then + printf 'Project fields: missing %s\n' "$(base_gh_join_csv "${missing_project_fields[@]}")" + else + printf 'Project fields: ok\n' + fi + else + printf 'Project fields: skipped\n' + printf 'Pass --project-owner and --project-number to validate Project fields.\n' + fi + printf 'Labels: %s\n' "$labels_summary" + printf 'Assignees: %s\n' "$assignees_summary" + + if ((${#missing_sections[@]})); then + printf 'Fix hint: add non-empty ## sections for the missing issue context.\n' + fi + if ((${#missing_project_fields[@]})); then + printf 'Fix hint: set missing Project fields before assigning implementation work.\n' + fi + + [[ "$issue_ready_state" == "ready" ]] +} + base_gh_pr_changed_paths() { local default_branch base_ref candidate @@ -585,6 +809,9 @@ base_gh_do_issue() { create) base_gh_issue_create "$@" ;; + readiness) + base_gh_issue_readiness "$@" + ;; start) base_gh_issue_start "$@" ;; diff --git a/cli/bash/commands/basectl/tests/completions.bats b/cli/bash/commands/basectl/tests/completions.bats index 2acc5142..0af30ead 100644 --- a/cli/bash/commands/basectl/tests/completions.bats +++ b/cli/bash/commands/basectl/tests/completions.bats @@ -335,7 +335,15 @@ EOF COMP_WORDS=(basectl gh issue create --); \ COMP_CWORD=4; \ _base_basectl_completion; \ - printf "reply=%s\n" "${COMPREPLY[*]}"' + printf "create_reply=%s\n" "${COMPREPLY[*]}"; \ + COMP_WORDS=(basectl gh issue ""); \ + COMP_CWORD=3; \ + _base_basectl_completion; \ + printf "issue_commands=%s\n" "${COMPREPLY[*]}"; \ + COMP_WORDS=(basectl gh issue readiness 123 --); \ + COMP_CWORD=5; \ + _base_basectl_completion; \ + printf "readiness_reply=%s\n" "${COMPREPLY[*]}"' [ "$status" -eq 0 ] [[ "$output" == *"--category"* ]] @@ -344,6 +352,8 @@ EOF [[ "$output" == *"--assignee"* ]] [[ "$output" == *"--no-assignee"* ]] [[ "$output" == *"--size"* ]] + [[ "$output" == *"issue_commands=list create start readiness"* ]] + [[ "$output" == *"readiness_reply=--repo --project-owner --project-number"* ]] [[ "$output" != *"--type"* ]] } diff --git a/cli/bash/commands/basectl/tests/gh.bats b/cli/bash/commands/basectl/tests/gh.bats index 981b64d2..5ceefe34 100644 --- a/cli/bash/commands/basectl/tests/gh.bats +++ b/cli/bash/commands/basectl/tests/gh.bats @@ -13,6 +13,91 @@ EOF chmod +x "$TEST_MOCKBIN/gh" } +write_issue_readiness_gh_mock() { + cat > "$TEST_MOCKBIN/gh" <<'EOF' +#!/usr/bin/env bash +if [[ "$*" == "auth status -h github.com" ]]; then + exit 0 +fi +printf '%s\n' "$*" >> "${BASE_GH_TEST_STATE_DIR:?}/gh-args" +if [[ "$1" == "issue" && "$2" == "view" ]]; then + if [[ "${BASE_GH_TEST_FAIL_ISSUE_VIEW:-0}" == "1" ]]; then + printf 'GraphQL: Could not resolve to an Issue\n' >&2 + exit 1 + fi + if [[ "$*" == *"--json body --jq .body"* ]]; then + cat "${BASE_GH_TEST_STATE_DIR:?}/issue-body" + exit 0 + fi + if [[ "$*" == *"--json labels --jq .labels[].name"* ]]; then + printf 'enhancement\nagent-ready\n' + exit 0 + fi + if [[ "$*" == *"--json assignees --jq .assignees[].login"* ]]; then + printf 'codeforester\n' + exit 0 + fi +fi +if [[ "$1" == "project" && "$2" == "item-list" ]]; then + case "${BASE_GH_TEST_PROJECT_MODE:-complete}" in + complete) + printf 'Ready\037P2\037M\037CLI\037Agentic Coding Platform\n' + ;; + missing) + printf 'Ready\037P2\037\037CLI\037\n' + ;; + none) + ;; + esac + exit 0 +fi +printf 'unexpected gh args: %s\n' "$*" >&2 +exit 99 +EOF + chmod +x "$TEST_MOCKBIN/gh" +} + +write_complete_issue_readiness_body() { + cat > "$TEST_STATE_DIR/issue-body" <<'EOF' +## Goal +Make agent assignment deterministic. + +## Background +Base needs issue context before a coding agent starts. + +## Scope +- Add a read-only readiness check. + +## Acceptance Criteria +- Complete issues report ready. + +## Validation +- Run focused BATS coverage. + +## Non-Goals +- Do not assign issues. + +## Project Fields +- Priority, Status, Size, Area, Initiative are required. + +## Agent Assignment +- Assign to codeforester after readiness passes. +EOF +} + +write_incomplete_issue_readiness_body() { + cat > "$TEST_STATE_DIR/issue-body" <<'EOF' +## Goal +Make agent assignment deterministic. + +## Background +Base needs issue context before a coding agent starts. + +## Scope +- Add a read-only readiness check. +EOF +} + run_gh_subcommand() { local cwd="${BASE_GH_TEST_CWD:-$TEST_HOME}" @@ -118,6 +203,7 @@ run_gh_subcommand() { [ "$status" -eq 0 ] [[ "$output" == *"basectl gh issue list"* ]] [[ "$output" == *"basectl gh issue create"* ]] + [[ "$output" == *"basectl gh issue readiness <number>"* ]] [[ "$output" == *"basectl gh issue start <number>"* ]] [[ "$output" == *"Issue create project options:"* ]] [[ "$output" == *"--assignee <login>"* ]] @@ -130,6 +216,72 @@ run_gh_subcommand() { [[ "$output" != *"basectl gh worktree prune"* ]] } +@test "basectl gh issue readiness reports ready when body and Project metadata are complete" { + write_issue_readiness_gh_mock + write_complete_issue_readiness_body + + run_gh_subcommand issue readiness 123 --repo basefoundry/base --project-owner basefoundry --project-number 10 + + [ "$status" -eq 0 ] + [[ "$output" == *"Issue #123 readiness: ready"* ]] + [[ "$output" == *"Repository: basefoundry/base"* ]] + [[ "$output" == *"Body sections: ok"* ]] + [[ "$output" == *"Project fields: ok"* ]] + [[ "$output" == *"Labels: enhancement, agent-ready"* ]] + [[ "$output" == *"Assignees: codeforester"* ]] +} + +@test "basectl gh issue readiness reports partial when Project validation is omitted" { + write_issue_readiness_gh_mock + write_complete_issue_readiness_body + + run_gh_subcommand issue readiness 123 --repo basefoundry/base + + [ "$status" -eq 1 ] + [[ "$output" == *"Issue #123 readiness: partial"* ]] + [[ "$output" == *"Body sections: ok"* ]] + [[ "$output" == *"Project fields: skipped"* ]] + [[ "$output" == *"Pass --project-owner and --project-number to validate Project fields."* ]] + [[ "$(cat "$TEST_STATE_DIR/gh-args")" != *"project item-list"* ]] +} + +@test "basectl gh issue readiness reports missing body sections with fix hints" { + write_issue_readiness_gh_mock + write_incomplete_issue_readiness_body + + run_gh_subcommand issue readiness 123 --repo basefoundry/base --project-owner basefoundry --project-number 10 + + [ "$status" -eq 1 ] + [[ "$output" == *"Issue #123 readiness: not ready"* ]] + [[ "$output" == *"Body sections: missing Acceptance Criteria, Validation, Non-Goals, Project Fields, Agent Assignment"* ]] + [[ "$output" == *"Fix hint: add non-empty ## sections for the missing issue context."* ]] +} + +@test "basectl gh issue readiness reports missing Project metadata" { + write_issue_readiness_gh_mock + write_complete_issue_readiness_body + + BASE_GH_TEST_PROJECT_MODE=missing \ + run_gh_subcommand issue readiness 123 --repo basefoundry/base --project-owner basefoundry --project-number 10 + + [ "$status" -eq 1 ] + [[ "$output" == *"Issue #123 readiness: not ready"* ]] + [[ "$output" == *"Project fields: missing Size, Initiative"* ]] + [[ "$output" == *"Fix hint: set missing Project fields before assigning implementation work."* ]] +} + +@test "basectl gh issue readiness reports GitHub API failures" { + write_issue_readiness_gh_mock + write_complete_issue_readiness_body + + BASE_GH_TEST_FAIL_ISSUE_VIEW=1 \ + run_gh_subcommand issue readiness 123 --repo basefoundry/base + + [ "$status" -eq 1 ] + [[ "$output" == *"GraphQL: Could not resolve to an Issue"* ]] + [[ "$output" == *"GitHub command failed: gh issue view 123 --repo basefoundry/base --json body --jq .body"* ]] +} + @test "basectl gh pr prints area help" { run_basectl gh pr --help diff --git a/docs/command-reference.md b/docs/command-reference.md index 6f3d440a..147ff058 100644 --- a/docs/command-reference.md +++ b/docs/command-reference.md @@ -106,6 +106,7 @@ daily project loop commands from the local checkout. | `basectl repo installer-template [path]` | Write the maintained project installer starter script to a path, defaulting to `./install.sh`, optionally through a draft PR. | `--print`, `--repo <owner/name>`, `--pr`, `--dry-run` | | `basectl gh issue list` | List GitHub issues through `gh`. | passes through `gh` options | | `basectl gh issue create` | Create an issue with Base category conventions, assign it, and add repo Project metadata when the repo is known. Defaults to `--category enhancement` and Project `Size=S` when omitted. | `--category <bug\|enhancement\|documentation\|ci\|security>`, `--title <title>`, `--body <body>`, `--repo <owner/name>`, `--project <title>`, `--project-owner <login>`, `--size <T\|S\|M\|L>`, `--no-project` | +| `basectl gh issue readiness <number>` | Check whether an issue has the required body sections and, when Project coordinates are supplied, Base Project fields before assignment. Omitting Project coordinates reports a partial result. | `--repo <owner/name>`, `--project-owner <login>`, `--project-number <number>` | | `basectl gh issue start <number>` | Start issue-backed branch naming workflow. | `--category <category>`, `--title <title>` | | `basectl gh pr create/status/checks/ready/merge` | Create and manage pull requests through Base's workflow wrapper. `pr create` auto-injects `Fixes #<issue>` from Base branch names unless `--no-fixes` is passed, and uses `github.pr` from `base_manifest.yaml` when present. | passes through `gh` options; `pr create` also accepts `--no-fixes` | | `basectl gh branch stale` | Report stale local branches. | `--days <days>` | diff --git a/docs/github-workflow.md b/docs/github-workflow.md index a502a51d..9903ce19 100644 --- a/docs/github-workflow.md +++ b/docs/github-workflow.md @@ -84,6 +84,20 @@ current primary maintainer. Today that maintainer is `codeforester`, and If assignment fails, the automation should mention that in its summary instead of silently leaving the issue unassigned. +Before assigning issue-backed implementation work to an agent, run: + +```bash +basectl gh issue readiness <number> --repo <owner/name> --project-owner <login> --project-number <number> +``` + +The readiness check is read-only. It verifies that the issue body has non-empty +`Goal`, `Background`, `Scope`, `Acceptance Criteria`, `Validation`, +`Non-Goals`, `Project Fields`, and `Agent Assignment` sections, reports label +and assignee state, and checks `Status`, `Priority`, `Size`, `Area`, and +`Initiative` when Project coordinates are provided. Omitting Project coordinates +reports a partial result so maintainers do not mistake body-only validation for +full assignment readiness. + ## Issue Project Metadata When an issue is tracked in the repo-named Project, use the standard Base diff --git a/lib/shell/completions/basectl_completion.sh b/lib/shell/completions/basectl_completion.sh index e7d687d3..b8a1f766 100644 --- a/lib/shell/completions/basectl_completion.sh +++ b/lib/shell/completions/basectl_completion.sh @@ -311,7 +311,9 @@ _base_basectl_completion() { ;; issue) if ((COMP_CWORD == 3)); then - _base_basectl_completion_compgen "list create start" "$cur" + _base_basectl_completion_compgen "list create start readiness" "$cur" + elif [[ "${COMP_WORDS[3]:-}" == "readiness" ]]; then + _base_basectl_completion_compgen "--repo --project-owner --project-number -h --help" "$cur" else _base_basectl_completion_compgen "--category --title --body --repo --assignee --no-assignee --project --project-owner --size --no-project -h --help" "$cur" fi diff --git a/lib/shell/completions/basectl_completion.zsh b/lib/shell/completions/basectl_completion.zsh index 9a3c2d71..5118c39f 100644 --- a/lib/shell/completions/basectl_completion.zsh +++ b/lib/shell/completions/basectl_completion.zsh @@ -480,7 +480,7 @@ _base_basectl_completion() { case "${words[3]:-}" in issue) _arguments '1:gh area:(issue pr branch worktree project)' \ - '2:issue command:(list create start)' \ + '2:issue command:(list create start readiness)' \ '--category[Issue category]:category:(bug enhancement documentation ci security)' \ '--title[Issue title]:title:' \ '--body[Issue body]:body:' \ @@ -489,6 +489,7 @@ _base_basectl_completion() { '--no-assignee[Do not assign the issue]' \ '--project[GitHub Project title]:title:' \ '--project-owner[GitHub Project owner]:owner:' \ + '--project-number[GitHub Project number]:number:' \ '--size[Project size option]:size:(T S M L)' \ '--no-project[Skip Project metadata updates]' \ '(-h --help)'{-h,--help}'[Show help text]' diff --git a/lib/shell/completions/tests/completions.bats b/lib/shell/completions/tests/completions.bats index f567ff21..0de42070 100644 --- a/lib/shell/completions/tests/completions.bats +++ b/lib/shell/completions/tests/completions.bats @@ -232,11 +232,13 @@ assert_bash_completion_options_match_help() { block="$(zsh_completion_nested_block gh issue)" + [[ "$block" == *"2:issue command:(list create start readiness)"* ]] [[ "$block" == *"--repo"* ]] [[ "$block" == *"--assignee"* ]] [[ "$block" == *"--no-assignee"* ]] [[ "$block" == *"--project"* ]] [[ "$block" == *"--project-owner"* ]] + [[ "$block" == *"--project-number"* ]] [[ "$block" == *"--size"* ]] [[ "$block" == *"--no-project"* ]] }