forked from mirrors/gecko-dev
193 lines
5.5 KiB
Python
193 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
import pathlib
|
|
import json
|
|
import urllib.request
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
class Logger:
|
|
@classmethod
|
|
def info(cls, s):
|
|
print('[INFO]', s)
|
|
|
|
# Flush to make it apeear immediately in automation log.
|
|
sys.stdout.flush()
|
|
|
|
@classmethod
|
|
def fetch(cls, url):
|
|
cls.info(f'Fetching {url}')
|
|
|
|
@classmethod
|
|
def cmd(cls, cmd):
|
|
def format_cmd(s):
|
|
if ' ' in s:
|
|
escaped = s.replace('"', '\"')
|
|
return f'"{escaped}"'
|
|
return s
|
|
|
|
formatted_command = ' '.join(list(map(format_cmd, cmd)))
|
|
cls.info(f'$ {formatted_command}')
|
|
|
|
|
|
class GitRepository:
|
|
def __init__(self, path):
|
|
self.path = path
|
|
|
|
self.git_dir = self.path / '.git'
|
|
if not self.git_dir.exists():
|
|
print(f'{self.path} is not a Git repository.', file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
def get_output(self, *args):
|
|
cmd = ['git'] + list(args)
|
|
Logger.cmd(cmd)
|
|
output = subprocess.run(cmd,
|
|
capture_output=True,
|
|
cwd=self.path)
|
|
|
|
return output.stdout.decode()
|
|
|
|
def run(self, *args):
|
|
cmd = ['git'] + list(args)
|
|
Logger.cmd(cmd)
|
|
subprocess.run(cmd,
|
|
check=True,
|
|
cwd=self.path)
|
|
|
|
def commit_message(self, rev):
|
|
return self.get_output('log', '-1', '--pretty=format:%s%n', rev)
|
|
|
|
|
|
class MCRemoteRepository:
|
|
HG_API_URL = 'https://hg.mozilla.org/mozilla-central/'
|
|
|
|
@classmethod
|
|
def call(cls, name, path):
|
|
url = f'{cls.HG_API_URL}{name}{path}'
|
|
Logger.fetch(url)
|
|
req = urllib.request.Request(url, None, {})
|
|
response = urllib.request.urlopen(req)
|
|
return response.read()
|
|
|
|
@classmethod
|
|
def call_json(cls, name, path):
|
|
return json.loads(cls.call(name, path))
|
|
|
|
@classmethod
|
|
def file(cls, rev, path):
|
|
return cls.call('raw-file', f'/{rev}{path}')
|
|
|
|
|
|
class TreeHerder:
|
|
API_URL = 'https://treeherder.mozilla.org/api/'
|
|
|
|
@classmethod
|
|
def call(cls, name):
|
|
url = f'{cls.API_URL}{name}'
|
|
Logger.fetch(url)
|
|
req = urllib.request.Request(url, None, {
|
|
'User-Agent': 'smoosh-tools',
|
|
})
|
|
response = urllib.request.urlopen(req)
|
|
return response.read()
|
|
|
|
@classmethod
|
|
def call_json(cls, name):
|
|
return json.loads(cls.call(name))
|
|
|
|
@classmethod
|
|
def push_id(cls, rev):
|
|
push = cls.call_json(f'project/mozilla-central/push/?full=true&format=json&count=1&revision={rev}')
|
|
return push['results'][0]['id']
|
|
|
|
@classmethod
|
|
def jobs(cls, push_id):
|
|
push = cls.call_json(f'jobs/?push_id={push_id}&format=json')
|
|
count = push['count']
|
|
results = []
|
|
results += push['results']
|
|
|
|
page = 2
|
|
while len(results) < count:
|
|
push = cls.call_json(f'jobs/?push_id={push_id}&format=json&page={page}')
|
|
results += push['results']
|
|
page += 1
|
|
|
|
return results
|
|
|
|
|
|
class Status:
|
|
def run(is_ci):
|
|
Logger.info('Fetching ci_generated branch')
|
|
|
|
jsparagus = GitRepository(pathlib.Path('./'))
|
|
jsparagus.run('fetch', 'origin', 'ci_generated')
|
|
|
|
Logger.info('Checking mozilla-central tip revision')
|
|
|
|
m_c_rev = MCRemoteRepository.call_json('json-log', '/tip/')['node']
|
|
cargo_file = MCRemoteRepository.file(
|
|
m_c_rev,
|
|
'/js/src/frontend/smoosh/Cargo.toml'
|
|
).decode()
|
|
m = re.search('rev = "(.+)"', cargo_file)
|
|
ci_generated_rev = m.group(1)
|
|
|
|
Logger.info('Checking jsparagus referred by mozilla-central')
|
|
|
|
message = jsparagus.commit_message(ci_generated_rev)
|
|
m = re.search('for ([A-Fa-f0-9]+)', message)
|
|
master_rev = m.group(1)
|
|
|
|
Logger.info('Checking build status')
|
|
|
|
push_id = TreeHerder.push_id(m_c_rev)
|
|
jobs = TreeHerder.jobs(push_id)
|
|
nonunified_job = None
|
|
smoosh_job = None
|
|
for job in jobs:
|
|
if 'spidermonkey-sm-nonunified-linux64/debug' in job:
|
|
nonunified_job = job
|
|
if 'spidermonkey-sm-smoosh-linux64/debug' in job:
|
|
smoosh_job = job
|
|
|
|
def get_result(job):
|
|
if job:
|
|
if 'completed' in job:
|
|
if 'success' in job:
|
|
return 'OK'
|
|
else:
|
|
return 'NG'
|
|
else:
|
|
return 'not yet finished'
|
|
else:
|
|
return 'unknown'
|
|
|
|
nonunified_result = get_result(nonunified_job)
|
|
smoosh_result = get_result(smoosh_job)
|
|
|
|
if is_ci:
|
|
print(f'##[set-output name=mc;]{m_c_rev}')
|
|
print(f'##[set-output name=jsparagus;]{master_rev}')
|
|
print(f'##[set-output name=build;]{nonunified_result}')
|
|
print(f'##[set-output name=test;]{smoosh_result}')
|
|
else:
|
|
print(f'mozilla-central tip: {m_c_rev}')
|
|
print(f'referred jsparagus revision: {master_rev}')
|
|
print(f'Build status:')
|
|
print(f' Build with --enable-smoosh: {nonunified_result}')
|
|
print(f' Test with --smoosh: {smoosh_result}')
|
|
|
|
|
|
is_ci = False
|
|
if len(sys.argv) > 1:
|
|
if sys.argv[1] == 'ci':
|
|
is_ci = True
|
|
|
|
Status.run(is_ci)
|