Skip to content

[INFRA-393] feat: add workflows, project templates, and ProjectFeature fields#38

Open
mguptahub wants to merge 2 commits into
mainfrom
infra-393/sdk-project-level-apis
Open

[INFRA-393] feat: add workflows, project templates, and ProjectFeature fields#38
mguptahub wants to merge 2 commits into
mainfrom
infra-393/sdk-project-level-apis

Conversation

@mguptahub
Copy link
Copy Markdown

@mguptahub mguptahub commented May 27, 2026

Summary

  • Add Workflows API resource with list/create/update and sub-resources:
    • WorkflowStatesattach / detach states to a workflow
    • WorkflowTransitions — full CRUD for state transitions
  • Add ProjectTemplates API resource with two sub-resources:
    • ProjectWorkItemTemplateslist / create / update / delete
    • ProjectPageTemplateslist / create / update / delete
  • Extend ProjectFeature model with the 3 missing fields (workflows, parallel_cycles, project_updates) — was 7 fields, now all 10
  • Export all new classes from plane/__init__.py
  • Add unit tests for workflows, project templates, and update existing project feature tests to cover all 10 fields

Test plan

  • tests/unit/test_workflows.py — list, create, update workflow; attach/detach states; list, create, update, delete transitions
  • tests/unit/test_project_templates.py — CRUD for work item templates and page templates
  • tests/unit/test_projects.pytest_get_features and test_update_features assert all 10 ProjectFeature fields

Co-authored-by: Plane AI noreply@plane.so

Summary by CodeRabbit

Release Notes

  • New Features
    • Workflow management system with capabilities to create, update, and manage workflow states and transitions
    • Project templates for work items and pages with full create, read, update, and delete operations
    • Enhanced project features including workflows and parallel cycles support

Review Change Stack

…FRA-393)

- Add Workflows API resource with list/create/update and sub-resources for
  WorkflowStates (attach/detach) and WorkflowTransitions (CRUD)
- Add ProjectTemplates API resource with WorkItemTemplates and PageTemplates
  sub-resources, each supporting list/create/update/delete
- Extend ProjectFeature model with missing fields: workflows, parallel_cycles,
  project_updates (was 7 fields, now all 10)
- Export all new classes from plane/__init__.py
- Add unit tests for workflows, project templates, and updated project feature tests

Co-authored-by: Plane AI <noreply@plane.so>
@makeplane
Copy link
Copy Markdown

makeplane Bot commented May 27, 2026

Linked to Plane Work Item(s)

This comment was auto-generated by Plane

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

📝 Walkthrough

Walkthrough

This PR introduces comprehensive Workflow and Project Template API support to the Plane Python SDK. It adds Pydantic models for workflows, workflow transitions, work-item templates, and page templates; implements API clients for CRUD operations and state/transition management; integrates the new APIs into PlaneClient; and provides test coverage for all new functionality.

Changes

Workflow API Feature

Layer / File(s) Summary
Workflow data models
plane/models/workflows.py
Workflow, CreateWorkflow, UpdateWorkflow, AttachWorkflowStates, WorkflowTransition, CreateWorkflowTransition, and UpdateWorkflowTransition Pydantic models with typed fields for IDs, names, descriptions, activation flags, state relationships, and rule payloads.
Workflow API clients
plane/api/workflows/base.py, plane/api/workflows/states.py, plane/api/workflows/transitions.py
Workflows, WorkflowStates, and WorkflowTransitions API clients extending BaseResource with list/create/update/delete CRUD methods, state attachment/detachment, response normalization, and special-case handling for "already exists" HTTP 400 responses.
Workflow package exports
plane/api/workflows/__init__.py
Re-exports Workflows, WorkflowStates, and WorkflowTransitions via all.
Workflow API tests
tests/unit/test_workflows.py
Smoke tests and CRUD test cases for listing, creating, updating workflows; attaching and detaching states; and listing, creating, updating, deleting transitions with feature enablement and graceful prerequisite checks.

Project Templates API Feature

Layer / File(s) Summary
Project template data models
plane/models/project_templates.py
WorkItemTemplate, CreateWorkItemTemplate, UpdateWorkItemTemplate, PageTemplate, CreatePageTemplate, and UpdatePageTemplate Pydantic models with consistent structure for content, metadata, and timestamps.
Project template API clients
plane/api/project_templates/base.py, plane/api/project_templates/work_item_templates.py, plane/api/project_templates/page_templates.py
ProjectTemplates, ProjectWorkItemTemplates, and ProjectPageTemplates API clients with list/create/update/delete CRUD operations, response normalization for both raw lists and {results: ...} payloads, and model validation.
Project templates package export
plane/api/project_templates/__init__.py
Re-exports ProjectTemplates, ProjectWorkItemTemplates, and ProjectPageTemplates via all.
Project template API tests
tests/unit/test_project_templates.py
Smoke tests and CRUD test cases for work-item and page templates with time-based unique names, fixture-based creation, field assertions, and best-effort deletion cleanup.

