nu 0.112.2

A new type of shell
on:
  pull_request:
  push:
    branches:
      - main
      - 'patch-release-*'

name: continuous-integration

env:
  NU_LOG_LEVEL: DEBUG
  CLIPPY_OPTIONS: "-D warnings"
  NUSHELL_CARGO_PROFILE: ci
  MAIN_OPTIONS: --workspace --exclude nu_plugin_* --all-targets
  PLUGIN_OPTIONS: --package nu_plugin_* --all-targets
  WASM_OPTIONS: >

    --no-default-features
    --target wasm32-unknown-unknown
    -p nu-cmd-base
    -p nu-cmd-extra
    -p nu-cmd-lang
    -p nu-color-config
    -p nu-command
    -p nu-derive-value
    -p nu-engine
    -p nu-glob
    -p nu-json
    -p nu-parser
    -p nu-path
    -p nu-pretty-hex
    -p nu-protocol
    -p nu-std
    -p nu-system
    -p nu-table
    -p nu-term-grid
    -p nu-utils
    -p nuon

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}
  cancel-in-progress: true

jobs:
  cargo:
    name: "`cargo` in ${{ matrix.workspace.name }} (${{ matrix.target.name }})"
    strategy:
      fail-fast: true
      matrix:
        target:
          # Pinning to Ubuntu 22.04 because building on newer Ubuntu versions causes linux-gnu
          # builds to link against a too-new-for-many-Linux-installs glibc version. Consider
          # revisiting this when 22.04 is closer to EOL (June 2027)
          - name: Ubuntu
            host: ubuntu-22.04
            target: x86_64-unknown-linux-gnu
            options: $MAIN_OPTIONS
            steps: [fmt, clippy, build, test]
          - name: Windows
            host: windows-latest
            target: x86_64-pc-windows-msvc
            options: $MAIN_OPTIONS
            steps: [fmt, clippy, build, test]
          - name: MacOS
            host: macos-latest
            target: x86_64-apple-darwin
            options: $MAIN_OPTIONS
            steps: [fmt, clippy, build, test]
          - name: Ubuntu Plugins
            host: ubuntu-22.04
            target: x86_64-unknown-linux-gnu
            options: $PLUGIN_OPTIONS
            steps: [clippy, build, test]
          - name: Windows Plugins
            host: windows-latest
            target: x86_64-pc-windows-msvc
            options: $PLUGIN_OPTIONS
            steps: [clippy, build, test]
          - name: MacOS Plugins
            host: macos-latest
            target: x86_64-apple-darwin
            options: $PLUGIN_OPTIONS
            steps: [clippy, build, test]
          - name: WASM
            host: ubuntu-22.04
            target: wasm32-unknown-unknown
            options: $WASM_OPTIONS
            steps: [build, check]

        workspace:
          - name: root
            path: ./
            profile: ci
            skip: []
          - name: nu-parser/fuzz
            path: ./crates/nu-parser/fuzz
            profile: dev
            skip: [build, test]
          - name: nu-path/fuzz
            path: ./crates/nu-path/fuzz
            profile: dev
            skip: [build, test]

        exclude:
          - target: { name: WASM }
            workspace: { name: nu-parser/fuzz }
          - target: { name: WASM }
            workspace: { name: nu-path/fuzz }
          - target: { name: Ubuntu Plugins }
            workspace: { name: nu-parser/fuzz }
          - target: { name: Ubuntu Plugins }
            workspace: { name: nu-path/fuzz }
          - target: { name: Windows Plugins }
            workspace: { name: nu-parser/fuzz }
          - target: { name: Windows Plugins }
            workspace: { name: nu-path/fuzz }
          - target: { name: MacOS Plugins }
            workspace: { name: nu-parser/fuzz }
          - target: { name: MacOS Plugins }
            workspace: { name: nu-path/fuzz }
    
    runs-on: ${{ matrix.target.host }}

    steps:
      - name: Checkout Repo
        uses: actions/checkout@v6

      - name: Setup Rust Toolchain
        run: rustup target add ${{ matrix.target.target }}
        working-directory: ${{ matrix.workspace.path }}

      - name: Cache Rust
        uses: Swatinem/rust-cache@v2
        with:
          workspaces: ${{ matrix.workspace.path }} -> target
          cache-all-crates: true
          cache-workspace-crates: true

      - name: cargo fmt
        if: contains(matrix.target.steps, 'fmt') && !contains(matrix.workspace.skip, 'fmt')
        working-directory: ${{ matrix.workspace.path }}
        run: |

          rustup component add rustfmt
          cargo fmt --all --check

      - name: cargo check
        if: contains(matrix.target.steps, 'check') && !contains(matrix.workspace.skip, 'check')
        working-directory: ${{ matrix.workspace.path }}
        run: cargo check ${{ matrix.target.options }} --profile ${{ matrix.workspace.profile }}
        
      - name: cargo clippy
        if: contains(matrix.target.steps, 'clippy') && !contains(matrix.workspace.skip, 'clippy')
        working-directory: ${{ matrix.workspace.path }}
        run: |

          rustup component add clippy
          cargo clippy ${{ matrix.target.options }} --profile ${{ matrix.workspace.profile }} -- $CLIPPY_OPTIONS

      - name: cargo build
        if: contains(matrix.target.steps, 'build') && !contains(matrix.workspace.skip, 'build')
        working-directory: ${{ matrix.workspace.path }}
        run: cargo build ${{ matrix.target.options }} --profile ${{ matrix.workspace.profile }}

      - name: cargo test
        if: contains(matrix.target.steps, 'test') && !contains(matrix.workspace.skip, 'test')
        working-directory: ${{ matrix.workspace.path }}
        run: cargo test ${{ matrix.target.options }} --profile ${{ matrix.workspace.profile }}

      - name: Assert Clean Repo
        run: git diff --quiet && git diff --cached --quiet

  std-lib-and-python-virtualenv:
    strategy:
      fail-fast: true
      matrix:
        platform: [ubuntu-22.04, macos-latest, windows-latest]
        py:
          - py

    runs-on: ${{ matrix.platform }}

    steps:
      - uses: actions/checkout@v6

      - name: Setup Rust toolchain and cache
        uses: actions-rust-lang/setup-rust-toolchain@v1.12.0

      - name: Install Nushell
        run: cargo install --path . --locked --force

      - name: Upload Nushell build (Ubuntu and macOS)
        uses: actions/upload-artifact@v7
        if: runner.os != 'Windows'
        with:
          name: "nu-${{ github.event.number || github.ref_name }}-${{ matrix.platform }}"
          path: "~/.cargo/bin/nu"
          retention-days: 14

      - name: Upload Nushell build (Windows)
        uses: actions/upload-artifact@v7
        if: runner.os == 'Windows'
        with:
          name: "nu-${{ github.event.number || github.ref_name }}-${{ matrix.platform }}"
          path: 'C:\Users\runneradmin\.cargo\bin\nu.exe'
          retention-days: 14

      - name: Standard library tests
        run: nu -c 'use crates/nu-std/testing.nu; testing run-tests --path crates/nu-std'

      - name: Ensure that Cargo.toml MSRV and rust-toolchain.toml use the same version
        run: nu .github/workflows/check-msrv.nu

      - name: Setup Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.10"

      - name: Install virtualenv
        run: pip install virtualenv
        shell: bash

      - name: Test Nushell in virtualenv
        run: nu scripts/test_virtualenv.nu
        shell: bash

      - name: Check for clean repo
        shell: bash
        run: |

          if [ -n "$(git status --porcelain)" ]; then
            echo "there are changes";
            git status --porcelain
            exit 1
          else
            echo "no changes in working directory";
          fi