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

Update GitHub Info #6

Merged
merged 11 commits into from
Feb 1, 2019
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ These are the hooks currently available in this repository
This hook checks that some important attributes are present in the ``ConanFile``: url,
license and description, and will output a warning for the missing ones.

### [GitHub Update](hooks/github-updater.py)

This Conan hook reads your recipe and updates its GitHub repository properties using the attributes.

The following attributes are updated:

- homepage

- description

- topics

It's necessary to pass GitHub token by environment variable: *GITHUB_TOKEN*.

The hook is automatically called when *export* command is executed.

## License

[MIT License](LICENSE)
87 changes: 87 additions & 0 deletions hooks/github-updater.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from conans import tools
import os
import requests
import re
import json


def pre_export(output, conanfile, conanfile_path, reference, **kwargs):
del conanfile_path, reference, kwargs

github_token = os.getenv('GITHUB_TOKEN')
if not github_token:
output.info('no GITHUB_TOKEN environment variable is set, skipping GitHub updater')
return

url = conanfile.url
if not url:
output.info('no url attribute was specified withing recipe, skipping GitHub updater')
return

pattern_https = re.compile(r'https?://github\.com/([a-zA-Z0-9_.-]+)/([a-zA-Z0-9_.-]+)(\.git)?')
pattern_git = re.compile(r'git@github\.com:([a-zA-Z0-9_.-]+)/([a-zA-Z0-9_.-]+)(\.git)?')
match = pattern_https.match(url) or pattern_git.match(url)
if not match:
output.info('not a GitHub repository %s, skipping GitHub updater' % url)
return

owner, repository = match.groups(0)[0], match.groups(0)[1]

headers = {
'Accept': 'application/vnd.github.v3+json',
'Authorization': 'token %s' % github_token
}

# https://developer.github.com/v3/repos/#edit
url = 'https://api.github.com/repos/{owner}/{repository}'.format(owner=owner,
repository=repository)

response = requests.get(url, headers=headers)
if response.status_code != 200:
output.error('GitHub GET request failed with %s %s' % (response.status_code,
response.content))

content = json.loads(response.content)
default_branch = content["default_branch"]
reference = "%s/%s" % (conanfile.channel, conanfile.version)
if reference != default_branch:
output.info('default "%s" branch doesn\'t match conanfile reference "%s"' % (default_branch,
reference))
return

request = dict()

if conanfile.description:
request['description'] = conanfile.description
if conanfile.homepage:
request['homepage'] = conanfile.homepage

if not request:
output.info('not attributes to update')
else:
request['name'] = repository

response = requests.patch(url, headers=headers, data=json.dumps(request))
if response.status_code != 200:
output.error('GitHub PATCH request failed with %s %s' % (response.status_code,
response.content))

topics = conanfile.topics
if not topics or not isinstance(topics, tuple):
output.info('no topics to update')
else:
if "conan" not in topics:
topics += ("conan",)

# https://developer.github.com/v3/repos/#replace-all-topics-for-a-repository
url += '/topics'
request = {"names": topics}
headers["Accept"] = "application/vnd.github.mercy-preview+json"

response = requests.put(url, headers=headers, data=json.dumps(request))
if response.status_code != 200:
output.error('GitHub PUT request failed with %s %s' % (response.status_code,
response.content))