Client and Module Integration

Layer / File(s) Summary
Feature flag expansion and tests
plane/models/projects.py, tests/unit/test_projects.py
Adds workflows, parallel_cycles, and project_updates boolean flags to ProjectFeature model; extends feature tests to assert these new fields.
PlaneClient integration
plane/client/plane_client.py
Imports and initializes Workflows and ProjectTemplates as self.workflows and self.project_templates instance attributes.
Top-level module exports
plane/__init__.py
Imports and re-exports all new API classes and models via all, making them accessible from the plane package.

Sequence Diagram

sequenceDiagram
  participant User
  participant PlaneClient
  participant Workflows
  participant WorkflowStates
  participant WorkflowTransitions
  participant ProjectTemplates
  User->>PlaneClient: client.workflows
  PlaneClient->>Workflows: list/create/update workflows
  Workflows-->>User: Workflow[] or Workflow
  User->>PlaneClient: client.workflows.states
  PlaneClient->>WorkflowStates: attach/detach states
  WorkflowStates-->>User: None (state management)
  User->>PlaneClient: client.workflows.transitions
  PlaneClient->>WorkflowTransitions: CRUD transitions
  WorkflowTransitions-->>User: WorkflowTransition[] or WorkflowTransition | None
  User->>PlaneClient: client.project_templates
  PlaneClient->>ProjectTemplates: access work_item/page templates
  ProjectTemplates-->>User: Template[] or Template
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • dheeru0198
  • Prashant-Surya

Poem

🐰 Workflows dance and templates shine,
State transitions intertwine,
CRUD operations, clean and neat,
Page and work-item templates complete!
With tests to guide and exports bright,
The SDK now has full flight! 🚀

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding workflows, project templates APIs, and extending ProjectFeature fields.
Docstring Coverage ✅ Passed Docstring coverage is 86.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch infra-393/sdk-project-level-apis

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (1)
tests/unit/test_project_templates.py (1)

33-37: ⚡ Quick win

Use higher-entropy test names to reduce collision-driven flakes.

int(time.time()) has 1-second granularity, so fast/parallel test runs can reuse names.

Proposed fix
+from uuid import uuid4
@@
-            name=f"Test WI Template {int(time.time())}",
+            name=f"Test WI Template {uuid4().hex}",
@@
-        data = CreateWorkItemTemplate(name=f"Delete Me WI {int(time.time())}")
+        data = CreateWorkItemTemplate(name=f"Delete Me WI {uuid4().hex}")
@@
-            name=f"Test Page Template {int(time.time())}",
+            name=f"Test Page Template {uuid4().hex}",
@@
-        data = CreatePageTemplate(name=f"Delete Me Page {int(time.time())}")
+        data = CreatePageTemplate(name=f"Delete Me Page {uuid4().hex}")

Also applies to: 106-107, 130-134, 202-203

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_project_templates.py` around lines 33 - 37, Test names use
int(time.time()) which has 1s granularity and causes collisions; update all uses
of CreateWorkItemTemplate name formatting to use a higher-entropy suffix (e.g.,
uuid.uuid4().hex or time.time_ns()) instead of int(time.time()) — search for
CreateWorkItemTemplate in tests/unit/test_project_templates.py (the occurrences
around lines ~33, ~106, ~130, ~202) and replace the timestamp-based suffix with
a uuid4 or nanosecond timestamp to ensure unique names across fast/parallel
runs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plane/api/project_templates/page_templates.py`:
- Around line 27-29: Update all API endpoint strings in
plane/api/project_templates/page_templates.py to include a trailing slash so
they follow the SDK URL convention; specifically change the f-strings used in
the _get calls (e.g., the occurrences like
f"{workspace_slug}/projects/{project_id}/pages/templates") and the other
endpoints referenced around lines 47-50, 71-74, and 90 to end with "/" (e.g.,
".../templates/") ensuring every resource path uses the
"{base_path}/api/v1{resource_base_path}/{endpoint}/" pattern.

In `@plane/api/project_templates/work_item_templates.py`:
- Around line 27-29: The API URL strings built in this resource are missing
trailing slashes; update every occurrence where the code calls self._get /
self._post with endpoints like
f"{workspace_slug}/projects/{project_id}/workitems/templates" (and the other
three occurrences referenced at lines 47-50, 71-74, and 90) to append a trailing
"/" so the endpoints follow the SDK convention
"{base_path}/api/v1{resource_base_path}/{endpoint}/"; ensure each URL string
used in the class (the self._get/self._post calls) ends with "/" before calling
the request helper.

In `@plane/api/workflows/__init__.py`:
- Line 5: The __all__ list in the module is not alphabetically sorted (currently
__all__ = ["Workflows", "WorkflowStates", "WorkflowTransitions"]) which triggers
Ruff RUF022; update the module-level __all__ to be sorted lexicographically so
the entries are in alphabetical order (e.g., reorder the elements of the __all__
list) while keeping the same exported names and quoting style.

