Skip to content

feat(pull-requests): support native Gitea lifecycle actions - #8

Open
kalvenschraut wants to merge 5 commits into
gitea/ssh-hostsfrom
gitea/lifecycle
Open

feat(pull-requests): support native Gitea lifecycle actions#8
kalvenschraut wants to merge 5 commits into
gitea/ssh-hostsfrom
gitea/lifecycle

Conversation

@kalvenschraut

@kalvenschraut kalvenschraut commented Sep 5, 2026

Copy link
Copy Markdown
Member

Gitea pull requests need reversible draft/ready actions and visible auto-merge state. Map drafts to the configured native title prefixes, verify each transition, and read Gitea’s durable timeline for scheduled/cancelled auto-merges. Enable native scheduling/cancellation, author permissions, and base comparison.

Validation: 41 focused tests passed. Live Gitea 1.27.3 tests verified draft/ready, scheduling with a pending required check, cancellation, and cleanup without merging the PR. The stock API does not expose the armed merge method; a separate Gitea API PR will add it. The final integrated server typecheck passes.

Final stack validation at 256fd6fe5: 228 focused tests passed, followed by 61 API/workflow cases and the final team-recovery regression; server typecheck and targeted lint passed. The live settle-on-merge E2E previously passed with fixture cleanup. Companion Gitea backend and focused integration tests passed, including native revert across all five merge styles.

Model: GPT-5.6 Sol (high), integration review GPT-6 Astra. Harness: Codex.

@kalvenschraut

Copy link
Copy Markdown
Member Author

@coderabbitai review

Please evaluate correctness, regressions, security boundaries, and test coverage against the existing source-control and pull-request integrations. For this fork, main is the clean upstream mirror and rtvision is the integration branch. Review the changes in this PR against its current base; report actionable findings with file references.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Repository and branches =='
git remote -v
git status --short
git branch --show-current
git branch -a --no-color | sed -n '1,160p'

echo '== Pull request metadata =='
gh pr view 8 --repo RTVision/t3code --json number,title,baseRefName,baseRefOid,headRefName,headRefOid,changedFiles,additions,deletions,mergeable,state,url

echo '== Merge bases and commit ranges =='
for base in rtvision main; do
  if git rev-parse --verify --quiet "origin/$base" >/dev/null; then
    printf '%s: ' "$base"
    git merge-base HEAD "origin/$base"
  fi
done
git log --oneline --decorate --no-merges "$(git merge-base HEAD origin/rtvision)..HEAD" 2>/dev/null || true

echo '== Changed files against integration base =='
git diff --name-status "$(git merge-base HEAD origin/rtvision)"...HEAD
echo '== Diff stat =='
git diff --stat "$(git merge-base HEAD origin/rtvision)"...HEAD

echo '== Changed source/test outlines =='
git diff --name-only "$(git merge-base HEAD origin/rtvision)"...HEAD \
  | grep -E '\.(ts|tsx|js|jsx|py|go|rs)$' \
  | while IFS= read -r file; do
      [ -f "$file" ] || continue
      echo "--- $file"
      ast-grep outline "$file" --items all 2>/dev/null || true
    done

Length of output: 2558


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='20841bcbd84e2e1348124e25385a9c25b3059fde'
head='582011ec14da9ea9d08e224889bc9870b0fdafbf'

echo '== Verify base and merge base =='
git cat-file -t "$base" || true
git merge-base "$base" "$head" || true

echo '== Changed files =='
git diff --name-status "$base...$head"
git diff --stat "$base...$head"

echo '== Complete pull request patch =='
git diff --find-renames --find-copies --unified=80 "$base...$head"

echo '== Nearby integration modules =='
fd . . --type f \
  | grep -Ei '(gitea|github|gitlab|pull.?request|source.?control)' \
  | sed -n '1,260p'

echo '== Structural map of changed TypeScript files =='
git diff --name-only "$base...$head" \
  | grep -E '\.tsx?$' \
  | while IFS= read -r file; do
      echo "--- $file"
      ast-grep outline "$file" --items all 2>/dev/null || true
    done

Length of output: 84524


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Gitea HTTP request boundary and URL construction =='
ast-grep outline apps/server/src/sourceControl/GiteaApi.ts --items all
sed -n '1,300p' apps/server/src/sourceControl/GiteaApi.ts

echo '== Gitea API focused implementations =='
sed -n '193,352p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
sed -n '565,760p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
sed -n '1100,1300p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
sed -n '1,300p' apps/server/src/pullRequest/GiteaPullRequestProvider.ts

