From 5991653708004dcad6b72e4a2e921462eb04525a Mon Sep 17 00:00:00 2001 From: EivindH06 Date: Tue, 7 Oct 2025 09:13:19 +0200 Subject: [PATCH] Fixed release process --- .../package_firmware.cpython-311.pyc | Bin 0 -> 12217 bytes scripts/package_firmware.py | 79 +++++++++++++++--- 2 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 scripts/__pycache__/package_firmware.cpython-311.pyc diff --git a/scripts/__pycache__/package_firmware.cpython-311.pyc b/scripts/__pycache__/package_firmware.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e6e93e0b99d1b18548fca3d07fb143203962b5e GIT binary patch literal 12217 zcmb_CTWlLwc0+PV4&P5bEm>pBvcy;qOR@Zr8D(utPVCr{63b4btjkiIkwu%Y&WtRJ z88zH((8`94n zhfi6?W{bTXp1E`9+;i_ebMJZG`(u~OPC>H#>whi((>{v&Pkg8*tDZ4@^S_XJKwYLd zYJuVmoH1cY8W)TP%$pLX1rxc`3pBZ#7tG{tS+KyJPFR!70z+`k30u;(U`yH;?Bv;! za3q}z&ZKL>m2@w-lb!_+lv@|PMv7-R<_iNwJ%PWT7JQtIvvUs4$+?SXqMH_9D=dmA^#4Zyvfd!0K3_YUp|HwgDmeh)Wv z!-y>iPH46B3&=geN0Oj7rc2}>8jnr`ntd)ByAi#{v$1qC6Ho9QJC}$`OKBl_ZkAn& z3(3`}z_U?7iZ4ZDlE}tWQkspjq7;?lF*XrhORq?*xDuD5iwT~EdiKo9Vj?as$5YqX zbc%f|F1@|7$j(6%B0G>4*l234T6>jWWS7&T6dGpF!W%vsTV|!GaE+H(K6NuLq*F;g zCD~W8bD1?(TIShne2N#M5_GfHx5aoWDy$8X0jx+o8;4%TmigEXaV0qj&2cQBj7!kx zWHc3D;zh}R{?hCW%cWy0NFK;W5%4U>-;Bp#4Anu$qA4Jn0x~?iy3D88L^^!~hXtc# zXXj6`D;W;DA`aW_)3>6@42)ltgq4`I0vyW-X>KJ3{ai_Lyg=v!r!v4SE-vsfDJ`r` z*zGJNE-p$VB*)g;u0FFYFJ@jJ6UXWWEOHNc-B?nuI22usas1NgFmR4;-Wvji*HRCNGHbbZU?l<5?a!+QdaJy_!m-qa2%wO3N@0aE`zvNT-JF zzs9*0GH8xyDwW2W0bHAbXL=4$Lq?53K1uN;uQ3R-=@cKLHF_!@lQia>1YZ;eq|q0E z6B;v{!TQmJX3+<#(a0gq3Y<7TcJ!!bCM+S($eC*9^-3o8x@OavmQJKY7QqEw6WjbxDZtTN{@Y!I@l5kaXOwU}2%+E&7ynSv?vj{wV%hU@$%*jkt5c%PmXcA~g zV|)xM*Ahw<6Ga)m(O_*qprqOgr>N_-JZE@nY+nECluYHxO07|aAd|S#n;YLaj5|&Z@XPTa^;0s-h9+ zKgWwPAxQcR-(h?*su$?z#I8*Y%U4Ki*(46z_rVP+9oJOE2Lx{?4vhQcfuG!$EgmB%Nt!?kYdvI&+jdBLV&;<8n;6BQ8> zf~9G#G$nMwh_lSlkS?XN;VEbcBrCR47gXL^l&Dg*36_JJ9auMg7B?M#i}$yLEFGAg3Ici6LH8DS(QCm8*-%t7cy2J zSOU(8>>}_K*;vyYkqX}MawzK_8mg!(o*Rlv*@<(PW?2+bAbOG+GFsFOHAz_?XKY0f zP1QCS_`(lqi*Tj*^2Z>ZQ*KlS{IEb7_Fa&>b z3~J=4ZC6Xlb)YbMvEZ6fTr(xtOzx~o+qdYpBHgAk9@Q04J#DJ%owAKGw|`BU&6eLF zC==kM%#JE*VB6cHy51;T2_B7j0Llc|8}R(wF5k9y?{^{DLQsSEu6*Xa@7!Efya!d+ zsqfGcmsj-$RoD67irT(iK|S{hRHuK-(N%PGDUQ7*$KC?H_ZwgxrFkp!C6b1W5a;+8 zuBwVc#c@^W1FTq0&clNl{zM<#gwh8fvxOi?dMJE3?UXT6O=5$LG&D=jb%Si!U0*a) z5d%_#JmZYA;YVQcJu)>@`yo=RX_m&GHB-yuXkJRqI8)TsVL?j@t*~LsEE+yhAUWD41*GvgMr8%MZ zDBDPd5G}k09n&0oLlHFUG#V>uW{@(HDB|2e%TX9WJSU-FSqcI=D3{?c{s({@rCQs{ zl)*fpdV01zeML{7;^{AW`U_0|SN_&Q+mzy;F8QZ(@2HN}Ek}3J(XBXoN{*f~Wis2h z-94&v;hCf0T+pwtO-7IXHxz&}WwhDL4CU+E^7a+IeTuig0@87!T z!QZ#rcIe@(VxKG7=L+;Y$PU8uriG2unk;M@KI)&FUS;YvFAi9?uQKy?Ebwva zj;V3!ZkU$9HT{I)OkcoEdQvkLVY#)f!?NCe`N})YOapbd-3E>>{+j6+sFb6Z8l^;f z)p*PF0kvu{P#;hR_yO(jui%w>{(P0IDFOuZOhr@|H~`Talc|GWOjeSbUr_rp1gd|(1X7R|aG6_-IwXeOYd(P^;JG&&9riDuCaD9yIa z-{Runyh^ZQ-T;CcgLSY~%^X`^N!<`mV_TKg@;!aEI2t-9T!8o25a*Wwpg-H5*1I3w zUcbAZdt0@+KJB>Eaqr0Op1ZIdjOO0W)7vc_h0epZ>shbTa2RF!dhx9tG})1zWw&w`a?s`LOFwtE4D!Q5U&1o z@Kmqqm%a3`~ z)2hur+0|HsHlxt9AWQJy0D^8c$`tV@3<%e)vNaC~FQ?`uDYiA~S)hR$QnvnxdPFzt zD2SJUwvieZgKTZaSZAP3obxZG<~Fa_bnUuLHgh!gS0=rdO{DL3*}nUt15eQW)UtEw z60L5PY3Mogh+cQdcG*GbIA!PV`WO1y$jMrNoBP>3IuHeR&PM3EWLh@K2H7SvvO~7W z6lZ_Pth;4bzQKR25v3%M0o8Q9=2gmW&hgaQJeHj;N^RA8z#;rHu17mW+Pa6M*1fVP zUq@`nHIGM_0dBj=2z;{dcjB#X@K5U|R6-aqx;%mjPsMm&>2 z7cSdASPO|Y8)F(%tvLS^aALt?0cT9q7-Aqr(l=fhhQP~2ny#wzMj~G!MtBz(D9j<4 z0ie+s>k_6hYg!Q!!Xkux}tfCabZfNG@4HTP>RRNSxWN{6mi<+HS zUX{H5f|z+UM)EW>x01|=x_Rh;zJbGjlaEMga7M*QCN0Kqh5QX2ovrp(XTy8=h$Gfq zRetK0pdIuZ$Y|7iU{6BVDxGmu1Uix54t#J12ZCGdPRsq z7!dOW6YNTzpGZ-}m>k-i%}Lj(fvTI^5H}HSL4`E@#p7Td<*2fsYT27NeKwmjl2%h6MG^eB#fCC5J0Y{6~DRd8R(n*hM|+xIq9iS38vB9W}cZ=yNGF_VsTis*D?lGnNNU8gX!i<-g@d7hmwou*xjtNE<+_x1R zDh7uhUsr-BO2HFb!PCXyX(c#S3QhsTw)~+YF#R>fKVI^WZ}}&S{z=9Ey^{ZX>g3si zXKv%xmZ!Jq>4n~UMoONMEzj|y=eXjTD0wCdo{3*gA=A8_z%D1UivY7lxB0CQ=ug5< z!i)B5MEb)WhRBN`MyPj|#%hWk=Ai}t#60;GWFCME{|N~AsU4xjby}u{OQ1lFsFpZg z{hMVo8m)TDqtp0Of}k+{)ZDB*K|vcqfzX`gp=sSBn|BWoG~srp_M$D?a_rAirHI@mV6cA3DgrYl9;0kfpPuXoPS0`?%q_bM7Qg&09w|r zlS278FT4*W5IA+#{rjjygr8=s?P?KGFI+`TGYPVRycd?>Q2=*@67ahSH}I`hAQE#8 z3y7jXWuiGNGbe&$()8AKF={3~5z*|bh_s4-&@g0S1K$1={vu|;nI>b*zYil*0^_B? zcpGgI#M`6MxCR|{`&$|ZH zw!LacU)f6gz>@~BVJ_P#TVRXnE;8MZxQEvtw>SMqpd)< z>FoSd=#fUxziyr_@)@(;&k)de2s!R2=o2w&tGkdb32VWG@yat%L)8m zSO@hDQ!t!gg}K9QU$?&!6Sh^FXFQnBucB&w3D?Pi@e3xYO?Cpb%M3urBkQ_Lwn3oE z#W`ggF<4DmFxA#wDKnJ0^}KAaVAuh}^Jq5=7i^A@da`AA2_UQmA95y6Tpt zWP&JsAqrnqSVVv}(hI|z#16?aVM&+_OWb7E79N2c$@**AaFksZ_@y`cvw{A}szntZ ziB1xXtP9cWIKKW#-3X~;I1wW?64mkD{gYs8)Zdz+SeSfauxFuR(ht~hNWh+6>W%*K z{>hni-QcW=hk96USnnp1$o^q?-_-1x`48r%Sse4EJ&ZTl5>H)wV?UqTj|C9Jn1pTE zaFUmzxEBMP0n!`$SEQw(hA-;4Hwl0Kg@zex6Ch*CV>^iBg z@6~_AE~W*DF%H4_6VZ&wPar2q4ywgdL#uI4TApB!9`37ETpna44qDc0POzhyTdbH) z#5uM%7K@#P4J?iW!+nB1JUk8!!tEH|PqJvS4n-63YtWShza-TuA~o2exh7yNbAs(% z8poghK0Hzxba+H(Wf(_J*tR^n3(p3!-6237B^a5>Gy3M&1o93J6I`3j!rMxgJ(!Gh zTpBtur=M4Vt@@}`M~#jW_E)gOBbf?K+&I_yx5y{bt1OCq_*k$}p!Lu>_Te*(q}5KxD<`^h$z*GYOR~_NGlI*ky;f3b;d18W&(1#WOGu z^$wA)=#wH0ul4DMsz#sO%fJJi{n9eb_T|ax`l*Uq*~QAKh+4sEa-O30xKOQ+lb%c; zd{t{HELA@Vwweu9F{-72jDc@h3?q6Gd>^t}-~fOLPI?F!+1Kdn>3E7L+mKgRv8Z`; zFOB$XMA`lsK^4-g;OJEsr&f10P;AuP5b{9W49pP;M8uC~g8G`BbSgqf(byjm&jsKJ z8k4T8y}GUz(rGC|)Vc5gaKD7V_*XDTKwNp(jzg9UdKuE*fa;Qh;W{SFY`J6a*Y zZriUqJ%zxj{7C@%r8rM*oY^?@-08VDsW|s-oKYQMUQ{tp=8qQwfQ*;oJh=mtacr#K zb^~$7`KjZMQc)GTrHAaKeG-~kmBbl2(<|amJIpDFVeTmTp`mG?jk;co*X`(y3C4->Rg%c4 zYfq_Bsipb`PPNo}Cbc(|g6X2CX1aNIwY>38Tp3tDPvEbobsEe^Gch0ES+_KDR<_jl z|JJQiPqhZb2Q4yw9bCO6LEcx(<9INlK$1*D3>6IVC$$(TL~a?O1q>bVWnND5j?;Qz zYF&^*b-X6pW{izCpOsm+Nrzs6ZQIdH`U^0wpVSQOib-W{cDitK5vS__WGYUV3!N^h z-U@Zo@G}Q-!Q7WB4wyl}(S?k{$8aMOu+a|_egLJ}_9UGC+RgL&8s3Wg0ifq~TE8~W zJbwM>HwuSN!FBJ9eg{ZaTekOdiX2sG+$3!X*T6BC2{vmSWFg|k!>Kb44>gb@VPb}l zfp=ApsJ$vs6>8OwHsHL&{Yp^KI6#fQ!LLEA>`FATqHk~te*wj0qf!rbUBXA?v1Wq9 zG=hcXR-~9_i;HRfEE|a?3AL6ri@sMuR21>jh~y91H5$)j2&4;6*a5=BIT0A9SZ_(Q z={{kc7aIme{6^GlB8sBAs?ikd~Mf3wv8W^U>^`AqpE@U4`<=~Ccy#d$QC7Yy6(_Cm)W zd@23=+P|#*s!MtEO6kojPym#gSS~=I=*tX-2MKefro>NtH0#x-*Sx>U87%~D7Z!y*L2A>ji*9c|Qdkw)Zcn!98l*p8Fr6)9PUY_OB@b zzd^8Jg}|N@C>d-ARcFhVv#aRr+I(Me_LZD{1!v#4UwQXzPCb0*amTX@zvx%I=S$x6 zxpUie@ZS9W5A&hN^H0D3<*{E}Q0R9{^t*-XMW(FAL?X!dNCehM5cn>joU81P3%G*y z(muTucK}JSwV~9je__PX?F^D5(+C%>ZpDx?V#<&l2_ulVWL}ao()v8MW7lmU@}A6@ zEYhiC*6ENsA7LG5Lmgr~Vd<`I*XfYjx3P9*>?Gf%StAiR9vg{h_DE!D1<$iaA_8bm zN?;L8A;6%BW=xA1e3x(!RcDJC-;u>-ffHb0wF)S21ynf#Y7+rxzR-){0D=Gj%@c_< zoE(L=4&tjYf(r<4A;9PeS%74T;CI8gGazH2Ne@>HKn}KulW_DFOitlv@QB()d zM-7HD?KOb;Q3D4kLvMlF-*`QzJUQ}HDR++iRLYSfKb5lO$WNu(3(c2G^%r)#RBE*F z+pg#S&YTBU!oA?VrO&$Vcjep=r}1{EuAu5^uUx*avdh|IEK>k-4!9XGUjbi}T(Hjo zTgc5|&fqb;YbaAM!2@OkoSSF{-s1)ciZ+9r28W@&Of`e9F|6DSt{Zv`??Fp1!6^ep hJ2$dLQ%Awnq0&rl>IY{(Ih!NDvWcQQp_qKV{{!LGtwjI; literal 0 HcmV?d00001 diff --git a/scripts/package_firmware.py b/scripts/package_firmware.py index 85568ce0..4c058755 100644 --- a/scripts/package_firmware.py +++ b/scripts/package_firmware.py @@ -25,7 +25,7 @@ import json import os from pathlib import Path from datetime import datetime, timezone -from typing import Dict, Iterable, Optional +from typing import Dict, Iterable, List, Optional DEFAULT_CHANNEL = "stable" DEFAULT_OUTPUT = Path("dist") @@ -167,19 +167,71 @@ def package_environment( } -def write_index(output_dir: Path, summary: Iterable[Dict[str, str]], published_at: str, version: str) -> None: +def write_index(output_dir: Path, summary: Iterable[Dict[str, str]], published_at: str, version: str) -> List[Dict[str, str]]: summary_list = [item for item in summary if item] - if not summary_list: - return + if summary_list: + index_path = output_dir / "firmware" / "index.json" + index_path.parent.mkdir(parents=True, exist_ok=True) + index = { + "generated_at": published_at, + "version": version, + "artifacts": summary_list, + } + index_path.write_text(json.dumps(index, indent=2)) + return summary_list - index_path = output_dir / "firmware" / "index.json" - index_path.parent.mkdir(parents=True, exist_ok=True) - index = { - "generated_at": published_at, - "version": version, - "artifacts": summary_list, - } - index_path.write_text(json.dumps(index, indent=2)) + +def write_root_index(output_dir: Path, artifacts: List[Dict[str, str]], channel: str, version: str, published_at: str) -> None: + index_path = output_dir / "index.html" + rows = [] + for artifact in artifacts: + manifest_href = artifact.get("manifest") + binary_href = artifact.get("binary") + zip_href = artifact.get("zip") + chip = artifact.get("chip", "?") + env = artifact.get("env", "?") + row = f"{chip}{env}manifest" + if binary_href: + row += f"binary" + else: + row += "n/a" + if zip_href: + row += f"zip" + else: + row += "n/a" + row += "" + rows.append(row) + + table_rows = "\n".join(rows) if rows else "No firmware artifacts generated." + + html = f""" + + + + Firmware packages {version} + + + +

Firmware packages ({version})

+

Channel: {channel} · Published at: {published_at}

+

The table below lists all firmware bundles generated by the release workflow. Devices should download the manifest matching their chip.

+ + + + + + {table_rows} + +
ChipEnvironmentManifestBinaryZip
+ + +""" + index_path.write_text(html) def main() -> None: @@ -212,7 +264,8 @@ def main() -> None: if summary: summaries.append(summary) - write_index(args.output, summaries, published_at, version) + artifacts = write_index(args.output, summaries, published_at, version) + write_root_index(args.output, artifacts, args.channel, version, published_at) if __name__ == "__main__":