From 23d315ad4094d9d625623ed264fbc8f6d437f8c0 Mon Sep 17 00:00:00 2001 From: Teddy Harnatkiewicz Date: Wed, 26 Aug 2026 13:16:51 -0400 Subject: [PATCH] fix(flutter): fetch the arm64 macOS archive on Apple Silicon hosts The macOS SDK repository always downloaded the x64 release archive (flutter_macos_-stable.zip). Its Dart binaries are x86_64, so on an Apple Silicon host without Rosetta 2 every fetch-time warm-up fails with 'Bad CPU type in executable' and the toolchain is unusable. Select the archive variant by host architecture: on aarch64/arm64 macOS the repository fetches flutter_macos_arm64_-stable.zip (the directory component stays 'macos'; only the file name carries the variant). Integrity is resolved against the variant actually fetched: the generated version table now records a 'macos_arm64' SRI for every version that publishes one, the flutter.toolchain integrity escape hatch accepts a 'macos_arm64' key, and flutter_repositories grew a matching integrity_arm64 attribute. update_flutter_versions.sh extracts both macOS hashes from the release metadata; regenerating the table also picked up the stable releases published since the last refresh (3.44.6 through 3.47.1). Verified on an arm64 Mac without Rosetta 2: examples/hello_world builds and its widget test passes against the working tree, with the fetched dart-sdk binaries confirmed Mach-O arm64; //... passes (14 tests). Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 10 +++ MODULE.bazel.lock | 5 +- docs/extensions.md | 2 +- examples/hello_world/MODULE.bazel.lock | 5 +- flutter/extensions.bzl | 6 +- flutter/private/versions.bzl | 92 ++++++++++++++++++++++++++ flutter/repositories.bzl | 65 +++++++++++++----- scripts/update_flutter_versions.sh | 52 ++++++++------- 8 files changed, 192 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b47957d..1bd87b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ it reaches 1.0. ## [Unreleased] +### Fixed + +- The macOS SDK repository fetches the arm64 release archive on Apple Silicon + hosts instead of always fetching the x64 one, whose Dart binaries fail with + "Bad CPU type in executable" when Rosetta 2 is not installed. The built-in + version table now records a `macos_arm64` integrity per version, the + `flutter.toolchain(integrity = {...})` escape hatch accepts a + `"macos_arm64"` key, and `flutter_repositories` grew an `integrity_arm64` + attribute to carry it. + ## [0.3.0] - 2026-08-23 ### Changed diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 7d514a9..f9add5e 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -206,7 +206,7 @@ "moduleExtensions": { "//flutter:extensions.bzl%flutter": { "general": { - "bzlTransitiveDigest": "lQUfT64j5RrfdhXGnH5A12lonb9meu2Kp6cDxIAJQaY=", + "bzlTransitiveDigest": "RvJFom/IApmXpnVuDvmM9H89s9ETdplu6UIPFy2kmmE=", "usagesDigest": "MPZC/xzGVbRvfxHYU74cPXZyyx32ojSPxKT0ZE+0WUE=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -217,6 +217,7 @@ "attributes": { "platform": "macos", "integrity": "", + "integrity_arm64": "", "flutter_version": "3.24.0", "precache": [] } @@ -226,6 +227,7 @@ "attributes": { "platform": "linux", "integrity": "", + "integrity_arm64": "", "flutter_version": "3.24.0", "precache": [] } @@ -235,6 +237,7 @@ "attributes": { "platform": "windows", "integrity": "", + "integrity_arm64": "", "flutter_version": "3.24.0", "precache": [] } diff --git a/docs/extensions.md b/docs/extensions.md index b29e008..b75d805 100644 --- a/docs/extensions.md +++ b/docs/extensions.md @@ -33,7 +33,7 @@ flutter.toolchain(name, name | Base name for generated repositories, allowing more than one flutter toolchain to be registered. Overriding the default is only permitted in the root module. | Name | optional | `"flutter"` | | flutter_version | Explicit version of flutter. | String | required | | -| integrity | Escape hatch for Flutter versions not in the built-in version table: a map from platform (macos, linux, windows) to the SRI integrity of that platform's stable release archive, e.g. {"macos": "sha256-...", "linux": "sha256-..."}. Only the platforms you actually build on need an entry (the per-platform SDK repositories are fetched lazily). When flutter_version is in the built-in table this may be omitted. Merged across registrations of the same name. | Dictionary: String -> String | optional | `{}` | +| integrity | Escape hatch for Flutter versions not in the built-in version table: a map from platform (macos, macos_arm64, linux, windows) to the SRI integrity of that platform's stable release archive, e.g. {"macos": "sha256-...", "macos_arm64": "sha256-...", "linux": "sha256-..."}. macOS ships separate x64 and arm64 archives; "macos_arm64" is the one fetched on Apple Silicon hosts. Only the platforms you actually build on need an entry (the per-platform SDK repositories are fetched lazily). When flutter_version is in the built-in table this may be omitted. Merged across registrations of the same name. | Dictionary: String -> String | optional | `{}` | | precache | Artifact groups (web, android, ios, macos, linux, windows) that must be present in the SDK cache after fetch. Stable archives already ship these; when one is missing, `flutter precache` runs at repository fetch time. Unioned across registrations of the same toolchain name. | List of strings | optional | `[]` | diff --git a/examples/hello_world/MODULE.bazel.lock b/examples/hello_world/MODULE.bazel.lock index 38de748..da81bd7 100644 --- a/examples/hello_world/MODULE.bazel.lock +++ b/examples/hello_world/MODULE.bazel.lock @@ -318,7 +318,7 @@ }, "@@rules_flutter+//flutter:extensions.bzl%flutter": { "general": { - "bzlTransitiveDigest": "TlsLQ+9IuduQk2CdQckTQPoWsTzk0L9uMs1ZiiiMv1Y=", + "bzlTransitiveDigest": "RvJFom/IApmXpnVuDvmM9H89s9ETdplu6UIPFy2kmmE=", "usagesDigest": "28OnpcYnSmzay/V6WMwTNE0upCyG0V5VmLKmR7xi70Y=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -329,6 +329,7 @@ "attributes": { "platform": "macos", "integrity": "", + "integrity_arm64": "", "flutter_version": "3.24.0", "precache": [ "web" @@ -340,6 +341,7 @@ "attributes": { "platform": "linux", "integrity": "", + "integrity_arm64": "", "flutter_version": "3.24.0", "precache": [ "web" @@ -351,6 +353,7 @@ "attributes": { "platform": "windows", "integrity": "", + "integrity_arm64": "", "flutter_version": "3.24.0", "precache": [ "web" diff --git a/flutter/extensions.bzl b/flutter/extensions.bzl index ddc6495..7c17e70 100644 --- a/flutter/extensions.bzl +++ b/flutter/extensions.bzl @@ -31,8 +31,10 @@ registrations of the same toolchain name. """, default = []), "integrity": attr.string_dict(doc = """\ Escape hatch for Flutter versions not in the built-in version table: a map -from platform (macos, linux, windows) to the SRI integrity of that platform's -stable release archive, e.g. {"macos": "sha256-...", "linux": "sha256-..."}. +from platform (macos, macos_arm64, linux, windows) to the SRI integrity of +that platform's stable release archive, e.g. {"macos": "sha256-...", +"macos_arm64": "sha256-...", "linux": "sha256-..."}. macOS ships separate x64 +and arm64 archives; "macos_arm64" is the one fetched on Apple Silicon hosts. Only the platforms you actually build on need an entry (the per-platform SDK repositories are fetched lazily). When flutter_version is in the built-in table this may be omitted. Merged across registrations of the same name. diff --git a/flutter/private/versions.bzl b/flutter/private/versions.bzl index 62ef254..e4c6e0b 100644 --- a/flutter/private/versions.bzl +++ b/flutter/private/versions.bzl @@ -12,281 +12,373 @@ https://storage.googleapis.com/flutter_infra_release/releases/stable/{platform}/ TOOL_VERSIONS = { "3.24.0": { "macos": "sha256-lKtzuIpKmWxOuTBkSDjQhjkYy8SgOagUTMr+Lhys0wQ=", + "macos_arm64": "sha256-PEQ5hcnNpfaVmidMrd/rOOEXd/yO2Kaa5wChSF5t0lg=", "linux": "sha256-1SpdEvF9i8+GjRzMAf4Pf/sFtT2WKKohsHoY+dM2IfI=", "windows": "sha256-aNvLaLOhk6Z/aZJL+fpI6ONOyMqULeqRLSD5EG0Hqbk=", }, "3.24.4": { "macos": "sha256-f+Ov3L03S6o8pOrrpnfNrnS6kbTtQUpYM7e36QizlN8=", + "macos_arm64": "sha256-SofEuMzDMKEvSSH9RY7xq5wkr3JiHQy78+ZRz5rDYkY=", "linux": "sha256-LOeNSlHwY++n8EZmrgENAm0Rnupr3qfgi3NoQP6I3bQ=", "windows": "sha256-dOpYxJtQcgkpQx2tbrfSoqMyHy8sHZg7wwyl+U9d37Y=", }, "3.24.5": { "macos": "sha256-MPM3rrL3oNMkz66aNxjByqilq8sZ7/kzszczJGX5z+g=", + "macos_arm64": "sha256-ypYkpt56Goli8vCj4qV7FkNMo08RN7jZ3GjFyh8YcTM=", "linux": "sha256-p8gvVRqergGOB49rsYYXHlp3kg01o9daYdmlk9Cp5K4=", "windows": "sha256-uKdIWs08b7I6dresCfiejZPWL7/3FHxvX4xWhtlJ7qw=", }, "3.27.0": { "macos": "sha256-PnwdJUCNntgXhVVYR0We7piwtmT66mD3c70QeGIpiPg=", + "macos_arm64": "sha256-2lSPEFvq82gSqkhfIcsUApQECQmnYYKlJWCF0ZarqxU=", "linux": "sha256-wFkhM8xh18TUJ2IofehLfguv3T/WLrJuqts0LEMJ1UE=", "windows": "sha256-wVi6+1yXvYHj0pNq9XEds7nOUZ3uXzrATB+soFdsqio=", }, "3.27.1": { "macos": "sha256-Oi55LEAUvmLfnY39nN8bjhgKEMrBEUQxDz0u4UmBDPU=", + "macos_arm64": "sha256-tZWAzbP+GOYMiOrBe8mlnP48esvJ79g/BB8HdkIXN+4=", "linux": "sha256-YUl+tkzXs6qZypkRzNkhyNq3mv2QnKHJ/5VGBn689so=", "windows": "sha256-fnK3GzVwoRfGBwpZNbzzzNAlSm1j5e/5nUvE3bUAbKk=", }, "3.27.2": { "macos": "sha256-Jsls1+RoL/wVp0HSljsVuHEjh1yy+7isXb3BruQfU4g=", + "macos_arm64": "sha256-6DM9f303GNgLUERQF6Qm/aP/oZNt/td1PsdOQ8kL7NQ=", "linux": "sha256-W6d6zisnSKJRRzqJeF6LgwXO/T6dr6/XoZfNoLgDxVo=", "windows": "sha256-7UrnGjDf3QSooQU9njVDFKuV9HMZMNOdm2VtNiCcxB0=", }, "3.27.3": { "macos": "sha256-sRF8ThqArhOhumKBuBQeQpy2L8U4I4bip44A0SpCNwY=", + "macos_arm64": "sha256-INHKedrWX5+fzUwxvbu8wiN6oM04SoPW3/eV1E/hA5o=", "linux": "sha256-tbYEJMUf8RtizC+tRM2zNMesSctzeuh0UcnAnhOqAdY=", "windows": "sha256-zRpmcE/gdajIvCxVjdTc7Bcbo5aoSuqI49SMI4UtYsM=", }, "3.27.4": { "macos": "sha256-ThC3SKAVmaec5BSmJX5kZdxxvvoSjzho1lnQ/KmDpIU=", + "macos_arm64": "sha256-zE1ubFsQSenKjH5kREMNkW7wjq8v2LygWfp55CQFGZA=", "linux": "sha256-ZN9Cc95iVDPHukGWeTK3gvX5q/MZnbgzB4LWRQg3k0Q=", "windows": "sha256-EUHT7bZMRUJz/qyI8x+ElFofMwmnLFiqml8rsrD8jbM=", }, "3.29.0": { "macos": "sha256-07LQG39nE/Oow8UepKT7d6J3XPxpcI9gi9L/aISTJCo=", + "macos_arm64": "sha256-jDGWNjx+eerVvSvWV8rWkVr99bMVylG/p+Vp9JDsPeQ=", "linux": "sha256-H5jz3ikx4dCXlw5W32kbA19oQKoFvmMsT6KiKYx8/dg=", "windows": "sha256-CwCAkS+Fa2aEOiBhvHPnOrHqILaPBoEAlW2ml4O0ynA=", }, "3.29.1": { "macos": "sha256-LJQJWMvEgAyj46xeUiF0HRrkzM/S2LJWftdOJyjm8D8=", + "macos_arm64": "sha256-vopMkR6bfYdIMQTRl3KJ3ohA/dthgop/9P5/qIXfBHY=", "linux": "sha256-ZbHI2C7g58+gcuzmDax7fmfy1Hbes6gEo6V1Jv78wCc=", "windows": "sha256-3H8FPPCjtgcCYIW6C+ztZCntPCO+3IFMkivWgbfYj6Q=", }, "3.29.2": { "macos": "sha256-G25xed1p0I7Hkd9twYxMmpnk4KnuIC7S8qp2J4ceCWc=", + "macos_arm64": "sha256-cuHOeqPqzz+FVLqZlczNcyJTc3z5zwEMfY5V96CipcI=", "linux": "sha256-YJbyE3B3MJPsGSQOEzZkwcEuuLWoVgWpLRbORioY6sQ=", "windows": "sha256-r6LQjBCKv0czinDdAXEW7+7irEYPC/rEyDJCZ/8/XSU=", }, "3.29.3": { "macos": "sha256-2WJqKSCm1sCLAtvDYq1twg6r5HfwboaDJCui5bahrnI=", + "macos_arm64": "sha256-vDriisG6ExeH+Z3EDTv5Ni9D5BHOiqtIx0Q7rN8DxLQ=", "linux": "sha256-ipCKWt1Twd/CAx2inlja79WabR1S+1y2H17lLHPjbhU=", "windows": "sha256-XV1ueOI02dyfuNp/tUuFsaa2vkF0vT2Ic7+bBaZ8eJQ=", }, "3.32.0": { "macos": "sha256-pRtWq1TIgKWppnVIHbWrD6pQQ3gMJCFjaV457FZtmhc=", + "macos_arm64": "sha256-i++TVBtglzHyjGjp0hr/uQuxhd9HtDTG7K5m7BVntxM=", "linux": "sha256-p+6LEbb+r/oK3Ab4LHFHqqMU/tsEmTSKpf9NtGiDevA=", "windows": "sha256-xlnYr1NHqKESDa86ROKAMUkPRihqTNWTCdAYV0Vy+fU=", }, "3.32.1": { "macos": "sha256-xvymgJQwoV87ybOF5zNKRhZIG19D5x4Gnq7uDDppQN4=", + "macos_arm64": "sha256-ceDEL2bDPyMyGTnIH48zZ9Ef6xyxUp52IDLmbMqhlJo=", "linux": "sha256-7ocBzu4VGDBIDsFpLPUQpBARhsr2RRUW94gn3ds+Rg8=", "windows": "sha256-t2Hj9KDBBiHFPlK1me/pTa+I262nBAOzYiCxdCficeg=", }, "3.32.2": { "macos": "sha256-1XzlmhOIVqJhqUfLCAAlnsxg19Y1eEmaSzOWE7xefo0=", + "macos_arm64": "sha256-jsx1XS/MYoGbCQ8E4GheQsjnctNHQ69hZLScnYspBDY=", "linux": "sha256-FXqheXJzB3TxyPhswYZNS8+2co4m9KGD8BNMcTf+qMw=", "windows": "sha256-AAWpKrQZIjzPTc1lpvf8BtT0M2pakl0vtWDk6/tm1hA=", }, "3.32.3": { "macos": "sha256-d09Fx7ETQ27SNV+Kf/qwNzJ1wQf2lEnRK+ovS+0/Wk4=", + "macos_arm64": "sha256-VXj6rNULIuic2Ki49xTw/bKTHQzGc3eRs3Tku8n5cro=", "linux": "sha256-eh/Kj/VlMmk8SPuS0clEsazjbj+4otOsWiNNiYfki0s=", "windows": "sha256-NpIz7FTo56204zKR19V6wkd0IU0F+uFcyZIMRKEuMU0=", }, "3.32.4": { "macos": "sha256-YWsRO4eza7mvzopxNUyAZxMep5PynYWGuaK9Rtq1yU8=", + "macos_arm64": "sha256-WZYkqRbOX/DFg+ArrSncXzi/NfIhAAmk72M4zCLLHy8=", "linux": "sha256-rq5MdHgkCPg8c9dLRSrjWq1y7QNIg6cN39JWOxcdxHw=", "windows": "sha256-7at9MS88+6GRTv2IfchuYlYLXyhYCZ6djLTkuL7ZYYA=", }, "3.32.5": { "macos": "sha256-g/ZUQEZFU/0qCmtwxU4hVaQ2Q902nxGzC5m2N1iXUlo=", + "macos_arm64": "sha256-be3Fv2rJ/7vMopGAAObns530LDxi4vLE9H7fZPzoJZg=", "linux": "sha256-NOk+d2nYc5xG3UVOhgK3kBYZpICTn+qkAfUjgxW6f6M=", "windows": "sha256-ToN2XnqkvIMAnFEQKa2mjQei2RMgswc9Ff2g6kU051g=", }, "3.32.6": { "macos": "sha256-NN8jZMjRXg1QRuwsDtd5bnCbovOejTNkFX2nTN+Z10s=", + "macos_arm64": "sha256-hIvKtKuCBOeG99ULyiXVpl+k5ouMne8sRNA01YDwesY=", "linux": "sha256-HIOP6N1b+Tciv0K/XaWUJb+AnL/tF/6oOFdx54zPRCs=", "windows": "sha256-BE6qdvvCmHcfGjGJtiL5RSz7WlF3zNaB/LJb5+1XS3k=", }, "3.32.7": { "macos": "sha256-HRoAzBJXDKcHooAYvhDamFTZKecRgRQd/x/pNC1kXbw=", + "macos_arm64": "sha256-KSj9XoqJdfHyR8yetNlXzvtWXvz2L/s6rMH2D8W8WYY=", "linux": "sha256-EjC+tNCSUNsGuz5iIx8jBpKzGmTwYGgIXGU/6CEx7II=", "windows": "sha256-TosV2W+YifRCweK00ATMYqUfmLEOyuZhgwdx5FXpYX0=", }, "3.32.8": { "macos": "sha256-i8NF+FVlNGoCsq+hkKWLul8e4XqmQjP1lcTo4xnvoj0=", + "macos_arm64": "sha256-Ia5Y6M+BSz0vYy+Sts4D6tAxgjyUSqLygeJuWNISLck=", "linux": "sha256-wsfXX5vlPxDz/bovfgQrLvCFLMCIOSs3S87DTGIE7Yw=", "windows": "sha256-bWHS+7Ov5oZ1hkCIk3rYS0WSCXSxLPcaErTRjQLrEYY=", }, "3.35.0": { "macos": "sha256-SvigFRl5LFu2RfngALolA37FEYLYIxOsvsRTLl8fi/U=", + "macos_arm64": "sha256-aeXIFrjNzHMgolncrxLyWqr12+l2txkFD6OCPsZa7UM=", "linux": "sha256-/y2UdNdo/bYcG41rdv1OuYI1wnHmixCr9BvZ+0G8Jz0=", }, "3.35.1": { "macos": "sha256-w5H1M6T+OMDv/996aUDJiIAVOdiggAKevNOx5w5SzR0=", + "macos_arm64": "sha256-y7CFNLVKZbBNDhOs/FZOu9+9tFH5DREZiBydMqNjK0Q=", "linux": "sha256-WO/Z0eVwob+XbiGM+7zKPyOyG4c9dlp04EXVuQIqtRU=", "windows": "sha256-+2t7SUMmrMzGT2ip61OtzoaaCR8215hRvltb6h8Q1yg=", }, "3.35.2": { "macos": "sha256-McqL3b5pYzD65NCwM9WUuunO5mSxrctY7N5IAXw6xlg=", + "macos_arm64": "sha256-e/z2g++AS186UjaY9SwHD2P3qC8+ggzphOh4BUDG6JE=", "linux": "sha256-8BMQgLR7+qH8xpjn6PWBT6dBuDXrizu8cP3pqTgIKLQ=", "windows": "sha256-hQYDIOKq2/0zEiFXxBhqFDlxr2OEx4seVTe17wOKFzg=", }, "3.35.3": { "macos": "sha256-PXoUqQCKKshgXn0Z3UodvKZb/drS+V3cGPJkTyziHJ0=", + "macos_arm64": "sha256-7dFYyEuf2a1RcAofQ+XAna/LxO/9niVBBqB1m+mRVHA=", "linux": "sha256-eRVQZS4pqViIFcDjqsfPfNHR1dah8WMdRssUboouGh0=", "windows": "sha256-xFXpQDGH42W2of/eiOVvOs0STWNqpnIZAnEyquHk4/w=", }, "3.35.4": { "macos": "sha256-m2u6RhDDZlWWOiAf0s7mZALb5x2ajdmBxItFEh0T/hg=", + "macos_arm64": "sha256-U5gjE7UQ9Cy2+UNHpiZ3k1U8jDNRTGQnEzIyWZMmNHs=", "linux": "sha256-FRx1U5qhwBuHSVTXtuAAamIqPxLHb9fx/K+tJ+ai1oo=", "windows": "sha256-lipdrrWeOyxtflmeIy/O5I3xWhEYjBFBY34fsjPsPFQ=", }, "3.35.5": { "macos": "sha256-Sc1kMU7Dze3dAz0e9DoO/BHmz6foya+tJFeb+Xe+jRg=", + "macos_arm64": "sha256-4OkXLh0tqEGP1uRTDSc2CPuUz9EjOjawi9bwk/uunik=", "linux": "sha256-jurWnl2EEx/Puyz9RBZMAOmgTfcl8kZy6iNMa9E2NT0=", "windows": "sha256-X8AfuqjSxdmB6N3LzbooZFSxGVROBxv+Zu92QzUzDsQ=", }, "3.35.6": { "macos": "sha256-Qa2kQ7jGFT/hR1HLvodqsIvRsHRjUpTBnWdLKn5Rd4M=", + "macos_arm64": "sha256-QMXQQBbkUYCb9XI1JtfiiHOPxH7Ic2FGB1V/X6UfLdI=", "linux": "sha256-h0k7cpFvEgVBdsKou/lUf+Y8tXVL3d/jACGdm1fmJq8=", "windows": "sha256-+ol1C8LKxsTiIaFvqWKP4uK8Z8dN0PA2+eZUy9QnAtY=", }, "3.35.7": { "macos": "sha256-HZYwvpTCAId6N5nYjbWH41dfiN0FyYuuczdWvsCo7Jc=", + "macos_arm64": "sha256-TXqq3EiT+SFtTi7L4Oj7QhPpvUnSn9X0QfNPzAV1jis=", "linux": "sha256-FG31MfmsahGpGAE8GnD6r8BT1IEcjLaaQT/XB0jVHD0=", "windows": "sha256-uARlO/0q0n+NN2xipgjqLHy9Sf8rhQEK9vilOqNS/WI=", }, "3.38.0": { "macos": "sha256-1gKXlkwQecKftaYvuezNJJ2kX9233xX2kUs3r3I9us8=", + "macos_arm64": "sha256-893+yj1E79PeSa4pMjjHyAuWeh0XUpq650TFrZtcLF4=", "linux": "sha256-ycx0YoPwLbrV2ieFtIN7YveVbjE1+pr4fH3eLSvWxaY=", "windows": "sha256-m1RIjEPXHC5NZL9sHo6n1A+2/rXwPYXxFugpZQkpQ3M=", }, "3.38.1": { "macos": "sha256-ixU6JT/g4teF0Sp6QwtPsf2pO2+DJu11wKf7b9JQjtk=", + "macos_arm64": "sha256-HquFETluJSQg79RoVKhDIDlgoU+4u3xl6hbNjfWmbvw=", "linux": "sha256-jxmj2ecLGDyLdGkQ+22QXCfFhltSRapyxkUgX6iq6rI=", "windows": "sha256-xmPS/1Yf5PpXtRdspcvufJfcPkDI8+VooVt03RLLrLQ=", }, "3.38.2": { "macos": "sha256-xUohHnfdde3uuEIJiELZD/lAB3JiQqh/VV1pguXl+/M=", + "macos_arm64": "sha256-DGr8Kigcpu3Ba7rKXA7r/irp5isu3eKHVGVIS/R6s5s=", "linux": "sha256-nZwNy5GAxt+xdu1d/d5P75pYmflmMxw2Xxj2QmKot3c=", "windows": "sha256-F9MEjRWHITWqPBaeV38h0/y1bXkbxNkzowCBrOlioMg=", }, "3.38.3": { "macos": "sha256-oJPCuau+UgWONj54MgCGvgCT8qB+P8K+NHheRQyjB7o=", + "macos_arm64": "sha256-dqQVJPWMT6u/0gNtRJ/rNpr3+BcR6XUqY3FWilWqg4E=", "linux": "sha256-c96II/X+Z65oKfnPLVH+Cx+9d2ozEydaslQVoV9iQGg=", "windows": "sha256-3ZZayE20NSJe6pxVQw3iYncHKGF9TfV6Nw/8VvJZEHc=", }, "3.38.4": { "macos": "sha256-+P3A593+pVPHPbh/+V9S3hz81AgXQ1ikZIeznFQrnUg=", + "macos_arm64": "sha256-JcbMFJb3MGtKd93IBAP5YNAlt/P2bZQ0+ZyiEsuDDD8=", "linux": "sha256-Hesyl1VgsStYCntXpGxQQ7W4VUA+9Lm3g702+Le5aGo=", "windows": "sha256-vDR+xvNbhk2GURMp87bqcE7+ItivfFbI71A+EqAiZ7g=", }, "3.38.5": { "macos": "sha256-089RjV3uuxg9p04SpWOWWdRyiCQJfB0NCbFE8ie3tQI=", + "macos_arm64": "sha256-7bu2L8NSI98xjUtBxZYkg+Ag2R/WrS9uCo9NCkFXdkY=", "linux": "sha256-omSUDPxDHBd48090E/pqtxRDrVLHHzjFCwKEOXpAObA=", "windows": "sha256-WOUEIzmhpTY8dBysDJSaghRfqFaBpOsm/wi8JrQFHOo=", }, "3.38.6": { "macos": "sha256-UN4YTPQIrqROx2aWSEsnQw1MhKwv6+E/BMbjolMdbGY=", + "macos_arm64": "sha256-+N7lUGFS7PGDglxzQE4E/6lkk1cOXlm5MJGCI8yIDtI=", "linux": "sha256-pw47gp9TrNATquZZlXVdsPQhRXtat1SvpaNEzV7E2NU=", "windows": "sha256-d2x5B/ROkcMXyMJc98BgI7wvZMMYTnV+/X9Jk5YLouM=", }, "3.38.7": { "macos": "sha256-mxDfsI91teQEdspkb1yq8IB388eOngyScoWaxGBZH4M=", + "macos_arm64": "sha256-MZCIi0KcrCa6GbDh0n25ukL7EufrLuPEC9cNl2AgEm8=", "linux": "sha256-LXLeMRGcy6FCE5GqmrU4kaPkkFmHoT+CcnZq1447v5M=", "windows": "sha256-pH5tkv5iBFQxjDVTrI/Jtto9hEUgfzY3FGqnSJk3XPk=", }, "3.38.8": { "macos": "sha256-6URhdf3MInyNwGFoEM4P+urAC912YyXGgZvuzmiKNWQ=", + "macos_arm64": "sha256-o4EZGQD5ulz1S27Tl2hbTLnNuOSCI61yhEsm3cgMv/M=", "linux": "sha256-aPcCueqbYyWZJL9ssjMOD24HaJiVhwndKFcfJ7zxL7o=", "windows": "sha256-orDJEot2uUhShga0IYcCUhjS8KVSPvlgbavjfV0T0SM=", }, "3.38.9": { "macos": "sha256-q4tmyKlf+3xSzSG7f9ed/rppBME1PP8KJjd4L9lwwdQ=", + "macos_arm64": "sha256-Wp8p1A1bky/0ldVoElsbIoFJIAA+bEvn+J7n5lKTYJg=", "linux": "sha256-yznutxfH19zpVza4YsraL97e68uwEHxEo0ZlnHcDEAM=", "windows": "sha256-HioSpBcw2KGsSRDn2R1l+T8v3yM5GgHSc/qdpMFfOV0=", }, "3.38.10": { "macos": "sha256-twVroACCubgUQV51Fih7uUYzwRCIOL/hD49mUwe5mvo=", + "macos_arm64": "sha256-s6jABDhSc7/ZubkBpy4+uT7Kpl9KfKgBqyJYiqBcSQw=", "linux": "sha256-OF4mKaClhag181HKFgXSx5ljd84voW5oKW6PyaeMz3o=", "windows": "sha256-l+Vg0CjxsLQU5fGawsTr8HnAAeihhWOg6UDE2EcA0zQ=", }, "3.41.0": { "macos": "sha256-8MGBtecbzY8EQMfqxcZCMcmjGrz1Gbzo+N2fhVoOrzM=", + "macos_arm64": "sha256-JKqY22Djax2tYPTghZ0ymb4qGFUZOSxY7wbohtqgRPY=", "linux": "sha256-Norltpk8UYYTJOcExC1hxOKQ+6chOoj9Dp/sFd7VRZk=", "windows": "sha256-nn520hfcNlx7aTw+3bLhVKHdRzTsnPX14BlvD0S3Nu0=", }, "3.41.1": { "macos": "sha256-DH6M90cc2SuCxX8zKtPeGIvYXH9oma98agbwGslHaY8=", + "macos_arm64": "sha256-fWfRWy8mqL34++VCpCwTElFqRUf0lXMfrwAwb//gzFI=", "linux": "sha256-aPUbG7NyjTvlp1byOjivH3duBcByndOpHT3PLCDXgTg=", "windows": "sha256-GysHejXuteEl1NrDhX0aFsH/wJQDwFoIcFSsNPr7poo=", }, "3.41.2": { "macos": "sha256-AnqaB1bUZLOhwLpJHIKwKywqIRj2SbL1RdrJGna+St4=", + "macos_arm64": "sha256-ZlChUoIzywb9glcYdkOe8Oi1xtaB0JuBWwjbzDHrlJc=", "linux": "sha256-SgT4phUphtFPwTf/r5gQbKdDwPmrZvG8LyDuhOtXPlw=", "windows": "sha256-a0WvIhdz5H+VpuNocLtYOOoyfr6zYIGLvjA13D4ENK0=", }, "3.41.3": { "macos": "sha256-GIbgLTJC8m8RIdLMYsQSL6MRSWgm8Kuv57HWiBfbYbE=", + "macos_arm64": "sha256-dRshJRwGxDeyDA6fhYQBLCo++5j6dWUso0FVeWEQ1xY=", "linux": "sha256-9iBzEYJmm+/c1/xWli3vgbBDTQukNY82PogFnzdlZnA=", "windows": "sha256-gXcW7ECQ4XtmsPcyKwfmfK9XK20io9qrwI7XT7eeScI=", }, "3.41.4": { "macos": "sha256-Bf010uTCne8KywLgjk+qaFMRXD2c8FxOMMfmh7UfdG0=", + "macos_arm64": "sha256-FphKDa4fE8ez4FuXOROpORRLfp46pkOfozglmaYyb4w=", "linux": "sha256-ycTnQevPg+6IMDQEF29+IsO2q/yOnWB4EJi21BBDJ6k=", "windows": "sha256-xSxPVGkQAd8YsH74kpCENydbopszfYAvZHaKkQyCI60=", }, "3.41.5": { "macos": "sha256-wvnRjmM3BNWKxF+Hlh6tIEN1cEdtBSp+Iry52YXdzsw=", + "macos_arm64": "sha256-kNjn1+bCwnzoY0psmeuKIY6mO6KXgbYeudtyxi0CdUY=", "linux": "sha256-GJAdRWpeRYxMafp4WYUrZPrCnan4lHapWav6y6x/T9s=", "windows": "sha256-i+0O920GeHdog/XuBrJQu+5XTx3XIi8ry+TmR5YlGLI=", }, "3.41.6": { "macos": "sha256-BuyDNw06ESwn2QN0lD36v4jmVU8hsy5UPQFY7Mdvi68=", + "macos_arm64": "sha256-Faccw3Gr5tr7smf0P83ZtL4mxNXl2/SSg6efWNz5By0=", "linux": "sha256-UDs+a301L8pdIbZHTsqVrVRNj8OwU3guq2OjYMf8dWk=", "windows": "sha256-4wMD1HqxPBfgOIMDreGookv+Vpi0ooSU5svuJfwHMCI=", }, "3.41.7": { "macos": "sha256-oLmvSebhpoAPMaQIuYwde9UemGUKi56813FotIyRb/A=", + "macos_arm64": "sha256-Lj5q9E0a3M9pXe/1Ll5Mi+sQ5WJQZrJ60IKzi4PvgF4=", "linux": "sha256-80TVBX21KrwqY806fHNwlXt2hdH8peX74s5N/nRlenk=", "windows": "sha256-3he1E7dAqTHF28P5a1plnBYS3+a14fkQxa2VSousF+4=", }, "3.41.8": { "macos": "sha256-KUT/AMmxkOjc8depxk9JETVY+MqMgKM8KaKnLZ7+Mzo=", + "macos_arm64": "sha256-IldlzW4zUuDgXavAqAQYOQqghQfdA9bCufVCjzgFdcs=", "linux": "sha256-DH5H/DnvhikLQXB9aHvcp/grJ3Jnpu90cX+OiKxCPeE=", "windows": "sha256-rs33f3Zj09CLpeNJ17N3c9WrbTOFb6L9xkRSve6IYNc=", }, "3.41.9": { "macos": "sha256-6u47aqbaEU6wvoQ6xT9PE409iCd3n/HkVGs0XHW5y6E=", + "macos_arm64": "sha256-1pKwMKY0ZsRNayvIhYM4A3HsvjKPIsxAV4NfWXOYIaE=", "linux": "sha256-zyYx3eAlcHM5IaUw9HqWq+iWteM0aC0nQ8KVMOqIuy4=", "windows": "sha256-A8MjWqnktv/9usIXb4A3Mc9aXJmKOl5X+EC0sgKvpPY=", }, "3.44.0": { "macos": "sha256-Lp77ZRszOyAUh8KsIT+RDHFzOEg8oky/SXoGewXwSOU=", + "macos_arm64": "sha256-DU0dPzedGK/zkikb5ocdY78JCp6BB41MS8hOYghgPco=", "linux": "sha256-4eyV5sVQRYo03pNYDLhdrCTaDpvtubtCgR8FCsWgx9U=", "windows": "sha256-iNoAGUiTv5VD/EfAvzHm3peNSf/bnC9uMMRt3gEWx2g=", }, "3.44.1": { "macos": "sha256-1ix+nKfHPjfFLbj8mC93+jLU2im/5gd59YEuXNy1SUY=", + "macos_arm64": "sha256-WGIghZyD83JawH5zgk58zJTfIIoBglcJkfxNTaW1rhc=", "linux": "sha256-KHk3RYEmpTKE7REsjH28ZHvqLQmrZdRuLVz5TpAarGk=", "windows": "sha256-HoO8jAMup/EaQaj14oU/d5PrzdrLUmjLDTQJAjkyCR4=", }, "3.44.2": { "macos": "sha256-Ak1OlBzrfAn9kDbgJccbuM5+kOspVvqAQaMmAWmqJHg=", + "macos_arm64": "sha256-V/v9xwMmeKswrVd4crv8QRSiXTy6lPv6FKBQ7GE4GiM=", "linux": "sha256-sN4dGXVGiOxnacmgZ9s7BZRHnT12f5cb/s/BMpBMjV4=", "windows": "sha256-15rpmAe6dEuEPlTwSDCMYpBhRW/cewdTJR+5brU0ag4=", }, "3.44.3": { "macos": "sha256-2HtgHLjLf8uW/s63yGGso2uPBwVyBpUaiySphsVO0ks=", + "macos_arm64": "sha256-cN6Zjp9EBIAZLao5a9TtF+OfRKLH8eWpfQBTFAIYiSY=", "linux": "sha256-ADQ+5SZJmejpDi0CxpUqw/rL9GzwxqJRisj31q+nZYw=", "windows": "sha256-jr+Lxwd56L15WRdevT531bGmqNKx+mkPqcLUqhqqQVQ=", }, "3.44.4": { "macos": "sha256-MrykOGEhBC6Cf/LZDtvXx/tHxRT8BNWofbbjIC2v3l0=", + "macos_arm64": "sha256-6sgz/pVsZw0fJ5RvJd6LxP5PuGFG1e+NU+ealxo7oEI=", "linux": "sha256-yFPNoDEqFihUxIH+ahvChthPu3S/q3A3w5dQBh3JtGY=", "windows": "sha256-jy1iJPxoctL38YDehs3pifzqN3bv4O30ipqsLNm+Kxs=", }, "3.44.5": { "macos": "sha256-Cn/WaReN9yM5XLqE+Z7Csy9X+fsq0FfGo7YEqRlVNBQ=", + "macos_arm64": "sha256-RCrs5mdMQzTUak8RAAikToNf9Tl5qPMXMzxecczAZbQ=", "linux": "sha256-KKoThU/rneRKMXuXxOiG6j8K90QCdBi35jiFz80pUfM=", "windows": "sha256-ZP8fVh4IEbxyTVl/n+b6prPnSxHALDIAdvu+I5pxehE=", }, + "3.44.6": { + "macos": "sha256-1piusFAZiHjsbVzcHmzPHvaFDsM2mFsDgSslJd8iic4=", + "macos_arm64": "sha256-5IJIdfIsx+D0h4v8i5OC6Y/wE3B0xdOrRob3pLWsd1w=", + "linux": "sha256-pjIP1y6aJpDAjipqcIdKMMsSDe58ePSdLGKL18niBSU=", + "windows": "sha256-LoA+JAyYFzPsa1Q3UkFRlv8bFuA/k0dL3dWcd3rAelY=", + }, + "3.44.7": { + "macos": "sha256-XbrBuOO9OoD+IbAnx63wggykJZoDddI4HfPrJkRnDVI=", + "macos_arm64": "sha256-kNe5K2LXPjEbmmXjYxyQXpRKO+MwGm+IZ1HO/1/WBXI=", + "linux": "sha256-oO3WRsFZwOgWeIwORqTwcRmcEyBJWJj1pnlZm1g6BaQ=", + "windows": "sha256-MnuJwv9hJBjB11bvyWNteBHFDktQqRbQe8O9wxe6JeU=", + }, + "3.44.8": { + "macos": "sha256-svdlI0IXMnpYWdBGyfOxZzh7YdpUCLWGbtRI2QWHfGY=", + "macos_arm64": "sha256-w9b+lQePcAHZR6MdQlJ96R1b/mLkz0RKFJOi6PH7GZ0=", + "linux": "sha256-ZyCJ4AFXGp+7IJpJXFg1gMDGxz75iZkmS6B/qTrOMy0=", + "windows": "sha256-CVwQigjgN32KZQH+1lrrKIkIoHDtPxNeUl3GQxx2huQ=", + }, + "3.44.9": { + "macos": "sha256-T/7ZOyBZqkz6gpcjzjoxxImIu9v8AUr4cMff6TfswPo=", + "macos_arm64": "sha256-m1hJ3sUdX2+e5V9ej7Z9ByNjaeL1q0yDSpqB2W+CbcA=", + "linux": "sha256-qRIPpKAQSL3vQ43cOi1Lc4lmLqmKlduG7q8QOCvE78s=", + "windows": "sha256-jvEQfSJmVHNnVbxRuWnWvUZ4f/AkFlD5Qud0+wyn0Kw=", + }, + "3.47.0": { + "macos": "sha256-dK8xkq5Ly86201+O0zKvFrf/AK8wBSCwL76kVq4+lV0=", + "macos_arm64": "sha256-vVnIXQMqnYHzGtqMAIWLxPde3tlhW2WEOQ6xPG7lCDs=", + "linux": "sha256-Js2Z09lLE2fmtQU1oYru8CgsEKU1u+PsSTU03Nq3UpY=", + "windows": "sha256-n5bTk8360FvqC0tCxgP/2gJ68Rra3I5M86yH5JEQwco=", + }, + "3.47.1": { + "macos": "sha256-IeBkNcUL6aQ//qirtUm9dkDNOBl+d0HdeA8GgK+7ZLo=", + "macos_arm64": "sha256-OMn/4K9KceRgD0/aMQ8OiVdXVQkmEo4oqld4Lql1OPo=", + "linux": "sha256-odgWbAMJJny33JnxQk7s8IuGlGrTtQcjxvWZRZZK6kU=", + "windows": "sha256-TL+U/eH1+Na5/FCySDtXzyB39hcSKCwvTPklYBaPRCs=", + }, } diff --git a/flutter/repositories.bzl b/flutter/repositories.bzl index 4b4a57d..c8060cc 100644 --- a/flutter/repositories.bzl +++ b/flutter/repositories.bzl @@ -22,6 +22,13 @@ _ATTRS = { Required only when `flutter_version` is not in the built-in version table (the escape hatch surfaced as `flutter.toolchain(integrity = {...})`). When empty and the version is known, the built-in integrity is used.""", + ), + "integrity_arm64": attr.string( + default = "", + doc = """SRI integrity of the platform's arm64 stable release archive, +for platforms that publish a separate arm64 archive (today only macOS). Used +instead of `integrity` when the fetch selects the arm64 archive. Surfaced as +the "macos_arm64" key of `flutter.toolchain(integrity = {...})`.""", ), "precache": attr.string_list( default = [], @@ -248,38 +255,60 @@ def _seal_sdk_cache(repository_ctx): if result.return_code != 0: fail("rules_flutter: unsealing engine frameworks failed: " + result.stderr) -def _resolve_integrity(repository_ctx): - """Pick the SRI to verify the SDK archive against. +def _archive_platform(repository_ctx): + """The platform string used in the release archive's file name. - A caller-supplied `integrity` (the escape hatch for unlisted versions) wins; - otherwise the built-in version table is consulted. Fails with an actionable - message when the version is unknown and no integrity was provided for this - platform — this runs lazily per-platform, so cross-OS repos that are never - fetched never trip on it. + macOS publishes separate x64 and arm64 archives (the x64 one needs Rosetta + 2 on Apple Silicon, which is not installed by default), so on an arm64 host + the macos repository fetches the arm64 archive. Linux and Windows stable + archives are x64-only. The Bazel JVM reports Apple Silicon as "aarch64"; + "arm64" is matched defensively. """ platform = repository_ctx.attr.platform + if platform == "macos" and repository_ctx.os.arch in ("aarch64", "arm64"): + return "macos_arm64" + return platform + +def _resolve_integrity(repository_ctx, archive_platform): + """Pick the SRI to verify the SDK archive against. + + A caller-supplied integrity (the escape hatch for unlisted versions) wins; + otherwise the built-in version table is consulted, keyed by the archive + variant actually being fetched (e.g. "macos_arm64" on Apple Silicon). + Fails with an actionable message when the version is unknown and no + integrity was provided for this archive — this runs lazily per-platform, + so cross-OS repos that are never fetched never trip on it. + """ version = repository_ctx.attr.flutter_version - override = repository_ctx.attr.integrity + if archive_platform.endswith("_arm64"): + override = repository_ctx.attr.integrity_arm64 + else: + override = repository_ctx.attr.integrity if override: return override known = TOOL_VERSIONS.get(version) - if known and platform in known: - return known[platform] + if known and archive_platform in known: + return known[archive_platform] fail(("rules_flutter: Flutter {version} is not in the built-in version table and no " + "integrity was provided for platform {platform}. Register it with " + "flutter.toolchain(flutter_version = \"{version}\", integrity = {{\"{platform}\": \"sha256-...\"}}). " + "Compute the SRI from the stable archive URL below, e.g. " + "`curl -sL | openssl dgst -sha256 -binary | openssl base64 -A` prefixed with 'sha256-'.").format( version = version, - platform = platform, + platform = archive_platform, )) def _flutter_repo_impl(repository_ctx): # Flutter SDK download URLs from Google Cloud Storage platform = repository_ctx.attr.platform + archive_platform = _archive_platform(repository_ctx) extension = "zip" if platform == "windows" else ("zip" if platform == "macos" else "tar.xz") - url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/{0}/flutter_{0}_{1}-stable.{2}".format( + + # The directory is the OS platform; the file name carries the archive + # variant (e.g. stable/macos/flutter_macos_arm64_-stable.zip). + url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/{0}/flutter_{1}_{2}-stable.{3}".format( platform, + archive_platform, repository_ctx.attr.flutter_version, extension, ) @@ -287,7 +316,7 @@ def _flutter_repo_impl(repository_ctx): # Download and verify Flutter SDK with integrity checking enabled repository_ctx.download_and_extract( url = url, - integrity = _resolve_integrity(repository_ctx), + integrity = _resolve_integrity(repository_ctx, archive_platform), ) _patch_engine_version_script(repository_ctx) @@ -425,10 +454,11 @@ def flutter_register_toolchains(name, register = True, integrity = None, **kwarg name: base name for all created repos, like "flutter1_14" register: whether to call through to native.register_toolchains. Set this to False when toolchain registration is handled elsewhere (for example by a module extension). - integrity: optional dict mapping platform (macos, linux, windows) to the - SRI integrity of that platform's stable Flutter archive. Required for - versions outside the built-in table; only the platforms you build on - need an entry. See flutter.toolchain(integrity = {...}). + integrity: optional dict mapping platform (macos, macos_arm64, linux, + windows) to the SRI integrity of that platform's stable Flutter + archive. Required for versions outside the built-in table; only the + platforms you build on need an entry ("macos_arm64" for macOS on + Apple Silicon). See flutter.toolchain(integrity = {...}). **kwargs: passed to each flutter_repositories call (e.g. flutter_version, precache) """ integrity = integrity or {} @@ -437,6 +467,7 @@ def flutter_register_toolchains(name, register = True, integrity = None, **kwarg name = name + "_" + platform, platform = platform, integrity = integrity.get(platform, ""), + integrity_arm64 = integrity.get(platform + "_arm64", ""), **kwargs ) if register: diff --git a/scripts/update_flutter_versions.sh b/scripts/update_flutter_versions.sh index 8889500..f6051e6 100755 --- a/scripts/update_flutter_versions.sh +++ b/scripts/update_flutter_versions.sh @@ -222,37 +222,43 @@ for version in "${SUPPORTED_VERSIONS[@]}"; do platform_name="" archive_path="" - # Determine platform name from URL + # Determine archive variants from URL. macOS publishes separate x64 + # and arm64 archives; both are recorded so the repository rule can + # verify whichever one the host architecture selects. + variants=() case "${URLS[$i]}" in *macos*) - platform_name="macos" - archive_path="stable/macos/flutter_macos_${version}-stable.zip" + variants+=("macos stable/macos/flutter_macos_${version}-stable.zip") + variants+=("macos_arm64 stable/macos/flutter_macos_arm64_${version}-stable.zip") ;; *linux*) - platform_name="linux" - archive_path="stable/linux/flutter_linux_${version}-stable.tar.xz" + variants+=("linux stable/linux/flutter_linux_${version}-stable.tar.xz") ;; *windows*) - platform_name="windows" - archive_path="stable/windows/flutter_windows_${version}-stable.zip" + variants+=("windows stable/windows/flutter_windows_${version}-stable.zip") ;; esac - - # Extract SHA-256 hash for this version and platform (stable channel only) - sha256_hash=$(jq -r ".releases[] | select(.version == \"$version\" and .channel == \"stable\" and (\"${archive_path}\" == \"\" or .archive == \"${archive_path}\")) | .sha256" "$platform_file" 2>/dev/null | head -1) - - if [[ "$sha256_hash" != "null" && -n "$sha256_hash" ]]; then - sri_hash=$(sha256_to_sri "$sha256_hash") - echo " \"$platform_name\": \"$sri_hash\"," >> flutter/private/versions.bzl - info " Found $platform_name: ${sha256_hash:0:16}..." - else - # No stable release published for this platform+version (e.g. Flutter - # 3.35.0 shipped for macOS/Linux but not Windows). Omit the key rather - # than emitting a placeholder hash: a phantom hash would 404 or fail - # integrity at fetch, whereas an omitted platform yields a clear - # "provide integrity" error only if someone selects that platform. - warn " No stable $platform_name archive for $version; omitting key" - fi + + for variant in "${variants[@]}"; do + platform_name="${variant%% *}" + archive_path="${variant#* }" + + # Extract SHA-256 hash for this version and archive (stable channel only) + sha256_hash=$(jq -r ".releases[] | select(.version == \"$version\" and .channel == \"stable\" and .archive == \"${archive_path}\") | .sha256" "$platform_file" 2>/dev/null | head -1) + + if [[ "$sha256_hash" != "null" && -n "$sha256_hash" ]]; then + sri_hash=$(sha256_to_sri "$sha256_hash") + echo " \"$platform_name\": \"$sri_hash\"," >> flutter/private/versions.bzl + info " Found $platform_name: ${sha256_hash:0:16}..." + else + # No stable release published for this archive+version (e.g. Flutter + # 3.35.0 shipped for macOS/Linux but not Windows). Omit the key rather + # than emitting a placeholder hash: a phantom hash would 404 or fail + # integrity at fetch, whereas an omitted platform yields a clear + # "provide integrity" error only if someone selects that platform. + warn " No stable $platform_name archive for $version; omitting key" + fi + done done echo " }," >> flutter/private/versions.bzl