echo '== Contract action and detail semantics =='
rg -n -C 8 'PullRequestAction|autoMergeEnabled|baseComparison|PullRequestViewerPermissions' packages/contracts/src/pullRequest.ts

echo '== Comparable auto-merge and permissions implementations =='
rg -n -C 12 'autoMergeEnabled|getAutoMerge|enable-auto-merge|disable-auto-merge|viewerPermissions|baseComparison' \
  apps/server/src/pullRequest/GitHubPullRequestProvider.ts \
  apps/server/src/pullRequest/GitLabPullRequestProvider.ts \
  apps/server/src/pullRequest/BitbucketPullRequestProvider.ts \
  apps/server/src/pullRequest/AzureDevOpsPullRequestProvider.ts \
  apps/server/src/pullRequest/GitHubPullRequestCli.ts \
  apps/server/src/pullRequest/GitLabPullRequestCli.ts || true

echo '== Existing Gitea pagination call sites =='
rg -n -C 8 'nextPagePath|readUnknownSlice|Link|x-total-count' \
  apps/server/src/pullRequest/GiteaPullRequestApi.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

Length of output: 110756


🤖 web_search executed:

Gitea 1.27.3 API GET /repos/{owner}/{repo}/issues/{index}/timeline pagination order pull_scheduled_merge pull_cancel_scheduled_merge

Length of output: 11158


@kalvenschraut Review complete against PR #8 base gitea/ssh-hosts.

Findings

  1. High — Auto-merge state is incorrect after a full timeline page
    apps/server/src/pullRequest/GiteaPullRequestApi.ts, Line 1206

    getAutoMergeEnabled passes x-total-count to nextPagePath. Gitea 1.27 sets this header to the number of items in the current timeline page, not the total number of timeline items. Therefore, if page 1 contains 50 ordinary events, the response has x-total-count: 50. The code sees rowsSeen === total and stops. It never reads page 2 or later.

    This can report autoMergeEnabled: false when the latest schedule or cancellation event is outside the first page. It can also retain a stale result when a later cancellation event is outside page 1.

    Do not use x-total-count for this timeline endpoint. Continue when pageEvents.length === PAGE_SIZE, or use an endpoint-specific pagination rule that Gitea documents as a true total. Add a test with:

    • A first page of 50 non-lifecycle events.
    • x-total-count: "50".
    • A second page with pull_scheduled_merge or pull_cancel_scheduled_merge.

    Gitea’s 1.27 timeline handler sets the header from the returned page length: https://github.com/go-gitea/gitea/blob/v1.27.2/routers/api/v1/repo/issue_comment.go.

  2. Medium — The Gitea support documentation contradicts the new feature
    docs/user/source-control.md, Line 112

    The new Gitea section documents draft/ready actions and auto-merge controls. The later “Review and merge” section still says that “draft/ready changes” and “auto-merge controls” are unavailable.

    Update the later capability list. Keep only the features that remain unavailable, such as reactions, comment editing, workflow approval, and revert pull requests.

Security boundary

The timeline Link handling does not create a new credential-forwarding boundary. GiteaApi.request rejects URLs outside the configured /api/v1/ root and does not follow redirects.

You are interacting with an AI system.

@kalvenschraut
kalvenschraut marked this pull request as ready for review September 5, 2026 05:57
@kalvenschraut

Copy link
Copy Markdown
Member Author

@coderabbitai review

Please review this PR at its exact current head in stack pingdotgg#6. Verify correctness, regressions, security boundaries, and focused coverage against its current base, and report any actionable findings with file references.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='RTVision/t3code'
pr='8'

echo '== Current pull request metadata =='
gh pr view "$pr" --repo "$repo" \
  --json number,title,state,url,baseRefName,baseRefOid,headRefName,headRefOid,changedFiles,additions,deletions

echo '== Local HEAD and branch =='
git status --short
git branch --show-current
git rev-parse HEAD

echo '== Current base and merge base =='
base_ref="$(gh pr view "$pr" --repo "$repo" --json baseRefName --jq .baseRefName)"
head_ref="$(gh pr view "$pr" --repo "$repo" --json headRefName --jq .headRefName)"
git fetch --quiet origin "$base_ref" "$head_ref" || true
base_oid="$(git rev-parse "origin/$base_ref")"
head_oid="$(git rev-parse HEAD)"
merge_base="$(git merge-base "$base_oid" "$head_oid")"
printf 'base_ref=%s\nbase_oid=%s\nhead_ref=%s\nhead_oid=%s\nmerge_base=%s\n' \
  "$base_ref" "$base_oid" "$head_ref" "$head_oid" "$merge_base"

