-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: adds automated GH pull request creation to trestlebot
Signed-off-by: Jennifer Power <[email protected]>
- Loading branch information
Showing
11 changed files
with
670 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,14 +16,17 @@ | |
|
||
"""Test for top-level Trestle Bot logic.""" | ||
|
||
import json | ||
import os | ||
from typing import Tuple | ||
from unittest.mock import Mock, patch | ||
|
||
import pytest | ||
from git.repo import Repo | ||
|
||
import trestlebot.bot as bot | ||
from tests.testutils import clean | ||
from trestlebot.provider import GitProvider | ||
|
||
|
||
def test_stage_files(tmp_repo: Tuple[str, Repo]) -> None: | ||
|
@@ -148,6 +151,47 @@ def test_local_commit_with_author(tmp_repo: Tuple[str, Repo]) -> None: | |
clean(repo_path, repo) | ||
|
||
|
||
def test_run(tmp_repo: Tuple[str, Repo]) -> None: | ||
"""Test bot run with mocked push""" | ||
repo_path, repo = tmp_repo | ||
|
||
# Create a test file | ||
test_file_path = os.path.join(repo_path, "test.txt") | ||
with open(test_file_path, "w") as f: | ||
f.write("Test content") | ||
|
||
repo.create_remote("origin", url="git.test.com/test/repo.git") | ||
|
||
with patch("git.remote.Remote.push") as mock_push: | ||
mock_push.return_value = "Mocked result" | ||
|
||
# Test running the bot | ||
commit_sha = bot.run( | ||
working_dir=repo_path, | ||
branch="main", | ||
commit_name="Test User", | ||
commit_email="[email protected]", | ||
commit_message="Test commit message", | ||
author_name="The Author", | ||
author_email="[email protected]", | ||
patterns=["*.txt"], | ||
dry_run=False, | ||
) | ||
assert commit_sha != "" | ||
|
||
# Verify that the commit is made | ||
commit = next(repo.iter_commits()) | ||
assert commit.message.strip() == "Test commit message" | ||
assert commit.author.name == "The Author" | ||
assert commit.author.email == "[email protected]" | ||
mock_push.assert_called_once_with(refspec="HEAD:main") | ||
|
||
# Verify that the file is tracked by the commit | ||
assert os.path.basename(test_file_path) in commit.stats.files | ||
|
||
clean(repo_path, repo) | ||
|
||
|
||
def test_run_dry_run(tmp_repo: Tuple[str, Repo]) -> None: | ||
"""Test bot run with dry run""" | ||
repo_path, repo = tmp_repo | ||
|
@@ -204,6 +248,48 @@ def test_empty_commit(tmp_repo: Tuple[str, Repo]) -> None: | |
clean(repo_path, repo) | ||
|
||
|
||
def test_non_matching_files(tmp_repo: Tuple[str, Repo]) -> None: | ||
"""Test that non-matching files are ignored""" | ||
repo_path, repo = tmp_repo | ||
|
||
# Create a test file | ||
test_file_path = os.path.join(repo_path, "test.txt") | ||
with open(test_file_path, "w") as f: | ||
f.write("Test content") | ||
|
||
# Create a test file | ||
data = {"test": "file"} | ||
test_json_path = os.path.join(repo_path, "test.json") | ||
with open(test_json_path, "w") as f: | ||
json.dump(data, f, indent=4) | ||
|
||
# Test running the bot | ||
commit_sha = bot.run( | ||
working_dir=repo_path, | ||
branch="main", | ||
commit_name="Test User", | ||
commit_email="[email protected]", | ||
commit_message="Test commit message", | ||
author_name="The Author", | ||
author_email="[email protected]", | ||
patterns=["*.json"], | ||
dry_run=True, | ||
) | ||
assert commit_sha != "" | ||
|
||
# Verify that the commit is made | ||
commit = next(repo.iter_commits()) | ||
assert commit.message.strip() == "Test commit message" | ||
assert commit.author.name == "The Author" | ||
assert commit.author.email == "[email protected]" | ||
|
||
# Verify that only the JSON file is tracked in the commits | ||
assert os.path.basename(test_file_path) not in commit.stats.files | ||
assert os.path.basename(test_json_path) in commit.stats.files | ||
|
||
clean(repo_path, repo) | ||
|
||
|
||
def test_run_check_only(tmp_repo: Tuple[str, Repo]) -> None: | ||
"""Test bot run with check_only""" | ||
repo_path, repo = tmp_repo | ||
|
@@ -229,3 +315,62 @@ def test_run_check_only(tmp_repo: Tuple[str, Repo]) -> None: | |
dry_run=True, | ||
check_only=True, | ||
) | ||
|
||
clean(repo_path, repo) | ||
|
||
|
||
def test_run_with_provider(tmp_repo: Tuple[str, Repo]) -> None: | ||
"""Test bot run with mock git provider""" | ||
repo_path, repo = tmp_repo | ||
|
||
# Create a test file | ||
test_file_path = os.path.join(repo_path, "test.txt") | ||
with open(test_file_path, "w") as f: | ||
f.write("Test content") | ||
|
||
mock = Mock(spec=GitProvider) | ||
mock.create_pull_request.return_value = "10" | ||
mock.parse_repository.return_value = ("ns", "repo") | ||
|
||
repo.create_remote("origin", url="git.test.com/test/repo.git") | ||
|
||
with patch("git.remote.Remote.push") as mock_push: | ||
mock_push.return_value = "Mocked result" | ||
|
||
# Test running the bot | ||
commit_sha = bot.run( | ||
working_dir=repo_path, | ||
branch="test", | ||
commit_name="Test User", | ||
commit_email="[email protected]", | ||
commit_message="Test commit message", | ||
author_name="The Author", | ||
author_email="[email protected]", | ||
patterns=["*.txt"], | ||
git_provider=mock, | ||
target_branch="main", | ||
dry_run=False, | ||
) | ||
assert commit_sha != "" | ||
|
||
# Verify that the commit is made | ||
commit = next(repo.iter_commits()) | ||
assert commit.message.strip() == "Test commit message" | ||
assert commit.author.name == "The Author" | ||
assert commit.author.email == "[email protected]" | ||
|
||
# Verify that the file is tracked by the commit | ||
assert os.path.basename(test_file_path) in commit.stats.files | ||
|
||
# Verify that the method was called with the expected arguments | ||
mock.create_pull_request.assert_called_once_with( | ||
ns="ns", | ||
repo_name="repo", | ||
head_branch="test", | ||
base_branch="main", | ||
title="Automatic updates from trestlebot", | ||
body="", | ||
) | ||
mock_push.assert_called_once_with(refspec="HEAD:test") | ||
|
||
clean(repo_path, repo) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#!/usr/bin/python | ||
|
||
# Copyright 2023 Red Hat, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
# not use this file except in compliance with the License. You may obtain | ||
# a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
# License for the specific language governing permissions and limitations | ||
# under the License. | ||
|
||
"""Test for GitHub provider logic""" | ||
|
||
from typing import Tuple | ||
|
||
import pytest | ||
from git.repo import Repo | ||
|
||
from tests.testutils import clean | ||
from trestlebot.github import GitHub | ||
from trestlebot.provider import GitProviderException | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"repo_url", | ||
[ | ||
"https://github.com/owner/repo", | ||
"https://github.com/owner/repo.git", | ||
"github.com/owner/repo.git", | ||
], | ||
) | ||
def test_parse_repository(repo_url: str) -> None: | ||
"""Tests parsing valid GitHub repo urls""" | ||
gh = GitHub("fake") | ||
|
||
owner, repo_name = gh.parse_repository(repo_url) | ||
|
||
assert owner == "owner" | ||
assert repo_name == "repo" | ||
|
||
|
||
def test_parse_repository_integration(tmp_repo: Tuple[str, Repo]) -> None: | ||
"""Tests integration with git remote get-url""" | ||
repo_path, repo = tmp_repo | ||
|
||
repo.create_remote("origin", url="github.com/test/repo.git") | ||
|
||
remote = repo.remote() | ||
|
||
gh = GitHub("fake") | ||
|
||
owner, repo_name = gh.parse_repository(remote.url) | ||
|
||
assert owner == "test" | ||
assert repo_name == "repo" | ||
|
||
clean(repo_path, repo) | ||
|
||
|
||
def test_parse_repository_with_incorrect_name() -> None: | ||
"""Test an invalid url input""" | ||
gh = GitHub("fake") | ||
with pytest.raises( | ||
GitProviderException, | ||
match="https://notgithub.com/owner/repo.git is an invalid GitHub repo URL", | ||
): | ||
gh.parse_repository("https://notgithub.com/owner/repo.git") |
Oops, something went wrong.