2 Commits

Author SHA256 Message Date
5669083388 pr: handle case of nil user in reviews
All checks were successful
go-generate-check / go-generate-check (push) Successful in 21s
Integration tests / t (push) Successful in 6m29s
This can happen when a review request is assigned automatically via
CODEOWNERS or perhaps the requesting user has account removed.
2026-02-26 13:15:58 +01:00
Andrii Nikitin
cb9131a5dd t: add init process to all services
Some checks failed
Integration tests / t (pull_request) Successful in 7m0s
Integration tests / t (push) Failing after 6m58s
Enable init: true for all services in podman-compose.yml to ensure
proper signal handling and zombie process reaping within containers.
2026-02-26 12:17:29 +01:00
6 changed files with 32 additions and 16 deletions

View File

@@ -17,16 +17,15 @@ type PRReviews struct {
}
func FetchGiteaReviews(rf GiteaReviewTimelineFetcher, org, repo string, no int64) (*PRReviews, error) {
rawReviews, err := rf.GetPullRequestReviews(org, repo, no)
if err != nil {
return nil, err
}
timeline, err := rf.GetTimeline(org, repo, no)
if err != nil {
return nil, err
}
rawReviews, err := rf.GetPullRequestReviews(org, repo, no)
if err != nil {
return nil, err
}
reviews := make([]*models.PullReview, 0, 10)
needNewReviews := []string{}
@@ -52,7 +51,7 @@ func FetchGiteaReviews(rf GiteaReviewTimelineFetcher, org, repo string, no int64
for idx, item := range timeline {
if item.Type == TimelineCommentType_Review || item.Type == TimelineCommentType_ReviewRequested {
for _, r := range rawReviews {
if r.ID == item.ReviewID {
if r.ID == item.ReviewID && r.User != nil {
if !alreadyHaveUserReview(r.User.UserName) {
if item.Type == TimelineCommentType_Review && idx > cutOffIdx {
needNewReviews = append(needNewReviews, r.User.UserName)
@@ -188,6 +187,8 @@ func (r *PRReviews) HasPendingReviewBy(reviewer string) bool {
switch r.State {
case ReviewStateRequestReview, ReviewStatePending:
return true
default:
return false
}
}
}
@@ -200,20 +201,18 @@ func (r *PRReviews) IsReviewedBy(reviewer string) bool {
return false
}
res := false
for _, i := range r.Reviews {
if i.User.UserName == reviewer && !i.Stale {
switch i.State {
for _, r := range r.Reviews {
if r.User.UserName == reviewer && !r.Stale {
switch r.State {
case ReviewStateApproved, ReviewStateRequestChanges:
res = true
case ReviewStateRequestReview, ReviewStatePending:
return true
default:
return false
}
}
}
return res
return false
}
func (r *PRReviews) IsReviewedByOneOf(reviewers ...string) bool {

View File

@@ -137,6 +137,14 @@ func TestReviews(t *testing.T) {
isApproved: false,
isReviewedByTest1: true,
},
{
name: "Ghost user review",
reviews: []*models.PullReview{
{State: common.ReviewStateApproved, User: nil},
},
reviewers: []string{"user1"},
isApproved: false,
},
}
for _, test := range tests {

View File

@@ -8,6 +8,7 @@ services:
gitea:
build: ./gitea
container_name: gitea-test
init: true
environment:
- GITEA_WORK_DIR=/var/lib/gitea
networks:
@@ -27,6 +28,7 @@ services:
rabbitmq:
image: rabbitmq:3.13.7-management
container_name: rabbitmq-test
init: true
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "check_running", "-q"]
interval: 30s
@@ -55,6 +57,7 @@ services:
context: ..
dockerfile: integration/gitea-events-rabbitmq-publisher/Dockerfile${GIWTF_IMAGE_SUFFIX}
container_name: gitea-publisher
init: true
networks:
- gitea-network
depends_on:
@@ -75,6 +78,7 @@ services:
context: ..
dockerfile: integration/workflow-pr/Dockerfile${GIWTF_IMAGE_SUFFIX}
container_name: workflow-pr
init: true
networks:
- gitea-network
depends_on:
@@ -103,6 +107,7 @@ services:
mock-obs:
build: ./mock-obs
container_name: mock-obs
init: true
networks:
- gitea-network
ports:
@@ -116,6 +121,7 @@ services:
context: ..
dockerfile: integration/obs-staging-bot/Dockerfile${GIWTF_IMAGE_SUFFIX}
container_name: obs-staging-bot
init: true
networks:
- gitea-network
depends_on:

View File

@@ -65,11 +65,11 @@ The testing will be conducted in a dedicated test environment that mimics the pr
| **TC-REVIEW-001** | P | **Add mandatory reviewers** | 1. Create a new PackageGit PR. | 1. All mandatory reviewers are added to both the PackageGit and ProjectGit PRs. | High |
| **TC-REVIEW-002** | - | **Add advisory reviewers** | 1. Create a new PackageGit PR with advisory reviewers defined in the configuration. | 1. Advisory reviewers are added to the PR, but their approval is not required for merging. | Medium |
| **TC-REVIEW-003** | - | **Re-add reviewers** | 1. Push a new commit to a PackageGit PR after it has been approved. | 1. The original reviewers are re-added to the PR. | Medium |
| **TC-REVIEW-004** | P | **Package PR created by a maintainer** | 1. Create a PackageGit PR from the account of a package maintainer. | 1. No review is requested from other package maintainers. | High |
| **TC-REVIEW-004** | x | **Package PR created by a maintainer** | 1. Create a PackageGit PR from the account of a package maintainer. | 1. No review is requested from other package maintainers. | High |
| **TC-REVIEW-005** | P | **Package PR created by an external user (approve)** | 1. Create a PackageGit PR from the account of a user who is not a package maintainer.<br>2. One of the package maintainers approves the PR. | 1. All package maintainers are added as reviewers.<br>2. Once one maintainer approves the PR, the other maintainers are removed as reviewers. | High |
| **TC-REVIEW-006** | P | **Package PR created by an external user (reject)** | 1. Create a PackageGit PR from the account of a user who is not a package maintainer.<br>2. One of the package maintainers rejects the PR. | 1. All package maintainers are added as reviewers.<br>2. Once one maintainer rejects the PR, the other maintainers are removed as reviewers. | High |
| **TC-REVIEW-007** | P | **Package PR created by a maintainer with ReviewRequired=true** | 1. Set `ReviewRequired = true` in `workflow.config`.<br>2. Create a PackageGit PR from the account of a package maintainer. | 1. A review is requested from other package maintainers if available. | High |
| **TC-MERGE-001** | P | **Automatic Merge** | 1. Create a PackageGit PR.<br>2. Ensure all mandatory reviews are completed on both project and package PRs. | 1. The PR is automatically merged. | High |
| **TC-MERGE-001** | x | **Automatic Merge** | 1. Create a PackageGit PR.<br>2. Ensure all mandatory reviews are completed on both project and package PRs. | 1. The PR is automatically merged. | High |
| **TC-MERGE-002** | - | **ManualMergeOnly with Package Maintainer** | 1. Create a PackageGit PR with `ManualMergeOnly` set to `true`.<br>2. Ensure all mandatory reviews are completed on both project and package PRs.<br>3. Comment "merge ok" on the package PR from the account of a package maintainer for that package. | 1. The PR is merged. | High |
| **TC-MERGE-003** | - | **ManualMergeOnly with unauthorized user** | 1. Create a PackageGit PR with `ManualMergeOnly` set to `true`.<br>2. Ensure all mandatory reviews are completed on both project and package PRs.<br>3. Comment "merge ok" on the package PR from the account of a user who is not a maintainer for that package. | 1. The PR is not merged. | High |
| **TC-MERGE-004** | - | **ManualMergeOnly with multiple packages** | 1. Create a ProjectGit PR that references multiple PackageGit PRs with `ManualMergeOnly` set to `true`.<br>2. Ensure all mandatory reviews are completed on both project and package PRs.<br>3. Comment "merge ok" on each package PR from the account of a package maintainer. | 1. The PR is merged only after "merge ok" is commented on all associated PackageGit PRs. | High |

View File

@@ -5,6 +5,7 @@ from pathlib import Path
from tests.lib.common_test_utils import GiteaAPIClient
@pytest.mark.t001
@pytest.mark.xfail(reason="The bot sometimes re-request reviews despite having all the approvals")
def test_001_automerge(automerge_env, test_user_client):
"""
Test scenario:

View File

@@ -43,6 +43,7 @@ index 0000000..e69de29
@pytest.mark.t004
@pytest.mark.xfail(reason="the bot sometimes re-requests review from autogits_obs_staging_bot despite having the approval")
def test_004_maintainer(maintainer_env, ownerA_client):
"""
Test scenario:
@@ -151,6 +152,7 @@ index 0000000..e69de29
@pytest.mark.t005
# @pytest.mark.xfail(reason="TBD troubleshoot")
def test_005_any_maintainer_approval_sufficient(maintainer_env, ownerA_client, ownerBB_client):
"""
Test scenario: