[#74415] Add JSON work package workflows on noun-first CLI#18
Open
myabc wants to merge 13 commits into
Open
Conversation
Ports the schema dto, customField capture via UnmarshalJSON, and nil-safe link conversion from the pre-noun-first branch onto main. https://community.openproject.org/wp/CLI-12
Inspect payload, summary, and dry-run plan models. Plan IDs are strings to match semantic identifier support. https://community.openproject.org/wp/CLI-12
Schema-driven custom field resolution: label or API-name lookup, writability check, and type coercion for String, Formattable, Integer, Float, Boolean, and Date fields. https://community.openproject.org/wp/CLI-12
Inspect returns a details payload with project, parent, custom fields, and field labels; InspectWithChildren adds direct children via the parent filter. IDs are semantic-identifier strings. https://community.openproject.org/wp/CLI-12
UpdateFields patches resolved custom field assignments with the current lockVersion; DryRunUpdateFields returns the validated plan without writing. https://community.openproject.org/wp/CLI-12
--status resolves the status name against the statuses collection before patching, and DryRunUpdate returns the resolved plan without writing. Coexists with --action workflow transitions. https://community.openproject.org/wp/CLI-12
Create accepts a parent work package option patched via _links.parent; DryRunCreate returns the draft plan without writing. https://community.openproject.org/wp/CLI-12
DryRunCreate now resolves --type against the project's available types and sets WorkPackage.Type, reusing the same helpers DryRunUpdate uses for UpdateType; an unresolvable type now errors instead of being silently dropped from the plan. https://community.openproject.org/wp/CLI-12
Extends the renderer interface with work package details and create/update plan output in both text and JSON formats. https://community.openproject.org/wp/CLI-12
Inspect gains a --children flag returning the full details payload with direct children, rendered as text or JSON via --format. https://community.openproject.org/wp/CLI-12
Schema-driven --set assignments with label resolution, validated --status changes, and --dry-run plans for both, rendered via --format. https://community.openproject.org/wp/CLI-12
Create can link a parent work package at creation time and preview the draft as a dry-run plan via --format json or text. https://community.openproject.org/wp/CLI-12
Adds README examples for inspect --children, update --set/--status, and create --parent, all composable with --dry-run and the global --format json flag, so scripts and agents can discover the final work package flag surface without reading the source. https://community.openproject.org/wp/CLI-12
There was a problem hiding this comment.
Pull request overview
This PR ports the agent-oriented work package JSON workflows onto the noun-first op work-package ... command structure by adding richer DTO/model representations (schema + custom fields), new resource helpers for inspect/create/update “plans”, and printer renderer support so --format json can be used consistently across these flows.
Changes:
- Add schema-aware inspect payloads (
inspect --children) including project info, direct children, and custom-field label→API-field mappings. - Add schema-driven custom-field updates (
update --set) plus validated status updates (update --status), each supporting--dry-runplan output. - Add parent linking for creation (
create --parent) and a--dry-runcreate plan, with both text and JSON renderers extended accordingly.
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents global --format, plus examples for inspect --children, update --set/--status, and --dry-run plans. |
| models/work_package_mutation.go | Introduces create/update “plan” models for dry-run output (JSON/text). |
| models/work_package_details.go | Adds inspect payload models for richer work package detail output (including children and field labels). |
| dtos/work_package.go | Extends WP DTO parsing to capture customField* values and adds schema/parent links. |
| dtos/work_package_test.go | Tests lockVersion marshaling plus new custom-field/schema/parent link unmarshalling behavior. |
| dtos/work_package_schema.go | Adds DTO to unmarshal schema custom-field definitions from the schema endpoint. |
| dtos/work_package_schema_test.go | Tests schema DTO behavior (custom fields only). |
| components/resources/work_packages/update.go | Adds UpdateStatus support and introduces dry-run update plan generation. |
| components/resources/work_packages/update_test.go | Adds tests for status patching and dry-run plan behavior. |
| components/resources/work_packages/update_fields.go | Adds schema-driven --set field resolution, dry-run plan, and PATCH building for custom fields. |
| components/resources/work_packages/update_fields_test.go | Tests label resolution and formattable-field PATCH shape. |
| components/resources/work_packages/schema.go | Fetches schema and builds label→API-name mapping with deterministic ordering. |
| components/resources/work_packages/schema_test.go | Tests empty-schema behavior and deterministic sorting/filtering. |
| components/resources/work_packages/field_resolution.go | Implements label/API-name resolution + type coercion + validation for --set. |
| components/resources/work_packages/field_resolution_test.go | Unit tests for ambiguity, writability, duplicates, and coercion. |
| components/resources/work_packages/details.go | Adds rich inspect helpers (schema-backed details + optional children fetch). |
| components/resources/work_packages/details_test.go | Tests inspect-with-children, no-children query path, and label mapping behavior. |
| components/resources/work_packages/create.go | Adds CreateParent support plus dry-run create plan generation. |
| components/resources/work_packages/create_test.go | Tests parent link creation and dry-run create plan output. |
| components/printer/work_packages.go | Adds new printer entry points for details + create/update plans. |
| components/printer/work_package_details_test.go | Tests JSON/text renderer output for details and plan rendering. |
| components/printer/text_renderer.go | Implements text rendering for details + dry-run plans, including deterministic custom-field output. |
| components/printer/renderer.go | Extends renderer interface for details + plan output. |
| components/printer/json_renderer.go | Implements JSON rendering for details + plan output. |
| components/paths/paths.go | Adds StatusById path helper for status link patching. |
| cmd/workpackage/workpackage.go | Registers new flags: create --parent/--dry-run, update --status/--set/--dry-run, inspect --children. |
| cmd/workpackage/update.go | Wires --set and --dry-run handling, and routes to plan/details printing. |
| cmd/workpackage/update_test.go | Adds cmd-layer tests for --set, --status, and dry-run behaviors and flag conflicts. |
| cmd/workpackage/inspect.go | Adds --children mode with conflict checks and details rendering. |
| cmd/workpackage/inspect_test.go | Adds cmd-layer tests for inspect --children output and flag incompatibility. |
| cmd/workpackage/create.go | Adds --parent and --dry-run handling and plan printing. |
| cmd/workpackage/create_test.go | Adds cmd-layer tests for create --dry-run and create --parent POST shape and conflicts. |
Comments suppressed due to low confidence (1)
components/resources/work_packages/update_fields.go:66
- UpdateFields can panic when the fetched work package has no _links.self (workPackage.Links or workPackage.Links.Self is nil). fetch() doesn’t guarantee _links is present, so this should be handled by returning a normal error before attempting the PATCH.
_, err = requests.Patch(workPackage.Links.Self.Href, &requests.RequestData{
ContentType: "application/json",
Body: bytes.NewReader(body),
})
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+307
to
+308
| # Changing the status by name. The name is resolved against the work | ||
| # package's available statuses before the request is sent. |
Comment on lines
+27
to
+32
| return &models.WorkPackageUpdatePlan{ | ||
| Valid: true, | ||
| Operation: "update", | ||
| WorkPackageID: id, | ||
| ResolvedFields: resolved, | ||
| }, nil |
Comment on lines
+109
to
+111
| for _, option := range []CreateOption{CreateSubject, CreateParent, CreateDescription} { | ||
| value, ok := options[option] | ||
| if !ok { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 This PR description and the branch it documents were authored by an agent.
Ticket
https://community.openproject.org/wp/CLI-12
What are you trying to accomplish?
Ports the agent-oriented JSON work package workflows onto the noun-first structure from #15:
inspect --childrenfor a richer payload (parent, direct children, project info, custom fields, and label→API field mappings), schema-drivenupdate --setcustom field updates, validatedupdate --status, parent-awarecreate --parent, and--dry-runplans for both create and update, all rendered through the global--format jsonflag. This supersedes #12, which built the same functionality on the older verb-first branch.This PR partially overlaps with #17 (external, currently conflicting): it covers
create --parent, while #17's remaining unique value isupdate --parent(re-parenting) and--description-file.What approach did you choose and why?
Kept the existing Cobra command structure and text printer intact and added a parallel JSON-capable path built from richer DTOs/models, a schema-aware custom field resolver, and a renderer interface extended for work package details and create/update plans, so
--format jsonand--format textshare the same command logic.