Skip to content

Commit fead805

Browse files
committed
[infra] Reworking the script that uploads files to google storage
1 parent 76d48d8 commit fead805

1 file changed

Lines changed: 154 additions & 0 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
"""Script for publishing new versions of Selenium to cloud storage.
2+
3+
When you run this script, it will use OAuth 2.0 to authenticate with
4+
Google Cloud Storage before attempting to upload any files. This script
5+
will fail if the authenticated account does not have write access to the
6+
indicated bucket.
7+
8+
By default, this script will use the adjacent client_secrets.json for
9+
OAuth authentication; this may be changed with the --client_secrets
10+
flag.
11+
12+
Example usage:
13+
14+
python publish_release.py \\
15+
--client_secrets my_secrets.json \\
16+
--project_id foo:bar \\
17+
--bucket releases \\
18+
--publish_version 3.14.15 \\
19+
--publish path/to/file/one.txt path/to/file/two.txt \\
20+
--acl "public-read"
21+
22+
This will publish
23+
http://releases.storage.googleapis.com/1.50/one.txt
24+
http://releases.storage.googleapis.com/1.50/two.txt
25+
"""
26+
27+
import argparse
28+
import logging
29+
import mimetypes
30+
import os.path
31+
import sys
32+
33+
34+
try:
35+
from google.oauth2.credentials import Credentials
36+
from google_auth_oauthlib.flow import InstalledAppFlow
37+
except ImportError:
38+
print ('Could not import the library that provides oauthlib integration for Google Auth\n'
39+
+ 'Download available at https://github.com/googleapis/google-auth-library-python-oauthlib\n'
40+
+ 'or run `pip install google-auth-oauthlib`')
41+
sys.exit(1)
42+
43+
try:
44+
from google.cloud import storage
45+
except ImportError:
46+
print ('Could not import Python Client for Google Cloud Storage\n'
47+
+ 'Download available at https://github.com/googleapis/python-storage\n'
48+
+ 'or run `pip install google-cloud-storage`')
49+
sys.exit(1)
50+
51+
OAUTH_SCOPE = ['https://www.googleapis.com/auth/devstorage.full_control']
52+
53+
mimetypes.add_type("application/java-archive", ".jar")
54+
55+
56+
def create_args_parser():
57+
parser = argparse.ArgumentParser()
58+
parser.add_argument(
59+
'--client_secrets',
60+
default='client_secrets.json',
61+
help='the OAuth 2.0 client secrets file to use (default: client_secrets.json)')
62+
parser.add_argument(
63+
'--save_credentials',
64+
default=False,
65+
action='store_true',
66+
help='should OAuth 2.0 credentials be saved to a local file or not (default: false)')
67+
parser.add_argument(
68+
'--credentials_file',
69+
default='credentials.json',
70+
help='a file to save OAuth 2.0 credentials to (default: credentials.json)')
71+
parser.add_argument(
72+
'--project_id',
73+
help='the Cloud Storage project id')
74+
parser.add_argument(
75+
'--bucket',
76+
help='the bucket to upload to')
77+
parser.add_argument(
78+
'--publish_version',
79+
help='the version being published (e.g. 1.23)')
80+
parser.add_argument(
81+
'--acl',
82+
default='private',
83+
choices=['private', 'public-read', 'authenticated-read'],
84+
help='the ACLs to assign to the uploaded files')
85+
parser.add_argument(
86+
'--publish',
87+
nargs='+',
88+
help='files to publish to Cloud Storage')
89+
parser.add_argument(
90+
'--logging_level',
91+
choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
92+
default='INFO',
93+
help='the level of logging detail')
94+
return parser
95+
96+
97+
def _authenticate(client_secrets, save_credentials=False, credentials_file=None):
98+
if os.path.isfile(credentials_file):
99+
credentials = Credentials.from_authorized_user_file(credentials_file)
100+
if credentials is not None:
101+
return credentials
102+
103+
flow = InstalledAppFlow.from_client_secrets_file(client_secrets, scopes=OAUTH_SCOPE)
104+
flow.run_local_server()
105+
credentials = flow.credentials
106+
if save_credentials:
107+
with open(credentials_file, 'w') as f:
108+
f.write(credentials.to_json())
109+
return credentials
110+
111+
112+
def _upload(bucket, file_path, object_name, acl):
113+
blob = bucket.blob(object_name)
114+
# blob.delete()
115+
blob.upload_from_filename(file_path, predefined_acl=acl)
116+
return blob.public_url
117+
118+
119+
def main():
120+
parser = create_args_parser()
121+
args = parser.parse_args()
122+
123+
logging.basicConfig(level=args.logging_level)
124+
125+
def die(message):
126+
logging.fatal(message)
127+
sys.exit(2)
128+
129+
if args.client_secrets is None:
130+
die('You must specify a client secrets file via --client_secrets')
131+
if args.project_id is None:
132+
die('You must specify a project ID via --project_id')
133+
if args.bucket is None:
134+
die('You must specify a bucket via --bucket')
135+
if args.publish_version is None:
136+
die('You must specify a published version identifier via --publish_version')
137+
138+
credentials = _authenticate(args.client_secrets, args.save_credentials, args.credentials_file)
139+
client = storage.Client(project=args.project_id, credentials=credentials)
140+
bucket = client.get_bucket(args.bucket)
141+
142+
published = []
143+
for f in args.publish:
144+
object_name = '%s/%s' % (args.publish_version, os.path.basename(f))
145+
logging.info('Publishing %s as %s', f, object_name)
146+
public_url = _upload(bucket, f, object_name, args.acl)
147+
published.append(public_url)
148+
149+
if published:
150+
logging.info('Published:\n %s' % '\n '.join(published))
151+
152+
153+
if __name__ == '__main__':
154+
main()

0 commit comments

Comments
 (0)