Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support using the merge ref instead of the head ref in a pull request #601

Merged
merged 3 commits into from
Jul 12, 2021

Conversation

bcrocker15
Copy link
Contributor

Add merge_commit_sha and mergeable properties to GithubPullRequest class
(and PullRequest superclass).

OGR issue #584.

Signed-off-by: Ben Crocker [email protected]

@bcrocker15 bcrocker15 self-assigned this Jun 13, 2021
@bcrocker15 bcrocker15 linked an issue Jun 13, 2021 that may be closed by this pull request
@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

Copy link
Member

@TomasTomecek TomasTomecek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so far so good! can we have this for gitlab as well? tests would be very much appreciated here :)

ogr/abstract.py Outdated
@@ -404,6 +404,14 @@ def patch(self) -> bytes:
def head_commit(self) -> str:
raise NotImplementedError

@property
def merge_commit_sha(self) -> str:
raise NotImplementedError
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise NotImplementedError
raise NotImplementedError()

an instance should be raised instead of the class

Copy link
Member

@lachmanfrantisek lachmanfrantisek Jun 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not matter, you can use class or and instance: https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement :

raise evaluates the first expression as the exception object. It must be either a subclass or an instance of BaseException. If it is a class, the exception instance will be obtained when needed by instantiating the class with no arguments.

