Skip to content

fix: paginate ListNotCompletedDeployments in pipedv1#6727

Open
sridhar-panigrahi wants to merge 5 commits into
pipe-cd:masterfrom
sridhar-panigrahi:fix/pipedv1-list-not-completed-deployments-pagination
Open

fix: paginate ListNotCompletedDeployments in pipedv1#6727
sridhar-panigrahi wants to merge 5 commits into
pipe-cd:masterfrom
sridhar-panigrahi:fix/pipedv1-list-not-completed-deployments-pagination

Conversation

@sridhar-panigrahi
Copy link
Copy Markdown

@sridhar-panigrahi sridhar-panigrahi commented Apr 28, 2026

What this PR does:

Makes pipedv1's deployment store actually paginate when it calls ListNotCompletedDeployments. The store now loops on the cursor returned by the server until the cursor comes back empty, instead of taking only the first page and discarding the cursor.

Why we need it:

pipedv1's deployment store was calling ListNotCompletedDeployments once per sync tick and ignoring the cursor on the response. If the datastore returned a partial page, anything past that boundary got dropped — those deployments looked stuck in PENDING/PLANNED until the overall volume dropped enough to fit in a single page. The TODO at the top of sync() had been there since the RPC was introduced.

Scope — why pipedv0 is not touched here:

Issue #6696 calls out the same bug in pkg/app/piped/apistore/deploymentstore/store.go. pipedv0 is on the deprecation path per RFC 0015 (support intended through end of 2025), so this PR is scoped to pipedv1 to keep the diff small. Happy to mirror the loop into pipedv0 in a follow-up if maintainers prefer it covered.

Which issue(s) this PR fixes:

Fixes #6696

Does this PR introduce a user-facing change?:

  • How are users affected by this change: Deployments stop being silently skipped when the not-completed list spans more than one page. Anyone running pipedv1 under heavier deployment volume should see every pending/planned/running deployment picked up each sync tick.
  • Is this breaking change: No
  • How to migrate (if breaking change): N/A

@sridhar-panigrahi
Copy link
Copy Markdown
Author

sridhar-panigrahi commented Apr 28, 2026

@khanhtc1202 updated the patch at #6727 — went with the proto approach as originally proposed. Added cursor and page_size to the request, forwarded them server-side, and the pipedv1 store now loops until it gets an empty cursor. v0 store untouched. Let me know if anything needs changing!

piped was calling ListNotCompletedDeployments once per sync tick and
throwing away the cursor on the response. If the datastore returned a
partial page, every deployment past the first page would be silently
skipped until the next tick — showing up as stuck PENDING or PLANNED.

Fix:
- Add cursor and page_size to ListNotCompletedDeploymentsRequest proto
- Forward them in PipedAPI.ListNotCompletedDeployments into the
  datastore ListOptions so the server honours the client's position
- Replace the single RPC call in the pipedv1 deployment store with a
  loop that follows the cursor until the server returns an empty one,
  accumulating all deployments before classifying them
- Add table-driven tests for the v1 store covering single-page,
  multi-page, and all deployment status classifications

v0 store is intentionally untouched (frozen).

Fixes pipe-cd#6696

Signed-off-by: Shridhar Panigrahi <sridharpanigrahi2006@gmail.com>
@sridhar-panigrahi sridhar-panigrahi force-pushed the fix/pipedv1-list-not-completed-deployments-pagination branch from 0dc66c0 to fb7eff4 Compare April 28, 2026 06:48
@sridhar-panigrahi sridhar-panigrahi changed the title fix: make ListNotCompletedDeployments fetch all pages fix: paginate ListNotCompletedDeployments in pipedv1 Apr 28, 2026
@mohammedfirdouss
Copy link
Copy Markdown
Contributor

mohammedfirdouss commented Apr 30, 2026

@sridhar-panigrahi please follow the PR template used for pipecd. It is hard to tell why this PR/Change is needed. Look at previous PRs for any idea.
Example of a PR template: #6724

@sridhar-panigrahi
Copy link
Copy Markdown
Author

@mohammedfirdouss thanks for the nudge — you're right, the original description didn't make the motivation clear. I've rewritten it to follow the PR template (using #6724 as the reference). Let me know if it reads better now.

@mohammedfirdouss
Copy link
Copy Markdown
Contributor

@mohammedfirdouss thanks for the nudge — you're right, the original description didn't make the motivation clear. I've rewritten it to follow the PR template (using #6724 as the reference). Let me know if it reads better now.

@sridhar-panigrahi This is good, but try and remove the extra details beneath the template "A bit more detail on the changes"

@sridhar-panigrahi
Copy link
Copy Markdown
Author

@mohammedfirdouss got it — dropped the extra section, just the template now. Thanks for the review!

@mohammedfirdouss
Copy link
Copy Markdown
Contributor

mohammedfirdouss commented May 1, 2026

@mohammedfirdouss got it — dropped the extra section, just the template now. Thanks for the review!

Remove the sign-off as well, at the bottom.

@sridhar-panigrahi
Copy link
Copy Markdown
Author

@mohammedfirdouss , removed the signoff part too .

Drop page_size from the proto for ListNotCompletedDeployments. Nothing
was reading the field — the pipedv1 store only forwards the cursor —
so adding it to the wire format was a speculative API surface cost. A
follow-up PR can add it back when a real use case appears.

Tighten the head-deployment assertions in store_test.go to compare the
full map of application id to deployment rather than just checking
that the application ids are present. While writing this I noticed the
sync() function's write order makes the running deployment win over a
pending or planned one for the same application, which contradicts
the Lister docstring ("head = oldest uncompleted"). Filed separately
as pipe-cd#6780 — not fixing it in this PR to keep the diff focused on
pagination.

Signed-off-by: Cyrus <sridharpanigrahi2006@gmail.com>
@sridhar-panigrahi
Copy link
Copy Markdown
Author

Just did a fresh self-review pass and pushed updates.

  1. Dropped page_size from the proto. Nothing was reading it — the pipedv1 store only forwards the cursor — so adding it to the wire format was a speculative API surface cost. Easy to add back in a follow-up if a real use case appears.

  2. Tightened the head-deployment assertions in the new test. While writing them I noticed the overwrite order in sync() makes a running deployment win over a pending one for the same application, which contradicts the Lister docstring ("head = oldest uncompleted"). Filed that separately as bug: pipedv1 deployment store returns newest deployment as head, not oldest #6780 — not fixing it here so this PR stays focused on the pagination bug.

  3. Updated the PR description to spell out why pipedv0 is intentionally not touched (deprecation track per RFC 0015). Happy to mirror the loop into v0 inside this PR if anyone wants it covered together.

@khanhtc1202 @Warashi @ffjlabo @t-kikuc when one of you has a minute — would appreciate a maintainer look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: piped's ListNotCompletedDeployments call ignores pagination and can miss deployments

2 participants