From 3f38477928b6b6ce5831348fad2d3f06a3d58214 Mon Sep 17 00:00:00 2001 From: wenkaifan0720 Date: Tue, 30 Jun 2026 16:38:33 -0700 Subject: [PATCH 1/3] feat(bundle): auto-embed cef_host via podspec script_phase (INC 0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make flutter_cef self-bundling so a consumer gets a working app from a plain `flutter build macos` — no `make cef-host`, no manual ditto, no FLUTTER_CEF_HOST. - podspec :after_compile script_phase ditto's native/cef_host/prebuilt/cef_host.app into the built flutter_cef_macos.framework's Versions/A/Frameworks (a pod build phase can't reach the app's top-level Contents/Frameworks — it runs before the app bundle exists; CocoaPods then embeds the framework, host and all, into the app). - resolver probes the framework's Versions/Current/Frameworks (no top-level Frameworks symlink exists), so the embedded host resolves with zero consumer wiring. - no-op when no prebuilt is present (co-dev from-source / FLUTTER_CEF_HOST still win). Proven in the example app: `flutter build macos --debug` + open with NO FLUTTER_CEF_HOST -> resolver finds the embedded host, cef_host (+5 helpers) spawn. The prebuilt is gitignored (fetched at pod install in a later increment). See specs/prebuilt-cef-host/PLAN.md. Co-Authored-By: Claude Opus 4.8 --- example/macos/Podfile.lock | 2 +- packages/flutter_cef_macos/.gitignore | 1 + .../macos/Classes/FlutterCefPlugin.swift | 9 +++ .../macos/flutter_cef_macos.podspec | 36 ++++++++- specs/prebuilt-cef-host/PLAN.md | 74 +++++++++++++++++++ 5 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 packages/flutter_cef_macos/.gitignore create mode 100644 specs/prebuilt-cef-host/PLAN.md diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index 9df0e63..4386c10 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -14,7 +14,7 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral SPEC CHECKSUMS: - flutter_cef_macos: f4ec14a9d75c0a198b6c8ba620ec4e56d4ad22f0 + flutter_cef_macos: 278a857bbcc40d7823a191e01e532b49ca8f20f3 FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009 diff --git a/packages/flutter_cef_macos/.gitignore b/packages/flutter_cef_macos/.gitignore new file mode 100644 index 0000000..84ce10b --- /dev/null +++ b/packages/flutter_cef_macos/.gitignore @@ -0,0 +1 @@ +native/cef_host/prebuilt/ diff --git a/packages/flutter_cef_macos/macos/Classes/FlutterCefPlugin.swift b/packages/flutter_cef_macos/macos/Classes/FlutterCefPlugin.swift index c021c6e..e080fb8 100644 --- a/packages/flutter_cef_macos/macos/Classes/FlutterCefPlugin.swift +++ b/packages/flutter_cef_macos/macos/Classes/FlutterCefPlugin.swift @@ -737,7 +737,16 @@ public class FlutterCefPlugin: NSObject, FlutterPlugin { return env } let inner = "/cef_host.app/Contents/MacOS/cef_host" + // The plugin podspec's :after_compile script phase embeds cef_host.app into THIS framework's + // Versions/A/Frameworks (a pod build phase can't reach the app's top-level Contents/Frameworks — + // it runs before the app bundle exists). The framework exposes no top-level `Frameworks` symlink, + // so reach it through `Versions/Current/Frameworks`. This makes a prebuilt-bundled host resolve + // with zero consumer wiring. The Contents/Frameworks + Contents/Helpers probes remain for a + // consumer that copies the host to the app's top level itself. + let fwFrameworks = Bundle(for: FlutterCefPlugin.self).bundleURL + .appendingPathComponent("Versions/Current/Frameworks").path for base in [ + fwFrameworks, Bundle(for: FlutterCefPlugin.self).resourceURL?.path, Bundle.main.bundlePath + "/Contents/Frameworks", Bundle.main.bundlePath + "/Contents/Helpers", diff --git a/packages/flutter_cef_macos/macos/flutter_cef_macos.podspec b/packages/flutter_cef_macos/macos/flutter_cef_macos.podspec index 3b4592a..f03a916 100644 --- a/packages/flutter_cef_macos/macos/flutter_cef_macos.podspec +++ b/packages/flutter_cef_macos/macos/flutter_cef_macos.podspec @@ -26,8 +26,36 @@ rendering when off-screen. macOS only. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } s.swift_version = '5.0' s.resource_bundles = {'flutter_cef_privacy' => ['Resources/PrivacyInfo.xcprivacy']} - # cef_host.app is bundled into the host .app by the app target, not the pod - # (a pod script-phase runs before the app bundle exists). For dev, point the - # app at it via $FLUTTER_CEF_HOST; for a distributable build, add a Run Script - # phase calling tool/bundle_cef_host.sh — see the README. + + # Auto-embed cef_host.app into the consuming app's Contents/Frameworks. cef_host.app is a + # nested SIGNED app (Chromium + 5 helper apps) — CocoaPods can't auto-embed a nested .app the + # way it does a .framework (resource_bundles would nest it inside this pod's framework and break + # its seal; vendored_frameworks only embeds .framework). So we copy it ourselves in an + # :after_compile script phase, which runs DURING `flutter build macos` AFTER the app bundle + + # `[CP] Embed Pods Frameworks` exist and BEFORE Xcode's codesign — the moment the destination + # Contents/Frameworks is real (the old "a pod script-phase runs before the app bundle exists" + # was only true for :before_compile). ditto (never cp -R) preserves the prebuilt's inside-out + # signatures. The prebuilt is fetched at `pod install` by prepare_command (see fetch_cef_host.sh) + # into native/cef_host/prebuilt/. When absent (co-dev from-source, or FLUTTER_CEF_HOST set) this + # is a clean no-op — the runtime resolver falls back to FLUTTER_CEF_HOST / a make-built host. + s.script_phase = { + :name => 'Embed cef_host.app', + :execution_position => :after_compile, + :script => <<-SCRIPT +set -e +PREBUILT="${PODS_TARGET_SRCROOT}/../native/cef_host/prebuilt/cef_host.app" +DEST_DIR="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}" +echo "[flutter_cef] embed: PODS_TARGET_SRCROOT=${PODS_TARGET_SRCROOT}" +echo "[flutter_cef] embed: prebuilt=${PREBUILT}" +echo "[flutter_cef] embed: dest=${DEST_DIR}/cef_host.app" +if [ -d "${PREBUILT}" ]; then + mkdir -p "${DEST_DIR}" + rm -rf "${DEST_DIR}/cef_host.app" + ditto "${PREBUILT}" "${DEST_DIR}/cef_host.app" + echo "[flutter_cef] embedded cef_host.app into Contents/Frameworks" +else + echo "[flutter_cef] no prebuilt cef_host.app; skipping (co-dev from-source / FLUTTER_CEF_HOST path)" +fi +SCRIPT + } end diff --git a/specs/prebuilt-cef-host/PLAN.md b/specs/prebuilt-cef-host/PLAN.md new file mode 100644 index 0000000..092753a --- /dev/null +++ b/specs/prebuilt-cef-host/PLAN.md @@ -0,0 +1,74 @@ +# Prebuilt, auto-bundled cef_host — make flutter_cef "just a Flutter package" + +## Problem +The Dart/Swift half of flutter_cef is already a normal pod. The native `cef_host.app` +(a nested SIGNED app: ~200MB Chromium + 5 helper apps) is NOT — every consumer must +**build it from source** (cmake/ninja + a CEF SDK fetch) and **manually copy + sign** it +into `Contents/Frameworks` via make/scripts. A plain `flutter build macos` produces a +broken app (no cef_host → crashes ~30s in). This is the recurring "bundle the right cef" +pain, and it created a silent pin-drift class. + +## Goal +A consumer gets a working app from `flutter pub get` + a normal `flutter build macos`: +- **debug/local**: zero extra steps, no `make cef-host`, no `FLUTTER_CEF_HOST`. +- **release**: one inside-out Developer-ID re-sign (consumer identity — irreducible). +- no pin-drift: one plugin version ⇒ exactly one cef_host. + +## Mechanism (the two load-bearing decisions) +1. **EMBED** — a podspec `script_phase` with `execution_position: :after_compile` that + `ditto`s the prebuilt into `${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/cef_host.app`. + This runs DURING `flutter build macos`, AFTER `[CP] Embed Pods Frameworks` creates + `Contents/Frameworks`, BEFORE Xcode's codesign. (`resource_bundles` nests it inside the + pod framework — wrong place + breaks the framework seal; `vendored_frameworks` only + embeds `.framework`, not a nested `.app`. So `:after_compile` script_phase it is.) + The runtime resolver already probes `Contents/Frameworks` (FlutterCefPlugin.swift:691). +2. **FETCH** — a podspec `prepare_command` (runs at `pod install`) downloads + SHA256-verifies + a version-matched prebuilt from a GitHub release asset, driven by a committed manifest + `cef_host_prebuilt.json` (tag, urls, the four sha256s, source_sha, cef_version). + +## Signing +- **dev**: embed the ad-hoc / get-task-allow variant; non-hardened debug runtime tolerates the + unsealed nested app. Do NOT re-sign the main app (strips the Firebase Auth keychain entitlement). +- **release**: consumer re-signs the embedded tree in place with its own Developer-ID, inside-out + (helpers → CEF framework Versions/A dylibs + Versions/A → root). Exactly today's + release-macos-firebase.sh:888-901, just no longer preceded by a build. The prebuilt's own + signature is throwaway (overwritten). + +## Co-dev escape hatch (retained, additive — prebuilt is default) +`FLUTTER_CEF_HOST` env still wins over the bundled prebuilt (probed first). `build_cef_host.sh`, +`bundle_cef_host.sh`, and the consumer `make cef-host` loop all keep working for native hackers. + +## Increments (each independently shippable + verifiable) +- **INC 0** — de-risk the embedding. Hand-build a cef_host.app → `native/cef_host/prebuilt/`, + add ONLY the `:after_compile` script_phase, `flutter build macos` the example, assert cef_host.app + lands at `Contents/Frameworks` (and exactly one, nowhere nested). Validate the actual phase order + in the generated Runner.xcodeproj; fall back to a consumer Run Script if CocoaPods won't guarantee + `:after_compile` after embed-frameworks. **This proves the whole approach.** +- **INC 1** — dev turnkey: add a dev (get-task-allow) variant; build work_canvas with a path-override, + no `make cef-host`, no `FLUTTER_CEF_HOST` → app survives past 30s, tiles render. +- **INC 2** — release: rewire release-macos-firebase.sh to delete the build+ditto block, keep only the + inside-out re-sign pointed at the embedded host; produce a notarized DMG + Gatekeeper-verify. +- **INC 3** — fetch automation: `tool/fetch_cef_host.sh` + `cef_host_prebuilt.json` + podspec + `prepare_command`; hand-upload tarballs to a `v0.2.x` GitHub release; verify turnkey from a clean + machine (no cmake/ninja). Escape hatches still win. +- **INC 4** — publishing CI: `.github/workflows/release-cef-host.yml` on `v*` — arm64 (+x86_64) + matrix, build both variants, inside-out sign + standalone-notarize the release variant, stamp + provenance, tar+sha256, `gh release upload` + GCS mirror, commit the manifest back. +- **INC 5** — consumer cleanup: delete the Makefile `cef-host` target/vars, the open-firebase manual + bundle, the release-script build block, the cmake/ninja preflight; retire cef-doctor ASSERT 2 and + repoint ASSERT 1's host-match to the fetched `cef_host_source_sha.txt`. + +## Open risks (validate as we go) +- **CocoaPods phase ordering** (the linchpin): `:after_compile` must run after embed-frameworks + + before codesign. Validate in INC 0; fall back to a one-time consumer Run Script if not guaranteed. +- **resourceURL vs Frameworks**: resolver probes the pod resourceURL before Contents/Frameworks — + ensure no cef_host fragment leaks into the pod resource bundle. +- **git-dep prepare_command**: confirm it runs for a git-sourced flutter_cef and the fetched prebuilt + survives Flutter's `.symlinks/plugins` copy into the build. +- **x86_64 cross-build/sign/notarize** unproven — may ship arm64-only first, keep from-source for x64. +- **notarization** of the consumer-resigned host (prebuilt's stapled ticket is invalidated by the + re-sign — verify the whole-app notarize still passes in INC 2). +- **manifest source_sha staleness**: a consumer pinned to an untagged commit fetches the last tag's + prebuilt; cef-doctor's repointed assert must allow `tag <= resolved && IPC-compatible`, not strict sha. +- **artifact size**: ~293MB × 4 per tag — cache `~/.cache/flutter_cef/prebuilt/`; consider + arm64-only default. From a2266e95eeca413d9360e85a07ba3367cc383a39 Mon Sep 17 00:00:00 2001 From: wenkaifan0720 Date: Tue, 30 Jun 2026 16:55:58 -0700 Subject: [PATCH 2/3] feat(bundle): fetch prebuilt cef_host at pod install (INC 3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit podspec prepare_command runs tool/fetch_cef_host.sh, which downloads + SHA256- verifies the version-matched cef_host.app named in cef_host_prebuilt.json into native/cef_host/prebuilt/ (cached under ~/.cache/flutter_cef; fail-open; FLUTTER_CEF_FROM_SOURCE=1 skips for co-dev). Combined with the INC 0 :after_compile embed, a clean consumer now gets a working app from a single `flutter build macos` — pod install fetches, the build embeds, no make/cef-host, no FLUTTER_CEF_HOST. Artifact hosted (ad-hoc, unsigned — consumers sign their own release) at gs://flutterflow-downloads/flutter_cef_prebuilt/v0.2.0/. Proven end-to-end in the example app from a wiped prebuilt+cache+Pods state. Co-Authored-By: Claude Opus 4.8 --- example/macos/Podfile.lock | 2 +- .../flutter_cef_macos/cef_host_prebuilt.json | 12 +++ .../macos/flutter_cef_macos.podspec | 6 ++ .../flutter_cef_macos/tool/fetch_cef_host.sh | 78 +++++++++++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 packages/flutter_cef_macos/cef_host_prebuilt.json create mode 100755 packages/flutter_cef_macos/tool/fetch_cef_host.sh diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index 4386c10..c5bd1d0 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -14,7 +14,7 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral SPEC CHECKSUMS: - flutter_cef_macos: 278a857bbcc40d7823a191e01e532b49ca8f20f3 + flutter_cef_macos: 663fd8075939eb7efa312c8900630e16bc3c0063 FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009 diff --git a/packages/flutter_cef_macos/cef_host_prebuilt.json b/packages/flutter_cef_macos/cef_host_prebuilt.json new file mode 100644 index 0000000..14d3278 --- /dev/null +++ b/packages/flutter_cef_macos/cef_host_prebuilt.json @@ -0,0 +1,12 @@ +{ + "version": "v0.2.0", + "cef_version": "144.0.27+g3fae261+chromium-144.0.7559.254", + "source_sha": "3f38477928b6b6ce5831348fad2d3f06a3d58214", + "base_url": "https://storage.googleapis.com/flutterflow-downloads/flutter_cef_prebuilt/v0.2.0", + "artifacts": { + "macos-arm64-dev": { + "file": "cef_host-macos-arm64-dev.tar.gz", + "sha256": "a9eaceeb06a25097ddae8ee573b662b419753bc822ef06c15cc615c08d802f52" + } + } +} diff --git a/packages/flutter_cef_macos/macos/flutter_cef_macos.podspec b/packages/flutter_cef_macos/macos/flutter_cef_macos.podspec index f03a916..d2d2ba1 100644 --- a/packages/flutter_cef_macos/macos/flutter_cef_macos.podspec +++ b/packages/flutter_cef_macos/macos/flutter_cef_macos.podspec @@ -27,6 +27,12 @@ rendering when off-screen. macOS only. s.swift_version = '5.0' s.resource_bundles = {'flutter_cef_privacy' => ['Resources/PrivacyInfo.xcprivacy']} + # Fetch the prebuilt, version-matched cef_host.app at `pod install` (downloads + SHA256-verifies + # the artifact named in cef_host_prebuilt.json into native/cef_host/prebuilt/). Fail-open + cached; + # FLUTTER_CEF_FROM_SOURCE=1 skips it for co-dev. The :after_compile phase below embeds whatever + # lands there, so `flutter pub get` + `flutter build macos` is turnkey with no make/host steps. + s.prepare_command = 'bash ../tool/fetch_cef_host.sh' + # Auto-embed cef_host.app into the consuming app's Contents/Frameworks. cef_host.app is a # nested SIGNED app (Chromium + 5 helper apps) — CocoaPods can't auto-embed a nested .app the # way it does a .framework (resource_bundles would nest it inside this pod's framework and break diff --git a/packages/flutter_cef_macos/tool/fetch_cef_host.sh b/packages/flutter_cef_macos/tool/fetch_cef_host.sh new file mode 100755 index 0000000..724cfe7 --- /dev/null +++ b/packages/flutter_cef_macos/tool/fetch_cef_host.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +# Fetch the prebuilt, version-matched cef_host.app — run at `pod install` via the podspec's +# prepare_command. Downloads + SHA256-verifies the artifact named in cef_host_prebuilt.json, +# caches it, and extracts cef_host.app into native/cef_host/prebuilt/ where the :after_compile +# script phase embeds it. Self-locating (CWD-independent). Fail-OPEN: any problem leaves no +# prebuilt, and the build falls back to FLUTTER_CEF_HOST / build-from-source. +# +# Escape hatch: FLUTTER_CEF_FROM_SOURCE=1 skips the fetch entirely (co-dev builds cef_host from +# source via native/build_cef_host.sh and points the app at it with $FLUTTER_CEF_HOST). +set -uo pipefail + +if [ -n "${FLUTTER_CEF_FROM_SOURCE:-}" ]; then + echo "[flutter_cef] FLUTTER_CEF_FROM_SOURCE set — skipping prebuilt fetch (build-from-source)" + exit 0 +fi + +HERE="$(cd "$(dirname "$0")" && pwd)" # .../flutter_cef_macos/tool +PKG="$(cd "$HERE/.." && pwd)" # .../flutter_cef_macos +MANIFEST="$PKG/cef_host_prebuilt.json" +DEST="$PKG/native/cef_host/prebuilt" + +[ -f "$MANIFEST" ] || { echo "[flutter_cef] no $MANIFEST — skipping fetch"; exit 0; } + +case "$(uname -m)" in + arm64) arch=arm64 ;; + x86_64) arch=x86_64 ;; + *) echo "[flutter_cef] unsupported arch $(uname -m) — skipping fetch"; exit 0 ;; +esac +key="macos-${arch}-dev" + +# Parse the manifest with python3 (present on every macOS dev box). Prints: base file sha src ver +read -r base file sha src ver </dev/null)" = "$src" ]; then + echo "[flutter_cef] prebuilt cef_host already current ($src) — skipping fetch" + exit 0 +fi + +CACHE="${FLUTTER_CEF_CACHE:-$HOME/.cache/flutter_cef}/prebuilt/$src/$arch" +mkdir -p "$CACHE" +tarball="$CACHE/$file" + +if [ ! -f "$tarball" ] || [ "$(shasum -a 256 "$tarball" 2>/dev/null | awk '{print $1}')" != "$sha" ]; then + echo "[flutter_cef] downloading prebuilt cef_host ($key, cef $ver)…" + if ! curl -fL --retry 3 "$base/$file" -o "$tarball.part"; then + echo "[flutter_cef] download failed — leaving no prebuilt (FLUTTER_CEF_HOST / from-source will be used)" >&2 + rm -f "$tarball.part"; exit 0 + fi + got="$(shasum -a 256 "$tarball.part" | awk '{print $1}')" + if [ "$got" != "$sha" ]; then + echo "[flutter_cef] SHA256 mismatch (got $got, want $sha) — refusing the artifact" >&2 + rm -f "$tarball.part"; exit 1 + fi + mv "$tarball.part" "$tarball" +fi + +echo "[flutter_cef] extracting prebuilt cef_host -> $DEST" +mkdir -p "$DEST" +rm -rf "$DEST/cef_host.app" +tar -xzf "$tarball" -C "$DEST" +echo "[flutter_cef] prebuilt cef_host ready ($src)" From 82d9ec387040404580f20c9a5586cfe7ea0cc60c Mon Sep 17 00:00:00 2001 From: wenkaifan0720 Date: Tue, 30 Jun 2026 17:00:21 -0700 Subject: [PATCH 3/3] feat(bundle): publish prebuilt cef_host via CI on cef-host-v* tags (INC 4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit release-cef-host.yml builds cef_host ad-hoc (arm64 dev variant), packages + checksums it with provenance, uploads to the tag's GitHub release, and commits the updated cef_host_prebuilt.json back to the default branch — using only GITHUB_TOKEN, no signing secrets (consumers re-sign their own release builds). Point the manifest at the GitHub release host (cef-host-v0.2.0). x86_64 + a hardened release-compiled variant are documented follow-ups. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/release-cef-host.yml | 88 +++++++++++++++++++ .../flutter_cef_macos/cef_host_prebuilt.json | 2 +- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release-cef-host.yml diff --git a/.github/workflows/release-cef-host.yml b/.github/workflows/release-cef-host.yml new file mode 100644 index 0000000..ca22a13 --- /dev/null +++ b/.github/workflows/release-cef-host.yml @@ -0,0 +1,88 @@ +# Publish a prebuilt cef_host.app when a `cef-host-v*` tag is pushed, and update the committed +# manifest (cef_host_prebuilt.json) so consumers' `pod install` fetches it. Uses only GITHUB_TOKEN +# — NO signing secrets: the published artifact is ad-hoc signed; consumers re-sign their own release +# builds with their own Developer-ID. See specs/prebuilt-cef-host/PLAN.md. +# +# TODO (follow-ups): add an x86_64 matrix leg (needs an Intel/Rosetta runner — cross-arch sign is +# unproven) and a hardened "release-compiled" variant (CEF_HOST_ADHOC=OFF drops the dev mock-keychain +# / Mach-port bypass) once the signing path is wired. +name: release-cef-host + +on: + push: + tags: ['cef-host-v*'] + workflow_dispatch: + inputs: + tag: + description: 'Existing cef-host-v* tag to (re)publish for' + required: true + +permissions: + contents: write # upload release assets + commit the manifest back + +jobs: + arm64: + runs-on: macos-14 # Apple Silicon + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.tag || github.ref_name }} + + - name: Build cef_host (ad-hoc, dev variant) + run: | + CEF_HOST_ADHOC=ON bash packages/flutter_cef_macos/native/build_cef_host.sh "$RUNNER_TEMP/out" + test -d "$RUNNER_TEMP/out/cef_host.app" + + - name: Package + checksum (with provenance) + id: pkg + run: | + TAG="${{ github.event.inputs.tag || github.ref_name }}" + SRC_SHA="$(git rev-parse HEAD)" + CEF_VER="$(grep '^CEF_VERSION=' packages/flutter_cef_macos/native/build_cef_host.sh | head -1 | cut -d'"' -f2)" + FILE="cef_host-macos-arm64-dev.tar.gz" + cd "$RUNNER_TEMP/out" + echo "$SRC_SHA" > cef_host_source_sha.txt + echo "$CEF_VER" > cef_version.txt + tar -czf "$RUNNER_TEMP/$FILE" cef_host.app cef_host_source_sha.txt cef_version.txt + SHA="$(shasum -a 256 "$RUNNER_TEMP/$FILE" | awk '{print $1}')" + echo "$SHA $FILE" > "$RUNNER_TEMP/$FILE.sha256" + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + echo "file=$FILE" >> "$GITHUB_OUTPUT" + echo "sha=$SHA" >> "$GITHUB_OUTPUT" + echo "src=$SRC_SHA" >> "$GITHUB_OUTPUT" + echo "cef=$CEF_VER" >> "$GITHUB_OUTPUT" + + - name: Upload to the release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release upload "${{ steps.pkg.outputs.tag }}" \ + "$RUNNER_TEMP/${{ steps.pkg.outputs.file }}" \ + "$RUNNER_TEMP/${{ steps.pkg.outputs.file }}.sha256" \ + --repo "${{ github.repository }}" --clobber + + - name: Update committed manifest on the default branch + env: + GH_TOKEN: ${{ github.token }} + run: | + DEF="${{ github.event.repository.default_branch }}" + git fetch origin "$DEF" + git checkout "$DEF" + python3 - "$DEF" "${{ steps.pkg.outputs.tag }}" "${{ steps.pkg.outputs.file }}" \ + "${{ steps.pkg.outputs.sha }}" "${{ steps.pkg.outputs.src }}" "${{ steps.pkg.outputs.cef }}" <<'PY' + import json, sys + _def, tag, file, sha, src, cef = sys.argv[1:7] + p = "packages/flutter_cef_macos/cef_host_prebuilt.json" + m = json.load(open(p)) + m["version"] = tag + m["cef_version"] = cef + m["source_sha"] = src + m["base_url"] = f"https://github.com/${{ github.repository }}/releases/download/{tag}" + m.setdefault("artifacts", {})["macos-arm64-dev"] = {"file": file, "sha256": sha} + json.dump(m, open(p, "w"), indent=2); open(p, "a").write("\n") + PY + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add packages/flutter_cef_macos/cef_host_prebuilt.json + git commit -m "chore(cef): publish prebuilt cef_host ${{ steps.pkg.outputs.tag }} [skip ci]" || echo "manifest already current" + git push origin "$DEF" diff --git a/packages/flutter_cef_macos/cef_host_prebuilt.json b/packages/flutter_cef_macos/cef_host_prebuilt.json index 14d3278..081ca0b 100644 --- a/packages/flutter_cef_macos/cef_host_prebuilt.json +++ b/packages/flutter_cef_macos/cef_host_prebuilt.json @@ -2,7 +2,7 @@ "version": "v0.2.0", "cef_version": "144.0.27+g3fae261+chromium-144.0.7559.254", "source_sha": "3f38477928b6b6ce5831348fad2d3f06a3d58214", - "base_url": "https://storage.googleapis.com/flutterflow-downloads/flutter_cef_prebuilt/v0.2.0", + "base_url": "https://github.com/FlutterFlow/flutter_cef/releases/download/cef-host-v0.2.0", "artifacts": { "macos-arm64-dev": { "file": "cef_host-macos-arm64-dev.tar.gz",