pebble/release/release.py

124 lines
3.7 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import argparse
import json
import os
import re
import sh
import shutil
import sys
import tempfile
def prepare_staging_directory(board_type, git_tag):
temp_path = tempfile.mkdtemp('tintin')
artifacts_root = os.path.join(temp_path, 'pebble_{}_{}'.format(board_type, git_tag))
os.mkdir(artifacts_root)
return artifacts_root
def waf_build(root, board, cflags, is_release=True):
waf_env = os.environ.copy()
waf_env["CFLAGS"] = ' '.join(cflags)
waf = sh.Command('{}/waf'.format(root))
sh.cd(root)
waf.distclean()
try:
waf.configure(release=is_release, jtag='olimex', board=board, _env = waf_env)
except sh.ErrorReturnCode_1, e:
print(e.stderr)
for target in ('build', 'build_safe'):
waf(target, _env = waf_env)
def waf_cleanup(root):
sh.cd(root)
waf.distclean()
def copy_files(root, staging, files, tag):
for f in files:
s = os.path.join(root, f['src'])
d = os.path.join(staging, f['dst'].format(tag=tag))
if not os.path.isfile(s):
raise Exception("File '{}' does not exist".format(s))
dest_dir = os.path.dirname(d)
if not os.path.isdir(dest_dir):
os.makedirs(dest_dir)
shutil.copyfile(s, d)
def do_release(root, recipe, no_build):
print('releasing {}...'.format(recipe['name']))
fw_params = recipe['firmware']
for board in recipe['firmware']['boards']:
sh.cd(root)
tag = sh.git.describe().strip()
dest_dir = prepare_staging_directory(board, tag)
outfile = '/tmp/pebble_fw_{}_{}'.format(board, tag)
outfile_format = 'zip'
archive_file = outfile + '.' + outfile_format
if os.path.exists(archive_file):
print('Deleted old archive {}'.format(archive_file))
os.remove(archive_file)
if not no_build:
print('building')
waf_build(root,
board = board,
cflags = fw_params['cflags'],
is_release = fw_params['release'])
print('copying files')
copy_files(root, dest_dir, recipe['files'], tag)
print('archiving')
shutil.make_archive(outfile, outfile_format, dest_dir)
print('created release archive')
print(outfile + '.' + outfile_format)
print()
print('release complete')
def main():
if 'TINTIN_HOME' not in os.environ:
raise Exception('\'TINTIN_HOME\' is must be defined')
tintin_root = os.path.abspath(os.path.expanduser(os.environ['TINTIN_HOME']))
if not os.path.isdir(tintin_root):
raise Exception('TINTIN_HOME points to invalid directory \'{}\''.format(tintin_root))
parser = argparse.ArgumentParser()
parser.add_argument('release_recipe')
parser.add_argument('-v', '--verbose', action='store_true')
parser.add_argument('-s', '--summary', action='store_true')
parser.add_argument('--no-build', action='store_true')
args = parser.parse_args()
with open(args.release_recipe, 'r') as f:
recipe = json.load(f)
do_release(tintin_root, recipe, args.no_build)
if __name__ == '__main__':
main()