echo '== Commits in current PR range =='
git log --oneline --decorate --no-merges "$merge_base..$head_oid"

echo '== Files in current PR range =='
git diff --name-status --find-renames "$merge_base...$head_oid"
git diff --stat "$merge_base...$head_oid"

echo '== Changed TypeScript file structure =='
git diff --name-only "$merge_base...$head_oid" \
  | grep -E '\.(ts|tsx)$' \
  | while IFS= read -r file; do
      test -f "$file" || continue
      echo "--- $file"
      ast-grep outline "$file" --items all 2>/dev/null || true
    done

echo '== Patch =='
git diff --find-renames --unified=45 "$merge_base...$head_oid"

Length of output: 2539


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='0b6bf7c20edb07f47180fd9385a2ac3375e73a2c'
head='39a28c350b81b130f9bb4eda3e41172fd69f17d3'

echo '== Verify immutable review endpoints =='
git cat-file -t "$base"
git cat-file -t "$head"
printf 'merge_base=%s\n' "$(git merge-base "$base" "$head")"

echo '== Current PR commits =='
git log --oneline --decorate --no-merges "$base..$head"

echo '== Current PR files and stats =='
git diff --name-status --find-renames "$base...$head"
git diff --stat "$base...$head"

echo '== Changed source and test structure =='
git diff --name-only "$base...$head" \
  | grep -E '\.(ts|tsx)$' \
  | while IFS= read -r file; do
      test -f "$file" || continue
      echo "--- $file"
      ast-grep outline "$file" --items all 2>/dev/null || true
    done

echo '== Current PR patch =='
git diff --find-renames --unified=45 "$base...$head"

Length of output: 61686


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Pagination and Gitea API request boundary =='
sed -n '300,420p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
ast-grep outline apps/server/src/sourceControl/GiteaApi.ts --items all
sed -n '1,310p' apps/server/src/sourceControl/GiteaApi.ts

echo '== Changed action and detail implementation =='
sed -n '565,710p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
sed -n '1280,1470p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
sed -n '100,205p' apps/server/src/pullRequest/GiteaPullRequestProvider.ts
sed -n '1,180p' apps/server/src/pullRequest/GiteaLifecycle.ts

echo '== Pull-request detail contract and other provider behavior =='
rg -n -C 8 'autoMergeEnabled|baseComparison|PullRequestViewerPermissions|enable-auto-merge|disable-auto-merge' \
  packages/contracts apps/server/src/pullRequest \
  -g '*.ts' \
  -g '!apps/server/src/pullRequest/GiteaPullRequestApi.ts' \
  -g '!apps/server/src/pullRequest/GiteaPullRequestProvider.ts' \
  -g '!apps/server/src/pullRequest/GiteaPullRequestApi.test.ts' \
  -g '!apps/server/src/pullRequest/GiteaPullRequestProvider.test.ts' \
  -g '!apps/server/src/pullRequest/GiteaLifecycle.ts' \
  -g '!apps/server/src/pullRequest/GiteaLifecycle.test.ts' \
  | sed -n '1,1000p'

echo '== Gitea test setup and full changed test portions =='
sed -n '1,130p' apps/server/src/pullRequest/GiteaPullRequestApi.test.ts
sed -n '850,1120p' apps/server/src/pullRequest/GiteaPullRequestApi.test.ts
sed -n '1,160p' apps/server/src/pullRequest/GiteaPullRequestProvider.test.ts

echo '== References to the timeline endpoint and pagination helper =='
rg -n -C 5 'issues/.*/timeline|nextPagePath\(' apps/server/src \
  -g '*.ts'

Length of output: 153682


🤖 web_search executed:

In the Gitea v1.27.3 source, how does GET /api/v1/repos/{owner}/{repo}/issues/{index}/timeline set the X-Total-Count response header? Does it contain the count of the current page or the total matching timeline events? Cite the relevant source file and lines.

Length of output: 11260


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Remaining Gitea provider methods =='
sed -n '180,300p' apps/server/src/pullRequest/GiteaPullRequestProvider.ts

echo '== Permission refresh in action service =='
sed -n '1180,1285p' apps/server/src/pullRequest/PullRequestService.ts

