feat(issue): add yt issue create #22
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/issue-create"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds
yt issue createas a new subcommand underissue. Creates an issue from the command line with the project's YouTrack short name (theABCprefix inABC-123).Two-step API flow under the hood:
GET /api/admin/projects?fields=id,shortNameto resolve the short name to the project's internal id (required by the create body).POST /api/issues?fields=idReadable,summary,customFields(...)with{project:{id}, summary, description?, customFields?}.--typeturns into aSingleEnumIssueCustomFieldbody element,--assigneeinto aSingleUserIssueCustomFieldwith{value:{login}}. The fields= selector matchesissue inspect, so the response decodes straight into the existingIssuemodel and we can render it immediately.Validation: empty/whitespace summary and empty project short name are rejected client-side before any HTTP call. Other validation is left to the server (unknown type values come back as a 400 with a useful body, which the existing
ClientError::Statusformatting surfaces).New surface
yt::models::Project(id + shortName).yt::api::{list_projects, resolve_project_id, create_issue, CreateIssueRequest}.Client::post_jsonreintroduced (was dropped earlier when no mutation needed a JSON response; now needed).IssueCommands::Create(IssueCreateArgs)incli.rsplus dispatch incommands/issue/mod.rspluscommands/issue/create.rs.Output
Created <ID>: <summary>once the POST succeeds.--json: pretty-printedIssueJSON (idReadable + summary + customFields), suitable for piping to jq.Verification
cargo fmt --checkclean.cargo clippy --all-targets -- -D warningsclean.cargo test --all-targets: 175 tests pass (15 new on this branch).yt issue create --helpshows the flag surface (--project,--summary,--description,--type,--assignee,--json).Coverage: project list decode, project-id resolution (found + not-found), client-side validation (empty summary, empty project), minimal POST body, body with description, body with type + assignee custom fields, JSON output mode, missing-credentials guard, server error propagation. Plus
Client::post_jsongets decode + non-2xx wiremock tests of its own.Out of scope
--stateand--priorityon create. State is normally auto-set to the project's initial state at creation time, and priority defaults too. They can be set after creation withyt issue set-state(state) or via a follow-upissue updatefor priority. Easy to add to create if you want.issue updatesubcommand for the full field-edit surface. Not needed for "create".Test plan
yt issue create --project <SHORT> --summary "smoke test"returnsCreated <SHORT>-N: smoke testand the issue is visible in the YouTrack UI.yt issue create --project <SHORT> --summary x --type Bug --assignee <you>lands with the right Type + Assignee on the issue.yt issue create --project NOPE --summary xexits non-zero withproject 'NOPE' not found.yt issue create --project <SHORT> --summary ""exits non-zero with a clear "summary required" message before any HTTP call.yt issue create --project <SHORT> --summary x --json | jq .idreturns<SHORT>-N.yt issue createNew subcommand that creates an issue from the command line. ``` yt issue create --project ABC --summary "fix crash" [--description ...] [--type Bug] [--assignee jdoe] [--json] ``` The project is referenced by its YouTrack short name (the prefix that appears in issue ids like ABC-123). Under the hood the helper calls `GET /api/admin/projects?fields=id,shortName` to resolve the short name to the project's internal id, then `POST /api/issues?fields=idReadable,summary,customFields(...)` with `{project:{id}, summary, description?, customFields?}`. The fields= selector on the response matches what `issue inspect` uses, so the returned `Issue` is ready to render. `--type` becomes a `SingleEnumIssueCustomField` body element, `--assignee` becomes a `SingleUserIssueCustomField` with `{value:{login}}`. Empty/whitespace summaries and empty project short names are rejected client-side before any HTTP call; other validation is left to the server (e.g. unknown type values come back as a 400 with a useful message). New surface: - `yt::models::Project` (id + shortName). - `yt::api::{list_projects, resolve_project_id, create_issue, CreateIssueRequest}`. - `Client::post_json` (reintroduced; was dropped when no mutation needed a JSON response, now needed again). - `IssueCommands::Create(IssueCreateArgs)` + dispatch in `commands/issue/mod.rs` + `commands/issue/create.rs`. Output: - Non-json: `Created <ID>: <summary>` once the POST succeeds. - `--json`: pretty-printed `Issue` JSON (idReadable + summary + customFields), suitable for piping to jq. Tests cover: project listing decode, project-id resolution (found + not-found), client-side validation (empty summary, empty project), minimal POST body, body with description, body with type + assignee custom fields, JSON output mode, missing-credentials guard, server error propagation. Plus the reintroduced `Client::post_json` gets its own pair of decode + non-2xx wiremock tests. 175 tests pass (15 new); clippy clean; fmt clean.