Skip to content

Commit

Permalink
Create repo from template (#2090)
Browse files Browse the repository at this point in the history
Co-authored-by: bagashvilit <bagashvilit@allegheny.edu>
Co-authored-by: WonjoonC <chos@allegheny.edu>
Co-authored-by: Isac Souza <isouza@daitangroup.com>
Co-authored-by: Isac Souza <isouza@daitan.com>
Co-authored-by: Liuyang Wan <tsfdye@gmail.com>
  • Loading branch information
6 people committed Oct 13, 2022
1 parent 7e6333d commit b50283a
Show file tree
Hide file tree
Showing 11 changed files with 270 additions and 1 deletion.
41 changes: 41 additions & 0 deletions github/AuthenticatedUser.py
Expand Up @@ -509,6 +509,47 @@ def create_fork(self, repo):
self._requester, headers, data, completed=True
)

def create_repo_from_template(
self,
name,
repo,
description=github.GithubObject.NotSet,
private=github.GithubObject.NotSet,
):
"""
:calls: `POST /repos/{template_owner}/{template_repo}/generate <https://docs.github.com/en/rest/reference/repos#create-a-repository-using-a-template>`_
:param name: string
:param repo :class:`github.Repository.Repository`
:param description: string
:param private: bool
:rtype: :class:`github.Repository.Repository`
"""
assert isinstance(name, str), name
assert isinstance(repo, github.Repository.Repository), repo
assert description is github.GithubObject.NotSet or isinstance(
description, str
), description
assert private is github.GithubObject.NotSet or isinstance(
private, bool
), private
post_parameters = {
"name": name,
"owner": self.login,
}
if description is not github.GithubObject.NotSet:
post_parameters["description"] = description
if private is not github.GithubObject.NotSet:
post_parameters["private"] = private
headers, data = self._requester.requestJsonAndCheck(
"POST",
f"/repos/{repo.owner.login}/{repo.name}/generate",
input=post_parameters,
headers={"Accept": "application/vnd.github.v3+json"},
)
return github.Repository.Repository(
self._requester, headers, data, completed=True
)

def create_gist(self, public, files, description=github.GithubObject.NotSet):
"""
:calls: `POST /gists <http://docs.github.com/en/rest/reference/gists>`_
Expand Down
3 changes: 3 additions & 0 deletions github/Consts.py
Expand Up @@ -99,6 +99,9 @@
# https://developer.github.com/changes/2018-05-24-user-migration-api/
mediaTypeMigrationPreview = "application/vnd.github.wyandotte-preview+json"

# https://developer.github.com/changes/2019-07-16-repository-templates-api/
mediaTypeTemplatesPreview = "application/vnd.github.baptiste-preview+json"

# https://docs.github.com/en/rest/reference/search#highlighting-code-search-results-1
highLightSearchPreview = "application/vnd.github.v3.text-match+json"

Expand Down
41 changes: 41 additions & 0 deletions github/Organization.py
Expand Up @@ -403,6 +403,47 @@ def create_fork(self, repo):
self._requester, headers, data, completed=True
)

def create_repo_from_template(
self,
name,
repo,
description=github.GithubObject.NotSet,
private=github.GithubObject.NotSet,
):
"""self.name
:calls: `POST /repos/{template_owner}/{template_repo}/generate <https://docs.github.com/en/rest/reference/repos#create-a-repository-using-a-template>`_
:param name: string
:param repo :class:`github.Repository.Repository`
:param description: string
:param private: bool
:rtype: :class:`github.Repository.Repository`
"""
assert isinstance(name, str), name
assert isinstance(repo, github.Repository.Repository), repo
assert description is github.GithubObject.NotSet or isinstance(
description, str
), description
assert private is github.GithubObject.NotSet or isinstance(
private, bool
), private
post_parameters = {
"name": name,
"owner": self.login,
}
if description is not github.GithubObject.NotSet:
post_parameters["description"] = description
if private is not github.GithubObject.NotSet:
post_parameters["private"] = private
headers, data = self._requester.requestJsonAndCheck(
"POST",
f"/repos/{repo.owner.login}/{repo.name}/generate",
input=post_parameters,
headers={"Accept": "application/vnd.github.v3+json"},
)
return github.Repository.Repository(
self._requester, headers, data, completed=True
)

def create_hook(
self,
name,
Expand Down
23 changes: 22 additions & 1 deletion github/Repository.py
Expand Up @@ -473,6 +473,14 @@ def id(self):
self._completeIfNotSet(self._id)
return self._id.value

@property
def is_template(self):
"""
:type: bool
"""
self._completeIfNotSet(self._is_template)
return self._is_template.value

@property
def issue_comment_url(self):
"""
Expand Down Expand Up @@ -763,6 +771,14 @@ def teams_url(self):
self._completeIfNotSet(self._teams_url)
return self._teams_url.value

