Completed
Push — master ( 354263...1d37e4 )
by Ionel Cristian
56s
created

ci.make_url()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 3
rs 10
1
#!/usr/bin/env python
2
"""
3
Use the AppVeyor API to download Windows artifacts.
4
5
Taken from: https://bitbucket.org/ned/coveragepy/src/tip/ci/download_appveyor.py
6
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
7
# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
8
"""
9
import argparse
10
import os
11
import requests
12
import zipfile
13
14
15
def make_auth_headers():
16
    """Make the authentication headers needed to use the Appveyor API."""
17
    path = os.path.expanduser("~/.appveyor.token")
18
    if not os.path.exists(path):
19
        raise RuntimeError(
20
            "Please create a file named `.appveyor.token` in your home directory. "
21
            "You can get the token from https://ci.appveyor.com/api-token"
22
        )
23
    with open(path) as f:
24
        token = f.read().strip()
25
26
    headers = {
27
        'Authorization': 'Bearer {}'.format(token),
28
    }
29
    return headers
30
31
32
def download_latest_artifacts(account_project, build_id):
33
    """Download all the artifacts from the latest build."""
34
    if build_id is None:
35
        url = "https://ci.appveyor.com/api/projects/{}".format(account_project)
36
    else:
37
        url = "https://ci.appveyor.com/api/projects/{}/build/{}".format(account_project, build_id)
38
    build = requests.get(url, headers=make_auth_headers()).json()
39
    jobs = build['build']['jobs']
40
    print("Build {0[build][version]}, {1} jobs: {0[build][message]}".format(build, len(jobs)))
41
42
    for job in jobs:
43
        name = job['name']
44
        print("  {0}: {1[status]}, {1[artifactsCount]} artifacts".format(name, job))
45
46
        url = "https://ci.appveyor.com/api/buildjobs/{}/artifacts".format(job['jobId'])
47
        response = requests.get(url, headers=make_auth_headers())
48
        artifacts = response.json()
49
50
        for artifact in artifacts:
51
            is_zip = artifact['type'] == "Zip"
52
            filename = artifact['fileName']
53
            print("    {0}, {1} bytes".format(filename, artifact['size']))
54
55
            url = "https://ci.appveyor.com/buildjobs/{}/artifacts/{}".format(job['jobId'], filename)
56
            download_url(url, filename, make_auth_headers())
57
58
            if is_zip:
59
                unpack_zipfile(filename)
60
                os.remove(filename)
61
62
63
def ensure_dirs(filename):
64
    """Make sure the directories exist for `filename`."""
65
    dirname, _ = os.path.split(filename)
66
    if dirname and not os.path.exists(dirname):
67
        os.makedirs(dirname)
68
69
70
def download_url(url, filename, headers):
71
    """Download a file from `url` to `filename`."""
72
    ensure_dirs(filename)
73
    response = requests.get(url, headers=headers, stream=True)
74
    if response.status_code == 200:
75
        with open(filename, 'wb') as f:
76
            for chunk in response.iter_content(16 * 1024):
77
                f.write(chunk)
78
79
80
def unpack_zipfile(filename):
81
    """Unpack a zipfile, using the names in the zip."""
82
    with open(filename, 'rb') as fzip:
83
        z = zipfile.ZipFile(fzip)
84
        for name in z.namelist():
85
            print("      extracting {}".format(name))
86
            ensure_dirs(name)
87
            z.extract(name)
88
89
parser = argparse.ArgumentParser(description='Download artifacts from AppVeyor.')
90
parser.add_argument('--id',
91
                    metavar='PROJECT_ID',
92
                    default='ionelmc/python-hunter',
93
                    help='Project ID in AppVeyor.')
94
parser.add_argument('build',
95
                    nargs='?',
96
                    metavar='BUILD_ID',
97
                    help='Build ID in AppVeyor. Eg: master-123')
98
99
if __name__ == "__main__":
100
    # import logging
101
    # logging.basicConfig(level="DEBUG")
102
    args = parser.parse_args()
103
    download_latest_artifacts(args.id, args.build)
104