mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-03 20:11:00 +00:00
support: finish support.py release
flow
This commit is contained in:
parent
0abfb6cd91
commit
15a971764a
120
tools/support.py
120
tools/support.py
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import click
|
import click
|
||||||
import coin_info
|
import coin_info
|
||||||
@ -204,13 +205,13 @@ def cli():
|
|||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
def fix():
|
@click.option("-n", "--dry-run", is_flag=True, help="Do not write changes")
|
||||||
|
def fix(dry_run):
|
||||||
"""Fix expected problems.
|
"""Fix expected problems.
|
||||||
|
|
||||||
Prunes orphaned keys and ensures that ERC20 duplicate info matches support info.
|
Prunes orphaned keys and ensures that ERC20 duplicate info matches support info.
|
||||||
"""
|
"""
|
||||||
all_coins = coin_info.get_all(deduplicate=False)
|
all_coins, _ = coin_info.coin_info_with_duplicates()
|
||||||
coin_info.mark_duplicate_shortcuts(all_coins.as_list())
|
|
||||||
coins_dict = all_coins.as_dict()
|
coins_dict = all_coins.as_dict()
|
||||||
|
|
||||||
orphaned = find_orphaned_support_keys(coins_dict)
|
orphaned = find_orphaned_support_keys(coins_dict)
|
||||||
@ -220,7 +221,8 @@ def fix():
|
|||||||
clear_support(device, orphan)
|
clear_support(device, orphan)
|
||||||
|
|
||||||
process_erc20(coins_dict)
|
process_erc20(coins_dict)
|
||||||
write_support_info()
|
if not dry_run:
|
||||||
|
write_support_info()
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -242,8 +244,7 @@ def check(ignore_tokens, ignore_missing):
|
|||||||
support info, but will not fail when missing coins are found. This is
|
support info, but will not fail when missing coins are found. This is
|
||||||
useful in Travis.
|
useful in Travis.
|
||||||
"""
|
"""
|
||||||
all_coins = coin_info.get_all(deduplicate=False)
|
all_coins, _ = coin_info.coin_info_with_duplicates()
|
||||||
coin_info.mark_duplicate_shortcuts(all_coins.as_list())
|
|
||||||
coins_dict = all_coins.as_dict()
|
coins_dict = all_coins.as_dict()
|
||||||
checks_ok = True
|
checks_ok = True
|
||||||
|
|
||||||
@ -281,14 +282,27 @@ def check(ignore_tokens, ignore_missing):
|
|||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
# fmt: off
|
# fmt: off
|
||||||
@click.argument("version")
|
@click.argument("device")
|
||||||
@click.option("--git-tag/--no-git-tag", "-g", default=False, help="create a corresponding Git tag")
|
@click.option("-r", "--version", help="Set explicit version string (default: guess from latest release)")
|
||||||
|
@click.option("--git-tag/--no-git-tag", "-g", default=False, help="Create a corresponding Git tag")
|
||||||
@click.option("--release-soon/--no-release-soon", default=True, help="Release coins marked 'soon'")
|
@click.option("--release-soon/--no-release-soon", default=True, help="Release coins marked 'soon'")
|
||||||
@click.option("--release-missing/--no-release-missing", default=True, help="Release coins with missing support info")
|
@click.option("--release-missing/--no-release-missing", default=True, help="Release coins with missing support info")
|
||||||
@click.option("-n", "--dry-run", is_flag=True, help="Do not write changes")
|
@click.option("-n", "--dry-run", is_flag=True, help="Do not write changes")
|
||||||
@click.option("-s", "--soon", is_flag=True, help="Only set missing support-infos to be released 'soon'.")
|
@click.option("-s", "--soon", is_flag=True, help="Only set missing support-infos to be released 'soon'")
|
||||||
|
@click.option("-f", "--force", is_flag=True, help="Proceed even with bad version/device info")
|
||||||
# fmt: on
|
# fmt: on
|
||||||
def release(version, git_tag, release_soon, release_missing, dry_run, soon):
|
@click.pass_context
|
||||||
|
def release(
|
||||||
|
ctx,
|
||||||
|
device: str,
|
||||||
|
version,
|
||||||
|
git_tag,
|
||||||
|
release_soon,
|
||||||
|
release_missing,
|
||||||
|
dry_run,
|
||||||
|
soon,
|
||||||
|
force,
|
||||||
|
):
|
||||||
"""Release a new Trezor firmware.
|
"""Release a new Trezor firmware.
|
||||||
|
|
||||||
Update support infos so that all coins have a clear support status.
|
Update support infos so that all coins have a clear support status.
|
||||||
@ -297,41 +311,87 @@ def release(version, git_tag, release_soon, release_missing, dry_run, soon):
|
|||||||
released firmware version.
|
released firmware version.
|
||||||
|
|
||||||
Optionally tags the repository with the given version.
|
Optionally tags the repository with the given version.
|
||||||
"""
|
|
||||||
version_tuple = list(map(int, version.split(".")))
|
|
||||||
device = f"trezor{version_tuple[0]}"
|
|
||||||
|
|
||||||
|
`device` can be "1", "2", or a string matching `support.json` key. Version
|
||||||
|
is autodetected by downloading a list of latest releases and incrementing
|
||||||
|
micro version by one, or you can specify `--version` explicitly.
|
||||||
|
"""
|
||||||
|
# check condition(s)
|
||||||
if soon and git_tag:
|
if soon and git_tag:
|
||||||
raise click.ClickException("Cannot git-tag a 'soon' revision")
|
raise click.ClickException("Cannot git-tag a 'soon' revision")
|
||||||
|
|
||||||
|
# process `device`
|
||||||
|
if device.isnumeric():
|
||||||
|
device = f"trezor{device}"
|
||||||
|
|
||||||
|
if not force and device not in coin_info.VERSIONED_SUPPORT_INFO:
|
||||||
|
raise click.ClickException(
|
||||||
|
f"Non-releasable device {device} (support info is not versioned). "
|
||||||
|
"Use --force to proceed anyway."
|
||||||
|
)
|
||||||
|
|
||||||
|
if not soon:
|
||||||
|
# guess `version` if not given
|
||||||
|
if not version:
|
||||||
|
versions = coin_info.latest_releases()
|
||||||
|
latest_version = versions.get(device)
|
||||||
|
if latest_version is None:
|
||||||
|
raise click.ClickException(
|
||||||
|
"Failed to guess version. "
|
||||||
|
"Please use --version to specify it explicitly."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
latest_version = list(latest_version)
|
||||||
|
latest_version[-1] += 1
|
||||||
|
version = ".".join(str(n) for n in latest_version)
|
||||||
|
|
||||||
|
# process `version`
|
||||||
|
try:
|
||||||
|
version_numbers = list(map(int, version.split(".")))
|
||||||
|
expected_device = f"trezor{version_numbers[0]}"
|
||||||
|
if not force and device != expected_device:
|
||||||
|
raise click.ClickException(
|
||||||
|
f"Device {device} should not be version {version}. "
|
||||||
|
"Use --force to proceed anyway."
|
||||||
|
)
|
||||||
|
except ValueError as e:
|
||||||
|
if not force:
|
||||||
|
raise click.ClickException(
|
||||||
|
f"Failed to parse '{version}' as a version. "
|
||||||
|
"Use --force to proceed anyway."
|
||||||
|
) from e
|
||||||
|
|
||||||
if soon:
|
if soon:
|
||||||
version = "soon"
|
version = "soon"
|
||||||
print(f"Moving {device} missing infos to 'soon'")
|
print(f"Moving {device} missing infos to 'soon'")
|
||||||
else:
|
else:
|
||||||
print(f"Releasing {device} firmware version {version}")
|
print(f"Releasing {device} firmware version {version}")
|
||||||
|
|
||||||
defs = coin_info.get_all(deduplicate=False)
|
defs, _ = coin_info.coin_info_with_duplicates()
|
||||||
coin_info.mark_duplicate_shortcuts(defs.as_list())
|
|
||||||
coins_dict = defs.as_dict()
|
coins_dict = defs.as_dict()
|
||||||
|
|
||||||
# process those darned ERC20 duplicates
|
# Invoke data fixup as dry-run. That will modify data internally but won't write
|
||||||
|
# changes. We will write changes at the end based on our own `dry_run` value.
|
||||||
|
print("Fixing up data...")
|
||||||
|
ctx.invoke(fix, dry_run=True)
|
||||||
|
|
||||||
|
# process missing (not listed) supportinfos
|
||||||
if release_missing:
|
if release_missing:
|
||||||
missing_list = find_unsupported_coins(coins_dict)[device]
|
missing_list = find_unsupported_coins(coins_dict)[device]
|
||||||
for coin in missing_list:
|
for coin in missing_list:
|
||||||
key = coin["key"]
|
key = coin["key"]
|
||||||
if coin.get("duplicate") and coin_info.is_token(coin):
|
# we should have no unprocessed dup tokens at this point
|
||||||
print(f"UNsupporting duplicate coin {key} ({coin['name']})")
|
assert not (coin.get("duplicate") and coin_info.is_token(coin))
|
||||||
set_unsupported(device, key, ERC20_DUPLICATE_KEY)
|
print(f"Adding missing {key} ({coin['name']})")
|
||||||
else:
|
set_supported(device, key, version)
|
||||||
print(f"Adding missing {key} ({coin['name']})")
|
|
||||||
set_supported(device, key, version)
|
|
||||||
|
|
||||||
|
# if we're releasing, process coins marked "soon"
|
||||||
|
# (`not soon` because `soon` means set release version to "soon")
|
||||||
if not soon and release_soon:
|
if not soon and release_soon:
|
||||||
supported, _ = support_dicts(device)
|
supported, _ = support_dicts(device)
|
||||||
soon_list = [
|
soon_list = [
|
||||||
coins_dict[key]
|
coins_dict[key]
|
||||||
for key, val in supported
|
for key, val in supported.items()
|
||||||
if val == "soon" and key in coins_dict
|
if val == "soon" and key in coins_dict
|
||||||
]
|
]
|
||||||
for coin in soon_list:
|
for coin in soon_list:
|
||||||
@ -339,8 +399,13 @@ def release(version, git_tag, release_soon, release_missing, dry_run, soon):
|
|||||||
print(f"Adding soon-released {key} ({coin['name']})")
|
print(f"Adding soon-released {key} ({coin['name']})")
|
||||||
set_supported(device, key, version)
|
set_supported(device, key, version)
|
||||||
|
|
||||||
|
tagname = f"{device}-{version}"
|
||||||
if git_tag:
|
if git_tag:
|
||||||
print("git tag not supported yet")
|
if dry_run:
|
||||||
|
print(f"Would tag current commit with {tagname}")
|
||||||
|
else:
|
||||||
|
print(f"Tagging current commit with {tagname}")
|
||||||
|
subprocess.check_call(["git", "tag", tagname])
|
||||||
|
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
write_support_info()
|
write_support_info()
|
||||||
@ -355,8 +420,7 @@ def show(keyword):
|
|||||||
|
|
||||||
Keywords match against key, name or shortcut (ticker symbol) of coin.
|
Keywords match against key, name or shortcut (ticker symbol) of coin.
|
||||||
"""
|
"""
|
||||||
defs = coin_info.get_all(deduplicate=False).as_list()
|
defs = coin_info.coin_info_with_duplicates()
|
||||||
coin_info.mark_duplicate_shortcuts(defs)
|
|
||||||
|
|
||||||
for kw in keyword:
|
for kw in keyword:
|
||||||
for coin in coin_info.search(defs, kw):
|
for coin in coin_info.search(defs, kw):
|
||||||
@ -388,8 +452,8 @@ def set_support_value(key, entries, reason):
|
|||||||
Entries with other names will be inserted into "others". This is a good place
|
Entries with other names will be inserted into "others". This is a good place
|
||||||
to store links to 3rd party software, such as Electrum forks or claim tools.
|
to store links to 3rd party software, such as Electrum forks or claim tools.
|
||||||
"""
|
"""
|
||||||
coins = coin_info.get_all(deduplicate=False).as_dict()
|
defs, _ = coin_info.coin_info_with_duplicates()
|
||||||
coin_info.mark_duplicate_shortcuts(coins.values())
|
coins = defs.as_dict()
|
||||||
if key not in coins:
|
if key not in coins:
|
||||||
click.echo(f"Failed to find key {key}")
|
click.echo(f"Failed to find key {key}")
|
||||||
click.echo("Use 'support.py show' to search for the right one.")
|
click.echo("Use 'support.py show' to search for the right one.")
|
||||||
|
Loading…
Reference in New Issue
Block a user