Skip to content

fix: split PR comments exceeding the VCS size limit (#1645) - #2671

Open
GLEF1X wants to merge 8 commits into
diggerhq:developfrom
GLEF1X:fix/1645-split-long-comments
Open

GLEF1X wants to merge 8 commits into
diggerhq:developfrom
GLEF1X:fix/1645-split-long-comments

Conversation

@GLEF1X

@GLEF1X GLEF1X commented Jul 12, 2026

Copy link
Copy Markdown

Problem

GitHub rejects comment bodies over 65,536 characters. When a terraform plan output exceeds that, Digger fails the whole job with exit code 5 even though the plan succeeded:

error editing comment: PATCH https://api.github.com/repos/.../issues/comments/...: 422 Validation Failed [{Resource:IssueComment Field:body Code:custom Message:body is too long (maximum is 65536 characters)}]

Setting reporting-strategy doesn't help (see #1645 discussion): a single oversized report fails on create with multiple_comments, and the per-run strategies keep PATCHing a shared comment until every later project's report is lost — with 20+ projects, everything after the comment fills up fails.

Fixes #1645

What this does

  • Splits oversized reports into a chain of comments. A markdown-aware
    splitter closes open structures (code fences, <details>) at each chunk
    boundary and reopens them in the next chunk, so every comment renders
    valid on its own. Fence detection is line-anchored and marker-aware
    (```` vs ```, ~~~), matching how renderers actually parse
    fences — a plan containing a literal ``` inside a string value can't
    desync the splitter.
  • Chunks are carved from the end of the report, so the tail (plan
    summary, warnings, errors) always survives. A single report is capped at
    10 comments; beyond that the head is truncated with a warning.
  • Per-run strategies (comments_per_run, latest_run_comment) leave
    the full existing comment untouched on overflow and continue in new
    comment(s) under the same title; later reports append to the newest
    continuation.
  • Continuation comments link back to their predecessor, so chains stay
    navigable when parallel projects interleave.
  • Per-VCS limits via a new optional ci.CommentMaxLengthProvider
    interface: GitHub 65,536 / GitLab 1,000,000 / Bitbucket 32,768 / Azure
    DevOps 150,000. No breaking interface changes; behavior for reports under
    the limit is unchanged.
  • Drift issue notifications reuse the splitter with a single-chunk cap:
    structure-aware truncation that keeps the plan summary instead of cutting
    mid-fence and dropping the tail.
  • Fixes a rendering bug in collapsible comments (missing blank line after
    </summary> suppressed markdown; re-wrapping on append accumulated
    indentation until content rendered as a code block).

Testing

  • Unit tests for the splitter (fence closure, truncation, unicode
    boundaries, renderer-faithful fence parsing) and all three strategies.
  • Env-gated live integration tests against real APIs:
    • GitHub: oversized plan splitting, per-run overflow continuation, drift
      issue truncation at the real 65,536 boundary
    • GitLab: splitting via the discussions API, backlink URL correctness
    • Bitbucket: genuine 32,768 limit, full per-run overflow flow
  • End-to-end per CONTRIBUTING, from this branch via
    uses: GLEF1X/digger@fix/1645-split-long-comments in no-backend mode:
    Digger comment splitting: oversized plan output (#1645) GLEF1X/demo-opentofu#2 — a ~230KB OpenTofu plan
    (~4x the limit) posts as a chain of five linked comments plus a
    continuation for the second project, job exits 0. On current Digger this
    exact scenario fails with the 422 above.
  • Tested bitbucket and gitlab on my personal test repositories by running integration tests against them.

🧠 Ai UsageDetails (if applicable):

IMPORTANT: Please disclose any usage of ai tooling while making this change. If you did not use any AI write "NA" below

Example: Used ChatGPT to help with doc phrasing.
Example: Code generated by Copilot; reviewed and verified manually.

Some parts of the code, including tests and comments for methods, functions, and constants, etc were generated by Codex. I also used Codex to better understand the codebase and ask questions about it. I reviewed and verified all generated code and manually performed e2e testing in accordance with the contribution guidelines.

GLEF1X added 8 commits July 12, 2026 01:44
SplitComment breaks a formatted report into chunks under a size limit,
closing and reopening markdown structures (code fences, <details>) at
chunk boundaries so every chunk renders valid on its own. Fence
detection is line-anchored and marker-aware (```` vs ```, ~~~),
matching how VCS renderers parse fences. Chunks are carved from the end
of the report so the plan summary tail always survives; past the chunk
cap the head is truncated with a warning instead.

Refs diggerhq#1645
Optional CommentMaxLengthProvider interface lets PullRequestService
implementations declare their comment body limit: GitHub 65,536,
Bitbucket 32,768, Azure DevOps 150,000. Callers fall back to GitHub's
limit when a service does not implement it.

Refs diggerhq#1645
Declare GitLab's 1,000,000-character comment limit and populate the
web URL of published notes (the Notes API does not return one) so
comments can be linked to. Handles self-hosted instances under a
path prefix.

Refs diggerhq#1645
GitHub rejects comment bodies over 65,536 characters, so a large
terraform plan failed the job with 422 even though the plan itself
succeeded. Setting reporting-strategy made no difference: a single
oversized report failed on create, and the per-run strategies kept
PATCHing a shared comment until every later project's report was lost.

- multiple_comments publishes one comment per chunk
- per-run strategies leave the full existing comment untouched on
  overflow and continue in new comment(s) under the same title; title
  matching targets the newest comment so later reports append to the
  continuation
- continuation comments link back to their predecessor; the URL is
  substituted at publish time with a size reserve
- guard against providers that do not return the created comment

Closes diggerhq#1645
A blank line after </summary> is required for markdown (links, bold,
fences) to render inside an HTML details block. The old template also
indented content, and re-wrapping on every appended report accumulated
two more spaces each time until content turned into a markdown code
block.
Drift issues share GitHub's 65,536-character limit. The previous
truncation cut the head of the plan at the limit, which could land
inside a code fence and always discarded the tail where warnings and
the plan summary live. Reuse the comment splitter with a single-chunk
cap: structure-aware truncation that drops the head and keeps the
summary.

Refs diggerhq#1645
Env-gated tests against real APIs: GitHub (oversized plan splitting,
per-run overflow continuation, drift issue truncation), GitLab
(splitting via discussions, backlink URL correctness) and Bitbucket
(genuine 32,768 limit, full per-run overflow flow).

Refs diggerhq#1645
@GLEF1X

GLEF1X commented Aug 4, 2026

Copy link
Copy Markdown
Author

@motatoes, would you have a chance to take a look at this PR? I’m running into this issue with larger plans, particularly for providers like Auth0, Okta, and Datadog. Happy to provide any additional context or make changes if helpful. Thank you and your team for creating digger!

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.

Split GitHub comments into multiple comments if plan output is long

1 participant