Skip to content

feat: update Releases API#61

Open
akhil-vamshi-konam wants to merge 3 commits into
mainfrom
feat-update-releases
Open

feat: update Releases API#61
akhil-vamshi-konam wants to merge 3 commits into
mainfrom
feat-update-releases

Conversation

@akhil-vamshi-konam

@akhil-vamshi-konam akhil-vamshi-konam commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Description

Brings the SDK's releases surface in line with the API.

Added

  • releasesretrieve, delete
  • releases.tags / releases.labelsretrieve, update, delete
  • releases.work_itemslist, add, remove
  • releases.comments — full CRUD
  • releases.links — full CRUD

Fixed

  • Every list() raised ValidationError: the endpoints return a paginated envelope, but the SDK iterated it as a list. They now parse the envelope (Paginated*Response) and accept per_page / cursor.
  • ReleaseTag was modeled as a label (name/color). A tag is a version marker — it now carries version, commit_hash, git_tag, description. CreateReleaseTag sends the required version.
  • item_labels.delete called a route that does not exist; it now detaches via DELETE /releases/{id}/labels/ with a label_ids body.
  • Release dropped fields the API never returns and gained the real ones (target_date, lead, tag, is_latest, is_prerelease, external_source, external_id). The body is written with description_html / description_json; description reads back as a nested object.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)

Test Scenarios

tests/unit/test_releases.py rewritten: 8 → 25 tests covering releases, tags, labels, item labels, work items, comments, links, and the backward-compatibility guarantees.

References

Version bumped to 0.2.20.

Summary by CodeRabbit

  • New Features
    • Added complete release lifecycle support, including retrieval, updates, deletion, and pagination.
    • Added management for release comments, links, and associated work items.
    • Added retrieval, updating, and deletion for release labels and tags.
    • Expanded release details with dates, descriptions, metadata, and version information.
  • Bug Fixes
    • Improved label detachment behavior.
  • Tests
    • Expanded coverage across release, tag, label, comment, link, and work-item workflows.
  • Chores
    • Updated the package version to 0.2.20.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@akhil-vamshi-konam, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 013dd062-06fe-4ba9-83bf-4a7a6af791ea

📥 Commits

Reviewing files that changed from the base of the PR and between 7491e83 and 84ce79d.

📒 Files selected for processing (4)
  • plane/api/releases/item_labels.py
  • plane/api/releases/work_items.py
  • plane/models/releases.py
  • tests/unit/test_releases.py
📝 Walkthrough

Walkthrough

Release APIs now support paginated responses, expanded release and tag schemas, CRUD operations, label detachment, and new work-item, comment, and link sub-resources. Tests cover lifecycle behavior, pagination envelopes, compatibility fields, and deletion failures.

Changes

Release API expansion

Layer / File(s) Summary
Release models and pagination contracts
plane/models/releases.py
Release and tag schemas were expanded, compatibility fields retained, and typed request, response, and pagination models were added for release sub-resources.
Release, tag, label, and item-label APIs
plane/api/releases/base.py, plane/api/releases/tags.py, plane/api/releases/labels.py, plane/api/releases/item_labels.py, tests/unit/test_releases.py, pyproject.toml
Primary release resources now support pagination, retrieval, updates, deletion, and label detachment, with expanded lifecycle tests and the package version updated to 0.2.20.
Release work-item, comment, and link resources
plane/api/releases/work_items.py, plane/api/releases/comments.py, plane/api/releases/links.py, tests/unit/test_releases.py
New sub-resources provide listing and lifecycle operations for work items, comments, and links, with integration coverage.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Releases
  participant ReleaseComments
  participant ReleaseLinks
  participant API
  Client->>Releases: list/retrieve/update/delete release
  Releases->>API: GET/PATCH/DELETE release endpoint
  Client->>ReleaseComments: create/update/delete comment
  ReleaseComments->>API: POST/PATCH/DELETE comment endpoint
  Client->>ReleaseLinks: create/update/delete link
  ReleaseLinks->>API: POST/PATCH/DELETE link endpoint
Loading

Possibly related PRs

