blob: e491541a90beb060592461452a9923324bc79260 [file] [log] [blame]
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -08001#!/usr/bin/env python3
2# -*- coding: utf-8 -*-"
3#
4# Copyright 2020 The Chromium OS Authors. All rights reserved.
5# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
7
8"""Module containing methods interfacing with gerrit.
9
10i.e Create new bugfix change tickets, and reading metadata about a specific change.
Hirthanan Subenderan40368002020-03-10 15:36:48 -070011
12Example CURL command that creates CL:
13curl -b /home/chromeos_patches/.git-credential-cache/cookie \
14 --header "Content-Type: application/json" \
15 --data \
16 '{"project":"chromiumos/third_party/kernel",\
17 "subject":"test",\
18 "branch":"chromeos-4.19",\
19 "topic":"test_topic"}' https://chromium-review.googlesource.com/a/changes/
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -080020"""
21
22from __future__ import print_function
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -080023import json
Hirthanan Subenderan40368002020-03-10 15:36:48 -070024import http
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -080025import requests
Hirthanan Subenderan3f029112020-03-11 12:33:05 -070026import os
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -080027
Hirthanan Subenderan40368002020-03-10 15:36:48 -070028from common import CHROMIUM_REVIEW_BASEURL, GIT_COOKIE_PATH
29
30
31def get_auth_cookie():
32 """Load cookies in order to authenticate requests with gerrit/googlesource."""
33 # This cookie should exist on GCE in order to perform GAIA authenticated requests
34 gerrit_credentials_cookies = http.cookiejar.MozillaCookieJar(GIT_COOKIE_PATH, None, None)
35 gerrit_credentials_cookies.load()
36 return gerrit_credentials_cookies
37
38def retrieve_and_parse_endpoint(endpoint_url):
39 """Retrieves Gerrit endpoint response and removes XSSI prefix )]}'"""
Hirthanan Subenderan40368002020-03-10 15:36:48 -070040 try:
Hirthanan Subenderan3f029112020-03-11 12:33:05 -070041 resp = requests.get(endpoint_url, cookies=get_auth_cookie())
42 resp.raise_for_status()
Hirthanan Subenderan40368002020-03-10 15:36:48 -070043 resp_json = json.loads(resp.text[5:])
Hirthanan Subenderan3f029112020-03-11 12:33:05 -070044 except requests.exceptions.HTTPError as e:
45 raise type(e)('Endpoint %s should have HTTP response 200' % endpoint_url) from e
Hirthanan Subenderan40368002020-03-10 15:36:48 -070046 except json.decoder.JSONDecodeError as e:
Hirthanan Subenderan3f029112020-03-11 12:33:05 -070047 raise ValueError('Response should contain json )]} prefix to prevent XSSI attacks') from e
Hirthanan Subenderan40368002020-03-10 15:36:48 -070048
49 return resp_json
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -080050
Hirthanan Subenderan3f029112020-03-11 12:33:05 -070051def set_and_parse_endpoint(endpoint_url, payload):
52 """POST request to gerrit endpoint with specified payload."""
53 try:
54 resp = requests.post(endpoint_url, json=payload, cookies=get_auth_cookie())
55 resp.raise_for_status()
56 resp_json = json.loads(resp.text[5:])
57 except requests.exceptions.HTTPError as e:
58 raise type(e)('Endpoint %s should have HTTP response 200' % endpoint_url) from e
59 except json.decoder.JSONDecodeError as e:
60 raise ValueError('Response should contain json )]} prefix to prevent XSSI attacks') from e
61
62 return resp_json
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -080063
64def get_commit(changeid):
65 """Retrieves current commit message for a change.
66
67 May add some additional information to the fix patch for tracking purposes.
68 i.e attaching a tag
69 """
Hirthanan Subenderan3f029112020-03-11 12:33:05 -070070 get_commit_endpoint = os.path.join(CHROMIUM_REVIEW_BASEURL, 'changes',
71 changeid, 'revisions/current/commit')
Hirthanan Subenderan40368002020-03-10 15:36:48 -070072 return retrieve_and_parse_endpoint(get_commit_endpoint)
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -080073
74
Hirthanan Subenderan3f029112020-03-11 12:33:05 -070075def get_changeid_reviewers(changeid):
76 """Retrieves list of reviewer emails from gerrit given a chromeos changeid."""
77 list_reviewers_endpoint = os.path.join(CHROMIUM_REVIEW_BASEURL, 'changes',
78 changeid, 'reviewers')
79
80 resp = retrieve_and_parse_endpoint(list_reviewers_endpoint)
81
82 try:
83 return [reviewer_resp['email'] for reviewer_resp in resp]
84 except KeyError as e:
85 raise type(e)('Gerrit API endpoint to list reviewers should contain key email') from e
86
87def set_changeid_reviewers(changeid, reviewer_emails):
88 """Adds reviewers to a Gerrit CL."""
89 add_reviewer_endpoint = os.path.join(CHROMIUM_REVIEW_BASEURL, 'changes',
90 changeid, 'reviewers')
91
92 for email in reviewer_emails:
93 payload = {'reviewer': email}
94 set_and_parse_endpoint(add_reviewer_endpoint, payload)
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -080095
96
97def get_change(changeid):
98 """Retrieves ChangeInfo from gerrit using its changeid"""
Hirthanan Subenderan3f029112020-03-11 12:33:05 -070099 get_change_endpoint = os.path.join(CHROMIUM_REVIEW_BASEURL, 'changes', changeid)
Hirthanan Subenderan40368002020-03-10 15:36:48 -0700100 return retrieve_and_parse_endpoint(get_change_endpoint)
Hirthanan Subenderanb8402a12020-02-05 14:11:00 -0800101
102
103def generate_fix_commit_message(old_changeid):
104 """Generates new commit message for a fix change.
105
106 Use script ./contrib/from_upstream.py to generate new commit msg
107 Commit message should include essential information:
108 i.e:
109 FROMGIT, FROMLIST, ANDROID, CHROMIUM, etc.
110 commit message indiciating what is happening
111 BUG=...
112 TEST=...
113 tag for Fixes: <upstream-sha>
114 """
115 old_commit_msg = get_commit(old_changeid)
116 print(old_commit_msg)
117
118
119def create_gerrit_change(reviewers, commit_msg):
120 """Uses gerrit api to handle creating gerrit change.
121
122 Determines whether a change for a fix has already been created,
123 and avoids duplicate creations.
124
125 May add some additional information to the fix patch for tracking purposes.
126 i.e attaching a tag,
127 """
128
129 # Call gerrit api to create new change if neccessary
130 print('Calling gerrit api', reviewers, commit_msg)