[docs] Limit git submodule recurse to depth 1
[releng.git] / releases / scripts / create_branch.py
1 #!/usr/bin/env python2
2 # SPDX-License-Identifier: Apache-2.0
3 ##############################################################################
4 # Copyright (c) 2018 The Linux Foundation and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
10 """
11 Create Gerrit Branchs
12 """
13
14 import argparse
15
16 try:
17     import ConfigParser
18 except ImportError:
19     import configparser as ConfigParser
20
21 import logging
22 import os
23 import yaml
24
25 from requests.compat import quote
26 from requests.exceptions import RequestException
27
28 from pygerrit2.rest import GerritRestAPI
29 from pygerrit2.rest.auth import HTTPDigestAuthFromNetrc, HTTPBasicAuthFromNetrc
30
31
32 logging.basicConfig(level=logging.INFO)
33
34
35 def quote_branch(arguments):
36     """
37     Quote is used here to escape the '/' in branch name. By
38     default '/' is listed in 'safe' characters which aren't escaped.
39     quote is not used in the data of the PUT request, as quoting for
40     arguments is handled by the request library
41     """
42     new_args = arguments.copy()
43     new_args['branch'] = quote(new_args['branch'], '')
44     return new_args
45
46
47 def create_branch(api, arguments):
48     """
49     Create a branch using the Gerrit REST API
50     """
51     logger = logging.getLogger(__file__)
52
53     branch_data = """
54     {
55       "ref": "%(branch)s"
56       "revision": "%(commit)s"
57     }""" % arguments
58
59     # First verify the commit exists, otherwise the branch will be
60     # created at HEAD
61     try:
62         request = api.get("/projects/%(project)s/commits/%(commit)s" %
63                           arguments)
64         logger.debug(request)
65         logger.debug("Commit exists: %(commit)s", arguments)
66     except RequestException as err:
67         if hasattr(err, 'response') and err.response.status_code in [404]:
68             logger.warn("Commit %(commit)s for %(project)s does"
69                         " not exist. Not creating branch.", arguments)
70             logger.warn(err)
71         else:
72             logger.error("Error: %s", str(err))
73         # Skip trying to create the branch
74         return
75
76     # Try to create the branch and let us know if it already exist.
77     try:
78         request = api.put("/projects/%(project)s/branches/%(branch)s" %
79                           quote_branch(arguments), branch_data)
80         logger.info("Branch %(branch)s for %(project)s successfully created",
81                     arguments)
82     except RequestException as err:
83         if hasattr(err, 'response') and err.response.status_code in [412, 409]:
84             logger.info("Branch %(branch)s already created for %(project)s",
85                         arguments)
86             logger.info(err)
87         else:
88             logger.error("Error: %s", str(err))
89
90
91 def main():
92     """Given a yamlfile that follows the release syntax, create branches
93     in Gerrit listed under branches"""
94
95     config = ConfigParser.ConfigParser()
96     config.read(os.path.join(os.path.abspath(os.path.dirname(__file__)),
97                 'defaults.cfg'))
98     config.read([os.path.expanduser('~/releases.cfg'), 'releases.cfg'])
99
100     gerrit_url = config.get('gerrit', 'url')
101
102     parser = argparse.ArgumentParser()
103     parser.add_argument('--file', '-f',
104                         type=argparse.FileType('r'),
105                         required=True)
106     parser.add_argument('--basicauth', '-b', action='store_true')
107     args = parser.parse_args()
108
109     GerritAuth = HTTPDigestAuthFromNetrc
110     if args.basicauth:
111         GerritAuth = HTTPBasicAuthFromNetrc
112
113     try:
114         auth = GerritAuth(url=gerrit_url)
115     except ValueError as err:
116         logging.error("%s for %s", err, gerrit_url)
117         quit(1)
118     restapi = GerritRestAPI(url=gerrit_url, auth=auth)
119
120     project = yaml.safe_load(args.file)
121
122     create_branches(restapi, project)
123
124
125 def create_branches(restapi, project):
126     """Create branches for a specific project defined in the release
127     file"""
128
129     branches = []
130     for branch in project['branches']:
131         repo, ref = next(iter(branch['location'].items()))
132         branches.append({
133             'project': repo,
134             'branch': branch['name'],
135             'commit': ref
136         })
137
138     for branch in branches:
139         create_branch(restapi, branch)
140
141
142 if __name__ == "__main__":
143     main()