aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/send-qa-email
blob: 1b69307e7efa7a5abd4c953f7d58e8c57de875c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env python3
#
# Send email about the build to prompt QA to begin testing
#

import json
import os
import sys
import subprocess
import errno
import tempfile

import utils


parser = utils.ArgParser(description='Process test results and optionally send an email about the build to prompt QA to begin testing.')

parser.add_argument('send',
                    help="True to send email, otherwise the script will display a message and exit")
parser.add_argument('repojson',
                    help="The json file containing the repositories to use")
parser.add_argument('sharedrepodir',
                    help="The shared repos directory (to resolve the repo revision hashes)")
parser.add_argument('-p', '--publish-dir',
                    action='store',
                    help="Where the artefacts were published")
parser.add_argument('-R', '--results-dir',
                    action='store',
                    help="Where the test results were published")
parser.add_argument('-r', '--release',
                    action='store',
                    help="The build/release 'name' for release purposes (optional)")

args = parser.parse_args()

scriptsdir = os.path.dirname(os.path.realpath(__file__))
ourconfig = utils.loadconfig()

with open(args.repojson) as f:
    repos = json.load(f)

resulttool = os.path.dirname(args.repojson) + "/build/scripts/resulttool"

buildtoolsdir = os.path.dirname(args.repojson) + "/build/buildtools"
if os.path.exists(buildtoolsdir):
    utils.enable_buildtools_tarball(buildtoolsdir)

if 'poky' in repos and os.path.exists(resulttool) and args.results_dir:
    # Need the finalised revisions (not 'HEAD')
    targetrepodir = "%s/poky" % (args.sharedrepodir)
    revision = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=targetrepodir).decode('utf-8').strip()
    branch = repos['poky']['branch']
    repo = repos['poky']['url']

    extraopts = None
    basebranch, comparebranch = utils.getcomparisonbranch(ourconfig, repo, branch)
    if basebranch:
        extraopts = " --branch %s --commit %s" % (branch, revision)
    if comparebranch:
        extraopts = extraopts + " --branch2 %s" % (comparebranch)
    elif basebranch:
        print("No comparision branch found, comparing to %s" % basebranch)
        extraopts = extraopts + " --branch2 %s" % basebranch

    report = subprocess.check_output([resulttool, "report", args.results_dir])
    with open(args.results_dir + "/testresult-report.txt", "wb") as f:
        f.write(report)

    tempdir = tempfile.mkdtemp(prefix='sendqaemail.')
    try:
        cloneopts = []
        if comparebranch:
            cloneopts = ["--branch", comparebranch]
        elif basebranch:
            cloneopts = ["--branch", basebranch]
        try:
            subprocess.check_call(["git", "clone", "git@push.yoctoproject.org:yocto-testresults", tempdir, "--depth", "5"] + cloneopts)
        except subprocess.CalledProcessError:
            print("No comparision branch found, falling back to master")
            subprocess.check_call(["git", "clone", "git@push.yoctoproject.org:yocto-testresults", tempdir, "--depth", "5"])

        # If the base comparision branch isn't present regression comparision won't work
        # at least until we can tell the tool to ignore internal branch information
        if basebranch:
            try:
                subprocess.check_call(["git", "rev-parse", "--verify", basebranch], cwd=tempdir)
            except subprocess.CalledProcessError:
                # Doesn't exist so base it off master
                # some older hosts don't have git branch old new
                subprocess.check_call(["git", "checkout", "master"], cwd=tempdir)
                subprocess.check_call(["git", "branch", basebranch], cwd=tempdir)
                subprocess.check_call(["git", "checkout", basebranch], cwd=tempdir)
                extraopts = None

        subprocess.check_call([resulttool, "store", args.results_dir, tempdir])
        if comparebranch:
            subprocess.check_call(["git", "push", "--all", "--force"], cwd=tempdir)
            subprocess.check_call(["git", "push", "--tags", "--force"], cwd=tempdir)
        elif basebranch:
            subprocess.check_call(["git", "push", "--all"], cwd=tempdir)
            subprocess.check_call(["git", "push", "--tags"], cwd=tempdir)

        if extraopts:
            regreport = subprocess.check_output([resulttool, "regression-git", tempdir] + extraopts.split())
            with open(args.results_dir + "/testresult-regressions-report.txt", "wb") as f:
                f.write(regreport)

    finally:
        subprocess.check_call(["rm", "-rf",  tempdir])
        pass

if args.send.lower() != 'true' or not args.publish_dir or not args.release:
    utils.printheader("Not sending QA email")
    sys.exit(0)

buildhashes = ""
for repo in sorted(repos.keys()):
    # Need the finalised revisions (not 'HEAD')
    targetrepodir = "%s/%s" % (args.sharedrepodir, repo)
    revision = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=targetrepodir).decode('utf-8').strip()
    buildhashes += "%s: %s\n" % (repo, revision)

web_root = utils.getconfig('WEBPUBLISH_DIR', ourconfig)
web_url = utils.getconfig('WEBPUBLISH_URL', ourconfig)

email = ""
mailto = utils.getconfig("QAMAIL_TO", ourconfig)
if mailto:
    email += "To: " + mailto + "\n"
mailcc = utils.getconfig("QAMAIL_CC", ourconfig)
if mailcc:
    email += "Cc: " + mailcc + "\n"
mailbcc = utils.getconfig("QAMAIL_BCC", ourconfig)
if mailbcc:
    email += "Bcc: " + mailbcc + "\n"

email += "Subject: " + "QA notification for completed autobuilder build (%s)\n" % args.release
email += '''\n
A build flagged for QA (%s) was completed on the autobuilder and is available at:\n\n
    %s\n\n
Build hash information: \n
%s

\nThis is an automated message from the Yocto Project Autobuilder\nGit: git://git.yoctoproject.org/yocto-autobuilder2\nEmail: richard.purdie@linuxfoundation.org\n

''' % (args.release, args.publish_dir.replace(web_root, web_url), buildhashes)

# Store a copy of the email in case it doesn't reach the lists
with open(os.path.join(args.publish_dir, "qa-email"), "wb") as qa_email:
    qa_email.write(email.encode('utf-8'))

utils.printheader("Sending QA email")
env = os.environ.copy()
# Many distros have sendmail in */sbin
env["PATH"] = env["PATH"] + ":/usr/sbin:/sbin"
subprocess.check_call('echo "' + email +' " | sendmail -t', shell=True, env=env)