diff --git a/docs/flutter-upgrade.md b/docs/flutter-upgrade.md index 2dd7bea..c2038d7 100644 --- a/docs/flutter-upgrade.md +++ b/docs/flutter-upgrade.md @@ -47,7 +47,7 @@ version and leaves it absent. Execute in Bash, ```bash -find ~/.vfox/cache/flutter/v-3.47.0 -name .vfox-manifest -print -delete +rm "$(vfox info --format '{{.Path}}' flutter@3.47.0)/.vfox-manifest" ``` ### Windows 11 @@ -55,6 +55,5 @@ find ~/.vfox/cache/flutter/v-3.47.0 -name .vfox-manifest -print -delete Assume that PowerShell 7 is already installed. Execute in PowerShell 7, ```powershell -Get-ChildItem "$env:USERPROFILE\.vfox\cache\flutter\v-3.47.0" -Recurse -Force -Filter .vfox-manifest | - Remove-Item +Remove-Item "$(vfox info --format '{{.Path}}' flutter@3.47.0)/.vfox-manifest" ``` diff --git a/metadata.lua b/metadata.lua index bb11cca..5a6a01e 100644 --- a/metadata.lua +++ b/metadata.lua @@ -24,5 +24,5 @@ NOTE: PLUGIN.minRuntimeVersion = "0.3.0" -- Some things that need user to be attention! PLUGIN.notes = { - "Do NOT run `flutter upgrade` (or `flutter downgrade`, `flutter channel`, or any in-place git operation) inside a vfox-managed Flutter SDK. It mutates the SDK in place and vfox will silently hand you the wrong version on the next `vfox use`. Change versions with `vfox install flutter@` and `vfox use flutter@`. This plugin detects such drift and prints a warning with the restore commands on the next `vfox use`.", + "See https://github.com/version-fox/vfox-flutter/blob/main/README.md for documentation.", } diff --git a/tests/e2e/linux/Dockerfile b/tests/e2e/linux/Dockerfile index df39f76..569f50d 100644 --- a/tests/e2e/linux/Dockerfile +++ b/tests/e2e/linux/Dockerfile @@ -3,14 +3,13 @@ FROM ubuntu:26.04 ENV DEBIAN_FRONTEND=noninteractive RUN </dev/null || exit 0 +fi +VFOX_E2E_CONFIG_SH=1 + +DEFAULT_OFFICIAL_VERSION="3.47.4" +DEFAULT_OHOS_VERSION="3.41.10-ohos-1.0.0" +DEFAULT_MIRROR_CN="https://storage.flutter-io.cn" + +# resolve_flutter_version honours $FLUTTER_VERSION / $OHOS_VERSION. +resolve_flutter_version() { + local flavor="$1" + local version="" + case "$flavor" in + official) version="${FLUTTER_VERSION:-$DEFAULT_OFFICIAL_VERSION}" ;; + ohos) version="${OHOS_VERSION:-$DEFAULT_OHOS_VERSION}" ;; + *) + echo "FAIL unknown flavor $flavor" >&2 + return 1 + ;; + esac + printf '%s' "$version" +} + +# default_flavours : ohos has no arm64 artefacts, so arm64 runs +# official only (same rule as the Windows matrix). +default_flavours() { + if [[ "$1" == "arm64" ]]; then + echo "official" + else + echo "official ohos" + fi +} + +default_mirrors() { + if [[ "$1" == "arm64" ]]; then + echo "default" + else + echo "default $DEFAULT_MIRROR_CN" + fi +} + +# releases_index_for_mirror +releases_index_for_mirror() { + printf '%s/flutter_infra_release/releases/releases_%s.json' "${1%/}" "$2" +} diff --git a/tests/e2e/linux/e2e.sh b/tests/e2e/linux/e2e.sh index eae451c..48febb5 100755 --- a/tests/e2e/linux/e2e.sh +++ b/tests/e2e/linux/e2e.sh @@ -1,66 +1,70 @@ #!/usr/bin/env bash -set -euo pipefail +# Host-side matrix runner: build the image once, then fan out one container +# per (vfox version x flavor x mirror) combination, at most $max_jobs at a +# time. Logs are prefixed so parallel runs stay readable. +set -o errexit -o nounset -o pipefail -here="$(dirname "${BASH_SOURCE[0]}")" -repo="$(cd "$here/../../.." && pwd)" - -host_arch="$(uname -m)" -case "$host_arch" in - x86_64) host_arch="amd64" ;; - aarch64|arm64) host_arch="arm64" ;; -esac -arch="${ARCH:-$host_arch}" -platform="linux/$arch" -image="vfox-flutter-e2e:linux-$arch" - -docker build --pull --platform "$platform" -f "$here/Dockerfile" -t "$image" "$repo" - -foxes="${VFOX_VERSION:-latest main}" -default_flavours="official ohos" -default_mirrors="default https://storage.flutter-io.cn" -if [ "$arch" = arm64 ]; then - default_flavours="official" - default_mirrors="default" -fi -flavours="${FLAVOR:-$default_flavours}" -mirrors="${MIRROR:-$default_mirrors}" -mirror_explicit="${MIRROR:-}" - -max_jobs=3 -failed=0 +here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=lib.sh +source "$here/lib.sh" +# shellcheck source=config.sh +source "$here/config.sh" run_one() { - local vfox="$1" - local flavor="$2" - local mirror="$3" + local image="$1" + local platform="$2" + local vfox="$3" + local flavor="$4" + local mirror="$5" local prefix="vfox $vfox, $flavor, mirror $mirror, $platform" - local env=("-e" "VFOX_VERSION=$vfox" "-e" "FLAVOR=$flavor") - if [ "$mirror" != default ]; then - env+=("-e" "FLUTTER_STORAGE_BASE_URL=$mirror") + local env=(--env "VFOX_VERSION=$vfox" --env "FLAVOR=$flavor") + if [[ "$mirror" != "default" ]]; then + env+=(--env "FLUTTER_STORAGE_BASE_URL=$mirror") fi - docker run --rm --platform "$platform" "${env[@]}" "$image" 2>&1 | sed -e "s|^|[$prefix] |" + docker run --rm --platform "$platform" "${env[@]}" "$image" 2>&1 | sed --expression "s|^|[$prefix] |" } -for vfox in $foxes; do - for flavor in $flavours; do - for mirror in $mirrors; do - if [ -z "$mirror_explicit" ] && [ "$mirror" != default ] && [ "$vfox" != latest ]; then - continue - fi - run_one "$vfox" "$flavor" "$mirror" & - while [ "$(jobs -p | wc -l)" -ge "$max_jobs" ]; do - if ! wait -n; then - failed=1 +main() { + local repo arch platform image + repo="$(cd "$here/../../.." && pwd)" + arch="$(normalize_arch "${ARCH:-$(uname --machine)}")" + platform="linux/$arch" + image="vfox-flutter-e2e:linux-$arch" + + docker build --pull --platform "$platform" --file "$here/Dockerfile" --tag "$image" "$repo" + + # Space-separated env lists (e.g. FLAVOR="official ohos") are split + # into arrays up front, so the loops below need no word splitting. + # (read is a bash builtin with no long-option form for -r/-a.) + local -a foxes flavours mirrors + read -ra foxes <<< "${VFOX_VERSION:-latest main}" + read -ra flavours <<< "${FLAVOR:-$(default_flavours "$arch")}" + read -ra mirrors <<< "${MIRROR:-$(default_mirrors "$arch")}" + local mirror_explicit="${MIRROR:-}" + local max_jobs="${E2E_MAX_JOBS:-3}" + local failed=0 + + for vfox in "${foxes[@]}"; do + for flavor in "${flavours[@]}"; do + for mirror in "${mirrors[@]}"; do + # The mirror matrix only runs against latest vfox unless the + # caller explicitly pins MIRROR, to keep CI time bounded. + if [[ -z "$mirror_explicit" && "$mirror" != "default" && "$vfox" != "latest" ]]; then + continue fi + run_one "$image" "$platform" "$vfox" "$flavor" "$mirror" & + while [[ "$(jobs -p | wc --lines)" -ge "$max_jobs" ]]; do + wait -n || failed=1 + done done done done -done -while [ "$(jobs -p | wc -l)" -gt 0 ]; do - if ! wait -n; then - failed=1 - fi -done + while [[ "$(jobs -p | wc --lines)" -gt 0 ]]; do + wait -n || failed=1 + done + + return "$failed" +} -exit "$failed" +main "$@" diff --git a/tests/e2e/linux/install.sh b/tests/e2e/linux/install.sh index 854df0c..0e3d5dd 100755 --- a/tests/e2e/linux/install.sh +++ b/tests/e2e/linux/install.sh @@ -1,28 +1,23 @@ #!/usr/bin/env bash -set -eu +# Install and activate one Flutter version: `bash install.sh `. +# Runs standalone (called as a subprocess by run.sh, like install.ps1). +set -o errexit -o nounset -o pipefail -version="${1:?missing version}" +here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=lib.sh +source "$here/lib.sh" -eval "$(vfox activate bash)" - -install_code=1 -for attempt in 1 2 3; do - if vfox install flutter@"$version"; then - install_code=0 - break - else - install_code=$? - fi - if [ "$attempt" -lt 3 ]; then - echo "retrying vfox install flutter@${version}, attempt ${attempt} exited ${install_code}" - sleep $((10 * attempt)) +install_flutter_version() { + local version="$1" + activate_vfox + if ! retry "vfox install flutter@${version}" vfox install flutter@"$version"; then + die "vfox install flutter@${version} failed after ${E2E_RETRY_ATTEMPTS:-3} attempts" fi -done + vfox use --global flutter@"$version" + activate_vfox +} -if [ "$install_code" -ne 0 ]; then - echo "FAIL vfox install flutter@${version} exited with code ${install_code}" >&2 - exit 1 +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + version="${1:?usage: install.sh }" + install_flutter_version "$version" fi - -vfox use --global flutter@"$version" -eval "$(vfox activate bash)" diff --git a/tests/e2e/linux/lib.sh b/tests/e2e/linux/lib.sh new file mode 100644 index 0000000..c9a60cc --- /dev/null +++ b/tests/e2e/linux/lib.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# Shared helpers for the Linux container E2E suite. Sourced, not executed: +# source "$here/lib.sh" +# +# Layout (mirrors tests/e2e/windows): +# lib.sh - generic helpers (this file; no side effects when sourced) +# config.sh - default versions / flavours / mirrors +# setup.sh - install vfox and register the local flutter plugin +# install.sh - install one Flutter version with retries +# verify.sh - assert on the installed SDK (layout, drift, toolchain) +# run.sh - thin in-container orchestrator: setup -> install -> verify +# e2e.sh - host-side matrix runner (builds the image, fans out containers) + +if [[ -n "${VFOX_E2E_LIB_SH:-}" ]]; then + return 0 2>/dev/null || exit 0 +fi +VFOX_E2E_LIB_SH=1 + +die() { + echo "FAIL $*" >&2 + exit 1 +} + +pass() { + echo "PASS $*" +} + +# assert_contains