453 lines
26 KiB
Markdown
453 lines
26 KiB
Markdown
# GitHub CI
|
|
|
|
The root workflow at `.github/workflows/open-shorebird-ci.yml` validates the
|
|
combined open Shorebird workspace rather than any single submodule in isolation.
|
|
|
|
## Default CI
|
|
|
|
Push and pull request runs perform source-level checks and build distributable
|
|
binaries:
|
|
|
|
1. `source-checks` runs the bootstrap test path with `SKIP_GCLIENT_SYNC=1`,
|
|
including CLI, code push client, artifact proxy, updater library, open patch
|
|
tooling, and server tests.
|
|
This checks the Shorebird CLI focused tests, code push client open-server
|
|
default tests, open patch tools, server tests, and the root shell scripts
|
|
without downloading the full engine dependency graph. It also runs
|
|
`scripts/verify_ci_workflow.sh`, which parses the
|
|
workflow YAML, checks every workflow `run:` block with `bash -n`, and
|
|
verifies the expected open SDK/CLI/server artifact contract, including
|
|
archive creation and checksum sidecar generation. It also checks
|
|
`.gitmodules`, `docs/REPOSITORIES.md`, and generated `.gclient` files so a
|
|
fresh GitHub checkout uses open HTTPS remotes instead of local paths, SSH
|
|
remotes, or official closed Shorebird repositories. The verifier also scans
|
|
runtime/build-sensitive CLI, updater, artifact-proxy, Flutter tool, Gradle,
|
|
engine metadata, and web UI artifact-copy sources to reject hosted Shorebird
|
|
endpoints and official `shorebirdtech` GitHub dependencies. It also reads
|
|
the forked engine BUILD files and checks that the GN targets and archive
|
|
names referenced by the manual engine jobs still exist.
|
|
Before uploading the workspace, run `scripts/verify_upload_readiness.sh`.
|
|
It invokes the same workflow contract verifier in upload-ready mode, which
|
|
requires every listed CI support file to be tracked in its owning checkout
|
|
and requires the root plus required submodule checkouts to be clean.
|
|
`scripts/verify_sync_open_sources.sh` also exercises the source-link helper
|
|
in an isolated temporary workspace so clean generated engine checkouts are
|
|
replaced by the workspace Dart/updater submodules and dirty targets are not
|
|
overwritten.
|
|
`scripts/verify_open_infrastructure_defaults.sh` independently scans
|
|
build-sensitive Flutter, Shorebird CLI, artifact-proxy, updater, `.gclient`,
|
|
and submodule metadata for closed Shorebird endpoints, official
|
|
`shorebirdtech` dependency remotes, and private prebuilt buckets, while
|
|
requiring the open local server and artifact mirror defaults.
|
|
`scripts/verify_powershell_open_defaults.sh` checks the Windows launcher and
|
|
Flutter Dart SDK updater PowerShell scripts for open Flutter/artifact
|
|
defaults and parses them with `pwsh` when it is available.
|
|
`scripts/verify_write_sha256.sh` smoke-tests the portable checksum helper
|
|
used by every artifact job.
|
|
`scripts/verify_ios_interpreter_route_validator.sh` smoke-tests the iOS
|
|
App Store route gate with synthetic GN args and encrypted patch artifacts,
|
|
covering a valid interpreter artifact and rejecting dynamic-module,
|
|
non-iOS, malformed JSON, and Mach-O native patch inputs.
|
|
2. All artifact and runtime-smoke jobs declare `needs: source-checks`, so no
|
|
uploaded CLI, server, SDK, or engine artifact is produced before the
|
|
source-level open-replacement contract passes.
|
|
3. `cli-artifacts` compiles:
|
|
- `shorebird` for Linux x64, macOS x64, macOS arm64, and Windows x64
|
|
- `open_aot_patch_tools` for Linux x64, macOS x64, macOS arm64, and
|
|
Windows x64
|
|
- `artifact_proxy` for Linux x64, macOS x64, macOS arm64, and Windows x64
|
|
- public updater `patch` binaries packaged as CLI-cache mirror artifacts:
|
|
`patch-linux-x64.zip`, `patch-darwin-x64.zip`,
|
|
`patch-darwin-arm64.zip`, and `patch-windows-x64.zip`
|
|
- `mirror-metadata`, containing
|
|
`shorebird/<engine-revision>/artifacts_manifest.yaml`
|
|
The job provisions stable Rust before building the updater `patch` binary,
|
|
so those mirror artifacts do not depend on preinstalled runner state.
|
|
CI opens each generated patch mirror ZIP before upload and verifies it has
|
|
exactly the cache-facing entry name (`patch` on Unix, `patch.exe` on
|
|
Windows) with a non-empty payload.
|
|
Each CLI upload is an `open-shorebird-cli-<os>-<arch>.tar.gz` archive with
|
|
`bin/shorebird`, `bin/open_aot_patch_tools`, `bin/artifact_proxy`,
|
|
`bin/internal` version metadata, `manifest.json`, and a `.sha256` sidecar.
|
|
The manifest records the Flutter revision and engine revision used by the
|
|
bundled CLI cache metadata. The macOS CLI split is intentional: macOS x64
|
|
runs on `macos-15-intel`, and macOS arm64 runs on `macos-14`. Before upload,
|
|
CI extracts the archive and runs `shorebird --version`,
|
|
`open_aot_patch_tools --help`, and `artifact_proxy --health-check` from the
|
|
extracted layout. The `shorebird --version` smoke must report the open
|
|
`https://git.tonycloud.org/flutter/shorebird.git` fork and rejects the old
|
|
official Shorebird SSH remote.
|
|
4. `server-artifacts` runs `go test ./...` and cross-compiles
|
|
`shorebird-server` for Linux x64/arm64, macOS x64/arm64, and Windows x64
|
|
targets. Each uploaded archive contains the server binary, `web/` dashboard
|
|
assets, `.env.example`, `README.md`, `openapi.yaml`, `manifest.json`, and a
|
|
`.sha256` sidecar. The manifest records both the root workflow commit and
|
|
the server submodule commit. Keep `web/` beside the executable when
|
|
unpacking; the server looks for dashboard assets relative to its working
|
|
directory and executable path.
|
|
The Linux x64 archive is extracted and smoke-tested in CI by starting the
|
|
packaged binary with SQLite/local storage, checking `/health`, fetching the
|
|
dashboard HTML from `/`, and verifying `/openapi.yaml`.
|
|
|
|
The CLI/server artifacts are uploaded from each workflow run. CLI archives are
|
|
intended for installation or release attachments; patch mirror ZIPs are separate
|
|
because the Shorebird CLI cache expects the `patch-*.zip` names and a `patch`
|
|
or `patch.exe` entry inside each ZIP. The patch mirror ZIPs include `.sha256`
|
|
sidecars and can be copied under
|
|
`/shorebird/<engine-revision>/` on the host referenced by
|
|
`SHOREBIRD_ARTIFACT_BASE_URL`. Each `mirror-patch-*.zip` GitHub artifact also
|
|
includes a publish-ready `shorebird/<engine-revision>/patch-*.zip` copy and
|
|
matching `.sha256` sidecar, so mirror publication can copy the `shorebird/`
|
|
subtree directly. The `mirror-metadata` artifact provides the matching
|
|
`artifacts_manifest.yaml` for the artifact proxy.
|
|
Manual engine artifacts also include a `mirror/` subtree whose contents are
|
|
already laid out under `shorebird/flutter_infra_release/...`; copy that subtree
|
|
to the same artifact mirror root to satisfy the generated
|
|
`artifacts_manifest.yaml` overrides.
|
|
On `full_sdk_build=true` runs, `artifact-mirror` downloads the mirror metadata,
|
|
all platform patch ZIPs, and the Linux/Android/web/iOS/macOS engine artifacts,
|
|
then uploads `open-shorebird-artifact-mirror`. It also downloads the CLI,
|
|
server, and custom Dart SDK artifacts and uploads
|
|
`open-shorebird-release-manifest`, a JSON manifest that verifies every archived
|
|
release artifact has a matching checksum sidecar and records its SHA-256 digest,
|
|
size, relative path, downloaded artifact group, file name, and workflow commit.
|
|
Zero-byte release artifacts are rejected even when their sidecars match.
|
|
The manifest job also requires every
|
|
expected CLI, server, custom Dart SDK, engine, patch-tool, metadata, and mirror
|
|
artifact family to be present. The mirror archive is the checked publish-ready
|
|
mirror root for `SHOREBIRD_ARTIFACT_BASE_URL`; the release manifest is the
|
|
provenance index for the full SDK/CLI/server/engine output set.
|
|
The artifact-mirror job validates the generated manifest with
|
|
`scripts/validate_release_manifest.py` before upload. After downloading workflow
|
|
artifacts, the same validator can audit the manifest against the downloaded
|
|
artifact directory and will reject missing files, duplicate or unsafe paths,
|
|
checksum/size mismatches, sidecar mismatches, orphan sidecars, mismatched
|
|
artifact group or file-name provenance fields, and artifacts that are present on
|
|
disk but missing from the manifest.
|
|
Use the wrapper below after downloading a completed `full_sdk_build=true` run:
|
|
|
|
```sh
|
|
gh run download <run-id> --dir downloaded-artifacts
|
|
./scripts/verify_downloaded_release_artifacts.sh \
|
|
--github-sha <run-head-sha> \
|
|
downloaded-artifacts
|
|
```
|
|
|
|
It verifies the release manifest sidecar, validates the manifest against every
|
|
downloaded artifact, optionally requires the manifest commit to match the
|
|
expected run SHA, verifies the mirror archive sidecar, safely extracts
|
|
`open-shorebird-artifact-mirror.tar.gz` after rejecting unsafe archive members,
|
|
and validates the extracted mirror root before anything is published.
|
|
|
|
After the workspace is uploaded to GitHub, the end-to-end proof can be driven
|
|
from a local checkout with:
|
|
|
|
```sh
|
|
./scripts/verify_hosted_full_sdk_build.sh \
|
|
--repo owner/repo \
|
|
--ref main
|
|
```
|
|
|
|
That helper dispatches `open-shorebird-ci.yml` with `full_sdk_build=true`,
|
|
waits for the hosted workflow run to succeed, downloads all artifacts, and runs
|
|
`scripts/verify_downloaded_release_artifacts.sh` against the downloaded output
|
|
with the workflow run's `headSha`.
|
|
It uses GitHub CLI when `gh` is installed; otherwise it uses the GitHub REST API
|
|
with `GITHUB_TOKEN` or `GH_TOKEN` plus `curl`, `jq`, and `unzip`.
|
|
Use `--linux-heavy-runner`, `--macos-heavy-runner`, and the disk-threshold flags
|
|
when the repository uses custom larger/self-hosted runner labels.
|
|
For local release assembly or reassembly after downloading workflow artifacts,
|
|
run:
|
|
|
|
```sh
|
|
./scripts/assemble_artifact_mirror.sh downloaded-artifacts public-mirror
|
|
```
|
|
|
|
The assembler scans direct artifact contents plus `*.tar.gz` engine archives,
|
|
validates archive member paths, rejects links/devices before extraction, copies
|
|
every `shorebird/` mirror subtree into `public-mirror`, rejects conflicting
|
|
files with different bytes, validates that each
|
|
`artifacts_manifest.yaml` override resolves to a copied non-empty file, verifies
|
|
every platform `patch-*.zip` contains exactly the cache-facing `patch` or
|
|
`patch.exe` entry, and writes missing `.sha256` sidecars.
|
|
`scripts/validate_artifact_mirror.py public-mirror` can be run independently
|
|
after safely extracting `open-shorebird-artifact-mirror.tar.gz`; the
|
|
`artifact-mirror` job safe-extracts and validates the assembled archive before
|
|
upload.
|
|
`scripts/verify_assemble_artifact_mirror.sh` keeps the low-level assembler
|
|
covered in default source checks. `scripts/verify_artifact_mirror_workflow_assembly.sh`
|
|
also dry-runs the full `artifact-mirror` aggregation flow with fake downloaded
|
|
artifacts, including the mirror-only input subset, extracted mirror validation,
|
|
and release manifest requirements. This catches path-layout regressions before
|
|
the hosted `full_sdk_build=true` run.
|
|
CI writes checksum sidecars through `scripts/write_sha256.sh` so the artifact
|
|
jobs do not depend on platform-specific checksum tools.
|
|
The workflow defaults all `run` steps to Bash, including Windows matrix jobs,
|
|
because the workspace scripts and packaging commands use Bash syntax.
|
|
|
|
On June 25, 2026, the Darwin arm64 CLI artifact path was smoke-tested locally:
|
|
the workflow-equivalent commands compiled `shorebird`, `open_aot_patch_tools`,
|
|
and `artifact_proxy`; built the Rust updater `patch` binary; produced
|
|
`open-shorebird-cli-macos-arm64.tar.gz` and `patch-darwin-arm64.zip`; wrote both
|
|
checksum sidecars; extracted the CLI archive; and verified the compiled tools
|
|
could run from the extracted layout.
|
|
The patch mirror ZIP contained a single `patch` entry, matching the CLI cache
|
|
contract.
|
|
|
|
The Darwin arm64 server artifact path was smoke-tested locally the same day:
|
|
the workflow-equivalent packaging command produced
|
|
`shorebird-server-darwin-arm64.tar.gz`, wrote a `.sha256` sidecar, extracted
|
|
the archive, started the packaged server with SQLite and local storage, and
|
|
verified `/health` returned `status=ok` while `/` served the packaged dashboard
|
|
HTML from the sibling `web/` directory. The packaged server also serves the
|
|
checked OpenAPI contract at `/openapi.yaml`.
|
|
|
|
## Open Artifact Hosts
|
|
|
|
The CLI can be used with a self-hosted server and open artifact mirror without
|
|
changing source code. When no project `base_url`, user config, or environment
|
|
override is present, the open CLI defaults API/auth traffic to the local
|
|
self-hosted server at `http://localhost:8080` instead of Shorebird's hosted
|
|
service:
|
|
|
|
```sh
|
|
export SHOREBIRD_HOSTED_URL=https://updates.example.com
|
|
export SHOREBIRD_ARTIFACT_BASE_URL=https://artifacts.example.com/open
|
|
export SHOREBIRD_FLUTTER_STORAGE_BASE_URL=https://artifacts.example.com/flutter
|
|
export SHOREBIRD_FLUTTER_GIT_URL=https://github.com/example/open-flutter.git
|
|
```
|
|
|
|
`SHOREBIRD_HOSTED_URL` points API calls at the self-hosted server and is also
|
|
written into new `shorebird.yaml` files as `base_url`. The bundled updater
|
|
library also defaults to `http://localhost:8080` when a legacy app omits
|
|
`base_url`. The self-hosted server publishes its checked OpenAPI contract at
|
|
`http://localhost:8080/openapi.yaml`. The artifact mirror keeps the same path
|
|
layout as Shorebird's default storage bucket:
|
|
|
|
```text
|
|
$SHOREBIRD_ARTIFACT_BASE_URL/shorebird/<engine-revision>/patch-linux-x64.zip
|
|
$SHOREBIRD_ARTIFACT_BASE_URL/shorebird/<engine-revision>/patch-darwin-x64.zip
|
|
$SHOREBIRD_ARTIFACT_BASE_URL/shorebird/<engine-revision>/patch-darwin-arm64.zip
|
|
$SHOREBIRD_ARTIFACT_BASE_URL/shorebird/<engine-revision>/patch-windows-x64.zip
|
|
$SHOREBIRD_ARTIFACT_BASE_URL/shorebird/<engine-revision>/artifacts_manifest.yaml
|
|
```
|
|
|
|
When `SHOREBIRD_ARTIFACT_BASE_URL` is not set, the open CLI defaults CLI-managed
|
|
artifact downloads to `http://localhost:8080/artifacts`. Use that local mirror
|
|
root for development, or set `SHOREBIRD_ARTIFACT_BASE_URL` to the public mirror
|
|
where the CI-produced `patch-*.zip` artifacts are hosted.
|
|
|
|
If the mirror is a bucket-style host, `SHOREBIRD_STORAGE_BASE_URL` and
|
|
`SHOREBIRD_STORAGE_BUCKET` can be used instead of
|
|
`SHOREBIRD_ARTIFACT_BASE_URL`. `SHOREBIRD_FLUTTER_STORAGE_BASE_URL` controls the
|
|
`FLUTTER_STORAGE_BASE_URL` passed to vended Flutter commands; when unset it
|
|
defaults to `http://localhost:8080/download.flutter.io`.
|
|
`SHOREBIRD_FLUTTER_GIT_URL` controls where the CLI clones vended Flutter
|
|
revisions during cache installation. When unset, the open CLI defaults to this
|
|
workspace's open Flutter fork instead of `github.com/shorebirdtech/flutter.git`.
|
|
The Flutter fork also defaults its own engine downloads, Dart SDK refresh
|
|
scripts, doctor network check, Android Gradle Maven host, Android host-app
|
|
integration fixtures, docs artifact scripts, and Shorebird integration tests to
|
|
`http://localhost:8080/download.flutter.io` when `FLUTTER_STORAGE_BASE_URL` is
|
|
unset, so direct Flutter use does not fall back to Shorebird's closed artifact
|
|
host.
|
|
|
|
The open CI currently does not publish `aot-tools.dill`. That file is a
|
|
different Shorebird linker artifact used by the legacy native-AOT iOS linker
|
|
path. The open App Store-safe iOS path uses encrypted Dart bytecode interpreter
|
|
artifacts instead, and Android/Linux/macOS/Windows patch creation uses the
|
|
public updater `patch` binaries above.
|
|
The CLI cache does not download `aot-tools.dill` by default. Set
|
|
`SHOREBIRD_ENABLE_LEGACY_AOT_TOOLS=1` only when deliberately validating the
|
|
development-only legacy native-AOT linker path.
|
|
|
|
Runtime smoke scripts that need external targets are kept out of default CI:
|
|
`scripts/android_runtime_patch_smoke.sh` requires an attached Android
|
|
device/emulator with app-private storage access, and
|
|
`scripts/linux_runtime_patch_smoke.sh` requires a Linux desktop runtime or
|
|
`xvfb-run`. Use them on suitable self-hosted runners when extending runtime
|
|
coverage beyond the artifact build matrix.
|
|
|
|
Use `workflow_dispatch` with `run_runtime_smokes=true` to run those external
|
|
runtime smokes from CI. The runtime jobs are intentionally separate from
|
|
`full_sdk_build=true`: they are for provisioned runners that already have the
|
|
matching local engine build outputs in the checkout workspace. Runtime checkout
|
|
uses `clean: false` so self-hosted runners can preserve those `out/` directories
|
|
between preparation and smoke runs.
|
|
|
|
| Input | Default | Used by |
|
|
| --- | --- | --- |
|
|
| `run_runtime_smokes` | `false` | Enables `linux-runtime-smoke` and `android-runtime-smoke` |
|
|
| `linux_runtime_runner` | `self-hosted` | Runner label for `scripts/linux_runtime_patch_smoke.sh` |
|
|
| `android_runtime_runner` | `self-hosted` | Runner label for `scripts/android_runtime_patch_smoke.sh` |
|
|
| `android_serial` | empty | Optional `adb` serial passed as `ANDROID_SERIAL` |
|
|
|
|
The Linux runtime runner must provide
|
|
`flutter/engine/src/out/linux_release_x64`. The Android runtime runner must provide
|
|
`flutter/engine/src/out/android_release_arm64` and
|
|
`flutter/engine/src/out/host_release_arm64`, plus an Android target where either
|
|
`adb shell run-as` works for the test package or `adb root` works. It must also
|
|
provide Java on `PATH` because the smoke builds APKs before seeding the patch.
|
|
|
|
## Heavy SDK Builds
|
|
|
|
Default push and pull request runs build the custom SDK and engine artifacts.
|
|
Manual `workflow_dispatch` runs also build them by default because
|
|
`full_sdk_build=true` is the default input value; set `full_sdk_build=false`
|
|
only for source/CLI/server-only manual runs.
|
|
|
|
The heavy jobs install Chromium's `depot_tools` into the workflow workspace
|
|
before running `gclient`, so they can bootstrap from a clean runner. The
|
|
workflow defaults heavy jobs to managed GitHub-hosted runners:
|
|
|
|
- `ubuntu-latest` for Linux SDK, Linux engine, Android engine, and web SDK
|
|
builds
|
|
- `macos-latest` for macOS Dart SDK, iOS engine, and macOS engine builds
|
|
|
|
Override `linux_heavy_runner` / `macos_heavy_runner` when a repository wants
|
|
larger or self-hosted runners. Every SDK/engine job also runs
|
|
`scripts/check_ci_capacity.sh` before `gclient sync` or `ninja`; SDK-only jobs
|
|
and engine jobs require at least 8 GiB free by default. Raise the dispatch
|
|
thresholds for runner images where a larger preflight budget should be enforced.
|
|
The hosted Android engine job also provisions Temurin Java 17 before building
|
|
Android JAR/APK-related engine artifacts. Every SDK/engine job verifies
|
|
`python3`, `gclient`, and `ninja` before generating build files, so
|
|
PATH/toolchain problems fail before a long build starts. CI sets
|
|
`DEPOT_TOOLS_UPDATE=0`, and the local bootstrap scripts default the same way,
|
|
so depot_tools uses the pinned submodule revision unless explicitly overridden.
|
|
|
|
Manual dispatch accepts these workflow inputs:
|
|
|
|
| Input | Default | Used by |
|
|
| --- | --- | --- |
|
|
| `linux_heavy_runner` | `ubuntu-latest` | `custom-dart-sdk`, `linux-engine`, `android-engine`, `web-sdk` |
|
|
| `macos_heavy_runner` | `macos-latest` | `custom-dart-sdk-macos`, `ios-engine` / Apple engine artifacts |
|
|
| `sdk_min_free_disk_gb` | `8` | Minimum free disk GiB for `custom-dart-sdk` and `custom-dart-sdk-macos` |
|
|
| `engine_min_free_disk_gb` | `8` | Minimum free disk GiB for Linux, Android, web, iOS, and macOS engine builds |
|
|
| `base_flutter_engine_revision` | empty | Optional upstream Flutter engine revision recorded in `artifacts_manifest.yaml` for non-overridden artifact proxy fallbacks |
|
|
|
|
Use these inputs to move the SDK/engine jobs onto different larger or
|
|
self-hosted runners without editing the workflow file. The Linux heavy jobs also run
|
|
`scripts/free_ci_disk_linux.sh`, which removes unrelated preinstalled toolchain
|
|
caches only when `GITHUB_ACTIONS=true` and `RUNNER_ENVIRONMENT=github-hosted`.
|
|
Self-hosted runners skip that cleanup by default. Set `CI_FREE_DISK_SPACE=0` to
|
|
skip cleanup anywhere, or `CI_FREE_DISK_SPACE_FORCE=1` to opt in on a
|
|
self-hosted runner.
|
|
When `base_flutter_engine_revision` is empty, `mirror-metadata` records the
|
|
same revision as `flutter/bin/internal/engine.version`. Set it when the open
|
|
Shorebird engine revision is a custom fork revision and unchanged artifacts
|
|
should be proxied back to a different upstream Flutter engine revision.
|
|
|
|
The engine jobs perform two syncs when `run_gclient_sync=true`: the root
|
|
workspace sync for the Dart SDK checkout, then a second sync from `flutter/` for
|
|
Flutter engine dependencies written by `scripts/write_gclient.sh`. Linux engine
|
|
jobs use `INCLUDE_ENGINE_DEPS=1` to include Flutter engine dependencies,
|
|
Android dependencies, and emsdk; the Apple engine job uses the same flag to
|
|
include iOS, Android, and emsdk
|
|
dependencies on macOS.
|
|
Before building, `scripts/sync_open_sources.sh` links
|
|
`flutter/engine/src/flutter/third_party/dart` to the `dart-sdk` submodule
|
|
and `flutter/engine/src/flutter/third_party/updater` to the `updater`
|
|
submodule. It does not clone the official `shorebirdtech/updater` repository by
|
|
default; set `UPDATER_URL` explicitly only when testing a different updater
|
|
fork. The helper rejects known unpatched upstream Dart SDK remotes and official
|
|
Shorebird updater remotes so CI does not accidentally build from the wrong
|
|
component checkout.
|
|
The Flutter fork's `DEPS` file also points its Dart SDK and updater dependency
|
|
URLs at the open mirrors and does not reference Shorebird's private
|
|
`shorebird-dart-sdk-prebuilt` bucket; custom SDK jobs build and archive the
|
|
open Dart SDK fork directly.
|
|
|
|
`custom-dart-sdk` and `custom-dart-sdk-macos` build the Dart SDK fork with:
|
|
|
|
```gn
|
|
dart_dynamic_modules = false
|
|
dart_enable_aot_patching = true
|
|
dart_enable_shorebird_interpreter = true
|
|
```
|
|
|
|
They run `scripts/verify_dart_sdk_args.sh`, then the focused VM patch API
|
|
tests. The Linux job uploads `custom-dart-sdk-linux-x64`; the macOS job uploads
|
|
`custom-dart-sdk-macos-arm64`. Each archive contains the Dart SDK,
|
|
`gen_snapshot`, `dartaotruntime`, `args.gn`, and a `manifest.json` that records
|
|
the root workflow commit, Dart SDK source commit, and patch-related build
|
|
flags. The workflow also uploads `.sha256` sidecars for the SDK archives.
|
|
Before writing the checksum, each SDK job extracts the archive, verifies
|
|
`manifest.json`, `args.gn`, `gen_snapshot`, `dartaotruntime`, and
|
|
`dart-sdk/bin/dart`, then runs the extracted `dart --version`.
|
|
|
|
`ios-engine` builds:
|
|
|
|
- `host_release_arm64` with `--shorebird-interpreter`,
|
|
`dart_dynamic_modules=false`, `dart_enable_aot_patching=true`, and
|
|
`dart_enable_shorebird_interpreter=true`
|
|
- `ios_release` with `--shorebird-interpreter`
|
|
- `macos_release_arm64` with `dart_dynamic_modules=false`,
|
|
`dart_enable_aot_patching=true`, `shorebird_enable_aot_patching=true`, and
|
|
`shorebird_use_interpreter=false`
|
|
|
|
It runs `scripts/verify_ios_interpreter_route.sh` before uploading the
|
|
`ios-interpreter-engine` artifact, so the archived build proves
|
|
`DART_DYNAMIC_MODULES` is off and the iOS route uses the bytecode interpreter
|
|
instead of native AOT patch loading. The archive includes `Flutter.framework`,
|
|
`Flutter.xcframework`, a mirror-ready `ios-release/artifacts.zip` containing
|
|
the xcframework plus `gen_snapshot_arm64`, `analyze_snapshot_arm64`, and the
|
|
code-sign configuration files Flutter expects, the
|
|
`host_release_arm64/gen_snapshot` binary built with `--shorebird-interpreter`,
|
|
the iOS and host `args.gn` files, and a `manifest.json` that records
|
|
`dart_dynamic_modules=false`,
|
|
`dart_enable_aot_patching=true`, `dart_enable_shorebird_interpreter=true`,
|
|
`shorebird_enable_aot_patching=false`, `shorebird_use_interpreter=true`, and
|
|
the Flutter engine revision; the workflow also uploads a `.sha256` sidecar for
|
|
the engine archive.
|
|
Before checksum upload, CI extracts the iOS engine archive and verifies
|
|
`Flutter.framework`, `Flutter.xcframework`, `ios-release/artifacts.zip`, the
|
|
mirror copy under `mirror/shorebird/flutter_infra_release/flutter/<engine>`,
|
|
both args files, `manifest.json`, and the executable host `gen_snapshot`.
|
|
When an app or IPA is supplied to the gate, strict mode also rejects bundled
|
|
patch payloads, executable-memory entitlements, and raw `aot_patch_key_hex`
|
|
material in `shorebird.yaml`.
|
|
|
|
The same Apple job uploads a separate `macos-engine-arm64` artifact containing
|
|
`FlutterMacOS.framework.zip`, `flutter_patched_sdk_product.zip`, the macOS
|
|
`args.gn`, a mirror-ready copy of the macOS framework override, a manifest with
|
|
the Flutter engine revision, and a `.sha256` sidecar. The shared
|
|
`flutter_patched_sdk_product.zip` mirror override is published only by the Linux
|
|
engine job to avoid duplicate producers for the same mirror path. The macOS
|
|
build is checked with
|
|
`scripts/verify_engine_args.sh` so CI fails if `dart_dynamic_modules=true`
|
|
appears or if the native AOT patch runtime flags are missing from the generated
|
|
args. CI extracts the macOS engine archive before upload and verifies the
|
|
framework zip, patched SDK zip, args file, manifest, and framework mirror
|
|
subtree.
|
|
|
|
`linux-engine` builds `linux_release_x64` on Ubuntu with
|
|
`dart_dynamic_modules=false`, `dart_enable_aot_patching=true`,
|
|
`shorebird_enable_aot_patching=true`, and `shorebird_use_interpreter=false`. It
|
|
uploads `linux-x64-flutter-gtk.zip`, `flutter_patched_sdk_product.zip`,
|
|
`artifacts.zip`, mirror-ready copies of those engine override files, `args.gn`,
|
|
a manifest with the Flutter engine revision, and a `.sha256` sidecar. CI
|
|
extracts the archive before upload and verifies the GTK zip, patched SDK zip,
|
|
artifacts zip, args file, manifest, and mirror subtree.
|
|
|
|
`android-engine` builds `android_release_arm64` on Ubuntu with
|
|
`dart_dynamic_modules=false`, `dart_enable_aot_patching=true`,
|
|
`shorebird_enable_aot_patching=true`, and `shorebird_use_interpreter=false`. It
|
|
uploads `artifacts.zip`, `symbols.zip`, `flutter.jar`, `libflutter.so`, host
|
|
`gen_snapshot_arm64`, `analyze_snapshot_arm64`, mirror-ready copies of the
|
|
Android engine override files, `args.gn`, a manifest with the Flutter engine
|
|
revision, and a `.sha256` sidecar. CI extracts the archive before upload and
|
|
verifies the Android artifacts/symbols zips, `flutter.jar`, `libflutter.so`,
|
|
host snapshot/analyzer tools, args file, manifest, and mirror subtree.
|
|
|
|
`web-sdk` builds the Flutter web SDK archive from `wasm_release` with
|
|
`dart_dynamic_modules=false` and uploads `flutter-web-sdk.zip`, a mirror-ready
|
|
copy of that SDK archive, `args.gn`, a manifest with the Flutter engine
|
|
revision, and a `.sha256` sidecar. Web is still not a Shorebird CodePush release
|
|
platform in this CLI/protocol; this job exists to keep the open Flutter SDK/web
|
|
artifacts buildable from the workspace. CI extracts the web SDK archive before
|
|
upload and verifies the SDK zip, args file, manifest, and mirror subtree.
|
|
|
|
Set `run_gclient_sync=false` only for debugging a runner image that already has
|
|
all gclient-managed dependencies restored.
|