Skip to content

Commit 15da8c6

Browse files
committed
feat: First iteration ui
1 parent f5eb970 commit 15da8c6

30 files changed

Lines changed: 2175 additions & 48 deletions

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ __pycache__/
1515
# Generated tool output
1616
tools/out/
1717
tools/labels
18+
ui/workspaces/
19+
ui/state/
1820

1921
device_manifest.csv
2022
matter-labels.html
@@ -27,4 +29,4 @@ matter-labels.html
2729
*.swo
2830
*.log
2931

30-
build
32+
build

docs/pipeline.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ If `gn` is missing, pipeline runs Matter bootstrap automatically.
5252

5353
If nested submodules are missing, pipeline initializes them automatically.
5454

55+
If you run with `--skip-build`, pipeline can use `provisioning-support/connectedhomeip` from the release bundle instead of a live `esp-matter/` checkout.
56+
5557
## Build Output Path
5658

5759
Default build dir:
@@ -75,6 +77,10 @@ When flashing, pipeline:
7577
4. optionally erases flash first
7678
5. flashes selected device
7779

80+
Plain flashing from a released build works without submodules.
81+
82+
`erase-flash` and `idf.py monitor` still need the upstream example checkout.
83+
7884
## Labels
7985

8086
Unless `--skip-labels` is passed, pipeline also creates:

tools/generate_attestation_chain.py

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@
2323
render_chip_cert_missing_message,
2424
resolve_chip_cert_path,
2525
)
26-
from tool_paths import CHIP_ROOT, DEFAULT_CHIP_CERT, DEFAULT_MANIFEST_PATH, DEFAULT_OUTPUT_DIR
26+
from tool_paths import (
27+
DEFAULT_MANIFEST_PATH,
28+
DEFAULT_OUTPUT_DIR,
29+
resolve_chip_root,
30+
resolve_default_chip_cert_path,
31+
)
2732
else:
2833
from .fleet_data import load_manifest_rows
2934
from .generate_factory_data import (
@@ -35,7 +40,12 @@
3540
render_chip_cert_missing_message,
3641
resolve_chip_cert_path,
3742
)
38-
from .tool_paths import CHIP_ROOT, DEFAULT_CHIP_CERT, DEFAULT_MANIFEST_PATH, DEFAULT_OUTPUT_DIR
43+
from .tool_paths import (
44+
DEFAULT_MANIFEST_PATH,
45+
DEFAULT_OUTPUT_DIR,
46+
resolve_chip_root,
47+
resolve_default_chip_cert_path,
48+
)
3949

4050

4151
DEFAULT_ATTESTATION_OUTPUT_DIR = DEFAULT_OUTPUT_DIR / "attestation"
@@ -46,6 +56,7 @@
4656

4757