(discussion: https://stackoverflow.com/questions/16706956/is-there-a-difference-between-raise-exception-and-raise-exception-without#16709222)

I know it works but this was the first time I've checked it in the docs..;) So, thanks for pointing that out!

But it would be nice to unify this across the project.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned on IRC, in GitHub, 'mergeable' is a boolean, while in
GitLab, the closest thing seems to be merge_status which, if I'm
reading the doc (https://docs.gitlab.com/ee/api/merge_requests.html)
correctly, is a string that can have several values including "unchecked",
"checking", "can_be_merged", and "cannot_be_merged".

I went on to say that "...Maybe the answer is to map GL's
"can_be_merged" to 'True' and everything else to 'False'" and Tomas
like this idea, at least provisionally.

OR we could map "can_be_merged" to True, "cannot_be_merged" to False,
and everything else to None.

Copy link
Contributor Author

@bcrocker15 bcrocker15 Jun 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the Packit Arthitecture meeting on 06/15/2021, we decided that we
would present GitLab-like behavior, and map GitHub behavior onto it.

This means that we will provide a (GitLab-like) 'merge_status' @Property
instead of (GitHub-like) 'mergeable', with GitHub's
'mergeable' values mapped as follows:

mergeable => merge_status
True "can_be_merged"
False "cannot_be_merged"
<> "unchecked"
<> "checking"
<> "cannot_be_merged_recheck"

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

return self._raw_pr.mergeable
def merge_status(self) -> str:
if self._raw_pr.mergeable:
return "can_be_merged"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought you meant an enumeration like this for commit statuses.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, an enum here would be much better

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@bcrocker15
Copy link
Contributor Author

On my last run, I got some errors that I do not understand:

E OSError: You are in Requre write mode, please set proper GITHUB_TOKEN env variables

See below.

I have a GITHUB_TOKEN defined in my environment (set in ~/.bashrc);
I do not understand why these errors are cropping up in the new
test_merge_commit_sha_* methods I just introduced, and not in the very
similar test_head_commit method on which I modeled test_merge_commit_sha_*.

____________________ PullRequests.test_merge_commit_sha_240 ____________________

self = <tests.integration.github.test_pull_requests.PullRequests testMethod=test_merge_commit_sha_240>

def setUp(self):
    super().setUp()
    self.token = os.environ.get("GITHUB_TOKEN")
    if not Path(get_datafile_filename(obj=self)).exists() and not self.token:
      raise EnvironmentError(
            "You are in Requre write mode, please set proper GITHUB_TOKEN env variables"
        )

E OSError: You are in Requre write mode, please set proper GITHUB_TOKEN env variables

class = <class 'tests.integration.github.base.GithubTests'>
self = <tests.integration.github.test_pull_requests.PullRequests testMethod=test_merge_commit_sha_240>

@bcrocker15
Copy link
Contributor Author

I expect that, once we get the aforementioned issues and errors straightened out,
I'll be able to write some tests for GitLab and Pagure, as well.

BTW, 'make check' takes about 10 minutes in my experience; less if the test domain
is restricted by, e.g.,

%%% TEST_TARGET=./tests/integration/github/ make check

@jscotka
Copy link
Contributor

jscotka commented Jun 17, 2021

@bcrocker15 Hi Ben,
I've investigated that we've made issue inside requre project when reworking decorators.
Bad was that it affected just write mode of requre, so that we was not able to catch it by reverse dependency testing.
last working commit hash of requre is: 0dbd6ca8899bb3e0fda72363f03bfe0adb4b19db
so you can try it to regenerate it via installing requre to this commit or I can do it for you. But it would be better if you try it as well to prove that my investigation is right. (just ensure that you have just one installation (user or system or requre, to aovid situation that you install this commit hash version, but finally requre will be used from another location.))

EDIT: issue is more complicated and causing, that currently tests does not test anything and there may be false negative results and may hide regressions (see: https://github.com/packit/requre/pull/206/files#diff-013a26cea674b9569659c20d86db214c9d25108da1a8c54c5bab6a265a442619R64 )
have to fix the issue as soon as possible inside requre project. with @lachmanfrantisek working on that.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@bcrocker15
Copy link
Contributor Author

I'm anticipating a question like, "Why didn't I combine all my
test_merge_commit_sha_* methods into a single method that looks
like this:

def test_merge_commit_sha_240(self):
    pr240 = self.hello_world_project.get_pr(240)
    pr111 = self.hello_world_project.get_pr(111)
    pr112 = self.hello_world_project.get_pr(112)
    assert pr240.head_commit == "dabfd3862702e49b6877da7f224e6d6458eb961a"
    assert pr240.merge_commit_sha == "f502aae6920d82948f2dba0b70c9260fb1e34822"
    assert pr240.merge_status == "cannot_be_merged"  # Because it's already merged
    assert pr111.head_commit == "1abb19255a7c1bec7ffcae2487f022b23175af2b"
    assert pr111.merge_commit_sha == "8512ef316918edc39c4a6eee13e6cc45344d03ac"
    assert pr111.merge_status == "cannot_be_merged"  # Conflicts
    assert pr112.head_commit == "9ab13fa4b4944510022730708045f42aea106cef"
    assert pr112.merge_commit_sha == "0dc8211e10e37370f49364495249f5c693a9eff7"
    # Not (yet) merged; good thing! (invalid specfile):
    assert pr112.merge_status == "can_be_merged"

The answer is that it appears to break pytest; I see this in the log (changed > to ->
below because > affects the formatting):

______________________ PullRequests.test_merge_commit_sha ______________________

self = <tests.integration.github.test_pull_requests.PullRequests testMethod=test_merge_commit_sha>

def test_merge_commit_sha(self):
    pr240 = self.hello_world_project.get_pr(240)

-> pr111 = self.hello_world_project.get_pr(111)

pr240 = <GithubPullRequest(title='testing-farm: migrate to official TMT format', id=240, status='merged', url='https://github....n='Not sure w...', author='thrix', source_branch='fix-fmf-tests', target_branch='main', created='2021-02-17 17:10:34')>
self = <tests.integration.github.test_pull_requests.PullRequests testMethod=test_merge_commit_sha>

...
followed, after about 170 lines of text, by

E requre.exceptions.ItemNotInStorage: Keys not in storage:/home/bcrocker/Work/packit-all/ogr/tests/integration/github/test_data/test_pull_requests/PullRequests.test_merge_commit_sha.yaml Matched: ['requests.sessions', 'send', 'GET'], Missing: ['https://api.github.com:443/repos/packit/hello-world/pulls/111']

@jscotka
Copy link
Contributor

jscotka commented Jun 18, 2021

@bcrocker15 It can be combined together, it should no be any issue. Just be sure that when you do that. You have to regenerate the data files. because data file is connected with one test. so that In case you'll extend one test you have to regenerate the file.
so that in case your test contains eg. self.hello_world_project.get_pr(240) and you will add second call self.hello_world_project.get_pr(240) you have to regenerate file because it will there stored one times but extended test expect to have it there twice.

There is bigger reason why it is solved in this way: as example you can have command like with creating new PR

  • get pull requests count
  • create new PR
  • get pull requests count
  • see if count after create PR increased by one.

Another issue could be when you reorder commands calls (just in some cases), it may also lead to need of regenereate data (it depends on stored keys for the data and how data are sent to server) e.g. in case some requests to github differs (stored is HTTP method and URL) so that in case it differs just by sent data, it will be concatenated inside one list, so that in case you will change order of commands data will be server in reversed order.

And it seems that you've used old data file, beucase pr240 is there but pr11 is not stored there.

I'm anticipating a question like, "Why didn't I combine all my
test_merge_commit_sha_* methods into a single method that looks
like this:

def test_merge_commit_sha_240(self):
    pr240 = self.hello_world_project.get_pr(240)
    pr111 = self.hello_world_project.get_pr(111)
    pr112 = self.hello_world_project.get_pr(112)
    assert pr240.head_commit == "dabfd3862702e49b6877da7f224e6d6458eb961a"
    assert pr240.merge_commit_sha == "f502aae6920d82948f2dba0b70c9260fb1e34822"
    assert pr240.merge_status == "cannot_be_merged"  # Because it's already merged
    assert pr111.head_commit == "1abb19255a7c1bec7ffcae2487f022b23175af2b"
    assert pr111.merge_commit_sha == "8512ef316918edc39c4a6eee13e6cc45344d03ac"
    assert pr111.merge_status == "cannot_be_merged"  # Conflicts
    assert pr112.head_commit == "9ab13fa4b4944510022730708045f42aea106cef"
    assert pr112.merge_commit_sha == "0dc8211e10e37370f49364495249f5c693a9eff7"
    # Not (yet) merged; good thing! (invalid specfile):
    assert pr112.merge_status == "can_be_merged"

The answer is that it appears to break pytest; I see this in the log (changed > to ->
below because > affects the formatting):

______________________ PullRequests.test_merge_commit_sha ______________________

self = <tests.integration.github.test_pull_requests.PullRequests testMethod=test_merge_commit_sha>

def test_merge_commit_sha(self):
    pr240 = self.hello_world_project.get_pr(240)

-> pr111 = self.hello_world_project.get_pr(111)

pr240 = <GithubPullRequest(title='testing-farm: migrate to official TMT format', id=240, status='merged', url='https://github....n='Not sure w...', author='thrix', source_branch='fix-fmf-tests', target_branch='main', created='2021-02-17 17:10:34')>
self = <tests.integration.github.test_pull_requests.PullRequests testMethod=test_merge_commit_sha>

...
followed, after about 170 lines of text, by

E requre.exceptions.ItemNotInStorage: Keys not in storage:/home/bcrocker/Work/packit-all/ogr/tests/integration/github/test_data/test_pull_requests/PullRequests.test_merge_commit_sha.yaml Matched: ['requests.sessions', 'send', 'GET'], Missing: ['https://api.github.com:443/repos/packit/hello-world/pulls/111']

Copy link
Member

@TomasTomecek TomasTomecek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Let's have the enum for the status and I believe we're good to go

return self._raw_pr.mergeable
def merge_status(self) -> str:
if self._raw_pr.mergeable:
return "can_be_merged"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, an enum here would be much better

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

Copy link
Member

@lachmanfrantisek lachmanfrantisek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the progress!

Regarding the requre responses, I think we are doing too much here:

  • regenerating some response files (not needed probably)
  • renaming the response files to match the new (shorter) naming scheme (can be done in a separate commit or PR)
  • response files for the tests you've created (yes, those need to be here and are the only needed changes (specifically additions) of response files in this PR)

ogr/abstract.py Outdated
Comment on lines 318 to 326
class CommitStatus(Enum):
pending = 1
success = 2
failure = 3
error = 4
canceled = 5
running = 6
mergeable = 7
notmergeable = 8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure merging those two use-cases together is a good idea. I can't think of any use where both mergeable and success/failure/.. makes sense.

I think others suggested using a new enum and get inspired by CommitStatus. Not to reuse CommitStatus.

Comment on lines 110 to 115
@property
def merge_commit_status(self) -> CommitStatus:
if self._raw_pr.merge_status == "can_be_merged":
return CommitStatus.mergeable
else:
return CommitStatus.notmergeable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, we can convert all possible values to the newly created Enum. As we discussed at the arch meeting, we want to differentiate e.g. pending and notmergeable. So, I would not treat all statuses that are not can_be_merged as notmergeable since it can't easily be a false statement.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@bcrocker15
Copy link
Contributor Author

I did a 'git reset' to get back to the state before I attempted to
regenerate tests (PLUS the MergeCommitStatus changes we agreed on
today), so we're back to these errors:

=================================== FAILURES ===================================
______________________ PullRequests.test_merge_commit_sha ______________________

self = <tests.integration.github.test_pull_requests.PullRequests testMethod=test_merge_commit_sha>

def setUp(self):
    super().setUp()
    self.token = os.environ.get("GITHUB_TOKEN")
    if not Path(get_datafile_filename(obj=self)).exists() and not self.token:

-> raise EnvironmentError(
"You are in Requre write mode, please set proper GITHUB_TOKEN env variables"
)
E OSError: You are in Requre write mode, please set proper GITHUB_TOKEN env variables

class = <class 'tests.integration.github.base.GithubTests'>
self = <tests.integration.github.test_pull_requests.PullRequests testMethod=test_merge_commit_sha>

tests/integration/github/base.py:15: OSError
______________________ PullRequests.test_merge_commit_sha ______________________

self = <tests.integration.gitlab.test_pull_requests.PullRequests testMethod=test_merge_commit_sha>

def setUp(self):
    super().setUp()
    self.token = os.environ.get("GITLAB_TOKEN")

    if not Path(get_datafile_filename(obj=self)).exists() and not self.token:

-> raise EnvironmentError(
"You are in Requre write mode, please set GITLAB_TOKEN env variables"
E OSError: You are in Requre write mode, please set GITLAB_TOKEN env variables

class = <class 'tests.integration.gitlab.base.GitlabTests'>
self = <tests.integration.gitlab.test_pull_requests.PullRequests testMethod=test_merge_commit_sha>

tests/integration/gitlab/base.py:16: OSError
=========================== short test summary info ============================
FAILED tests/integration/github/test_pull_requests.py::PullRequests::test_merge_commit_sha
FAILED tests/integration/gitlab/test_pull_requests.py::PullRequests::test_merge_commit_sha
============= 2 failed, 372 passed, 2 skipped in 289.30s (0:04:49) =============
make: *** [Makefile:12: check] Error 1

and the requre-0.8.1 update did NOT seem to help.

@bcrocker15 bcrocker15 marked this pull request as ready for review June 22, 2021 11:32
@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@bcrocker15
Copy link
Contributor Author

I implemented code changes as suggested by Frantisek, making the
code much more idiomatically Python-esque.

With two new test_data files, note success on all Zuul tests!

Copy link
Member

@TomasTomecek TomasTomecek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\o/

Comment on lines 177 to 187
def test_merge_commit_sha(self):
pr1 = self.project.get_pr(1)
pr12 = self.project.get_pr(12)
pr19 = self.project.get_pr(19)
assert pr1.merge_commit_sha == "101a42bbbe174d04b465d49caf274dc3b4defeca"
assert pr1.merge_commit_status == MergeCommitStatus.can_be_merged
assert pr12.merge_commit_sha == "f6de56d97ec3ec74cd5194e79175162d9f969195"
assert pr12.merge_commit_status == MergeCommitStatus.can_be_merged
assert pr19.merge_commit_sha == "b8e18207cfdad954f1b3a96db34d0706b272e6cf"
assert pr19.merge_commit_status == MergeCommitStatus.can_be_merged
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about having some example with MergeCommitStatus.cannot_be_merged?

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@lachmanfrantisek
Copy link
Member

recheck

Copy link
Member

@lachmanfrantisek lachmanfrantisek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one change-request, otherwise LGTM.

Can you please take care of finishing this?

@property
def merge_commit_status(self) -> MergeCommitStatus:
status = self._raw_pr.merge_status
assert status in self._merge_commit_status
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert status in self._merge_commit_status

Using assert in the production code is not expected -- python, when run in the optimise mode, ignores such commands so we can't really on the execution of this.

Note that you are checking this one line bellow so it's not needed here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by myself.

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

bcrocker15 and others added 3 commits July 12, 2021 09:02
Add merge_commit_sha and merge_commit_status properties
to GithubPullRequest class (and PullRequest superclass);
merge_commit_status returns a MergeCommitStatus.

GitHub's 'mergeable' boolean maps to MergeCommitStatus.can_be_merged (true)
or MergeCommitStatus.cannot_be_merged (false).

GitLab's 'merge_status' string values map to MergeCommitStatus
values verbatim.

New test_pull_requests.py:test_merge_commit_sha methods for
GitHub and GitLab.

In Makefile, pass GITHUB_TOKEN, GITLAB_TOKEN in check-in-container

OGR issue packit#584.

Signed-off-by: Ben Crocker <[email protected]>
Signed-off-by: Ben Crocker <[email protected]>
The assert code is ignored when Python is run in the optimised mode.

Signed-off-by: Frantisek Lachman <[email protected]>
@lachmanfrantisek
Copy link
Member

lachmanfrantisek commented Jul 12, 2021

I've rebased the PR myself so we can merge it.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

Copy link
Member

@lachmanfrantisek lachmanfrantisek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bcrocker15 thanks for working on this!

I've just rebased the PR for you and add one commit with a small fix I've mentioned in the comments but you still have the credits..;)

@lachmanfrantisek lachmanfrantisek added the mergeit When set, zuul wil gate and merge the PR. label Jul 12, 2021
@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded (gate pipeline).

@softwarefactory-project-zuul softwarefactory-project-zuul bot merged commit 3809720 into packit:main Jul 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mergeit When set, zuul wil gate and merge the PR.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[GitHub] Support using the merge ref instead of the head ref
5 participants