name: Set up proxied Flutter
description: Set up Flutter with protected provider transport and isolated official GitHub caches
inputs:
  channel:
    description: The Flutter build release channel
    required: false
    default: stable
  flutter-version:
    description: The Flutter version to make available on the path
    required: false
    default: ''
  flutter-version-file:
    description: The pubspec.yaml or FVM config file with exact Flutter version defined
    required: false
    default: ''
  architecture:
    description: The architecture of Flutter SDK executable (x64 or arm64)
    required: false
    default: ${{ runner.arch }}
  cache:
    description: Cache the Flutter SDK
    required: false
    default: 'false'
  cache-key:
    description: Identifier for the Flutter SDK cache
    required: false
    default: ''
  cache-path:
    description: Flutter SDK cache path
    required: false
    default: ''
  pub-cache:
    description: Cache the Dart pub dependencies
    required: false
    default: ''
  pub-cache-key:
    description: Identifier for the Dart .pub-cache cache
    required: false
    default: ''
  pub-cache-path:
    description: Flutter pub cache path
    required: false
    default: default
  dry-run:
    description: If true, get outputs but do not install Flutter
    required: false
    default: 'false'
  git-source:
    description: Git clone source
    required: false
    default: https://github.com/flutter/flutter.git
  archive-budget-seconds:
    description: >-
      Seconds the proxied SDK archive transfer may take. Raise it in a release
      job, whose own timeout is far longer than a validation job's; the helper
      clamps it and the partial archive is cached either way.
    required: false
    default: ''
outputs:
  CHANNEL:
    value: ${{ steps.flutter-action.outputs.CHANNEL }}
    description: The selected Flutter release channel
  VERSION:
    value: ${{ steps.flutter-action.outputs.VERSION }}
    description: The selected Flutter version
  ARCHITECTURE:
    value: ${{ steps.flutter-action.outputs.ARCHITECTURE }}
    description: The selected Flutter CPU architecture
  CACHE-KEY:
    value: ${{ steps.flutter-action.outputs.CACHE-KEY }}
    description: Key used to cache the Flutter SDK
  CACHE-PATH:
    value: ${{ steps.flutter-action.outputs.CACHE-PATH }}
    description: Path to Flutter SDK
  PUB-CACHE-KEY:
    value: ${{ steps.flutter-action.outputs.PUB-CACHE-KEY }}
    description: Key used to cache the pub dependencies
  PUB-CACHE-PATH:
    value: ${{ steps.flutter-action.outputs.PUB-CACHE-PATH }}
    description: Path to pub cache
  GIT_SOURCE:
    value: ${{ steps.flutter-action.outputs.GIT_SOURCE }}
    description: Git source of Flutter SDK repository to clone
  CACHE-HIT:
    value: ${{ steps.cache-flutter.outputs.cache-hit }}
    description: '`true` if the flutter cache was a hit'
  PUB-CACHE-HIT:
    value: ${{ steps.cache-pub.outputs.cache-hit }}
    description: '`true` if the pub cache was a hit'
