deploy scripts
This commit is contained in:
parent
c600d373aa
commit
dffab21a1c
|
@ -0,0 +1,129 @@
|
|||
import struct
|
||||
from collections import namedtuple
|
||||
from datetime import datetime
|
||||
import subprocess
|
||||
from distutils.version import StrictVersion
|
||||
from esptool import LoadFirmwareImage # required to get hash and checksum right
|
||||
import os
|
||||
|
||||
# locale.setlocale(locale.LC_ALL, 'en_US')
|
||||
|
||||
APP_DESC_SIZE = 256 # sizeof(esp_app_desc_t)
|
||||
|
||||
APP_DESC_STRUCT = "<II2I32s32s16s16s32s32B20I"
|
||||
AppDesc = namedtuple('AppDesc',
|
||||
[
|
||||
"secure_version",
|
||||
"version",
|
||||
"project_name",
|
||||
"time",
|
||||
"date",
|
||||
"idf_ver",
|
||||
"app_elf_sha256",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def version_number_from_git(tag_prefix='release/', sha_length=10, version_format="{version}.dev{commits}+{sha}"):
|
||||
def get_released_versions():
|
||||
tags = sorted(subprocess.getoutput('git tag').split('\n'))
|
||||
versions = [t[len(tag_prefix):]
|
||||
for t in tags if t.startswith(tag_prefix)]
|
||||
return versions
|
||||
|
||||
def tag_from_version(v):
|
||||
return tag_prefix + v
|
||||
|
||||
def increment_version(v):
|
||||
parsed_version = [int(i) for i in v.split('.')]
|
||||
parsed_version[-1] += 1
|
||||
return '.'.join(str(i) for i in parsed_version)
|
||||
|
||||
version_strings = get_released_versions()
|
||||
version_strings.sort(key=StrictVersion)
|
||||
latest_release = version_strings[-1]
|
||||
commits_since_tag = subprocess.getoutput(
|
||||
'git rev-list {}..HEAD --count'.format(tag_from_version(latest_release)))
|
||||
sha = subprocess.getoutput('git rev-parse HEAD')[:sha_length]
|
||||
is_dirty = len(subprocess.getoutput(
|
||||
"git status --untracked-files=no -s")) > 0
|
||||
|
||||
if int(commits_since_tag) == 0:
|
||||
version_string = latest_release
|
||||
else:
|
||||
next_version = increment_version(latest_release)
|
||||
version_string = version_format.format(
|
||||
version=next_version, commits=commits_since_tag, sha=sha)
|
||||
|
||||
if is_dirty:
|
||||
version_string += ".dirty"
|
||||
return version_string
|
||||
|
||||
|
||||
def read_app_description_from_segment(segment):
|
||||
def process_bytes(b):
|
||||
if not isinstance(b, bytes):
|
||||
return b
|
||||
s = b.decode()
|
||||
return s[:s.find("\x00")]
|
||||
|
||||
unpacked = struct.unpack(APP_DESC_STRUCT, segment.data[:APP_DESC_SIZE])
|
||||
unpacked = tuple(process_bytes(e) for e in unpacked)
|
||||
magic_word, secure_version, _, _, version, project_name, time, date, idf_ver, app_elf_sha256, *_ = unpacked
|
||||
assert magic_word == 0xABCD5432
|
||||
return AppDesc(secure_version, version, project_name, time, date, idf_ver, app_elf_sha256)
|
||||
|
||||
|
||||
|
||||
def patch_app_description_in_segment(segment, version, project_name, time, date):
|
||||
assert len(version) < 32
|
||||
assert len(project_name) < 32
|
||||
assert len(time) < 16
|
||||
assert len(date) < 16
|
||||
|
||||
def fill_zeros(s, total_length):
|
||||
s += "\x00" * (total_length - len(s))
|
||||
s = s.encode()
|
||||
assert len(s) == total_length
|
||||
return s
|
||||
|
||||
raw_app_desc = segment.data[:APP_DESC_SIZE]
|
||||
unpacked = list(struct.unpack(APP_DESC_STRUCT, raw_app_desc))
|
||||
unpacked[4] = fill_zeros(version, 32)
|
||||
unpacked[5] = fill_zeros(project_name, 32)
|
||||
unpacked[6] = fill_zeros(time, 16)
|
||||
unpacked[7] = fill_zeros(date, 16)
|
||||
packed = struct.pack(APP_DESC_STRUCT, *unpacked)
|
||||
|
||||
original_data = segment.data
|
||||
segment.data = packed + original_data[APP_DESC_SIZE:]
|
||||
|
||||
|
||||
def patch_firmware(input_file, output_file):
|
||||
img = LoadFirmwareImage("esp32", input_file)
|
||||
version = version_number_from_git()
|
||||
|
||||
now = datetime.now()
|
||||
time = now.strftime("%H:%M:%S")
|
||||
date = now.strftime("%b %d %Y")
|
||||
patch_app_description_in_segment(img.segments[0], version, "swimtracker.bauer.tech", time, date)
|
||||
img.save(output_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
firmware_file = ".pio/build/esp32/firmware.bin"
|
||||
version_file_name = "VERSION"
|
||||
|
||||
patch_firmware(firmware_file, firmware_file) # patch inplace
|
||||
|
||||
version = version_number_from_git()
|
||||
print("Deploying ", version)
|
||||
with open(version_file_name, "w") as version_file:
|
||||
print(version, file=version_file)
|
||||
|
||||
subprocess.run(["scp", firmware_file, "root@server:/volumes/swimtracker-update"])
|
||||
subprocess.run(["scp", version_file_name, "root@server:/volumes/swimtracker-update"])
|
||||
|
||||
os.unlink(firmware_file)
|
||||
os.unlink(version_file_name)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
git clone -b v3.3 --recursive https://github.com/espressif/esp-idf.git
|
||||
set -x IDF_TOOLS_PATH /home/martin/code/swimtracker-firmware/idf-tools
|
||||
cd esp-idf
|
||||
./install.fish
|
||||
|
||||
# install arduino
|
||||
mdir components
|
||||
cd components
|
||||
git clone https://github.com/espressif/arduino-esp32.git arduino
|
||||
|
||||
# to get into environment (works only bash?)
|
||||
export IDF_TOOLS_PATH=/home/martin/code/swimtracker-firmware/idf-tools/
|
||||
. /home/martin/code/swimtracker-firmware/esp-idf/export.sh
|
||||
|
||||
|
||||
+ use only arduino libraries that are really necessary => smaller firmware
|
||||
|
||||
-> result: new esp-idf version doesn't work together with arduino-esp
|
||||
-> use 3.3?
|
||||
-> not yet clear: how to use arduino component libraries
|
Loading…
Reference in New Issue