name: Node

on:
  pull_request:
    paths:
      - 'src/**'
      - 'tests/**'
      - 'examples/**'
      - 'Cargo.*'
      - 'rust-toolchain.toml'
      - 'sources.lock.json'
      - 'scripts/release.nu'
      - 'analizer/node-*.nu'
      - '.github/workflows/node.yml'
  push:
    branches: [master]
    paths:
      - 'src/**'
      - 'tests/**'
      - 'examples/**'
      - 'Cargo.*'
      - 'rust-toolchain.toml'
      - 'sources.lock.json'
      - 'scripts/release.nu'
      - 'analizer/node-*.nu'
      - '.github/workflows/node.yml'
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: node-${{ github.ref }}
  cancel-in-progress: ${{ github.ref_type != 'tag' }}

jobs:
  build:
    name: Build ${{ matrix.target }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - runner: ubuntu-24.04
            target: x86_64-unknown-linux-gnu
          - runner: ubuntu-24.04-arm
            target: aarch64-unknown-linux-gnu
          - runner: macos-14
            target: aarch64-apple-darwin
    runs-on: ${{ matrix.runner }}
    timeout-minutes: 30
    defaults:
      run:
        shell: nu {0}
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
        with:
          persist-credentials: false
      - uses: hustcer/setup-nu@9215c80adb545a85c419d5085b76eb6d082f49e7 # v3.27
        with:
          version: '0.112.2'
      - name: Install pinned Rust
        run: |
          let toolchain = (open rust-toolchain.toml | get toolchain.channel)
          rustup toolchain install $toolchain --profile minimal --component rustfmt
          if $env.LAST_EXIT_CODE != 0 { error make {msg: "Rust installation failed"} }
      - name: Assemble pinned sources
        run: nu analizer/node-sources.nu . checkout --destination ($env.RUNNER_TEMP | path join node-sources)
      - name: Build and qualify native binary
        working-directory: ${{ runner.temp }}/node-sources/cyber
        run: nu scripts/release.nu --locked-sources
      - name: Test source and release guards
        if: matrix.target == 'x86_64-unknown-linux-gnu'
        working-directory: ${{ runner.temp }}/node-sources/cyber
        run: |
          nu analizer/node-sources-test.nu .
          if $env.LAST_EXIT_CODE != 0 { error make {msg: "source guard tests failed"} }
          nu analizer/node-release-test.nu .
      - name: Package qualified binary
        working-directory: ${{ runner.temp }}/node-sources/cyber
        env:
          EXPECTED_TARGET: ${{ matrix.target }}
        run: |
          if (open dist/build.json | get target) != $env.EXPECTED_TARGET {
            error make {msg: "runner architecture differs from release target"}
          }
          nu analizer/node-release.nu . package
      - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: node-${{ matrix.target }}
          path: ${{ runner.temp }}/node-sources/cyber/dist/release/
          if-no-files-found: error
          retention-days: 14

Graph