runs:
  using: composite
  steps:
  - name: Publish the manifest recovery helpers
    id: transport
    shell: bash
    run: |
      printf 'manifest_env=%s\nmanifest_helper=%s\n' \
        "$GITHUB_ACTION_PATH/../scripts/flutter_manifest_env.sh" \
        "$GITHUB_ACTION_PATH/../scripts/flutter_manifest.py" >> "$GITHUB_OUTPUT"
  - name: Retain the cache process scope
    id: scope
    if: ${{ inputs.cache == 'true' || inputs.pub-cache == 'true' }}
    continue-on-error: true
    shell: bash
    run: node "$GITHUB_ACTION_PATH/../scripts/cache_scope.cjs" --snapshot
  - name: Identify an exact Flutter release metadata cache
    id: release-metadata
    if: ${{ inputs.cache == 'true' && steps.scope.outcome == 'success' }}
    continue-on-error: true
    shell: bash
    env:
      GOWALK_FLUTTER_VERSION: ${{ inputs.flutter-version }}
      GOWALK_FLUTTER_VERSION_FILE: ${{ inputs.flutter-version-file }}
      GOWALK_FLUTTER_CHANNEL: ${{ inputs.channel }}
      GOWALK_FLUTTER_ARCHITECTURE: ${{ inputs.architecture }}
    run: python3 "$GITHUB_ACTION_PATH/../scripts/flutter_release_cache.py"
  - name: Restore exact Flutter release metadata
    id: cache-release
    if: ${{ steps.release-metadata.outputs.enabled == 'true' }}
    uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25
    continue-on-error: true
    env:
      NODE_OPTIONS: --require "${{ steps.scope.outputs.preloader }}"
      SEGMENT_DOWNLOAD_TIMEOUT_MINS: '1'
    with:
      path: ${{ steps.release-metadata.outputs.path }}
      key: ${{ steps.release-metadata.outputs.key }}
  - name: Resolve Flutter release and cache identities
    id: flutter-action
    uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2
    env:
      BASH_ENV: ${{ steps.transport.outputs.manifest_env }}
      GOWALK_FLUTTER_MANIFEST_HELPER: ${{ steps.transport.outputs.manifest_helper }}
      GOWALK_FLUTTER_RELEASE_CACHE: ${{ steps.release-metadata.outputs.path }}
      GOWALK_FLUTTER_RELEASE_PIN: ${{ steps.release-metadata.outputs.pin }}
    with:
      channel: ${{ inputs.channel }}
      flutter-version: ${{ inputs.flutter-version }}
      flutter-version-file: ${{ inputs.flutter-version-file }}
      architecture: ${{ inputs.architecture }}
      cache: 'false'
      cache-key: ${{ inputs.cache-key }}
      cache-path: ${{ inputs.cache-path }}
      pub-cache: 'false'
      pub-cache-key: ${{ inputs.pub-cache-key }}
      pub-cache-path: ${{ inputs.pub-cache-path }}
      dry-run: 'true'
      git-source: ${{ inputs.git-source }}
  - name: Save resolved Flutter release metadata
    if: >-
      ${{ steps.release-metadata.outputs.enabled == 'true' && steps.flutter-action.outcome == 'success'
          && steps.cache-release.outputs.cache-hit != 'true' }}
    uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25
    continue-on-error: true
    env:
      NODE_OPTIONS: --require "${{ steps.scope.outputs.preloader }}"
    with:
      path: ${{ steps.release-metadata.outputs.path }}
      key: ${{ steps.release-metadata.outputs.key }}
  - name: Cache Flutter
    id: cache-flutter
    if: ${{ inputs.cache == 'true' }}
    uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25
    continue-on-error: true
    env:
      NODE_OPTIONS: --require "${{ steps.scope.outputs.preloader }}"
      SEGMENT_DOWNLOAD_TIMEOUT_MINS: '1'
    with:
      path: ${{ steps.flutter-action.outputs.CACHE-PATH }}
      key: ${{ steps.flutter-action.outputs.CACHE-KEY }}
  - name: Cache pub dependencies
    id: cache-pub
    if: ${{ (inputs.pub-cache == '' && inputs.cache == 'true') || inputs.pub-cache == 'true' }}
    uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25
    continue-on-error: true
    env:
      NODE_OPTIONS: --require "${{ steps.scope.outputs.preloader }}"
      SEGMENT_DOWNLOAD_TIMEOUT_MINS: '1'
    with:
      path: ${{ steps.flutter-action.outputs.PUB-CACHE-PATH }}
      key: ${{ steps.flutter-action.outputs.PUB-CACHE-KEY }}-${{ hashFiles('**/pubspec.lock') }}
  - name: Restore interrupted Flutter archive
    if: ${{ inputs.cache == 'true' && inputs.dry-run != 'true' && steps.cache-flutter.outputs.cache-hit != 'true' }}
    uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25
    continue-on-error: true
    env:
      NODE_OPTIONS: --require "${{ steps.scope.outputs.preloader }}"
      SEGMENT_DOWNLOAD_TIMEOUT_MINS: '1'
    with:
      path: ${{ runner.temp }}/gowalk-flutter-archives
      key: >-
        flutter-archive-v1-${{ steps.flutter-action.outputs.CACHE-KEY }}-${{ github.run_id }}-${{ github.run_attempt }}
      restore-keys: flutter-archive-v1-${{ steps.flutter-action.outputs.CACHE-KEY }}-
  - name: Install or reuse the resolved Flutter SDK
    id: install
    if: ${{ inputs.dry-run != 'true' }}
    uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2
    env:
      BASH_ENV: ${{ steps.transport.outputs.manifest_env }}
      GOWALK_FLUTTER_MANIFEST_HELPER: ${{ steps.transport.outputs.manifest_helper }}
      GOWALK_FLUTTER_ARCHIVE_CACHE: >-
        ${{ inputs.cache == 'true' && format('{0}/gowalk-flutter-archives', runner.temp) || '' }}
      GOWALK_FLUTTER_RELEASE_CACHE: ${{ steps.release-metadata.outputs.path }}
      GOWALK_FLUTTER_RELEASE_PIN: ${{ steps.release-metadata.outputs.pin }}
      GOWALK_FLUTTER_ARCHIVE_BUDGET_S: ${{ inputs.archive-budget-seconds }}
    with:
      channel: ${{ steps.flutter-action.outputs.CHANNEL }}
      flutter-version: ${{ steps.flutter-action.outputs.VERSION }}
      flutter-version-file: ''
      architecture: ${{ steps.flutter-action.outputs.ARCHITECTURE }}
      cache: 'false'
      cache-key: ${{ inputs.cache-key }}
      cache-path: ${{ steps.flutter-action.outputs.CACHE-PATH }}
      pub-cache: 'false'
      pub-cache-key: ${{ inputs.pub-cache-key }}
      pub-cache-path: ${{ steps.flutter-action.outputs.PUB-CACHE-PATH }}
      dry-run: 'false'
      git-source: ${{ inputs.git-source }}
  - name: Preserve interrupted Flutter archive
    if: >-
      ${{ !cancelled() && inputs.cache == 'true' && steps.install.outcome == 'failure'
          && steps.scope.outcome == 'success' }}
    uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25
    continue-on-error: true
    env:
      NODE_OPTIONS: --require "${{ steps.scope.outputs.preloader }}"
    with:
      path: ${{ runner.temp }}/gowalk-flutter-archives
      key: >-
        flutter-archive-v1-${{ steps.flutter-action.outputs.CACHE-KEY }}-${{ github.run_id }}-${{ github.run_attempt }}
  # A later app failure must not discard a successfully installed, expensive SDK.
  - name: Save installed Flutter SDK
    if: >-
      ${{ inputs.cache == 'true' && inputs.dry-run != 'true'
          && steps.install.outcome == 'success' && steps.scope.outcome == 'success'
          && steps.cache-flutter.outputs.cache-hit != 'true' }}
    uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25
    continue-on-error: true
    env:
      NODE_OPTIONS: --require "${{ steps.scope.outputs.preloader }}"
    with:
      path: ${{ steps.flutter-action.outputs.CACHE-PATH }}
      key: ${{ steps.flutter-action.outputs.CACHE-KEY }}