In `@plane/api/workflows/base.py`:
- Around line 28-29: The workflow endpoint URLs are missing required trailing
slashes causing potential 404s; update all calls that build workflow resource
paths (e.g., the self._get calls that construct
f"{workspace_slug}/projects/{project_id}/workflows", the similar f-strings
around lines referencing project/workflows and workflow_runs) to append a
trailing '/' so they follow the API convention (e.g., change ".../workflows" to
".../workflows/"); ensure every endpoint string returned to
self._get/self._post/etc. for workflows and workflow runs consistently ends with
a '/'.

In `@plane/api/workflows/states.py`:
- Around line 29-30: The endpoint URL strings for workflow states are missing
the required trailing slash; update the constructed paths (the f-strings that
use workspace_slug, project_id, workflow_id and the "/states" segment) to append
a trailing "/" so they follow the URL convention (e.g.
f"{workspace_slug}/projects/{project_id}/workflows/{workflow_id}/states/"); make
the same change for the other occurrence noted (the f-string at the other call
that builds ".../states") so all API calls to the workflow-state endpoints end
with a trailing slash and match the
`{base_path}/api/v1{resource_base_path}/{endpoint}/` pattern.

In `@plane/api/workflows/transitions.py`:
- Around line 34-35: Update the transition endpoint strings so they always end
with a trailing slash and follow the API URL convention (include the /api/v1
prefix and resource base path). Specifically, change the f-string that builds
the "state-transitions" endpoint (e.g.
f"{workspace_slug}/projects/{project_id}/workflows/{workflow_id}/state-transitions")
and the other transition-related f-strings referenced (lines noted around 63-64,
90-92, 111-112) to append a trailing "/" and ensure the full path follows
"{base_path}/api/v1{resource_base_path}/{endpoint}/". Ensure any callers that
expect these endpoints continue to receive the normalized URLs.

In `@tests/unit/test_project_templates.py`:
- Around line 53-56: The test teardown currently swallows all exceptions (e.g.,
the client.project_templates.work_item_templates.delete(...) calls) using bare
"except Exception: pass"; replace each silent except with capturing the
exception (except Exception as e) and either log it with full exception info
(logger.exception or similar) or explicitly fail the test/raise so cleanup
errors are visible (e.g., pytest.fail or re-raise) for the calls in the teardown
blocks around the delete calls
(client.project_templates.work_item_templates.delete and related cleanup
statements referenced at the noted locations).

---

Nitpick comments:
In `@tests/unit/test_project_templates.py`:
- Around line 33-37: Test names use int(time.time()) which has 1s granularity
and causes collisions; update all uses of CreateWorkItemTemplate name formatting
to use a higher-entropy suffix (e.g., uuid.uuid4().hex or time.time_ns())
instead of int(time.time()) — search for CreateWorkItemTemplate in
tests/unit/test_project_templates.py (the occurrences around lines ~33, ~106,
~130, ~202) and replace the timestamp-based suffix with a uuid4 or nanosecond
timestamp to ensure unique names across fast/parallel runs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 774352eb-ccc9-4a15-bfec-afd85645afd7

📥 Commits

Reviewing files that changed from the base of the PR and between 88ade49 and 23e9f9e.

📒 Files selected for processing (17)
  • plane/__init__.py
  • plane/api/project_templates/__init__.py
  • plane/api/project_templates/base.py
  • plane/api/project_templates/page_templates.py
  • plane/api/project_templates/work_item_templates.py
  • plane/api/projects.py
  • plane/api/workflows/__init__.py
  • plane/api/workflows/base.py
  • plane/api/workflows/states.py
  • plane/api/workflows/transitions.py
  • plane/client/plane_client.py
  • plane/models/project_templates.py
  • plane/models/projects.py
  • plane/models/workflows.py
  • tests/unit/test_project_templates.py
  • tests/unit/test_projects.py
  • tests/unit/test_workflows.py

Comment thread plane/api/project_templates/page_templates.py Outdated
Comment thread plane/api/project_templates/work_item_templates.py Outdated
Comment thread plane/api/workflows/__init__.py Outdated
Comment thread plane/api/workflows/base.py Outdated
Comment thread plane/api/workflows/states.py Outdated
Comment thread plane/api/workflows/transitions.py Outdated
Comment thread tests/unit/test_project_templates.py Outdated
- Add trailing slashes to all API endpoint paths (workflows, workflow
  states, workflow transitions, work item templates, page templates)
- Sort __all__ in plane/api/workflows/__init__.py (Ruff RUF022)
- Replace int(time.time()) with uuid4().hex in test fixtures to prevent
  name collisions on fast/parallel runs
- Replace silent `except Exception: pass` with warnings.warn in test
  teardown to surface cleanup failures

Co-authored-by: Plane AI <noreply@plane.so>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants