Skip to content

Commit da7a809

Browse files
committed
feat: add support for commit GPG signature API
1 parent 8c03771 commit da7a809

File tree

6 files changed

+76
-0
lines changed

6 files changed

+76
-0
lines changed

docs/cli.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,18 @@ Create a snippet:
236236
$ gitlab project-snippet create --project-id 2 --title "the title" \
237237
--file-name "the name" --code "the code"
238238
239+
Get a specific project commit by its SHA id:
240+
241+
.. code-block:: console
242+
243+
$ gitlab project-commit get --project-id 2 --id a43290c
244+
245+
Get the GPG signature of a signed commit:
246+
247+
.. code-block:: console
248+
249+
$ gitlab project-commit signature --project-id 2 --id a43290c
250+
239251
Define the status of a commit (as would be done from a CI tool for example):
240252

241253
.. code-block:: console

docs/gl_objects/commits.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ Get the references the commit has been pushed to (branches and tags)::
8282
commit.refs('tag') # only tags
8383
commit.refs('branch') # only branches
8484

85+
Get the GPG signature of the commit (if the commit was signed)::
86+
87+
commit.signature()
88+
8589
List the merge requests related to a commit::
8690

8791
commit.merge_requests()

gitlab/tests/objects/test_commits.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,26 @@ def resp_revert_commit(url, request):
4848
return response(200, content, headers, None, 5, request)
4949

5050

51+
@urlmatch(
52+
scheme="http",
53+
netloc="localhost",
54+
path="/api/v4/projects/1/repository/commits/6b2257ea/signature",
55+
method="get",
56+
)
57+
def resp_get_commit_gpg_signature(url, request):
58+
"""Mock for commit GPG signature GET response."""
59+
content = """{
60+
"gpg_key_id": 1,
61+
"gpg_key_primary_keyid": "8254AAB3FBD54AC9",
62+
"gpg_key_user_name": "John Doe",
63+
"gpg_key_user_email": "johndoe@example.com",
64+
"verification_status": "verified",
65+
"gpg_key_subkey_id": null
66+
}"""
67+
content = content.encode("utf-8")
68+
return response(200, content, headers, None, 5, request)
69+
70+
5171
class TestCommit(TestProject):
5272
"""
5373
Base class for commit tests. Inherits from TestProject,
@@ -77,3 +97,10 @@ def test_revert_commit(self):
7797
revert_commit = commit.revert(branch="master")
7898
self.assertEqual(revert_commit["short_id"], "8b090c1b")
7999
self.assertEqual(revert_commit["title"], 'Revert "Initial commit"')
100+
101+
@with_httmock(resp_get_commit_gpg_signature)
102+
def test_get_commit_gpg_signature(self):
103+
commit = self.project.commits.get("6b2257ea", lazy=True)
104+
signature = commit.signature()
105+
self.assertEqual(signature["gpg_key_primary_keyid"], "8254AAB3FBD54AC9")
106+
self.assertEqual(signature["verification_status"], "verified")

gitlab/v4/objects.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,6 +2172,24 @@ def revert(self, branch, **kwargs):
21722172
post_data = {"branch": branch}
21732173
return self.manager.gitlab.http_post(path, post_data=post_data, **kwargs)
21742174

2175+
@cli.register_custom_action("ProjectCommit")
2176+
@exc.on_http_error(exc.GitlabGetError)
2177+
def signature(self, **kwargs):
2178+
"""Get the GPG signature of the commit.
2179+
2180+
Args:
2181+
**kwargs: Extra options to send to the server (e.g. sudo)
2182+
2183+
Raises:
2184+
GitlabAuthenticationError: If authentication is not correct
2185+
GitlabGetError: If the signature could not be retrieved
2186+
2187+
Returns:
2188+
dict: The commit's GPG signature data
2189+
"""
2190+
path = "%s/%s/signature" % (self.manager.path, self.get_id())
2191+
return self.manager.gitlab.http_get(path, **kwargs)
2192+
21752193

21762194
class ProjectCommitManager(RetrieveMixin, CreateMixin, RESTManager):
21772195
_path = "/projects/%(project_id)s/repository/commits"

tools/cli_test_v4.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,13 @@ testcase "revert commit" '
113113
--id "$COMMIT_ID" --branch master
114114
'
115115

116+
# Test commit GPG signature
117+
testcase "attempt to get GPG signature of unsigned commit" '
118+
OUTPUT=$(GITLAB project-commit signature --project-id "$PROJECT_ID" \
119+
--id "$COMMIT_ID" 2>&1 || exit 0)
120+
echo "$OUTPUT" | grep -q "404 GPG Signature Not Found"
121+
'
122+
116123
# Test project labels
117124
testcase "create project label" '
118125
OUTPUT=$(GITLAB -v project-label create --project-id $PROJECT_ID \

tools/python_test_v4.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,14 @@
473473
# assert commit.refs()
474474
# assert commit.merge_requests()
475475

476+
# commit GPG signature (for unsigned commits)
477+
# TODO: reasonable tests for signed commits?
478+
try:
479+
signature = commit.signature()
480+
except gitlab.GitlabGetError as e:
481+
error_message = e.error_message
482+
assert error_message == "404 GPG Signature Not Found"
483+
476484
# commit comment
477485
commit.comments.create({"note": "This is a commit comment"})
478486
# assert len(commit.comments.list()) == 1

0 commit comments

Comments
 (0)