name: Setup Node environment
description: >
  Install Node 24 by default, pnpm, optionally Bun, and optionally run pnpm
  install. Requires actions/checkout to run first.
inputs:
  node-version:
    description: Node.js version to install.
    required: false
    default: "24.x"
  install-bun:
    description: Whether to install Bun alongside Node.
    required: false
    default: "true"
  install-deps:
    description: Whether to run pnpm install after environment setup.
    required: false
    default: "true"
  frozen-lockfile:
    description: Whether to use --frozen-lockfile for install.
    required: false
    default: "true"
  use-actions-cache:
    description: Whether to restore the pnpm store with actions/cache.
    required: false
    default: "true"
  save-actions-cache:
    description: Whether to save the pnpm store with actions/cache after install when no exact cache restored.
    required: false
    default: "false"
runs:
  using: composite
  steps:
    - name: Normalize container toolcache
      shell: bash
      run: |
        set -euo pipefail
        if [[ -d /__t && ! -e /opt/hostedtoolcache ]]; then
          mkdir -p /opt
          ln -s /__t /opt/hostedtoolcache
        fi

    - name: Setup Node.js
      shell: bash
      env:
        REQUESTED_NODE_VERSION: ${{ inputs.node-version }}
      run: |
        set -euo pipefail
        source "$GITHUB_ACTION_PATH/../setup-pnpm-store-cache/ensure-node.sh"
        openclaw_ensure_node "$REQUESTED_NODE_VERSION"

    - name: Setup pnpm
      id: setup-pnpm
      uses: ./.github/actions/setup-pnpm-store-cache
      with:
        node-version: ${{ inputs.node-version }}
        use-actions-cache: ${{ inputs.use-actions-cache }}

    - name: Setup Bun
      if: inputs.install-bun == 'true'
      shell: bash
      run: |
        set -euo pipefail
        npm install -g bun@1.3.14

    - name: Runtime versions
      shell: bash
      run: |
        node -v
        npm -v
        pnpm -v
        if command -v bun &>/dev/null; then bun -v; fi

    - name: Capture node path
      shell: bash
      run: |
        node_bin="$(dirname "$(node -p 'process.execPath')")"
        if command -v cygpath >/dev/null 2>&1; then
          node_bin="$(cygpath -u "$node_bin")"
        fi
        # zizmor: ignore[github-env] node_bin comes from trusted actions/setup-node output in this composite action.
        echo "NODE_BIN=$node_bin" >> "$GITHUB_ENV"
        echo "$node_bin" >> "$GITHUB_PATH"

    - name: Install dependencies
      if: inputs.install-deps == 'true'
      shell: bash
      env:
        CI: "true"
        FROZEN_LOCKFILE: ${{ inputs.frozen-lockfile }}
      run: |
        set -euo pipefail
        export PATH="$NODE_BIN:$PATH"
        which node
        node -v
        pnpm -v
        case "$FROZEN_LOCKFILE" in
          true) LOCKFILE_FLAG="--frozen-lockfile" ;;
          false) LOCKFILE_FLAG="" ;;
          *)
            echo "::error::Invalid frozen-lockfile input: '$FROZEN_LOCKFILE' (expected true or false)"
            exit 2
            ;;
        esac

        install_args=(
          install
          --prefer-offline
          --ignore-scripts=false
          --config.engine-strict=false
          --config.enable-pre-post-scripts=true
          --config.side-effects-cache=true
        )
        if [ -n "$LOCKFILE_FLAG" ]; then
          install_args+=("$LOCKFILE_FLAG")
        fi
        append_pnpm_option_arg() {
          local env_name="$1"
          local option_name="$2"
          local value="${!env_name-}"
          if [ -n "$value" ]; then
            install_args+=("--${option_name}=${value}")
          fi
        }
        append_pnpm_option_arg PNPM_CONFIG_CHILD_CONCURRENCY child-concurrency
        append_pnpm_option_arg PNPM_CONFIG_MODULES_DIR modules-dir
        append_pnpm_option_arg PNPM_CONFIG_NETWORK_CONCURRENCY network-concurrency
        append_pnpm_option_arg PNPM_CONFIG_VIRTUAL_STORE_DIR virtual-store-dir
        if [ -n "${PNPM_CONFIG_MODULES_DIR:-}" ]; then
          mkdir -p "$PNPM_CONFIG_MODULES_DIR"
          ln -sfn . "$PNPM_CONFIG_MODULES_DIR/node_modules"
        fi
        pnpm "${install_args[@]}" || pnpm "${install_args[@]}"
        if [ -n "${PNPM_CONFIG_MODULES_DIR:-}" ]; then
          rm -rf node_modules
          ln -sfn "$PNPM_CONFIG_MODULES_DIR" node_modules
          ln -sfn . "$PNPM_CONFIG_MODULES_DIR/node_modules"
        fi

    - name: Save pnpm store cache
      if: ${{ inputs.install-deps == 'true' && inputs.use-actions-cache == 'true' && inputs.save-actions-cache == 'true' && runner.os != 'Windows' && steps.setup-pnpm.outputs.store-cache-hit != 'true' }}
      uses: actions/cache/save@v5
      with:
        path: ${{ steps.setup-pnpm.outputs.store-path }}
        key: ${{ steps.setup-pnpm.outputs.store-cache-primary-key }}