echo '== Exact changed line ranges =='
nl -ba apps/server/src/pullRequest/GiteaPullRequestApi.ts | sed -n '360,415p;1178,1230p;1285,1455p'
nl -ba apps/server/src/pullRequest/GiteaPullRequestProvider.ts | sed -n '1,115p;145,205p'
nl -ba docs/user/source-control.md | sed -n '65,125p'

echo '== Provider construction test coverage =='
rg -n -C 6 'GiteaPullRequestProvider\.layer|GiteaPullRequestProvider\.make|getChangeRequest\(' \
  apps/server/src/pullRequest \
  -g '*Gitea*test.ts' \
  -g '*.test.ts'

Length of output: 10078


🏁 Script executed:

#!/bin/bash
set -euo pipefail

numbered() {
  awk -v start="$2" -v end="$3" 'NR >= start && NR <= end { printf "%6d  %s\n", NR, $0 }' "$1"
}

echo '== Auto-merge pagination implementation =='
numbered apps/server/src/pullRequest/GiteaPullRequestApi.ts 386 405
numbered apps/server/src/pullRequest/GiteaPullRequestApi.ts 1184 1225

echo '== Auto-merge pagination tests =='
numbered apps/server/src/pullRequest/GiteaPullRequestApi.test.ts 990 1045

echo '== Current Gitea capability documentation =='
numbered docs/user/source-control.md 72 125

echo '== Current provider detail tests that exercise timeline state =='
rg -n -C 4 'getAutoMergeEnabled|autoMergeEnabled|timeline' \
  apps/server/src/pullRequest/GiteaPullRequestProvider.test.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

Length of output: 14030


@kalvenschraut Review complete at current head 39a28c35, against base 0b6bf7c2.

Findings

  1. High — The timeline reader still stops after the first full page.
    apps/server/src/pullRequest/GiteaPullRequestApi.ts, Line 1206

    getAutoMergeEnabled uses nextPagePath. That helper treats X-Total-Count as the total number of timeline events at Lines 396-399.

    Gitea 1.27 sets this header to len(apiComments) for the timeline endpoint. The header is the count of the returned page, not the total count. Therefore, if page 1 contains 50 events, Gitea returns X-Total-Count: 50. The code sees rowsSeen === total and does not request page 2.

    This can report autoMergeEnabled: false when the latest schedule event is on a later page. It can also retain an outdated state when a later cancellation event is on a later page.

    Do not use X-Total-Count for this endpoint. Continue while pageEvents.length === PAGE_SIZE, unless Gitea supplies a valid Link: rel="next" value. Add a regression test where:

    • Page 1 contains 50 non-lifecycle events.
    • Page 1 has X-Total-Count: "50".
    • Page 2 contains pull_scheduled_merge or pull_cancel_scheduled_merge.

    Gitea v1.27 sets the timeline header from len(apiComments): https://github.com/go-gitea/gitea/blob/v1.27.2/routers/api/v1/repo/issue_comment.go.

  2. Medium — The Gitea capability documentation is internally inconsistent.
    docs/user/source-control.md, Line 116

    Lines 73-76 state that T3 supports verified draft/ready transitions and native auto-merge scheduling. Lines 116-119 still state that draft/ready changes and auto-merge controls are unavailable.

    Update the “Review and merge” Gitea capability list. Keep only the unsupported features, such as reactions, comment editing, workflow approval, and revert pull requests.

Security boundary

I found no additional credential-forwarding issue in timeline pagination. GiteaApi.request rejects pagination URLs outside the configured /api/v1/ root and does not follow redirects.

You are interacting with an AI system.

@kalvenschraut

Copy link
Copy Markdown
Member Author

Addressed both findings in 3c866b6f6.

  • Timeline pagination now ignores this route's page-length X-Total-Count, follows Link: rel="next" when present, and otherwise continues after a full 50-row page. The regression covers X-Total-Count: 50 with the schedule event on page 2, plus a linked page-2 cancellation.
  • The Gitea capability paragraph now lists draft/ready transitions and auto-merge controls as supported.

Focused lifecycle/API tests: 35 passed. Targeted lint passed.

@kalvenschraut

Copy link
Copy Markdown
Member Author

@coderabbitai review

Please review this PR at its exact current head in stack pingdotgg#6. Verify correctness, regressions, security boundaries, and focused coverage against its current base, and report any actionable findings with file references.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='RTVision/t3code'
pr='8'

echo '== Pull request metadata =='
gh pr view "$pr" --repo "$repo" \
  --json number,title,state,url,baseRefName,baseRefOid,headRefName,headRefOid,changedFiles,additions,deletions

