Compare commits
7 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| 18435a8820 | |||
| 5f646f4520 | |||
| 88aa8c32fd | |||
| 99d27a48ff | |||
|
|
7832ef90c0 | ||
|
|
4691747038 | ||
| af2ff0bdd2 |
@@ -288,7 +288,7 @@ func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error
|
||||
func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error) {
|
||||
id, err := e.GitExecWithOutput(gitDir, "show-ref", "--heads", "--hash", branchName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Can't find default branch: %s", branchName)
|
||||
return "", fmt.Errorf("Can't find default branch: %s in %s", branchName, gitDir)
|
||||
}
|
||||
|
||||
id = strings.TrimSpace(SplitLines(id)[0])
|
||||
@@ -302,7 +302,7 @@ func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error
|
||||
func (e *GitHandlerImpl) GitRemoteHead(gitDir, remote, branchName string) (string, error) {
|
||||
id, err := e.GitExecWithOutput(gitDir, "show-ref", "--hash", "--verify", "refs/remotes/"+remote+"/"+branchName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Can't find default branch: %s", branchName)
|
||||
return "", fmt.Errorf("Can't find default branch: %s in %s", branchName, gitDir)
|
||||
}
|
||||
|
||||
return strings.TrimSpace(id), nil
|
||||
|
||||
@@ -711,13 +711,15 @@ func (r *BuildResultList) BuildResultSummary() (success, finished bool) {
|
||||
if !ok {
|
||||
panic("Unknown result code: " + result.Code)
|
||||
}
|
||||
if r.isLastBuild && result.Code == "unknown" {
|
||||
// it means the package has never build yet,
|
||||
// but we don't know the reason
|
||||
detail.Finished = true
|
||||
if r.isLastBuild {
|
||||
// we are always finished, since it is the last result
|
||||
// also when there is "unknown" state, it just means it
|
||||
// it was never done
|
||||
finished = true
|
||||
} else {
|
||||
finished = finished && detail.Finished
|
||||
}
|
||||
|
||||
finished = finished && detail.Finished
|
||||
success = success && detail.Success
|
||||
|
||||
if !finished {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<title>openSUSE Leap 16.0 based on SLFO</title>
|
||||
<description>Leap 16.0 based on SLES 16.0 (specifically SLFO:1.2)</description>
|
||||
<link project="openSUSE:Backports:SLE-16.0"/>
|
||||
<scmsync>http://gitea-test:3000/products/SLFO#main</scmsync>
|
||||
<scmsync>http://gitea-test:3000/myproducts/mySLFO#staging-main</scmsync>
|
||||
<person userid="dimstar_suse" role="maintainer"/>
|
||||
<person userid="lkocman-factory" role="maintainer"/>
|
||||
<person userid="maxlin_factory" role="maintainer"/>
|
||||
|
||||
@@ -59,8 +59,8 @@ The testing will be conducted in a dedicated test environment that mimics the pr
|
||||
| **TC-SYNC-002** | P | **Update ProjectGit PR from PackageGit PR** | 1. Push a new commit to an existing PackageGit PR. | 1. The corresponding ProjectGit PR's head branch is updated with the new commit. | High |
|
||||
| **TC-SYNC-003** | P | **WIP Flag Synchronization** | 1. Mark a PackageGit PR as "Work In Progress".<br>2. Remove the WIP flag from the PackageGit PR. | 1. The corresponding ProjectGit PR is also marked as "Work In Progress".<br>2. The WIP flag on the ProjectGit PR is removed. | Medium |
|
||||
| **TC-SYNC-004** | - | **WIP Flag (multiple referenced package PRs)** | 1. Create a ProjectGit PR that references multiple PackageGit PRs.<br>2. Mark one of the PackageGit PRs as "Work In Progress".<br>3. Remove the "Work In Progress" flag from all PackageGit PRs. | 1. The ProjectGit PR is marked as "Work In Progress".<br>2. The "Work In Progress" flag is removed from the ProjectGit PR only after it has been removed from all associated PackageGit PRs. | Medium |
|
||||
| **TC-SYNC-005** | x | **NoProjectGitPR = true, edits disabled** | 1. Set `NoProjectGitPR = true` in `workflow.config`.<br>2. Create a PackageGit PR without "Allow edits from maintainers" enabled. <br>3. Push a new commit to the PackageGit PR. | 1. No ProjectGit PR is created.<br>2. The bot adds a warning comment to the PackageGit PR explaining that it cannot update the PR. | High |
|
||||
| **TC-SYNC-006** | x | **NoProjectGitPR = true, edits enabled** | 1. Set `NoProjectGitPR = true` in `workflow.config`.<br>2. Create a PackageGit PR with "Allow edits from maintainers" enabled.<br>3. Push a new commit to the PackageGit PR. | 1. No ProjectGit PR is created.<br>2. The submodule commit on the project PR is updated with the new commit from the PackageGit PR. | High |
|
||||
| **TC-SYNC-005** | S | **NoProjectGitPR = true, edits disabled** | 1. Set `NoProjectGitPR = true` in `workflow.config`.<br>2. Create a PackageGit PR without "Allow edits from maintainers" enabled. <br>3. Push a new commit to the PackageGit PR. | 1. No ProjectGit PR is created.<br>2. The bot adds a warning comment to the PackageGit PR explaining that it cannot update the PR. | High |
|
||||
| **TC-SYNC-006** | S | **NoProjectGitPR = true, edits enabled** | 1. Set `NoProjectGitPR = true` in `workflow.config`.<br>2. Create a PackageGit PR with "Allow edits from maintainers" enabled.<br>3. Push a new commit to the PackageGit PR. | 1. No ProjectGit PR is created.<br>2. The submodule commit on the project PR is updated with the new commit from the PackageGit PR. | High |
|
||||
| **TC-COMMENT-001** | - | **Detect duplicate comments** | 1. Create a PackageGit PR.<br>2. Wait for the `workflow-pr` bot to act on the PR.<br>3. Edit the body of the PR to trigger the bot a second time. | 1. The bot should not post a duplicate comment. | High |
|
||||
| **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 |
|
||||
@@ -70,7 +70,7 @@ The testing will be conducted in a dedicated test environment that mimics the pr
|
||||
| **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-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-002** | P | **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 (or requested reviewer). | 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 |
|
||||
| **TC-MERGE-005** | - | **ManualMergeOnly with Project 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 project maintainer. | 1. The PR is merged. | High |
|
||||
@@ -84,6 +84,7 @@ The testing will be conducted in a dedicated test environment that mimics the pr
|
||||
|
||||
#### Legend:
|
||||
* P = implemented and passing;
|
||||
* S = skipped because is not implemented yet to save some execution time;
|
||||
* x = likely implemented, but investigation is needed;
|
||||
* X = implemented and likely to pass, but someteimes may fail, but troubleshooting is needed;
|
||||
* - = test is not implemented
|
||||
|
||||
@@ -13,9 +13,9 @@ from tests.lib.common_test_utils import GiteaAPIClient
|
||||
BRANCH_CONFIG_COMMON = {
|
||||
"workflow.config": {
|
||||
"Workflows": ["pr"],
|
||||
"Organization": "pool",
|
||||
"Organization": "mypool",
|
||||
"Reviewers": ["-autogits_obs_staging_bot"],
|
||||
"GitProjectName": "products/SLFO#{branch}"
|
||||
"GitProjectName": "myproducts/mySLFO#{branch}"
|
||||
},
|
||||
"_maintainership.json": {
|
||||
"": ["ownerX", "ownerY"],
|
||||
@@ -25,7 +25,8 @@ BRANCH_CONFIG_COMMON = {
|
||||
}
|
||||
|
||||
BRANCH_CONFIG_CUSTOM = {
|
||||
"main": {
|
||||
"main": {},
|
||||
"staging-main": {
|
||||
"workflow.config": {
|
||||
"ManualMergeProject": True
|
||||
},
|
||||
@@ -54,6 +55,12 @@ BRANCH_CONFIG_CUSTOM = {
|
||||
"NoProjectGitPR": True
|
||||
}
|
||||
},
|
||||
"manual-merge": {
|
||||
"workflow.config": {
|
||||
"ManualMergeOnly": True,
|
||||
"Reviewers": ["+usera", "+userb", "-autogits_obs_staging_bot"]
|
||||
}
|
||||
},
|
||||
"label-test": {
|
||||
"workflow.config": {
|
||||
"ManualMergeProject": True,
|
||||
@@ -67,6 +74,13 @@ BRANCH_CONFIG_CUSTOM = {
|
||||
}
|
||||
}
|
||||
|
||||
# Global state to track created Gitea objects during a pytest run
|
||||
_CREATED_ORGS = set()
|
||||
_CREATED_REPOS = set()
|
||||
_CREATED_USERS = set()
|
||||
_CREATED_LABELS = set()
|
||||
_ADDED_COLLABORATORS = set() # format: (org_repo, username)
|
||||
|
||||
def setup_users_from_config(client: GiteaAPIClient, wf: dict, mt: dict):
|
||||
"""
|
||||
Parses workflow.config and _maintainership.json, creates users, and adds them as collaborators.
|
||||
@@ -87,18 +101,27 @@ def setup_users_from_config(client: GiteaAPIClient, wf: dict, mt: dict):
|
||||
|
||||
# Create all users
|
||||
for username in all_users:
|
||||
client.create_user(username, "password123", f"{username}@example.com")
|
||||
client.add_collaborator("products", "SLFO", username, "write")
|
||||
if username not in _CREATED_USERS:
|
||||
client.create_user(username, "password123", f"{username}@example.com")
|
||||
_CREATED_USERS.add(username)
|
||||
|
||||
if ("myproducts/mySLFO", username) not in _ADDED_COLLABORATORS:
|
||||
client.add_collaborator("myproducts", "mySLFO", username, "write")
|
||||
_ADDED_COLLABORATORS.add(("myproducts/mySLFO", username))
|
||||
|
||||
# Set specific repository permissions based on maintainership
|
||||
for pkg, users in mt.items():
|
||||
repo_name = pkg if pkg else None
|
||||
for username in users:
|
||||
if not repo_name:
|
||||
client.add_collaborator("pool", "pkgA", username, "write")
|
||||
client.add_collaborator("pool", "pkgB", username, "write")
|
||||
for r in ["pkgA", "pkgB"]:
|
||||
if (f"mypool/{r}", username) not in _ADDED_COLLABORATORS:
|
||||
client.add_collaborator("mypool", r, username, "write")
|
||||
_ADDED_COLLABORATORS.add((f"mypool/{r}", username))
|
||||
else:
|
||||
client.add_collaborator("pool", repo_name, username, "write")
|
||||
if (f"mypool/{repo_name}", username) not in _ADDED_COLLABORATORS:
|
||||
client.add_collaborator("mypool", repo_name, username, "write")
|
||||
_ADDED_COLLABORATORS.add((f"mypool/{repo_name}", username))
|
||||
|
||||
def ensure_config_file(client: GiteaAPIClient, owner: str, repo: str, branch: str, file_name: str, expected_content_dict: dict):
|
||||
"""
|
||||
@@ -149,33 +172,41 @@ def gitea_env():
|
||||
raise Exception("Gitea not available.")
|
||||
|
||||
print("--- Starting Gitea Global Setup ---")
|
||||
client.create_org("products")
|
||||
client.create_org("pool")
|
||||
client.create_repo("products", "SLFO")
|
||||
client.create_repo("pool", "pkgA")
|
||||
client.create_repo("pool", "pkgB")
|
||||
client.update_repo_settings("products", "SLFO")
|
||||
client.update_repo_settings("pool", "pkgA")
|
||||
client.update_repo_settings("pool", "pkgB")
|
||||
for org in ["myproducts", "mypool"]:
|
||||
if org not in _CREATED_ORGS:
|
||||
client.create_org(org)
|
||||
_CREATED_ORGS.add(org)
|
||||
|
||||
for org, repo in [("myproducts", "mySLFO"), ("mypool", "pkgA"), ("mypool", "pkgB")]:
|
||||
if f"{org}/{repo}" not in _CREATED_REPOS:
|
||||
client.create_repo(org, repo)
|
||||
client.update_repo_settings(org, repo)
|
||||
_CREATED_REPOS.add(f"{org}/{repo}")
|
||||
|
||||
# Create labels
|
||||
client.create_label("products", "SLFO", "staging/Backlog", color="#0000ff")
|
||||
client.create_label("products", "SLFO", "review/Pending", color="#ffff00")
|
||||
for name, color in [("staging/Backlog", "#0000ff"), ("review/Pending", "#ffff00")]:
|
||||
if ("myproducts/mySLFO", name) not in _CREATED_LABELS:
|
||||
client.create_label("myproducts", "mySLFO", name, color=color)
|
||||
_CREATED_LABELS.add(("myproducts/mySLFO", name))
|
||||
|
||||
# Submodules in SLFO
|
||||
client.add_submodules("products", "SLFO")
|
||||
# Submodules in mySLFO
|
||||
client.add_submodules("myproducts", "mySLFO")
|
||||
|
||||
client.add_collaborator("products", "SLFO", "autogits_obs_staging_bot", "write")
|
||||
client.add_collaborator("products", "SLFO", "workflow-pr", "write")
|
||||
client.add_collaborator("pool", "pkgA", "workflow-pr", "write")
|
||||
client.add_collaborator("pool", "pkgB", "workflow-pr", "write")
|
||||
for repo_full, bot in [("myproducts/mySLFO", "autogits_obs_staging_bot"),
|
||||
("myproducts/mySLFO", "workflow-pr"),
|
||||
("mypool/pkgA", "workflow-pr"),
|
||||
("mypool/pkgB", "workflow-pr")]:
|
||||
if (repo_full, bot) not in _ADDED_COLLABORATORS:
|
||||
org_part, repo_part = repo_full.split("/")
|
||||
client.add_collaborator(org_part, repo_part, bot, "write")
|
||||
_ADDED_COLLABORATORS.add((repo_full, bot))
|
||||
|
||||
restart_needed = False
|
||||
|
||||
# Setup all branches and configs
|
||||
for branch_name, custom_configs in BRANCH_CONFIG_CUSTOM.items():
|
||||
# Ensure branch exists in all 3 repos
|
||||
for owner, repo in [("products", "SLFO"), ("pool", "pkgA"), ("pool", "pkgB")]:
|
||||
for owner, repo in [("myproducts", "mySLFO"), ("mypool", "pkgA"), ("mypool", "pkgB")]:
|
||||
if branch_name != "main":
|
||||
try:
|
||||
main_sha = client._request("GET", f"repos/{owner}/{repo}/branches/main").json()["commit"]["id"]
|
||||
@@ -201,9 +232,9 @@ def gitea_env():
|
||||
else:
|
||||
merged_configs[file_name] = custom_content
|
||||
|
||||
# Ensure config files in products/SLFO
|
||||
# Ensure config files in myproducts/mySLFO
|
||||
for file_name, content_dict in merged_configs.items():
|
||||
if ensure_config_file(client, "products", "SLFO", branch_name, file_name, content_dict):
|
||||
if ensure_config_file(client, "myproducts", "mySLFO", branch_name, file_name, content_dict):
|
||||
restart_needed = True
|
||||
|
||||
# Setup users (using configs from this branch)
|
||||
@@ -218,23 +249,35 @@ def gitea_env():
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def automerge_env(gitea_env):
|
||||
return gitea_env, "products/SLFO", "merge"
|
||||
return gitea_env, "myproducts/mySLFO", "merge"
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def staging_main_env(gitea_env):
|
||||
return gitea_env, "myproducts/mySLFO", "staging-main"
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def manual_merge_env(gitea_env):
|
||||
return gitea_env, "myproducts/mySLFO", "manual-merge"
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def maintainer_env(gitea_env):
|
||||
return gitea_env, "products/SLFO", "maintainer-merge"
|
||||
return gitea_env, "myproducts/mySLFO", "maintainer-merge"
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def review_required_env(gitea_env):
|
||||
return gitea_env, "products/SLFO", "review-required"
|
||||
return gitea_env, "myproducts/mySLFO", "review-required"
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def no_project_git_pr_env(gitea_env):
|
||||
return gitea_env, "products/SLFO", "dev"
|
||||
return gitea_env, "myproducts/mySLFO", "dev"
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def label_env(gitea_env):
|
||||
return gitea_env, "products/SLFO", "label-test"
|
||||
return gitea_env, "myproducts/mySLFO", "label-test"
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def usera_client(gitea_env):
|
||||
return GiteaAPIClient(base_url=gitea_env.base_url, token=gitea_env.headers["Authorization"].split(" ")[1], sudo="usera")
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def ownerA_client(gitea_env):
|
||||
@@ -256,6 +299,6 @@ def staging_bot_client(gitea_env):
|
||||
def test_user_client(gitea_env):
|
||||
username = f"test-user-{int(time.time())}"
|
||||
gitea_env.create_user(username, "password123", f"{username}@example.com")
|
||||
gitea_env.add_collaborator("pool", "pkgA", username, "write")
|
||||
gitea_env.add_collaborator("products", "SLFO", username, "write")
|
||||
gitea_env.add_collaborator("mypool", "pkgA", username, "write")
|
||||
gitea_env.add_collaborator("myproducts", "mySLFO", username, "write")
|
||||
return GiteaAPIClient(base_url=gitea_env.base_url, token=gitea_env.headers["Authorization"].split(" ")[1], sudo=username)
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<resultlist state="0fef640bfb56c3e76fcfb698b19b59c0">
|
||||
<result project="SUSE:SLFO:Main:PullRequest:1881" repository="standard" arch="aarch64" code="unpublished" state="unpublished">
|
||||
<scmsync>https://src.suse.de/products/SLFO.git?onlybuild=openjpeg2#d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scmsync>
|
||||
<scmsync>https://src.suse.de/myproducts/mySLFO.git?onlybuild=openjpeg2#d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scmsync>
|
||||
<scminfo>d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scminfo>
|
||||
<status package="openjpeg2" code="succeeded"/>
|
||||
</result>
|
||||
<result project="SUSE:SLFO:Main:PullRequest:1881" repository="standard" arch="ppc64le" code="unpublished" state="unpublished">
|
||||
<scmsync>https://src.suse.de/products/SLFO.git?onlybuild=openjpeg2#d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scmsync>
|
||||
<scmsync>https://src.suse.de/myproducts/mySLFO.git?onlybuild=openjpeg2#d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scmsync>
|
||||
<scminfo>d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scminfo>
|
||||
<status package="openjpeg2" code="succeeded"/>
|
||||
</result>
|
||||
<result project="SUSE:SLFO:Main:PullRequest:1881" repository="standard" arch="x86_64" code="unpublished" state="unpublished">
|
||||
<scmsync>https://src.suse.de/products/SLFO.git?onlybuild=openjpeg2#d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scmsync>
|
||||
<scmsync>https://src.suse.de/myproducts/mySLFO.git?onlybuild=openjpeg2#d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scmsync>
|
||||
<scminfo>d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scminfo>
|
||||
<status package="openjpeg2" code="succeeded"/>
|
||||
</result>
|
||||
<result project="SUSE:SLFO:Main:PullRequest:1881" repository="standard" arch="s390x" code="unpublished" state="unpublished">
|
||||
<scmsync>https://src.suse.de/products/SLFO.git?onlybuild=openjpeg2#d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scmsync>
|
||||
<scmsync>https://src.suse.de/myproducts/mySLFO.git?onlybuild=openjpeg2#d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scmsync>
|
||||
<scminfo>d99ac14dedf9f44e1744c71aaf221d15f6bed479ca11f15738e98f3bf9ae05a1</scminfo>
|
||||
<status package="openjpeg2" code="succeeded"/>
|
||||
</result>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<title>openSUSE Leap 16.0 based on SLFO</title>
|
||||
<description>Leap 16.0 based on SLES 16.0 (specifically SLFO:1.2)</description>
|
||||
<link project="openSUSE:Backports:SLE-16.0"/>
|
||||
<scmsync>http://gitea-test:3000/products/SLFO#main</scmsync>
|
||||
<scmsync>http://gitea-test:3000/myproducts/mySLFO#staging-main</scmsync>
|
||||
<person userid="dimstar_suse" role="maintainer"/>
|
||||
<person userid="lkocman-factory" role="maintainer"/>
|
||||
<person userid="maxlin_factory" role="maintainer"/>
|
||||
@@ -56,4 +56,4 @@
|
||||
<arch>ppc64le</arch>
|
||||
<arch>s390x</arch>
|
||||
</repository>
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -172,8 +172,8 @@ class GiteaAPIClient:
|
||||
raise
|
||||
|
||||
# Get latest commit SHAs for the submodules
|
||||
pkg_a_sha = self._request("GET", "repos/pool/pkgA/branches/main").json()["commit"]["id"]
|
||||
pkg_b_sha = self._request("GET", "repos/pool/pkgB/branches/main").json()["commit"]["id"]
|
||||
pkg_a_sha = self._request("GET", "repos/mypool/pkgA/branches/main").json()["commit"]["id"]
|
||||
pkg_b_sha = self._request("GET", "repos/mypool/pkgB/branches/main").json()["commit"]["id"]
|
||||
|
||||
if not pkg_a_sha or not pkg_b_sha:
|
||||
raise Exception("Error: Could not get submodule commit SHAs. Cannot apply patch.")
|
||||
@@ -186,10 +186,10 @@ index 0000000..f1838bd
|
||||
@@ -0,0 +1,6 @@
|
||||
+[submodule "pkgA"]
|
||||
+ path = pkgA
|
||||
+ url = ../../pool/pkgA.git
|
||||
+ url = ../../mypool/pkgA.git
|
||||
+[submodule "pkgB"]
|
||||
+ path = pkgB
|
||||
+ url = ../../pool/pkgB.git
|
||||
+ url = ../../mypool/pkgB.git
|
||||
diff --git a/pkgA b/pkgA
|
||||
new file mode 160000
|
||||
index 0000000..{pkg_a_sha}
|
||||
@@ -389,6 +389,14 @@ index 0000000..{pkg_b_sha}
|
||||
response = self._request("PATCH", url, json=kwargs)
|
||||
return response.json()
|
||||
|
||||
def create_issue_comment(self, repo_full_name: str, issue_number: int, body: str):
|
||||
owner, repo = repo_full_name.split("/")
|
||||
url = f"repos/{owner}/{repo}/issues/{issue_number}/comments"
|
||||
data = {"body": body}
|
||||
print(f"--- Creating comment on {repo_full_name} issue #{issue_number} ---")
|
||||
response = self._request("POST", url, json=data)
|
||||
return response.json()
|
||||
|
||||
def get_timeline_events(self, repo_full_name: str, pr_number: int):
|
||||
owner, repo = repo_full_name.split("/")
|
||||
url = f"repos/{owner}/{repo}/issues/{pr_number}/timeline"
|
||||
|
||||
@@ -14,27 +14,28 @@ from tests.lib.common_test_utils import (
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def test_pr_workflow_succeeded(gitea_env, mock_build_result):
|
||||
def test_pr_workflow_succeeded(staging_main_env, mock_build_result):
|
||||
"""End-to-end test for a successful PR workflow."""
|
||||
gitea_env, test_full_repo_name, merge_branch_name = staging_main_env
|
||||
diff = "diff --git a/test.txt b/test.txt\nnew file mode 100644\nindex 0000000..e69de29\n"
|
||||
pr = gitea_env.create_gitea_pr("pool/pkgA", diff, "Test PR - should succeed", False)
|
||||
pr = gitea_env.create_gitea_pr("mypool/pkgA", diff, "Test PR - should succeed", False, base_branch=merge_branch_name)
|
||||
initial_pr_number = pr["number"]
|
||||
|
||||
compose_dir = Path(__file__).parent.parent
|
||||
|
||||
forwarded_pr_number = None
|
||||
print(
|
||||
f"Polling pool/pkgA PR #{initial_pr_number} timeline for forwarded PR event..."
|
||||
f"Polling mypool/pkgA PR #{initial_pr_number} timeline for forwarded PR event..."
|
||||
)
|
||||
for _ in range(20):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgA", initial_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", initial_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
forwarded_pr_number = match.group(1)
|
||||
break
|
||||
@@ -43,13 +44,13 @@ def test_pr_workflow_succeeded(gitea_env, mock_build_result):
|
||||
assert (
|
||||
forwarded_pr_number is not None
|
||||
), "Workflow bot did not create a pull_ref event on the timeline."
|
||||
print(f"Found forwarded PR: products/SLFO #{forwarded_pr_number}")
|
||||
print(f"Found forwarded PR: myproducts/mySLFO #{forwarded_pr_number}")
|
||||
|
||||
print(f"Polling products/SLFO PR #{forwarded_pr_number} for reviewer assignment...")
|
||||
print(f"Polling myproducts/mySLFO PR #{forwarded_pr_number} for reviewer assignment...")
|
||||
reviewer_added = False
|
||||
for _ in range(15):
|
||||
time.sleep(1)
|
||||
pr_details = gitea_env.get_pr_details("products/SLFO", forwarded_pr_number)
|
||||
pr_details = gitea_env.get_pr_details("myproducts/mySLFO", forwarded_pr_number)
|
||||
if any(
|
||||
r.get("login") == "autogits_obs_staging_bot"
|
||||
for r in pr_details.get("requested_reviewers", [])
|
||||
@@ -69,11 +70,11 @@ def test_pr_workflow_succeeded(gitea_env, mock_build_result):
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
print(f"Polling products/SLFO PR #{forwarded_pr_number} for final status...")
|
||||
print(f"Polling myproducts/mySLFO PR #{forwarded_pr_number} for final status...")
|
||||
status_comment_found = False
|
||||
for _ in range(20):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("products/SLFO", forwarded_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("myproducts/mySLFO", forwarded_pr_number)
|
||||
for event in timeline_events:
|
||||
print(event.get("body", "not a body"))
|
||||
if event.get("body") and "successful" in event["body"]:
|
||||
@@ -84,27 +85,28 @@ def test_pr_workflow_succeeded(gitea_env, mock_build_result):
|
||||
assert status_comment_found, "Staging bot did not post a 'successful' comment."
|
||||
|
||||
|
||||
def test_pr_workflow_failed(gitea_env, mock_build_result):
|
||||
def test_pr_workflow_failed(staging_main_env, mock_build_result):
|
||||
"""End-to-end test for a failed PR workflow."""
|
||||
gitea_env, test_full_repo_name, merge_branch_name = staging_main_env
|
||||
diff = "diff --git a/another_test.txt b/another_test.txt\nnew file mode 100644\nindex 0000000..e69de29\n"
|
||||
pr = gitea_env.create_gitea_pr("pool/pkgA", diff, "Test PR - should fail", False)
|
||||
pr = gitea_env.create_gitea_pr("mypool/pkgA", diff, "Test PR - should fail", False, base_branch=merge_branch_name)
|
||||
initial_pr_number = pr["number"]
|
||||
|
||||
compose_dir = Path(__file__).parent.parent
|
||||
|
||||
forwarded_pr_number = None
|
||||
print(
|
||||
f"Polling pool/pkgA PR #{initial_pr_number} timeline for forwarded PR event..."
|
||||
f"Polling mypool/pkgA PR #{initial_pr_number} timeline for forwarded PR event..."
|
||||
)
|
||||
for _ in range(20):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgA", initial_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", initial_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
forwarded_pr_number = match.group(1)
|
||||
break
|
||||
@@ -113,13 +115,13 @@ def test_pr_workflow_failed(gitea_env, mock_build_result):
|
||||
assert (
|
||||
forwarded_pr_number is not None
|
||||
), "Workflow bot did not create a pull_ref event on the timeline."
|
||||
print(f"Found forwarded PR: products/SLFO #{forwarded_pr_number}")
|
||||
print(f"Found forwarded PR: myproducts/mySLFO #{forwarded_pr_number}")
|
||||
|
||||
print(f"Polling products/SLFO PR #{forwarded_pr_number} for reviewer assignment...")
|
||||
print(f"Polling myproducts/mySLFO PR #{forwarded_pr_number} for reviewer assignment...")
|
||||
reviewer_added = False
|
||||
for _ in range(15):
|
||||
time.sleep(1)
|
||||
pr_details = gitea_env.get_pr_details("products/SLFO", forwarded_pr_number)
|
||||
pr_details = gitea_env.get_pr_details("myproducts/mySLFO", forwarded_pr_number)
|
||||
if any(
|
||||
r.get("login") == "autogits_obs_staging_bot"
|
||||
for r in pr_details.get("requested_reviewers", [])
|
||||
@@ -139,11 +141,11 @@ def test_pr_workflow_failed(gitea_env, mock_build_result):
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
print(f"Polling products/SLFO PR #{forwarded_pr_number} for final status...")
|
||||
print(f"Polling myproducts/mySLFO PR #{forwarded_pr_number} for final status...")
|
||||
status_comment_found = False
|
||||
for _ in range(20):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("products/SLFO", forwarded_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("myproducts/mySLFO", forwarded_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("body") and "failed" in event["body"]:
|
||||
status_comment_found = True
|
||||
|
||||
@@ -29,23 +29,23 @@ def test_001_project_pr_labels(label_env, staging_bot_client):
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
"""
|
||||
print(f"--- Creating package PR in pool/pkgA on branch {branch_name} ---")
|
||||
package_pr = gitea_env.create_gitea_pr("pool/pkgA", diff, "Test Labels Fixture", False, base_branch=branch_name)
|
||||
print(f"--- Creating package PR in mypool/pkgA on branch {branch_name} ---")
|
||||
package_pr = gitea_env.create_gitea_pr("mypool/pkgA", diff, "Test Labels Fixture", False, base_branch=branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
print(f"Created package PR pool/pkgA#{package_pr_number}")
|
||||
print(f"Created package PR mypool/pkgA#{package_pr_number}")
|
||||
|
||||
# 2. Make sure the workflow-pr service created related project PR
|
||||
project_pr_number = None
|
||||
print(f"Polling pool/pkgA PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
print(f"Polling mypool/pkgA PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
for _ in range(40):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgA", package_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", package_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
project_pr_number = int(match.group(1))
|
||||
break
|
||||
@@ -53,16 +53,16 @@ index 0000000..e69de29
|
||||
break
|
||||
|
||||
assert project_pr_number is not None, "Workflow bot did not create a project PR."
|
||||
print(f"Found project PR: products/SLFO#{project_pr_number}")
|
||||
print(f"Found project PR: myproducts/mySLFO#{project_pr_number}")
|
||||
|
||||
# 3. Wait for the project PR to have the label "staging/Backlog"
|
||||
print(f"Checking for 'staging/Backlog' label on project PR products/SLFO#{project_pr_number}...")
|
||||
print(f"Checking for 'staging/Backlog' label on project PR myproducts/mySLFO#{project_pr_number}...")
|
||||
|
||||
backlog_label_found = False
|
||||
expected_backlog_label = "staging/Backlog"
|
||||
|
||||
for _ in range(20):
|
||||
project_pr_details = gitea_env.get_pr_details("products/SLFO", project_pr_number)
|
||||
project_pr_details = gitea_env.get_pr_details("myproducts/mySLFO", project_pr_number)
|
||||
labels = project_pr_details.get("labels", [])
|
||||
label_names = [l["name"] for l in labels]
|
||||
if expected_backlog_label in label_names:
|
||||
@@ -70,21 +70,21 @@ index 0000000..e69de29
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
assert backlog_label_found, f"Project PR products/SLFO#{project_pr_number} does not have the expected label '{expected_backlog_label}'."
|
||||
print(f"Project PR products/SLFO#{project_pr_number} has the expected label '{expected_backlog_label}'.")
|
||||
assert backlog_label_found, f"Project PR myproducts/mySLFO#{project_pr_number} does not have the expected label '{expected_backlog_label}'."
|
||||
print(f"Project PR myproducts/mySLFO#{project_pr_number} has the expected label '{expected_backlog_label}'.")
|
||||
|
||||
# 4. Post approval from autogits_obs_staging_bot
|
||||
print(f"--- Posting approval from autogits_obs_staging_bot on project PR products/SLFO#{project_pr_number} ---")
|
||||
staging_bot_client.create_review("products/SLFO", project_pr_number, event="APPROVED", body="Staging OK")
|
||||
print(f"--- Posting approval from autogits_obs_staging_bot on project PR myproducts/mySLFO#{project_pr_number} ---")
|
||||
staging_bot_client.create_review("myproducts/mySLFO", project_pr_number, event="APPROVED", body="Staging OK")
|
||||
|
||||
# 5. Check that the project PR has the label "review/Pending"
|
||||
print(f"Checking for 'review/Pending' label on project PR products/SLFO#{project_pr_number}...")
|
||||
print(f"Checking for 'review/Pending' label on project PR myproducts/mySLFO#{project_pr_number}...")
|
||||
|
||||
pending_label_found = False
|
||||
expected_pending_label = "review/Pending"
|
||||
|
||||
for _ in range(20):
|
||||
project_pr_details = gitea_env.get_pr_details("products/SLFO", project_pr_number)
|
||||
project_pr_details = gitea_env.get_pr_details("myproducts/mySLFO", project_pr_number)
|
||||
labels = project_pr_details.get("labels", [])
|
||||
label_names = [l["name"] for l in labels]
|
||||
print(f"Current labels: {label_names}")
|
||||
@@ -93,5 +93,5 @@ index 0000000..e69de29
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
assert pending_label_found, f"Project PR products/SLFO#{project_pr_number} does not have the expected label '{expected_pending_label}'."
|
||||
print(f"Project PR products/SLFO#{project_pr_number} has the expected label '{expected_pending_label}'.")
|
||||
assert pending_label_found, f"Project PR myproducts/mySLFO#{project_pr_number} does not have the expected label '{expected_pending_label}'."
|
||||
print(f"Project PR myproducts/mySLFO#{project_pr_number} has the expected label '{expected_pending_label}'.")
|
||||
|
||||
@@ -7,37 +7,35 @@ from tests.lib.common_test_utils import GiteaAPIClient
|
||||
@pytest.mark.t001
|
||||
def test_001_automerge(automerge_env, test_user_client):
|
||||
"""
|
||||
Test scenario:
|
||||
1. Setup custom workflow.config with mandatory reviewers (+usera, +userb).
|
||||
2. Create a package PR in 'merge' branch.
|
||||
3. Make sure the workflow-pr service created related project PR in 'merge' branch.
|
||||
4. React on 'requested' reviews by approving them.
|
||||
5. Make sure both PRs are merged automatically by the workflow-pr service.
|
||||
Test scenario TC-MERGE-001:
|
||||
1. Create a PackageGit PR.
|
||||
2. Ensure all mandatory reviews are completed on both project and package PRs.
|
||||
3. Verify the PR is merged automatically.
|
||||
"""
|
||||
gitea_env, test_full_repo_name, merge_branch_name = automerge_env
|
||||
|
||||
# 1. Create a package PR
|
||||
diff = """diff --git a/merge_test_fixture.txt b/merge_test_fixture.txt
|
||||
diff = """diff --git a/automerge_test.txt b/automerge_test.txt
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
"""
|
||||
print(f"--- Creating package PR in pool/pkgA on branch {merge_branch_name} ---")
|
||||
package_pr = test_user_client.create_gitea_pr("pool/pkgA", diff, "Test Automerge Fixture", False, base_branch=merge_branch_name)
|
||||
print(f"--- Creating package PR in mypool/pkgA on branch {merge_branch_name} ---")
|
||||
package_pr = test_user_client.create_gitea_pr("mypool/pkgA", diff, "Test Automerge Fixture", False, base_branch=merge_branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
print(f"Created package PR pool/pkgA#{package_pr_number}")
|
||||
print(f"Created package PR mypool/pkgA#{package_pr_number}")
|
||||
|
||||
# 2. Make sure the workflow-pr service created related project PR
|
||||
project_pr_number = None
|
||||
print(f"Polling pool/pkgA PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
print(f"Polling mypool/pkgA PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
for _ in range(40):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgA", package_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", package_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
project_pr_number = int(match.group(1))
|
||||
break
|
||||
@@ -45,37 +43,153 @@ index 0000000..e69de29
|
||||
break
|
||||
|
||||
assert project_pr_number is not None, "Workflow bot did not create a project PR."
|
||||
print(f"Found project PR: products/SLFO#{project_pr_number}")
|
||||
print(f"Found project PR: myproducts/mySLFO#{project_pr_number}")
|
||||
|
||||
# 4. Make sure both PRs are merged automatically by the workflow-pr service
|
||||
print("Polling for PR merge status and reacting on REQUEST_REVIEW...")
|
||||
# 3. Approve reviews and verify merged
|
||||
print("Approving reviews and verifying both PRs are merged...")
|
||||
package_merged = False
|
||||
project_merged = False
|
||||
|
||||
for i in range(15): # Poll for up to 15 seconds
|
||||
# Package PR
|
||||
for i in range(20): # Poll for up to 20 seconds
|
||||
gitea_env.approve_requested_reviews("mypool/pkgA", package_pr_number)
|
||||
gitea_env.approve_requested_reviews("myproducts/mySLFO", project_pr_number)
|
||||
|
||||
if not package_merged:
|
||||
pkg_details = gitea_env.get_pr_details("pool/pkgA", package_pr_number)
|
||||
pkg_details = gitea_env.get_pr_details("mypool/pkgA", package_pr_number)
|
||||
if pkg_details.get("merged"):
|
||||
package_merged = True
|
||||
print(f"Package PR pool/pkgA#{package_pr_number} merged.")
|
||||
else:
|
||||
gitea_env.approve_requested_reviews("pool/pkgA", package_pr_number)
|
||||
print(f"Package PR mypool/pkgA#{package_pr_number} merged.")
|
||||
|
||||
# Project PR
|
||||
if not project_merged:
|
||||
prj_details = gitea_env.get_pr_details("products/SLFO", project_pr_number)
|
||||
prj_details = gitea_env.get_pr_details("myproducts/mySLFO", project_pr_number)
|
||||
if prj_details.get("merged"):
|
||||
project_merged = True
|
||||
print(f"Project PR products/SLFO#{project_pr_number} merged.")
|
||||
else:
|
||||
gitea_env.approve_requested_reviews("products/SLFO", project_pr_number)
|
||||
print(f"Project PR myproducts/mySLFO#{project_pr_number} merged.")
|
||||
|
||||
if package_merged and project_merged:
|
||||
break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
assert package_merged, f"Package PR pool/pkgA#{package_pr_number} was not merged automatically."
|
||||
assert project_merged, f"Project PR products/SLFO#{project_pr_number} was not merged automatically."
|
||||
assert package_merged, f"Package PR mypool/pkgA#{package_pr_number} was not merged automatically."
|
||||
assert project_merged, f"Project PR myproducts/mySLFO#{project_pr_number} was not merged automatically."
|
||||
print("Both PRs merged successfully.")
|
||||
|
||||
@pytest.mark.t002
|
||||
def test_002_manual_merge(manual_merge_env, test_user_client, usera_client, staging_bot_client):
|
||||
"""
|
||||
Test scenario TC-MERGE-002:
|
||||
1. Create a PackageGit PR with ManualMergeOnly set to true.
|
||||
2. Ensure all mandatory reviews are completed on both project and package PRs.
|
||||
3. Comment "merge ok" on the package PR from the account of a requested reviewer.
|
||||
4. Verify the PR is merged.
|
||||
"""
|
||||
gitea_env, test_full_repo_name, merge_branch_name = manual_merge_env
|
||||
|
||||
# 1. Create a package PR
|
||||
diff = """diff --git a/manual_merge_test.txt b/manual_merge_test.txt
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
"""
|
||||
print(f"--- Creating package PR in mypool/pkgA on branch {merge_branch_name} ---")
|
||||
package_pr = test_user_client.create_gitea_pr("mypool/pkgA", diff, "Test Manual Merge Fixture", False, base_branch=merge_branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
print(f"Created package PR mypool/pkgA#{package_pr_number}")
|
||||
|
||||
# 2. Make sure the workflow-pr service created related project PR
|
||||
project_pr_number = None
|
||||
print(f"Polling mypool/pkgA PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
for _ in range(40):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", package_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
project_pr_number = int(match.group(1))
|
||||
break
|
||||
if project_pr_number:
|
||||
break
|
||||
|
||||
assert project_pr_number is not None, "Workflow bot did not create a project PR."
|
||||
print(f"Found project PR: myproducts/mySLFO#{project_pr_number}")
|
||||
|
||||
# 3. Approve reviews and verify NOT merged
|
||||
print("Waiting for all expected review requests and approving them...")
|
||||
# Expected reviewers based on manual-merge branch config and pkgA maintainership
|
||||
expected_reviewers = {"usera", "userb", "ownerA", "ownerX", "ownerY"}
|
||||
|
||||
# ManualMergeOnly still requires regular reviews to be satisfied.
|
||||
# We poll until all expected reviewers are requested, then approve them.
|
||||
all_requested = False
|
||||
for _ in range(30):
|
||||
# Trigger approvals for whatever is already requested
|
||||
gitea_env.approve_requested_reviews("mypool/pkgA", package_pr_number)
|
||||
gitea_env.approve_requested_reviews("myproducts/mySLFO", project_pr_number)
|
||||
|
||||
# Explicitly handle staging bot if it is requested or pending
|
||||
prj_reviews = gitea_env.list_reviews("myproducts/mySLFO", project_pr_number)
|
||||
if any(r["user"]["login"] == "autogits_obs_staging_bot" and r["state"] in ["REQUEST_REVIEW", "PENDING"] for r in prj_reviews):
|
||||
print("Staging bot has a pending/requested review. Approving...")
|
||||
staging_bot_client.create_review("myproducts/mySLFO", project_pr_number, event="APPROVED", body="Staging bot approves")
|
||||
|
||||
# Check if all expected reviewers have at least one review record (any state)
|
||||
pkg_reviews = gitea_env.list_reviews("mypool/pkgA", package_pr_number)
|
||||
current_reviewers = {r["user"]["login"] for r in pkg_reviews}
|
||||
|
||||
if expected_reviewers.issubset(current_reviewers):
|
||||
# Also ensure they are all approved (not just requested)
|
||||
approved_reviewers = {r["user"]["login"] for r in pkg_reviews if r["state"] == "APPROVED"}
|
||||
if expected_reviewers.issubset(approved_reviewers):
|
||||
# And check project PR for bot approval
|
||||
prj_approved = any(r["user"]["login"] == "autogits_obs_staging_bot" and r["state"] == "APPROVED" for r in prj_reviews)
|
||||
if prj_approved:
|
||||
all_requested = True
|
||||
print(f"All expected reviewers {expected_reviewers} and staging bot have approved.")
|
||||
break
|
||||
|
||||
pkg_details = gitea_env.get_pr_details("mypool/pkgA", package_pr_number)
|
||||
prj_details = gitea_env.get_pr_details("myproducts/mySLFO", project_pr_number)
|
||||
|
||||
assert not pkg_details.get("merged"), "Package PR merged prematurely (ManualMergeOnly ignored?)"
|
||||
assert not prj_details.get("merged"), "Project PR merged prematurely (ManualMergeOnly ignored?)"
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
assert all_requested, f"Timed out waiting for all expected reviewers {expected_reviewers} to approve. Current: {current_reviewers}"
|
||||
print("Both PRs have all required approvals but are not merged (as expected with ManualMergeOnly).")
|
||||
|
||||
# 4. Comment "merge ok" from a requested reviewer (usera)
|
||||
print("Commenting 'merge ok' on package PR...")
|
||||
usera_client.create_issue_comment("mypool/pkgA", package_pr_number, "merge ok")
|
||||
|
||||
# 5. Verify both PRs are merged
|
||||
print("Polling for PR merge status...")
|
||||
package_merged = False
|
||||
project_merged = False
|
||||
|
||||
for i in range(20): # Poll for up to 20 seconds
|
||||
if not package_merged:
|
||||
pkg_details = gitea_env.get_pr_details("mypool/pkgA", package_pr_number)
|
||||
if pkg_details.get("merged"):
|
||||
package_merged = True
|
||||
print(f"Package PR mypool/pkgA#{package_pr_number} merged.")
|
||||
|
||||
if not project_merged:
|
||||
prj_details = gitea_env.get_pr_details("myproducts/mySLFO", project_pr_number)
|
||||
if prj_details.get("merged"):
|
||||
project_merged = True
|
||||
print(f"Project PR myproducts/mySLFO#{project_pr_number} merged.")
|
||||
|
||||
if package_merged and project_merged:
|
||||
break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
assert package_merged, f"Package PR mypool/pkgA#{package_pr_number} was not merged after 'merge ok'."
|
||||
assert project_merged, f"Project PR myproducts/mySLFO#{project_pr_number} was not merged after 'merge ok'."
|
||||
print("Both PRs merged successfully after 'merge ok'.")
|
||||
|
||||
@@ -15,22 +15,24 @@ def test_001_review_requests_matching_config(automerge_env, ownerA_client):
|
||||
"""
|
||||
gitea_env, test_full_repo_name, branch_name = automerge_env
|
||||
|
||||
# 1. Create a package PR for pool/pkgB as ownerA
|
||||
diff = """diff --git a/pkgB_test_001.txt b/pkgB_test_001.txt
|
||||
# 1. Create a package PR for mypool/pkgB as ownerA
|
||||
ts = int(time.time() * 1000)
|
||||
filename = f"pkgB_test_{ts}.txt"
|
||||
diff = f"""diff --git a/{filename} b/{filename}
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
"""
|
||||
print(f"--- Creating package PR in pool/pkgB on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("pool/pkgB", diff, "Test Review Requests Config", True, base_branch=branch_name)
|
||||
print(f"--- Creating package PR in mypool/pkgB on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("mypool/pkgB", diff, "Test Review Requests Config", True, base_branch=branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
print(f"Created package PR pool/pkgB#{package_pr_number}")
|
||||
print(f"Created package PR mypool/pkgB#{package_pr_number}")
|
||||
|
||||
# 2. Check that review requests came to ownerB, ownerBB, usera, and userb
|
||||
print("Checking for review requests from maintainers and workflow.config...")
|
||||
reviewers_requested = set()
|
||||
expected_reviewers = {"ownerB", "ownerBB", "usera", "userb"}
|
||||
for _ in range(30):
|
||||
reviews = gitea_env.list_reviews("pool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
reviewers_requested = {r["user"]["login"] for r in reviews if r["state"] == "REQUEST_REVIEW"}
|
||||
if expected_reviewers.issubset(reviewers_requested):
|
||||
break
|
||||
@@ -61,9 +63,9 @@ def test_004_maintainer(maintainer_env, ownerA_client):
|
||||
# 0.1 Verify all users from config exist
|
||||
print("--- Verifying all users from config exist ---")
|
||||
import json
|
||||
wf_file = gitea_env.get_file_info("products", "SLFO", "workflow.config", branch=branch_name)
|
||||
wf_file = gitea_env.get_file_info("myproducts", "mySLFO", "workflow.config", branch=branch_name)
|
||||
wf = json.loads(base64.b64decode(wf_file["content"]).decode("utf-8"))
|
||||
mt_file = gitea_env.get_file_info("products", "SLFO", "_maintainership.json", branch=branch_name)
|
||||
mt_file = gitea_env.get_file_info("myproducts", "mySLFO", "_maintainership.json", branch=branch_name)
|
||||
mt = json.loads(base64.b64decode(mt_file["content"]).decode("utf-8"))
|
||||
|
||||
expected_users = set()
|
||||
@@ -80,27 +82,29 @@ def test_004_maintainer(maintainer_env, ownerA_client):
|
||||
print(f"Verified user exists: {username}")
|
||||
|
||||
# 1. Create a package PR as ownerA
|
||||
diff = """diff --git a/maintainer_test_fixture.txt b/maintainer_test_fixture.txt
|
||||
ts = int(time.time() * 1000)
|
||||
filename = f"maintainer_test_{ts}.txt"
|
||||
diff = f"""diff --git a/{filename} b/{filename}
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
"""
|
||||
print(f"--- Creating package PR in pool/pkgA on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("pool/pkgA", diff, "Test Maintainer Merge", True, base_branch=branch_name)
|
||||
print(f"--- Creating package PR in mypool/pkgA on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("mypool/pkgA", diff, "Test Maintainer Merge", True, base_branch=branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
print(f"Created package PR pool/pkgA#{package_pr_number}")
|
||||
print(f"Created package PR mypool/pkgA#{package_pr_number}")
|
||||
|
||||
# 2. Make sure the workflow-pr service created related project PR
|
||||
project_pr_number = None
|
||||
print(f"Polling pool/pkgA PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
print(f"Polling mypool/pkgA PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
for _ in range(40):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgA", package_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", package_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
project_pr_number = int(match.group(1))
|
||||
break
|
||||
@@ -108,7 +112,7 @@ index 0000000..e69de29
|
||||
break
|
||||
|
||||
assert project_pr_number is not None, "Workflow bot did not create a project PR."
|
||||
print(f"Found project PR: products/SLFO#{project_pr_number}")
|
||||
print(f"Found project PR: myproducts/mySLFO#{project_pr_number}")
|
||||
|
||||
# 3. Make sure both PRs are merged automatically WITHOUT manual approvals
|
||||
print("Polling for PR merge status (only bot approval allowed)...")
|
||||
@@ -118,39 +122,40 @@ index 0000000..e69de29
|
||||
for i in range(15): # Poll for up to 15 seconds
|
||||
# Package PR
|
||||
if not package_merged:
|
||||
pkg_details = gitea_env.get_pr_details("pool/pkgA", package_pr_number)
|
||||
pkg_details = gitea_env.get_pr_details("mypool/pkgA", package_pr_number)
|
||||
if pkg_details.get("merged"):
|
||||
package_merged = True
|
||||
print(f"Package PR pool/pkgA#{package_pr_number} merged.")
|
||||
print(f"Package PR mypool/pkgA#{package_pr_number} merged.")
|
||||
else:
|
||||
# Approve ONLY bot if requested
|
||||
reviews = gitea_env.list_reviews("pool/pkgA", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgA", package_pr_number)
|
||||
if any(r["state"] == "REQUEST_REVIEW" and r["user"]["login"] == "autogits_obs_staging_bot" for r in reviews):
|
||||
gitea_env.approve_requested_reviews("pool/pkgA", package_pr_number)
|
||||
gitea_env.approve_requested_reviews("mypool/pkgA", package_pr_number)
|
||||
|
||||
# Project PR
|
||||
if not project_merged:
|
||||
prj_details = gitea_env.get_pr_details("products/SLFO", project_pr_number)
|
||||
prj_details = gitea_env.get_pr_details("myproducts/mySLFO", project_pr_number)
|
||||
if prj_details.get("merged"):
|
||||
project_merged = True
|
||||
print(f"Project PR products/SLFO#{project_pr_number} merged.")
|
||||
print(f"Project PR myproducts/mySLFO#{project_pr_number} merged.")
|
||||
else:
|
||||
# Approve ONLY bot if requested
|
||||
reviews = gitea_env.list_reviews("products/SLFO", project_pr_number)
|
||||
reviews = gitea_env.list_reviews("myproducts/mySLFO", project_pr_number)
|
||||
if any(r["state"] == "REQUEST_REVIEW" and r["user"]["login"] == "autogits_obs_staging_bot" for r in reviews):
|
||||
gitea_env.approve_requested_reviews("products/SLFO", project_pr_number)
|
||||
gitea_env.approve_requested_reviews("myproducts/mySLFO", project_pr_number)
|
||||
|
||||
if package_merged and project_merged:
|
||||
break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
assert package_merged, f"Package PR pool/pkgA#{package_pr_number} was not merged automatically."
|
||||
assert project_merged, f"Project PR products/SLFO#{project_pr_number} was not merged automatically."
|
||||
assert package_merged, f"Package PR mypool/pkgA#{package_pr_number} was not merged automatically."
|
||||
assert project_merged, f"Project PR myproducts/mySLFO#{project_pr_number} was not merged automatically."
|
||||
print("Both PRs merged successfully by maintainer rule.")
|
||||
|
||||
|
||||
@pytest.mark.t005
|
||||
# @pytest.mark.xfail(reason="TBD troubleshoot")
|
||||
def test_005_any_maintainer_approval_sufficient(maintainer_env, ownerA_client, ownerBB_client):
|
||||
"""
|
||||
Test scenario:
|
||||
@@ -161,28 +166,30 @@ def test_005_any_maintainer_approval_sufficient(maintainer_env, ownerA_client, o
|
||||
"""
|
||||
gitea_env, test_full_repo_name, branch_name = maintainer_env
|
||||
|
||||
# 1. Create a package PR for pool/pkgB as ownerA
|
||||
diff = """diff --git a/pkgB_test_fixture.txt b/pkgB_test_fixture.txt
|
||||
# 1. Create a package PR for mypool/pkgB as ownerA
|
||||
ts = int(time.time() * 1000)
|
||||
filename = f"pkgB_test_{ts}.txt"
|
||||
diff = f"""diff --git a/{filename} b/{filename}
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
"""
|
||||
print(f"--- Creating package PR in pool/pkgB on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("pool/pkgB", diff, "Test Single Maintainer Merge", True, base_branch=branch_name)
|
||||
print(f"--- Creating package PR in mypool/pkgB on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("mypool/pkgB", diff, "Test Single Maintainer Merge", True, base_branch=branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
print(f"Created package PR pool/pkgB#{package_pr_number}")
|
||||
print(f"Created package PR mypool/pkgB#{package_pr_number}")
|
||||
|
||||
# 2. Make sure the workflow-pr service created related project PR
|
||||
project_pr_number = None
|
||||
print(f"Polling pool/pkgB PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
print(f"Polling mypool/pkgB PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
for _ in range(40):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgB", package_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgB", package_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
project_pr_number = int(match.group(1))
|
||||
break
|
||||
@@ -190,13 +197,13 @@ index 0000000..e69de29
|
||||
break
|
||||
|
||||
assert project_pr_number is not None, "Workflow bot did not create a project PR."
|
||||
print(f"Found project PR: products/SLFO#{project_pr_number}")
|
||||
print(f"Found project PR: myproducts/mySLFO#{project_pr_number}")
|
||||
|
||||
# 3. Check that review requests came to ownerB and ownerBB
|
||||
print("Checking for review requests from ownerB and ownerBB...")
|
||||
reviewers_requested = set()
|
||||
for _ in range(20):
|
||||
reviews = gitea_env.list_reviews("pool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
reviewers_requested = {r["user"]["login"] for r in reviews if r["state"] == "REQUEST_REVIEW"}
|
||||
if "ownerB" in reviewers_requested and "ownerBB" in reviewers_requested:
|
||||
break
|
||||
@@ -208,41 +215,21 @@ index 0000000..e69de29
|
||||
|
||||
# 4. ownerBB leaves review, ownerB does not.
|
||||
print("ownerBB approving the PR...")
|
||||
ownerBB_client.create_review("pool/pkgB", package_pr_number, event="APPROVED", body="Approval from ownerBB")
|
||||
ownerBB_client.create_review("mypool/pkgB", package_pr_number, event="APPROVED", body="Approval from ownerBB")
|
||||
|
||||
# 5. Check that both PRs are merged automatically
|
||||
print("Polling for PR merge status (only bot approval allowed for project PR)...")
|
||||
package_merged = False
|
||||
project_merged = False
|
||||
|
||||
for i in range(15): # Poll for up to 15 seconds
|
||||
# Package PR
|
||||
if not package_merged:
|
||||
pkg_details = gitea_env.get_pr_details("pool/pkgB", package_pr_number)
|
||||
if pkg_details.get("merged"):
|
||||
package_merged = True
|
||||
print(f"Package PR pool/pkgB#{package_pr_number} merged.")
|
||||
|
||||
# Project PR
|
||||
if not project_merged:
|
||||
prj_details = gitea_env.get_pr_details("products/SLFO", project_pr_number)
|
||||
if prj_details.get("merged"):
|
||||
project_merged = True
|
||||
print(f"Project PR products/SLFO#{project_pr_number} merged.")
|
||||
else:
|
||||
# Approve ONLY bot if requested
|
||||
reviews = gitea_env.list_reviews("products/SLFO", project_pr_number)
|
||||
if any(r["state"] == "REQUEST_REVIEW" and r["user"]["login"] == "autogits_obs_staging_bot" for r in reviews):
|
||||
gitea_env.approve_requested_reviews("products/SLFO", project_pr_number)
|
||||
|
||||
if package_merged and project_merged:
|
||||
break
|
||||
|
||||
# 5. Check that review request for ownerB is removed
|
||||
print("Polling for ownerB review request removal...")
|
||||
ownerB_removed = False
|
||||
for _ in range(30):
|
||||
time.sleep(1)
|
||||
|
||||
assert package_merged, f"Package PR pool/pkgB#{package_pr_number} was not merged automatically."
|
||||
assert project_merged, f"Project PR products/SLFO#{project_pr_number} was not merged automatically."
|
||||
print("Both PRs merged successfully with only one maintainer approval.")
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
reviewers_requested = {r["user"]["login"] for r in reviews if r["state"] == "REQUEST_REVIEW"}
|
||||
if "ownerB" not in reviewers_requested:
|
||||
ownerB_removed = True
|
||||
break
|
||||
|
||||
assert ownerB_removed, f"ownerB review request was not removed after ownerBB approval. Current requested: {reviewers_requested}"
|
||||
print("Confirmed: ownerB review request removed after single maintainer approval.")
|
||||
|
||||
|
||||
@pytest.mark.t006
|
||||
@@ -257,37 +244,39 @@ def test_006_maintainer_rejection_removes_other_requests(maintainer_env, ownerA_
|
||||
"""
|
||||
gitea_env, test_full_repo_name, branch_name = maintainer_env
|
||||
|
||||
# 1. Create a package PR for pool/pkgB as ownerA
|
||||
diff = """diff --git a/pkgB_rejection_test.txt b/pkgB_rejection_test.txt
|
||||
# 1. Create a package PR for mypool/pkgB as ownerA
|
||||
ts = int(time.time() * 1000)
|
||||
filename = f"pkgB_rejection_test_{ts}.txt"
|
||||
diff = f"""diff --git a/{filename} b/{filename}
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
"""
|
||||
print(f"--- Creating package PR in pool/pkgB on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("pool/pkgB", diff, "Test Maintainer Rejection", True, base_branch=branch_name)
|
||||
print(f"--- Creating package PR in mypool/pkgB on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("mypool/pkgB", diff, "Test Maintainer Rejection", True, base_branch=branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
print(f"Created package PR pool/pkgB#{package_pr_number}")
|
||||
print(f"Created package PR mypool/pkgB#{package_pr_number}")
|
||||
|
||||
# 2. Check that review requests came to ownerB and ownerBB
|
||||
print("Checking for review requests from ownerB and ownerBB...")
|
||||
for _ in range(20):
|
||||
reviews = gitea_env.list_reviews("pool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
reviewers_requested = {r["user"]["login"] for r in reviews if r["state"] == "REQUEST_REVIEW"}
|
||||
if "ownerB" in reviewers_requested and "ownerBB" in reviewers_requested:
|
||||
break
|
||||
time.sleep(1)
|
||||
else:
|
||||
reviews = gitea_env.list_reviews("pool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
reviewers_requested = {r["user"]["login"] for r in reviews if r["state"] == "REQUEST_REVIEW"}
|
||||
pytest.fail(f"ownerB and ownerBB were not both requested. Got: {reviewers_requested}")
|
||||
|
||||
# 3. ownerBB rejects the PR
|
||||
print("ownerBB rejecting the PR...")
|
||||
ownerBB_client.create_review("pool/pkgB", package_pr_number, event="REQUEST_CHANGES", body="Rejecting from ownerBB")
|
||||
ownerBB_client.create_review("mypool/pkgB", package_pr_number, event="REQUEST_CHANGES", body="Rejecting from ownerBB")
|
||||
|
||||
# 4. Check that review request for ownerB is removed
|
||||
print("Checking if ownerB's review request is removed...")
|
||||
for _ in range(20):
|
||||
reviews = gitea_env.list_reviews("pool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
reviewers_requested = {r["user"]["login"] for r in reviews if r["state"] == "REQUEST_REVIEW"}
|
||||
if "ownerB" not in reviewers_requested:
|
||||
print("Confirmed: ownerB's review request was removed.")
|
||||
@@ -315,28 +304,30 @@ def test_007_review_required_needs_all_approvals(review_required_env, ownerA_cli
|
||||
ownerA_client._request("GET", "users/admin")
|
||||
print(f"ownerA_client smoke test passed")
|
||||
|
||||
# 1. Create a package PR for pool/pkgB as ownerA
|
||||
diff = """diff --git a/pkgB_review_required_test.txt b/pkgB_review_required_test.txt
|
||||
# 1. Create a package PR for mypool/pkgB as ownerA
|
||||
ts = int(time.time() * 1000)
|
||||
filename = f"pkgB_review_required_test_{ts}.txt"
|
||||
diff = f"""diff --git a/{filename} b/{filename}
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
"""
|
||||
print(f"--- Creating package PR in pool/pkgB on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("pool/pkgB", diff, "Test Review Required", True, base_branch=branch_name)
|
||||
print(f"--- Creating package PR in mypool/pkgB on branch {branch_name} as ownerA ---")
|
||||
package_pr = ownerA_client.create_gitea_pr("mypool/pkgB", diff, "Test Review Required", True, base_branch=branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
print(f"Created package PR pool/pkgB#{package_pr_number}")
|
||||
print(f"Created package PR mypool/pkgB#{package_pr_number}")
|
||||
|
||||
# 2. Make sure the workflow-pr service created related project PR
|
||||
project_pr_number = None
|
||||
print(f"Polling pool/pkgB PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
print(f"Polling mypool/pkgB PR #{package_pr_number} timeline for forwarded PR event...")
|
||||
for _ in range(40):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgB", package_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgB", package_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
project_pr_number = int(match.group(1))
|
||||
break
|
||||
@@ -344,38 +335,38 @@ index 0000000..e69de29
|
||||
break
|
||||
|
||||
assert project_pr_number is not None, "Workflow bot did not create a project PR."
|
||||
print(f"Found project PR: products/SLFO#{project_pr_number}")
|
||||
print(f"Found project PR: myproducts/mySLFO#{project_pr_number}")
|
||||
|
||||
# 3. Check that review requests came to ownerB and ownerBB
|
||||
print("Checking for review requests from ownerB and ownerBB...")
|
||||
for _ in range(20):
|
||||
reviews = gitea_env.list_reviews("pool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
reviewers_requested = {r["user"]["login"] for r in reviews if r["state"] == "REQUEST_REVIEW"}
|
||||
if "ownerB" in reviewers_requested and "ownerBB" in reviewers_requested:
|
||||
break
|
||||
time.sleep(1)
|
||||
else:
|
||||
reviews = gitea_env.list_reviews("pool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
reviewers_requested = {r["user"]["login"] for r in reviews if r["state"] == "REQUEST_REVIEW"}
|
||||
pytest.fail(f"ownerB and ownerBB were not both requested. Got: {reviewers_requested}")
|
||||
|
||||
# 4. ownerBB leaves review, ownerB does not.
|
||||
print("ownerBB approving the PR...")
|
||||
ownerBB_client.create_review("pool/pkgB", package_pr_number, event="APPROVED", body="Approval from ownerBB")
|
||||
ownerBB_client.create_review("mypool/pkgB", package_pr_number, event="APPROVED", body="Approval from ownerBB")
|
||||
|
||||
# 5. Check that the PR is NOT merged automatically and ownerB request remains
|
||||
print("Waiting to ensure PR is NOT merged and ownerB request remains...")
|
||||
for i in range(10):
|
||||
pkg_details = gitea_env.get_pr_details("pool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("pool/pkgB", package_pr_number)
|
||||
pkg_details = gitea_env.get_pr_details("mypool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
review_states = [(r["user"]["login"], r["state"]) for r in reviews]
|
||||
print(f"Attempt {i+1}: Merged={pkg_details.get('merged')}, Reviews={review_states}")
|
||||
time.sleep(2)
|
||||
|
||||
pkg_details = gitea_env.get_pr_details("pool/pkgB", package_pr_number)
|
||||
pkg_details = gitea_env.get_pr_details("mypool/pkgB", package_pr_number)
|
||||
assert not pkg_details.get("merged"), "Package PR was merged automatically but it should NOT have been (ReviewRequired=true)."
|
||||
|
||||
reviews = gitea_env.list_reviews("pool/pkgB", package_pr_number)
|
||||
reviews = gitea_env.list_reviews("mypool/pkgB", package_pr_number)
|
||||
reviewers_requested = {r["user"]["login"] for r in reviews if r["state"] == "REQUEST_REVIEW"}
|
||||
assert "ownerB" in reviewers_requested, f"ownerB's review request was removed, but it should have remained. All reviews: {[(r['user']['login'], r['state']) for r in reviews]}"
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ pytest.forwarded_pr_number = None
|
||||
def test_001_project_pr(gitea_env):
|
||||
"""Forwarded PR correct title"""
|
||||
diff = "diff --git a/another_test.txt b/another_test.txt\nnew file mode 100644\nindex 0000000..e69de29\n"
|
||||
pytest.pr = gitea_env.create_gitea_pr("pool/pkgA", diff, "Test PR", False)
|
||||
pytest.pr = gitea_env.create_gitea_pr("mypool/pkgA", diff, "Test PR", False)
|
||||
pytest.initial_pr_number = pytest.pr["number"]
|
||||
time.sleep(5) # Give Gitea some time to process the PR and make the timeline available
|
||||
|
||||
@@ -31,18 +31,18 @@ def test_001_project_pr(gitea_env):
|
||||
|
||||
pytest.forwarded_pr_number = None
|
||||
print(
|
||||
f"Polling pool/pkgA PR #{pytest.initial_pr_number} timeline for forwarded PR event..."
|
||||
f"Polling mypool/pkgA PR #{pytest.initial_pr_number} timeline for forwarded PR event..."
|
||||
)
|
||||
# Instead of polling timeline, check if forwarded PR exists directly
|
||||
for _ in range(20):
|
||||
time.sleep(1)
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgA", pytest.initial_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", pytest.initial_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
pytest.forwarded_pr_number = match.group(1)
|
||||
break
|
||||
@@ -51,7 +51,7 @@ def test_001_project_pr(gitea_env):
|
||||
assert (
|
||||
pytest.forwarded_pr_number is not None
|
||||
), "Workflow bot did not create a forwarded PR."
|
||||
pytest.pr_details = gitea_env.get_pr_details("products/SLFO", pytest.forwarded_pr_number)
|
||||
pytest.pr_details = gitea_env.get_pr_details("myproducts/mySLFO", pytest.forwarded_pr_number)
|
||||
assert (
|
||||
pytest.pr_details["title"] == "Forwarded PRs: pkgA"
|
||||
), "Forwarded PR correct title"
|
||||
@@ -62,13 +62,13 @@ def test_001_project_pr(gitea_env):
|
||||
def test_002_updated_project_pr(gitea_env):
|
||||
"""Forwarded PR head is updated"""
|
||||
diff = "diff --git a/another_test.txt b/another_test.txt\nnew file mode 100444\nindex 0000000..e69de21\n"
|
||||
gitea_env.modify_gitea_pr("pool/pkgA", pytest.initial_pr_number, diff, "Tweaks")
|
||||
gitea_env.modify_gitea_pr("mypool/pkgA", pytest.initial_pr_number, diff, "Tweaks")
|
||||
sha_old = pytest.pr_details["head"]["sha"]
|
||||
|
||||
sha_changed = False
|
||||
for _ in range(20):
|
||||
time.sleep(1)
|
||||
new_pr_details = gitea_env.get_pr_details("products/SLFO", pytest.forwarded_pr_number)
|
||||
new_pr_details = gitea_env.get_pr_details("myproducts/mySLFO", pytest.forwarded_pr_number)
|
||||
sha_new = new_pr_details["head"]["sha"]
|
||||
if sha_new != sha_old:
|
||||
print(f"Sha changed from {sha_old} to {sha_new}")
|
||||
@@ -82,17 +82,17 @@ def test_002_updated_project_pr(gitea_env):
|
||||
@pytest.mark.dependency(depends=["test_001_project_pr"])
|
||||
def test_003_wip(gitea_env):
|
||||
"""WIP flag set for PR"""
|
||||
# 1. set WIP flag in PR f"pool/pkgA#{pytest.initial_pr_number}"
|
||||
initial_pr_details = gitea_env.get_pr_details("pool/pkgA", pytest.initial_pr_number)
|
||||
# 1. set WIP flag in PR f"mypool/pkgA#{pytest.initial_pr_number}"
|
||||
initial_pr_details = gitea_env.get_pr_details("mypool/pkgA", pytest.initial_pr_number)
|
||||
wip_title = "WIP: " + initial_pr_details["title"]
|
||||
|
||||
gitea_env.update_gitea_pr_properties("pool/pkgA", pytest.initial_pr_number, title=wip_title)
|
||||
# 2. in loop check whether WIP flag is set for PR f"products/SLFO #{pytest.forwarded_pr_number}"
|
||||
gitea_env.update_gitea_pr_properties("mypool/pkgA", pytest.initial_pr_number, title=wip_title)
|
||||
# 2. in loop check whether WIP flag is set for PR f"myproducts/mySLFO #{pytest.forwarded_pr_number}"
|
||||
wip_flag_set = False
|
||||
for _ in range(20):
|
||||
time.sleep(1)
|
||||
forwarded_pr_details = gitea_env.get_pr_details(
|
||||
"products/SLFO", pytest.forwarded_pr_number
|
||||
"myproducts/mySLFO", pytest.forwarded_pr_number
|
||||
)
|
||||
if "WIP: " in forwarded_pr_details["title"]:
|
||||
wip_flag_set = True
|
||||
@@ -100,19 +100,19 @@ def test_003_wip(gitea_env):
|
||||
|
||||
assert wip_flag_set, "WIP flag was not set in the forwarded PR."
|
||||
|
||||
# Remove WIP flag from PR f"pool/pkgA#{pytest.initial_pr_number}"
|
||||
initial_pr_details = gitea_env.get_pr_details("pool/pkgA", pytest.initial_pr_number)
|
||||
# Remove WIP flag from PR f"mypool/pkgA#{pytest.initial_pr_number}"
|
||||
initial_pr_details = gitea_env.get_pr_details("mypool/pkgA", pytest.initial_pr_number)
|
||||
non_wip_title = initial_pr_details["title"].replace("WIP: ", "")
|
||||
gitea_env.update_gitea_pr_properties(
|
||||
"pool/pkgA", pytest.initial_pr_number, title=non_wip_title
|
||||
"mypool/pkgA", pytest.initial_pr_number, title=non_wip_title
|
||||
)
|
||||
|
||||
# In loop check whether WIP flag is removed for PR f"products/SLFO #{pytest.forwarded_pr_number}"
|
||||
# In loop check whether WIP flag is removed for PR f"myproducts/mySLFO #{pytest.forwarded_pr_number}"
|
||||
wip_flag_removed = False
|
||||
for _ in range(20):
|
||||
time.sleep(1)
|
||||
forwarded_pr_details = gitea_env.get_pr_details(
|
||||
"products/SLFO", pytest.forwarded_pr_number
|
||||
"myproducts/mySLFO", pytest.forwarded_pr_number
|
||||
)
|
||||
if "WIP: " not in forwarded_pr_details["title"]:
|
||||
wip_flag_removed = True
|
||||
@@ -121,7 +121,7 @@ def test_003_wip(gitea_env):
|
||||
|
||||
|
||||
@pytest.mark.t005
|
||||
@pytest.mark.xfail(reason="works only in ibs_state branch?")
|
||||
@pytest.mark.skip(reason="works only in ibs_state branch?")
|
||||
@pytest.mark.dependency()
|
||||
def test_005_NoProjectGitPR_edits_disabled(no_project_git_pr_env, test_user_client):
|
||||
"""
|
||||
@@ -139,7 +139,7 @@ index 0000000..e69de29
|
||||
@@ -0,0 +1 @@
|
||||
+Initial content
|
||||
"""
|
||||
package_pr = test_user_client.create_gitea_pr("pool/pkgA", initial_diff, "Test PR for No Project PR, No Edits", False, base_branch=dev_branch_name)
|
||||
package_pr = test_user_client.create_gitea_pr("mypool/pkgA", initial_diff, "Test PR for No Project PR, No Edits", False, base_branch=dev_branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
print(f"Created Package PR #{package_pr_number}")
|
||||
|
||||
@@ -147,29 +147,29 @@ index 0000000..e69de29
|
||||
project_pr_created = False
|
||||
for i in range(10): # Poll for some time
|
||||
time.sleep(2)
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgA", package_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", package_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
project_pr_created = True
|
||||
break
|
||||
if project_pr_created:
|
||||
break
|
||||
|
||||
assert not project_pr_created, "Workflow bot unexpectedly created a Project PR in products/SLFO."
|
||||
assert not project_pr_created, "Workflow bot unexpectedly created a Project PR in myproducts/mySLFO."
|
||||
print("Verification complete: No Project PR was created by the bot.")
|
||||
|
||||
# 3. Manually create the Project PR
|
||||
pkgA_main_sha = gitea_env._request("GET", f"repos/pool/pkgA/branches/{dev_branch_name}").json()["commit"]["id"]
|
||||
package_pr_details = gitea_env.get_pr_details("pool/pkgA", package_pr_number)
|
||||
pkgA_main_sha = gitea_env._request("GET", f"repos/mypool/pkgA/branches/{dev_branch_name}").json()["commit"]["id"]
|
||||
package_pr_details = gitea_env.get_pr_details("mypool/pkgA", package_pr_number)
|
||||
pkgA_pr_head_sha = package_pr_details["head"]["sha"]
|
||||
|
||||
project_pr_title = "Forwarded PRs: pkgA (Manual)"
|
||||
project_pr_body = f"Manual Project PR for NoProjectGitPR. \nPR: pool/pkgA!{package_pr_number}"
|
||||
project_pr_body = f"Manual Project PR for NoProjectGitPR. \nPR: mypool/pkgA!{package_pr_number}"
|
||||
project_pr_diff = f"""diff --git a/pkgA b/pkgA
|
||||
index {pkgA_main_sha[:7]}..{pkgA_pr_head_sha[:7]} 160000
|
||||
--- a/pkgA
|
||||
@@ -199,14 +199,14 @@ index 0000000..e69de29
|
||||
@@ -0,0 +1 @@
|
||||
+Trigger content
|
||||
"""
|
||||
test_user_client.modify_gitea_pr("pool/pkgA", package_pr_number, new_diff_content, "Trigger bot update")
|
||||
test_user_client.modify_gitea_pr("mypool/pkgA", package_pr_number, new_diff_content, "Trigger bot update")
|
||||
|
||||
# 5. Verify that the bot adds a warning comment because it cannot update the manual PR (edits disabled)
|
||||
warning_found = False
|
||||
print(f"Polling Package PR #{package_pr_number} for warning comment...")
|
||||
for _ in range(20):
|
||||
time.sleep(3)
|
||||
comments = gitea_env.get_comments("pool/pkgA", package_pr_number)
|
||||
comments = gitea_env.get_comments("mypool/pkgA", package_pr_number)
|
||||
for comment in comments:
|
||||
# According to test-plan.md, the warning explains that it cannot update the PR.
|
||||
if "cannot update" in comment.get("body", "").lower():
|
||||
@@ -221,7 +221,7 @@ index 0000000..e69de29
|
||||
|
||||
|
||||
@pytest.mark.t006
|
||||
@pytest.mark.xfail(reason="works only in ibs_state branch?")
|
||||
@pytest.mark.skip(reason="works only in ibs_state branch?")
|
||||
@pytest.mark.dependency()
|
||||
def test_006_NoProjectGitPR_edits_enabled(no_project_git_pr_env, test_user_client):
|
||||
"""
|
||||
@@ -239,42 +239,42 @@ index 0000000..e69de29
|
||||
@@ -0,0 +1 @@
|
||||
+New feature content
|
||||
"""
|
||||
package_pr = test_user_client.create_gitea_pr("pool/pkgA", diff, "Test PR for NoProjectGitPR", False, base_branch=dev_branch_name)
|
||||
package_pr = test_user_client.create_gitea_pr("mypool/pkgA", diff, "Test PR for NoProjectGitPR", False, base_branch=dev_branch_name)
|
||||
package_pr_number = package_pr["number"]
|
||||
|
||||
# Enable "Allow edits from maintainers"
|
||||
test_user_client.update_gitea_pr_properties("pool/pkgA", package_pr_number, allow_maintainer_edit=True)
|
||||
test_user_client.update_gitea_pr_properties("mypool/pkgA", package_pr_number, allow_maintainer_edit=True)
|
||||
print(f"Created Package PR #{package_pr_number} and enabled 'Allow edits from maintainers'.")
|
||||
|
||||
# Get SHAs needed for the manual Project PR diff
|
||||
pkgA_main_sha = gitea_env._request("GET", f"repos/pool/pkgA/branches/{dev_branch_name}").json()["commit"]["id"]
|
||||
package_pr_details = gitea_env.get_pr_details("pool/pkgA", package_pr_number)
|
||||
pkgA_main_sha = gitea_env._request("GET", f"repos/mypool/pkgA/branches/{dev_branch_name}").json()["commit"]["id"]
|
||||
package_pr_details = gitea_env.get_pr_details("mypool/pkgA", package_pr_number)
|
||||
pkgA_pr_head_sha = package_pr_details["head"]["sha"]
|
||||
|
||||
# 3. Assert that the workflow-pr bot did not create a Project PR in the products/SLFO repository
|
||||
# 3. Assert that the workflow-pr bot did not create a Project PR in the myproducts/mySLFO repository
|
||||
project_pr_created = False
|
||||
for i in range(20): # Poll for a reasonable time
|
||||
time.sleep(2) # Wait a bit longer to be sure
|
||||
timeline_events = gitea_env.get_timeline_events("pool/pkgA", package_pr_number)
|
||||
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", package_pr_number)
|
||||
for event in timeline_events:
|
||||
if event.get("type") == "pull_ref":
|
||||
if not (ref_issue := event.get("ref_issue")):
|
||||
continue
|
||||
url_to_check = ref_issue.get("html_url", "")
|
||||
# Regex now searches for products/SLFO/pulls/(\d+)
|
||||
match = re.search(r"products/SLFO/pulls/(\d+)", url_to_check)
|
||||
# Regex now searches for myproducts/mySLFO/pulls/(\d+)
|
||||
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
||||
if match:
|
||||
project_pr_created = True
|
||||
break
|
||||
if project_pr_created:
|
||||
break
|
||||
|
||||
assert not project_pr_created, "Workflow bot unexpectedly created a Project PR in products/SLFO."
|
||||
print("Verification complete: No Project PR was created in products/SLFO as expected.")
|
||||
assert not project_pr_created, "Workflow bot unexpectedly created a Project PR in myproducts/mySLFO."
|
||||
print("Verification complete: No Project PR was created in myproducts/mySLFO as expected.")
|
||||
|
||||
# 1. Create that Project PR from the test code.
|
||||
project_pr_title = "Forwarded PRs: pkgA"
|
||||
project_pr_body = f"Test Project PR for NoProjectGitPR. \nPR: pool/pkgA!{package_pr_number}"
|
||||
project_pr_body = f"Test Project PR for NoProjectGitPR. \nPR: mypool/pkgA!{package_pr_number}"
|
||||
project_pr_diff = f"""diff --git a/pkgA b/pkgA
|
||||
index {pkgA_main_sha[:7]}..{pkgA_pr_head_sha[:7]} 160000
|
||||
--- a/pkgA
|
||||
@@ -304,7 +304,7 @@ index 0000000..f587a12
|
||||
@@ -0,0 +1 @@
|
||||
+Another file content
|
||||
"""
|
||||
test_user_client.modify_gitea_pr("pool/pkgA", package_pr_number, new_diff_content, "Add another file to Package PR")
|
||||
test_user_client.modify_gitea_pr("mypool/pkgA", package_pr_number, new_diff_content, "Add another file to Package PR")
|
||||
print(f"Added new commit to Package PR #{package_pr_number}.")
|
||||
time.sleep(5) # Give the bot time to react
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ export GITEA_TOKEN
|
||||
echo "GITEA_TOKEN exported (length: ${#GITEA_TOKEN})"
|
||||
|
||||
# Wait for the dummy data to be created by the gitea setup script
|
||||
echo "Waiting for workflow.config in products/SLFO..."
|
||||
API_URL="http://gitea-test:3000/api/v1/repos/products/SLFO/contents/workflow.config"
|
||||
echo "Waiting for workflow.config in myproducts/mySLFO..."
|
||||
API_URL="http://gitea-test:3000/api/v1/repos/myproducts/mySLFO/contents/workflow.config"
|
||||
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token $GITEA_TOKEN" "$API_URL")
|
||||
|
||||
while [ "$HTTP_STATUS" != "200" ]; do
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
[
|
||||
"products/SLFO#main",
|
||||
"products/SLFO#dev",
|
||||
"products/SLFO#merge",
|
||||
"products/SLFO#maintainer-merge",
|
||||
"products/SLFO#review-required",
|
||||
"products/SLFO#label-test"
|
||||
"myproducts/mySLFO#main",
|
||||
"myproducts/mySLFO#staging-main",
|
||||
"myproducts/mySLFO#dev",
|
||||
"myproducts/mySLFO#merge",
|
||||
"myproducts/mySLFO#maintainer-merge",
|
||||
"myproducts/mySLFO#review-required",
|
||||
"myproducts/mySLFO#label-test",
|
||||
"myproducts/mySLFO#manual-merge"
|
||||
]
|
||||
|
||||
@@ -309,14 +309,17 @@ func (pr *PRProcessor) UpdatePrjGitPR(prset *common.PRSet) error {
|
||||
PrjGit := PrjGitPR.PR.Base.Repo
|
||||
prjGitPRbranch := PrjGitPR.PR.Head.Name
|
||||
if PrjGitPR.PR.Base.RepoID != PrjGitPR.PR.Head.RepoID {
|
||||
PrjGitPR.RemoteName, err = git.GitClone(common.DefaultGitPrj, "", PrjGit.SSHURL)
|
||||
git.GitExecOrPanic(common.DefaultGitPrj, "fetch", PrjGitPR.RemoteName, PrjGitPR.PR.Head.Sha)
|
||||
git.GitExecOrPanic(common.DefaultGitPrj, "checkout", PrjGitPR.PR.Head.Sha)
|
||||
common.LogInfo("Cannot update this PR as it's on another remote, not branch:", prjGitPRbranch, "Assuming this is by-design. (eg. project git PR only)")
|
||||
return nil
|
||||
// permission check, if submission comes from foreign repo
|
||||
if !PrjGitPR.PR.AllowMaintainerEdit {
|
||||
// well, wrong place...
|
||||
// common.LogError("Warning: source and target branch are in different repositories. We may not have the right permissions...")
|
||||
// Gitea.AddComment(PrjGitPR.PR, "This PR does not allow maintainer changes, but referenced package branch has changed!")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
PrjGitPR.RemoteName, err = git.GitClone(common.DefaultGitPrj, prjGitPRbranch, PrjGit.SSHURL)
|
||||
// PrjGitPR.RemoteName, err = git.GitClone(common.DefaultGitPrj, prjGitPRbranch, PrjGit.SSHURL)
|
||||
PrjGitPR.RemoteName, err = git.GitClone(common.DefaultGitPrj, PrjGitPR.PR.Head.Ref, PrjGitPR.PR.Head.Repo.SSHURL)
|
||||
common.PanicOnError(err)
|
||||
git.GitExecOrPanic(common.DefaultGitPrj, "fetch", PrjGitPR.RemoteName, PrjGitBranch)
|
||||
|
||||
@@ -364,6 +367,7 @@ func (pr *PRProcessor) UpdatePrjGitPR(prset *common.PRSet) error {
|
||||
}
|
||||
common.PanicOnError(git.GitExec(common.DefaultGitPrj, params...))
|
||||
PrjGitPR.PR.Head.Sha = newHeadCommit
|
||||
Gitea.SetLabels(PrjGit.Owner.UserName, PrjGit.Name, PrjGitPR.PR.Index, []string{prset.Config.Label("PR/updated")})
|
||||
}
|
||||
|
||||
// update PR
|
||||
|
||||
@@ -396,7 +396,62 @@ func TestUpdatePrjGitPR(t *testing.T) {
|
||||
Name: "feature",
|
||||
RepoID: 2, // Different RepoID
|
||||
Sha: "sha1",
|
||||
Repo: &models.Repository{
|
||||
SSHURL: "url",
|
||||
},
|
||||
},
|
||||
User: &models.User{UserName: "someone"},
|
||||
Mergeable: true,
|
||||
AllowMaintainerEdit: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
PR: &models.PullRequest{
|
||||
State: "open",
|
||||
Base: &models.PRBranchInfo{
|
||||
Name: "other",
|
||||
Repo: &models.Repository{
|
||||
Name: "other-pkg",
|
||||
Owner: &models.User{UserName: "test-org"},
|
||||
},
|
||||
},
|
||||
Head: &models.PRBranchInfo{
|
||||
Sha: "other-sha",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
mockGit.EXPECT().GitClone(common.DefaultGitPrj, gomock.Any(), gomock.Any()).Return("remote2", nil)
|
||||
mockGit.EXPECT().GitExecOrPanic(common.DefaultGitPrj, "fetch", "remote2", "main")
|
||||
mockGit.EXPECT().GitBranchHead(common.DefaultGitPrj, gomock.Any()).Return("sha1", nil).Times(2)
|
||||
mockGit.EXPECT().GitSubmoduleList(common.DefaultGitPrj, "HEAD").Return(map[string]string{"other-pkg": "other-sha"}, nil)
|
||||
|
||||
err := processor.UpdatePrjGitPR(prset)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("PR on another remote - not allowed", func(t *testing.T) {
|
||||
prset := &common.PRSet{
|
||||
Config: config,
|
||||
PRs: []*common.PRInfo{
|
||||
{
|
||||
PR: &models.PullRequest{
|
||||
Base: &models.PRBranchInfo{
|
||||
Name: "main",
|
||||
RepoID: 1,
|
||||
Repo: &models.Repository{
|
||||
Name: "test-prj",
|
||||
Owner: &models.User{UserName: "test-org"},
|
||||
},
|
||||
},
|
||||
Head: &models.PRBranchInfo{
|
||||
Name: "feature",
|
||||
RepoID: 2, // Different RepoID
|
||||
},
|
||||
AllowMaintainerEdit: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -412,10 +467,6 @@ func TestUpdatePrjGitPR(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
mockGit.EXPECT().GitClone(gomock.Any(), gomock.Any(), gomock.Any()).Return("remote2", nil)
|
||||
mockGit.EXPECT().GitExecOrPanic(gomock.Any(), "fetch", "remote2", "sha1")
|
||||
mockGit.EXPECT().GitExecOrPanic(gomock.Any(), "checkout", "sha1")
|
||||
|
||||
err := processor.UpdatePrjGitPR(prset)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -445,6 +496,9 @@ func TestUpdatePrjGitPR(t *testing.T) {
|
||||
Name: "PR_branch",
|
||||
RepoID: 1,
|
||||
Sha: "old-head",
|
||||
Repo: &models.Repository{
|
||||
SSHURL: "url",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -483,6 +537,7 @@ func TestUpdatePrjGitPR(t *testing.T) {
|
||||
mockGit.EXPECT().GitStatus(gomock.Any()).Return(nil, nil).AnyTimes()
|
||||
|
||||
// UpdatePullRequest expectation
|
||||
gitea.EXPECT().SetLabels(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
|
||||
gitea.EXPECT().UpdatePullRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
|
||||
|
||||
err := processor.UpdatePrjGitPR(prset)
|
||||
@@ -514,6 +569,9 @@ func TestUpdatePrjGitPR(t *testing.T) {
|
||||
Name: "PR_branch",
|
||||
RepoID: 1,
|
||||
Sha: "head",
|
||||
Repo: &models.Repository{
|
||||
SSHURL: "url",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user