@property
def topics(self):
"""
:type: list of strings
"""
self._completeIfNotSet(self._topics)
return self._topics.value

@property
def trees_url(self):
"""
Expand Down Expand Up @@ -995,7 +1011,6 @@ def create_git_tag_and_release(
"""
Convenience function that calls :meth:`Repository.create_git_tag` and
:meth:`Repository.create_git_release`.
:param tag: string
:param tag_message: string
:param release_name: string
Expand Down Expand Up @@ -3729,6 +3744,7 @@ def _initAttributes(self):
self._hooks_url = github.GithubObject.NotSet
self._html_url = github.GithubObject.NotSet
self._id = github.GithubObject.NotSet
self._is_template = github.GithubObject.NotSet
self._issue_comment_url = github.GithubObject.NotSet
self._issue_events_url = github.GithubObject.NotSet
self._issues_url = github.GithubObject.NotSet
Expand Down Expand Up @@ -3765,6 +3781,7 @@ def _initAttributes(self):
self._svn_url = github.GithubObject.NotSet
self._tags_url = github.GithubObject.NotSet
self._teams_url = github.GithubObject.NotSet
self._topics = github.GithubObject.NotSet
self._trees_url = github.GithubObject.NotSet
self._updated_at = github.GithubObject.NotSet
self._url = github.GithubObject.NotSet
Expand Down Expand Up @@ -3871,6 +3888,8 @@ def _useAttributes(self, attributes):
self._html_url = self._makeStringAttribute(attributes["html_url"])
if "id" in attributes: # pragma no branch
self._id = self._makeIntAttribute(attributes["id"])
if "is_template" in attributes: # pragma no branch
self._is_template = self._makeBoolAttribute(attributes["is_template"])
if "issue_comment_url" in attributes: # pragma no branch
self._issue_comment_url = self._makeStringAttribute(
attributes["issue_comment_url"]
Expand Down Expand Up @@ -3971,6 +3990,8 @@ def _useAttributes(self, attributes):
self._teams_url = self._makeStringAttribute(attributes["teams_url"])
if "trees_url" in attributes: # pragma no branch
self._trees_url = self._makeStringAttribute(attributes["trees_url"])
if "topics" in attributes: # pragma no branch
self._topics = self._makeListOfStringsAttribute(attributes["topics"])
if "updated_at" in attributes: # pragma no branch
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
if "url" in attributes: # pragma no branch
Expand Down
26 changes: 26 additions & 0 deletions tests/AuthenticatedUser.py
Expand Up @@ -664,6 +664,32 @@ def testCreateFork(self):
repo = self.user.create_fork(self.g.get_user("nvie").get_repo("gitflow"))
self.assertEqual(repo.source.full_name, "nvie/gitflow")

def testCreateRepoFromTemplate(self):
template_repo = self.g.get_repo("actions/hello-world-docker-action")

repo = self.user.create_repo_from_template(
"hello-world-docker-action-new", template_repo
)
self.assertEqual(
repo.url,
"https://api.github.com/repos/jacquev6/hello-world-docker-action-new",
)
self.assertFalse(repo.is_template)

def testCreateRepoFromTemplateWithAllArguments(self):
template_repo = self.g.get_repo("actions/hello-world-docker-action")

description = "My repo from template"
private = True
repo = self.user.create_repo_from_template(
"hello-world-docker-action-new",
template_repo,
description=description,
private=private,
)
self.assertEqual(repo.description, description)
self.assertTrue(repo.private)

def testGetNotification(self):
notification = self.user.get_notification("8406712")
self.assertEqual(notification.id, "8406712")
Expand Down
26 changes: 26 additions & 0 deletions tests/Organization.py
Expand Up @@ -358,6 +358,32 @@ def testCreateFork(self):
self.assertFalse(repo.has_wiki)
self.assertFalse(repo.has_pages)

def testCreateRepoFromTemplate(self):
template_repo = self.g.get_repo("actions/hello-world-docker-action")

repo = self.org.create_repo_from_template(
"hello-world-docker-action-new", template_repo
)
self.assertEqual(
repo.url,
"https://api.github.com/repos/BeaverSoftware/hello-world-docker-action-new",
)
self.assertFalse(repo.is_template)

def testCreateRepoFromTemplateWithAllArguments(self):
template_repo = self.g.get_repo("actions/hello-world-docker-action")

description = "My repo from template"
private = True
repo = self.org.create_repo_from_template(
"hello-world-docker-action-new",
template_repo,
description=description,
private=private,
)
self.assertEqual(repo.description, description)
self.assertTrue(repo.private)

@mock.patch("github.PublicKey.encrypt")
def testCreateSecret(self, encrypt):
# encrypt returns a non-deterministic value, we need to mock it so the replay data matches
Expand Down

0 comments on commit b50283a

Please sign in to comment.