base_ref="$(gh pr view "$pr" --repo "$repo" --json baseRefName --jq .baseRefName)"
head_ref="$(gh pr view "$pr" --repo "$repo" --json headRefName --jq .headRefName)"
git fetch --quiet origin "$base_ref" "$head_ref"

base_oid="$(git rev-parse "origin/$base_ref")"
head_oid="$(git rev-parse HEAD)"
merge_base="$(git merge-base "$base_oid" "$head_oid")"
printf '\n== Exact review range ==\nbase_ref=%s\nbase_oid=%s\nhead_ref=%s\nhead_oid=%s\nmerge_base=%s\n' \
  "$base_ref" "$base_oid" "$head_ref" "$head_oid" "$merge_base"

echo '== Commits =='
git log --oneline --decorate --no-merges "$merge_base..$head_oid"

echo '== Changed files =='
git diff --name-status --find-renames "$merge_base...$head_oid"
git diff --stat "$merge_base...$head_oid"

echo '== Changed TypeScript outlines =='
git diff --name-only "$merge_base...$head_oid" \
  | grep -E '\.(ts|tsx)$' \
  | while IFS= read -r file; do
      test -f "$file" || continue
      echo "--- $file"
      ast-grep outline "$file" --items all 2>/dev/null || true
    done

echo '== Patch =='
git diff --find-renames --unified=55 "$merge_base...$head_oid"

Length of output: 2262


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='RTVision/t3code'
base='0b6bf7c20edb07f47180fd9385a2ac3375e73a2c'
head='3c866b6f6b26ebfc9f044ab8ba31c634dc4b516b'

ensure_commit() {
  local oid="$1"
  if ! git cat-file -e "${oid}^{commit}" 2>/dev/null; then
    git fetch --quiet "https://github.com/${repo}.git" "$oid"
  fi
}

ensure_commit "$base"
ensure_commit "$head"

echo '== Immutable review range =='
printf 'local_head=%s\n' "$(git rev-parse HEAD)"
printf 'base=%s\nhead=%s\nmerge_base=%s\n' \
  "$base" "$head" "$(git merge-base "$base" "$head")"
git show -s --format='base: %H %s%nhead: %H %s' "$base" "$head"

echo '== Files and patch =='
git diff --name-status --find-renames "$base...$head"
git diff --stat "$base...$head"
git diff --find-renames --unified=45 "$base...$head"

echo '== Changed TypeScript outlines =='
git diff --name-only "$base...$head" | grep -E '\.tsx?$' | while IFS= read -r file; do
  echo "--- $file"
  git show "$head:$file" > "/tmp/$(basename "$file")"
  ast-grep outline "/tmp/$(basename "$file")" --items all 2>/dev/null || true
done

echo '== Relevant current source with line numbers =='
git show "$head:apps/server/src/pullRequest/GiteaPullRequestApi.ts" \
  | nl -ba | sed -n '350,435p;555,725p;1140,1260p;1260,1500p'
git show "$head:apps/server/src/pullRequest/GiteaPullRequestProvider.ts" \
  | nl -ba | sed -n '1,280p'
git show "$head:apps/server/src/pullRequest/GiteaLifecycle.ts" \
  | nl -ba | sed -n '1,260p'

Length of output: 63756


🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='3c866b6f6b26ebfc9f044ab8ba31c634dc4b516b'

show_range() {
  local file="$1" start="$2" end="$3"
  echo "--- $file:$start-$end"
  git show "$head:$file" | sed -n "${start},${end}p" | awk -v n="$start" '{printf "%6d  %s\n", n++, $0}'
}

echo '== Gitea pagination and request boundary =='
show_range apps/server/src/pullRequest/GiteaPullRequestApi.ts 300 410
show_range apps/server/src/pullRequest/GiteaPullRequestApi.ts 565 660
show_range apps/server/src/pullRequest/GiteaPullRequestApi.ts 1170 1290
show_range apps/server/src/pullRequest/GiteaPullRequestApi.ts 1390 1465
show_range apps/server/src/sourceControl/GiteaApi.ts 1 330

echo '== Provider and lifecycle code =='
show_range apps/server/src/pullRequest/GiteaLifecycle.ts 1 140
show_range apps/server/src/pullRequest/GiteaPullRequestProvider.ts 1 260

