Skip to content

Allow tags from GitHub webhooks #3546

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

Merged
merged 10 commits into from
Jun 8, 2018

Conversation

stsewd
Copy link
Member

@stsewd stsewd commented Jan 24, 2018

This closes #3508

This is just a proposal, since I'm not sure if this is the best way of do it (since various methods are named branch* and no tags o versions, e.g. versions_from_branch_name)

The GitHub payload looks like this when a tag is pushed:

{
  "ref": "refs/tags/v02",
  ...
}

If the tag isn't registered on rtd active versions (recent created tags), the build isn't triggered; but if the tag is forced on the gh repo and the tag is an active version, the build is triggered.

@RichardLitt RichardLitt added Improvement Minor improvement to code PR: ready for review labels Jan 25, 2018
@ericholscher
Copy link
Member

This looks like a great PR. It needs to at least have a test that shows what wasn't working before, but does work now. I'm +1 on it though!

@RichardLitt RichardLitt added the Needed: tests Tests are required label Jan 30, 2018
@stsewd stsewd force-pushed the allow-tags-from-gh branch from 8ca0809 to 0859712 Compare January 31, 2018 22:14
@stsewd
Copy link
Member Author

stsewd commented Jan 31, 2018

Well, the current tests didn't really check this functionality, I'm not sure how to really test this.

@@ -335,17 +335,20 @@ class IntegrationsTests(TestCase):
def setUp(self):
self.project = get(Project)
self.version = get(Version, verbose_name='master', project=self.project)
self.version_tag = get(Version, verbose_name='v1.2', project=self.project)
Copy link
Member Author

Choose a reason for hiding this comment

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

This really doesn't make any difference to the current tests

{'ref': 'refs/tags/v1.2'},
format='json',
)
trigger_build.assert_has_calls(
Copy link
Member Author

@stsewd stsewd Jan 31, 2018

Choose a reason for hiding this comment

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

This just test if the method was called, no if the branch/tag was correctly parsed

@stsewd
Copy link
Member Author

stsewd commented Feb 1, 2018

@ericholscher After fighting with the mocks, the tests are ready 😊

trigger_build.assert_has_calls(
[mock.call(force=True, version=self.version, project=self.project)])

@mock.patch('readthedocs.restapi.views.integrations.WebhookMixin.get_response_push', return_value=None)
Copy link
Member Author

Choose a reason for hiding this comment

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

Here the return value is None, since we only care to test if the ref value is parsed correctly, the other test covers the all flow

Copy link
Member

Choose a reason for hiding this comment

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

Since what you want to test is the parsing, instead of writing the test in this way, why not avoid mocking this function and calling it for real and assert the return value with the one that it's expected?

Like this:

wm = WebhookMixin()
assertEqual(wm._normalize_ref('refs/heads/master'), 'master')

It's clearer this way.

Copy link
Member Author

Choose a reason for hiding this comment

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

I wasn't sure if that way was the correct one 😞.

Copy link
Member

@humitos humitos 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 this PR!

I didn't find anything that it's wrong, but I left some suggestions on the comments.

@@ -751,7 +751,8 @@ def versions_from_branch_name(self, branch):
return (
self.versions.filter(identifier=branch) |
self.versions.filter(identifier='remotes/origin/%s' % branch) |
self.versions.filter(identifier='origin/%s' % branch)
self.versions.filter(identifier='origin/%s' % branch) |
self.versions.filter(verbose_name=branch)
Copy link
Member

Choose a reason for hiding this comment

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

I think this could return duplicated values when the identifier and the verbose name are the same, right? Maybe we should use here the .distinct()

On the other hand, I don't follow why we need to add this line here, hehe. Can you clarify?

Copy link
Member Author

Choose a reason for hiding this comment

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

Tags are saved this way: {identifier: hash, verbose_name: tagname}.

GitHub only provides the tag name on the ref.

The only case were I think duplicate values may occur is for branches, since the identifier isn't a hash like they are for tags. I'm going to research a little.

Copy link
Member Author

Choose a reason for hiding this comment

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

These is what I found, looks like the querysets are really sets p:

>>> p.versions.filter(identifier=branch)
[<Version: Version awesome of Read The Docs (8)>]
>>> p.versions.filter(verbose_name=branch)
[<Version: Version awesome of Read The Docs (8)>]
>>> p.versions.filter(identifier=branch) | p.versions.filter(verbose_name=branch)
[<Version: Version awesome of Read The Docs (8)>]

Copy link
Member

Choose a reason for hiding this comment

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

They aren't really sets. In fact, that's why the distinct is: https://docs.djangoproject.com/en/2.0/ref/models/querysets/#django.db.models.query.QuerySet.distinct

Anyway, it seems that we are not bitten by this problem here.

[mock.call(force=True, version=mock.ANY, project=self.project)])
[mock.call(force=True, version=self.version, project=self.project)])

client.post(
Copy link
Member

Choose a reason for hiding this comment

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

Write this as a separte test for tag and rename this one for branch since they the branch was working previously and we are adding a new feature. It's good to each test written to try a specific thing.

trigger_build.assert_has_calls(
[mock.call(force=True, version=self.version, project=self.project)])

@mock.patch('readthedocs.restapi.views.integrations.WebhookMixin.get_response_push', return_value=None)
Copy link
Member

Choose a reason for hiding this comment

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

Since what you want to test is the parsing, instead of writing the test in this way, why not avoid mocking this function and calling it for real and assert the return value with the one that it's expected?

Like this:

wm = WebhookMixin()
assertEqual(wm._normalize_ref('refs/heads/master'), 'master')

It's clearer this way.


client.post(
'/api/v2/webhook/github/{0}/'.format(self.project.slug),
{'ref': 'refs/tags/v1.0'},
Copy link
Member

Choose a reason for hiding this comment

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

Same here: move this cases to a specific test.

@stsewd
Copy link
Member Author

stsewd commented Feb 16, 2018

@humitos all corrections were made, thanks again!

Copy link
Member

@humitos humitos left a comment

Choose a reason for hiding this comment

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

Good job! It's ready to be merged for me.

@RichardLitt RichardLitt removed the Needed: tests Tests are required label Feb 21, 2018
@stsewd stsewd force-pushed the allow-tags-from-gh branch from 8586e29 to 49fadeb Compare April 11, 2018 03:33
@stsewd
Copy link
Member Author

stsewd commented Apr 11, 2018

Nothing change on this PR, just rebase to the current master :)

@agjohnson agjohnson added this to the 2.6 milestone Jun 8, 2018
@agjohnson agjohnson merged commit 07bcf4c into readthedocs:master Jun 8, 2018
@stsewd stsewd deleted the allow-tags-from-gh branch June 8, 2018 22:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Improvement Minor improvement to code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ReadTheDocs does not pull tags
5 participants