Suggested reviewers: mguptahub, dheeru0198, prashant-surya

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: a broad update to the Releases API surface.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-update-releases

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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/releases/base.py`:
- Around line 35-48: Update each list method—Release.list in
plane/api/releases/base.py (35-48), Tag.list in plane/api/releases/tags.py
(21-34), Label.list in plane/api/releases/labels.py (21-34), ItemLabel.list in
plane/api/releases/item_labels.py (20-34), WorkItem.list in
plane/api/releases/work_items.py (19-33), Comment.list in
plane/api/releases/comments.py (21-35), and Link.list in
plane/api/releases/links.py (21-35)—to accept its corresponding typed Pydantic
query DTO instead of Mapping[str, Any], and pass params serialized with
model_dump(exclude_none=True) to _get.

In `@plane/api/releases/item_labels.py`:
- Around line 52-63: Update the delete method to accept the appropriate Pydantic
label-removal DTO, replacing the inline {"label_ids": [label_id]} dictionary
with that DTO’s model_dump(exclude_none=True) result when calling _delete.
Preserve the existing workspace, release, and label endpoint behavior.

In `@plane/api/releases/work_items.py`:
- Around line 35-59: Rename the release work-item methods `add` and `remove` to
the CRUD names `create` and `delete`. Update `delete` to accept the Pydantic
removal DTO instead of `list[str]`, and serialize that DTO with
`model_dump(exclude_none=True)` when passing its payload to `_delete`; preserve
the existing endpoint and create behavior.

In `@plane/models/releases.py`:
- Around line 116-129: Update the CreateReleaseTag model so version is a
required string rather than an optional field with a None default. Preserve the
existing optionality of description, commit_hash, and git_tag.

In `@tests/unit/test_releases.py`:
- Around line 35-38: Update each cleanup block around client.releases.delete to
catch only the expected HttpError for an already-deleted release, while
re-raising HttpError instances with other status codes and all non-HTTP
exceptions. Apply the same behavior to every listed cleanup occurrence,
preserving successful deletion handling.
🪄 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: 2a30ce34-2179-4eba-9dd1-86e89287e053

📥 Commits

Reviewing files that changed from the base of the PR and between 3795bed and 7491e83.

📒 Files selected for processing (10)
  • plane/api/releases/base.py
  • plane/api/releases/comments.py
  • plane/api/releases/item_labels.py
  • plane/api/releases/labels.py
  • plane/api/releases/links.py
  • plane/api/releases/tags.py
  • plane/api/releases/work_items.py
  • plane/models/releases.py
  • pyproject.toml
  • tests/unit/test_releases.py

Comment on lines +35 to +48
def list(
self, workspace_slug: str, params: Mapping[str, Any] | None = None
) -> PaginatedReleaseResponse:
"""List releases in the workspace (paginated).

def list(self, workspace_slug: str) -> list[Release]:
"""List all releases in the workspace.
Returns one page (20 by default). Pass `per_page`/`cursor` in params and
follow `next_cursor` to page through the rest.

Args:
workspace_slug: The workspace slug identifier
params: Optional query parameters, e.g. `per_page`, `cursor`
"""
response = self._get(f"{workspace_slug}/releases/")
return [Release.model_validate(item) for item in response]
response = self._get(f"{workspace_slug}/releases/", params=params)
return PaginatedReleaseResponse.model_validate(response)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Use typed Pydantic models for pagination parameters.

The new list methods expose raw Mapping[str, Any] inputs, bypassing validation and the repository’s DTO contract.

  • plane/api/releases/base.py#L35-L48: accept and serialize a release-list query model.
  • plane/api/releases/tags.py#L21-L34: accept and serialize a tag-list query model.
  • plane/api/releases/labels.py#L21-L34: accept and serialize a label-list query model.
  • plane/api/releases/item_labels.py#L20-L34: accept and serialize an item-label query model.
  • plane/api/releases/work_items.py#L19-L33: accept and serialize a work-item query model.
  • plane/api/releases/comments.py#L21-L35: accept and serialize a comment query model.
  • plane/api/releases/links.py#L21-L35: accept and serialize a link query model.

As per coding guidelines, resource methods must accept Pydantic DTOs and serialize them with model_dump(exclude_none=True).

📍 Affects 7 files
  • plane/api/releases/base.py#L35-L48 (this comment)
  • plane/api/releases/tags.py#L21-L34
  • plane/api/releases/labels.py#L21-L34
  • plane/api/releases/item_labels.py#L20-L34
  • plane/api/releases/work_items.py#L19-L33
  • plane/api/releases/comments.py#L21-L35
  • plane/api/releases/links.py#L21-L35
🤖 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 `@plane/api/releases/base.py` around lines 35 - 48, Update each list
method—Release.list in plane/api/releases/base.py (35-48), Tag.list in
plane/api/releases/tags.py (21-34), Label.list in plane/api/releases/labels.py
(21-34), ItemLabel.list in plane/api/releases/item_labels.py (20-34),
WorkItem.list in plane/api/releases/work_items.py (19-33), Comment.list in
plane/api/releases/comments.py (21-35), and Link.list in
plane/api/releases/links.py (21-35)—to accept its corresponding typed Pydantic
query DTO instead of Mapping[str, Any], and pass params serialized with
model_dump(exclude_none=True) to _get.

Source: Coding guidelines

Comment thread plane/api/releases/item_labels.py Outdated
Comment thread plane/api/releases/work_items.py Outdated
Comment thread plane/models/releases.py
Comment thread tests/unit/test_releases.py
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.

1 participant