echo '== Contract and action authorization paths =='
git show "$head:packages/contracts/src/pullRequest.ts" \
  | grep -n -E -C 8 'PullRequestAction|autoMergeEnabled|baseComparison|PullRequestViewerPermissions'
git show "$head:apps/server/src/pullRequest/PullRequestService.ts" \
  | grep -n -E -C 12 'viewerPermissions|enable-auto-merge|disable-auto-merge|runAction'

echo '== Comparable provider detail loading and permissions =='
for file in \
  apps/server/src/pullRequest/GitHubPullRequestProvider.ts \
  apps/server/src/pullRequest/GitLabPullRequestProvider.ts \
  apps/server/src/pullRequest/BitbucketPullRequestProvider.ts \
  apps/server/src/pullRequest/AzureDevOpsPullRequestProvider.ts; do
  git cat-file -e "$head:$file" 2>/dev/null || continue
  echo "--- $file"
  git show "$head:$file" | grep -n -E -C 8 'getAutoMergeEnabled|autoMergeEnabled|baseComparison|viewerPermissions|enable-auto-merge|disable-auto-merge'
done

echo '== Gitea provider/API test references and test setup =='
git show "$head:apps/server/src/pullRequest/GiteaPullRequestApi.test.ts" \
  | grep -n -E -C 10 'getAutoMergeEnabled|timeline|draft|ready|enable-auto-merge|disable-auto-merge|layer'
git show "$head:apps/server/src/pullRequest/GiteaPullRequestProvider.test.ts" \
  | sed -n '1,220p' | awk '{printf "%6d  %s\n", NR, $0}'

Length of output: 101167


🤖 web_search executed:

Gitea v1.27.3 source API resolve pull request review comment permission author without repository write access endpoint

Length of output: 20739


🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='3c866b6f6b26ebfc9f044ab8ba31c634dc4b516b'

echo '== Optional auto-merge field consumers =='
git grep -n -E 'autoMergeEnabled|autoMergeMethod' "$head" -- \
  'apps/**' 'packages/**' | sed -n '1,320p'

echo '== Detail and provider test construction =='
git grep -n -E -C 10 'getChangeRequest:|getAutoMergeEnabled|autoMergeEnabled|GiteaPullRequestProvider\.layer|GiteaPullRequestProvider\.make' \
  "$head" -- 'apps/server/src/pullRequest' \
  | sed -n '1,900p'

echo '== Optional enrichment patterns in all providers =='
git grep -n -E -C 8 'Effect\.orElseSucceed|autoMergeEnabled|Effect\.all' \
  "$head" -- 'apps/server/src/pullRequest/*Provider.ts' \
  | sed -n '1,1000p'

Length of output: 179626


🤖 web_search executed:

site:github.com/go-gitea/gitea/blob/v1.27.2 "func CanMarkConversation" Gitea

Length of output: 20126


@kalvenschraut Review complete at head 3c866b6f6, against base 0b6bf7c2.

Finding

  1. Medium — A timeline-read failure now prevents the pull request detail from loading
    apps/server/src/pullRequest/GiteaPullRequestProvider.ts, Line 160

    getChangeRequest includes api.getAutoMergeEnabled(input) in the required Effect.all. If the timeline endpoint returns an error, times out, returns malformed data, or reaches the pagination bound, the complete detail request fails.

    autoMergeEnabled is optional in ProviderChangeRequestDetail. The existing provider behavior degrades unavailable enrichment data. For example, Line 171 degrades a failed checks read to []. The contract also distinguishes an absent auto-merge value from false.

    Make the timeline read degrade to undefined on failure. Preserve the detail response and omit autoMergeEnabled when Gitea cannot provide a trustworthy state. Add a provider-level regression test that fails getAutoMergeEnabled while the pull request, repository access, and viewer reads succeed.

Verified

  • The timeline reader now ignores the route-specific page-length X-Total-Count.
  • The reader follows Link: rel="next" and otherwise continues after a full page.
  • The new tests cover both corrected pagination paths.
  • Pagination links remain within the configured Gitea API root. GiteaApi.request rejects external URLs and does not follow redirects.

You are interacting with an AI system.

@kalvenschraut

Copy link
Copy Markdown
Member Author

Fixed the latest review finding in 9276180. Pull-request detail now treats the Gitea timeline lookup as optional enrichment: a failed timeline read omits autoMergeEnabled while preserving the core detail and checks. Added a provider-level regression through the real Gitea adapter layer. Validation: 42 focused Gitea provider/API/lifecycle tests passed; targeted lint passed.

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