4858
def parse_args() -> argparse.Namespace:
59+
chip_root = resolve_chip_root()
4960
parser = argparse.ArgumentParser(
5061
description="Generate development PAA/PAI/DAC/CD assets for manifest rows.",
5162
)
@@ -66,9 +77,14 @@ def parse_args() -> argparse.Namespace:
6677
)
6778
parser.add_argument(
6879
"--chip-cert",
69-
default=str(DEFAULT_CHIP_CERT),
80+
default=str(resolve_default_chip_cert_path(chip_root=chip_root)),
7081
help="Path to CHIP host chip-cert tool.",
7182
)
83+
parser.add_argument(
84+
"--chip-root",
85+
default=str(chip_root),
86+
help="Path to connectedhomeip root used for test attestation assets.",
87+
)
7288
parser.add_argument(
7389
"--vendor-name",
7490
default=DEFAULT_VENDOR_NAME,
@@ -173,6 +189,7 @@ def generate_attestation_certificate(
173189
def generate_pair_attestation_bundle(
174190
*,
175191
chip_cert_path: pathlib.Path,
192+
chip_root: pathlib.Path,
176193
output_dir: pathlib.Path,
177194
vendor_id_hex: str,
178195
product_id_hex: str,
@@ -224,7 +241,7 @@ def generate_pair_attestation_bundle(
224241
"pai_cert_der": convert_cert_pem_to_der(pai_cert_pem, pair_dir / "pai_cert.der"),
225242
"cd": generate_test_cd(
226243
chip_cert=chip_cert_path,
227-
chip_root=CHIP_ROOT,
244+
chip_root=chip_root,
228245
output_path=pair_dir / f"Chip-Test-CD-{vendor_id_hex}-{product_id_hex}.der",
229246
vendor_id_hex=vendor_id_hex,
230247
product_id_hex=product_id_hex,
@@ -316,6 +333,7 @@ def augment_rows_with_attestation_paths(
316333
rows: list[dict[str, str]],
317334
output_dir: pathlib.Path,
318335
chip_cert_path: pathlib.Path,
336+
chip_root: pathlib.Path,
319337
vendor_name: str,
320338
product_name: str,
321339
valid_from: str,
@@ -332,6 +350,7 @@ def augment_rows_with_attestation_paths(
332350
if pair not in pair_bundles:
333351
pair_bundles[pair] = generate_pair_attestation_bundle(
334352
chip_cert_path=chip_cert_path,
353+
chip_root=chip_root,
335354
output_dir=output_dir / "pairs",
336355
vendor_id_hex=vendor_id_hex,
337356
product_id_hex=product_id_hex,
@@ -376,16 +395,22 @@ def main() -> int:
376395
manifest_path = pathlib.Path(args.manifest).resolve()
377396
output_dir = pathlib.Path(args.output_dir).resolve()
378397
manifest_out_path = pathlib.Path(args.manifest_out).resolve()
379-
requested_chip_cert = pathlib.Path(args.chip_cert).expanduser().resolve()
380-
chip_cert_path, searched_paths = resolve_chip_cert_path(requested_chip_cert, CHIP_ROOT)
398+
chip_root = pathlib.Path(args.chip_root).expanduser().resolve()
399+
default_chip_cert_arg = str(resolve_default_chip_cert_path())
400+
requested_chip_cert = (
401+
resolve_default_chip_cert_path(chip_root=chip_root)
402+
if args.chip_cert == default_chip_cert_arg
403+
else pathlib.Path(args.chip_cert).expanduser().resolve()
404+
)
405+
chip_cert_path, searched_paths = resolve_chip_cert_path(requested_chip_cert, chip_root)
381406

382407
if not manifest_path.is_file():
383408
raise SystemExit(f"Manifest not found: {manifest_path}")
384409
if chip_cert_path is None:
385410
raise SystemExit(
386411
render_chip_cert_missing_message(
387412
requested_path=requested_chip_cert,
388-
chip_root=CHIP_ROOT,
413+
chip_root=chip_root,
389414
searched_paths=searched_paths,
390415
)
391416
)
@@ -396,6 +421,7 @@ def main() -> int:
396421
rows=rows,
397422
output_dir=output_dir,
398423
chip_cert_path=chip_cert_path,
424+
chip_root=chip_root,
399425
vendor_name=args.vendor_name,
400426
product_name=args.product_name,
401427
valid_from=args.valid_from,

tools/generate_factory_data.py

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,23 @@
1616
from fleet_data import load_manifest_rows, read_onboarding_codes, write_devices_summary
1717
from tool_python import resolve_tool_python
1818
from tool_paths import (
19-
CHIP_ROOT,
20-
DEFAULT_CHIP_CERT,
21-
DEFAULT_FACTORY_GENERATOR,
2219
DEFAULT_MANIFEST_PATH,
2320
DEFAULT_OUTPUT_DIR,
21+
resolve_chip_root,
22+
resolve_default_chip_cert_path,
23+
resolve_factory_generator_path,
24+
resolve_setuppayload_requirements_path,
2425
)
2526
else:
2627
from .fleet_data import load_manifest_rows, read_onboarding_codes, write_devices_summary
2728
from .tool_python import resolve_tool_python
2829
from .tool_paths import (
29-
CHIP_ROOT,
30-
DEFAULT_CHIP_CERT,
31-
DEFAULT_FACTORY_GENERATOR,
3230
DEFAULT_MANIFEST_PATH,
3331
DEFAULT_OUTPUT_DIR,
32+
resolve_chip_root,
33+
resolve_default_chip_cert_path,
34+
resolve_factory_generator_path,
35+
resolve_setuppayload_requirements_path,
3436
)
3537

3638

@@ -40,16 +42,14 @@
4042
DEFAULT_COMMISSIONING_FLOW = "0"
4143
DEFAULT_LIGHT_DEVICE_TYPE = "0x010D"
4244
TEST_CERTIFICATION_ID = "ZIG0000000000000000"
43-
SETUPPAYLOAD_REQUIREMENTS = (
44-
CHIP_ROOT / "scripts" / "setup" / "requirements.setuppayload.txt"
45-
)
4645
SETUPPAYLOAD_IMPORT_CHECK = "import bitarray, click, construct, stdnum"
4746
TEST_PAI_CERT_PATTERN = re.compile(
4847
r"Chip-Test-PAI-([0-9A-F]{4})-([0-9A-F]{4})-Cert\.der$"
4948
)
5049

5150

5251
def parse_args() -> argparse.Namespace:
52+
chip_root = resolve_chip_root()
5353
parser = argparse.ArgumentParser(
5454
description="Generate per-device Matter factory data and onboarding codes.",
5555
)
@@ -90,14 +90,19 @@ def parse_args() -> argparse.Namespace:
9090
)
9191
parser.add_argument(
9292
"--generator",
93-
default=str(DEFAULT_FACTORY_GENERATOR),
93+
default=str(resolve_factory_generator_path(chip_root=chip_root)),
9494
help="Path to generate_esp32_chip_factory_bin.py.",
9595
)
9696
parser.add_argument(
9797
"--chip-cert",
98-
default=str(DEFAULT_CHIP_CERT),
98+
default=str(resolve_default_chip_cert_path(chip_root=chip_root)),
9999
help="Path to CHIP host chip-cert tool used to generate test CDs when needed.",
100100
)
101+
parser.add_argument(
102+
"--chip-root",
103+
default=str(chip_root),
104+
help="Path to connectedhomeip root used for factory generator assets.",
105+
)
101106
parser.add_argument(
102107
"--use-test-attestation",
103108
action="store_true",
@@ -266,6 +271,8 @@ def render_chip_cert_missing_message(
266271
" source scripts/activate.sh",
267272
" gn gen out/host",
268273
" ninja -C out/host chip-cert",
274+
"",
275+
"Or extract a release bundle that includes provisioning-support/connectedhomeip.",
269276
]
270277
)
271278
return "\n".join(lines)
@@ -667,8 +674,19 @@ def build_generator_pythonpath(
667674
def main() -> int:
668675
args = parse_args()
669676
manifest_path = pathlib.Path(args.manifest).resolve()
670-
generator_path = pathlib.Path(args.generator).resolve()
671-
chip_cert_path = pathlib.Path(args.chip_cert).expanduser().resolve()
677+
chip_root = pathlib.Path(args.chip_root).expanduser().resolve()
678+
default_generator_arg = str(resolve_factory_generator_path())
679+
default_chip_cert_arg = str(resolve_default_chip_cert_path())
680+
generator_path = (
681+
resolve_factory_generator_path(chip_root=chip_root)
682+
if args.generator == default_generator_arg
683+
else pathlib.Path(args.generator).resolve()
684+
)
685+
chip_cert_path = (
686+
resolve_default_chip_cert_path(chip_root=chip_root)
687+
if args.chip_cert == default_chip_cert_arg
688+
else pathlib.Path(args.chip_cert).expanduser().resolve()
689+
)
672690
output_root = pathlib.Path(args.output_dir).resolve()
673691
shim_root = pathlib.Path(__file__).resolve().parent / "_factory_generator_shim"
674692
tool_python = resolve_tool_python()
@@ -677,13 +695,14 @@ def main() -> int:
677695
raise SystemExit(f"Manifest not found: {manifest_path}")
678696
if not generator_path.is_file():
679697
raise SystemExit(f"Generator not found: {generator_path}")
680-
if not SETUPPAYLOAD_REQUIREMENTS.is_file():
698+
requirements_path = resolve_setuppayload_requirements_path(chip_root=chip_root)
699+
if not requirements_path.is_file():
681700
raise SystemExit(
682-
f"Missing CHIP setup-payload requirements file: {SETUPPAYLOAD_REQUIREMENTS}"
701+
f"Missing CHIP setup-payload requirements file: {requirements_path}"
683702
)
684703
verify_setup_payload_python_dependencies(
685704
python_executable=tool_python,
686-
requirements_path=SETUPPAYLOAD_REQUIREMENTS,
705+
requirements_path=requirements_path,
687706
auto_install=not args.no_auto_install_deps,
688707
)
689708
rows = load_manifest_rows(manifest_path)
@@ -699,7 +718,7 @@ def main() -> int:
699718
row=row,
700719
row_index=row_index,
701720
manifest_dir=manifest_path.parent,
702-
chip_root=CHIP_ROOT,
721+
chip_root=chip_root,
703722
chip_cert=chip_cert_path,
704723
device_output_dir=device_output_dir,
705724
use_test_attestation=args.use_test_attestation,

0 commit comments

Comments
 (0)