name: Build nash (darwin arm64)

# The darwin half of nash's build+publish (docs/NASH.md §8). Linux slices ship from
# naros.yml (static musl → debs → naros images); nothing there can produce a Mach-O, so
# this workflow builds the **arm64 macOS binary** — the single artifact both M5 (the
# macOS-VM guest: provisioning stages it → /usr/local/bin/nash, NASH.md §7.5) and M5.5
# (the in-app-bundle host copy, §7.7) depend on.
#
# arm64 only, deliberately: both consumers floor at macOS 27 (Package.swift; the guest pin
# in MACOS_VM_NATIVE_AGENT.md), and macOS 26 was Apple's last Intel release — so no x86_64
# host or guest can ever run this binary. The old universal/lipo build burned a second
# release cargo build per run for a slice with no reachable consumer.
#
# Gates before publishing: the nash + nash-observe test suites run natively (arm64), the
# binary must carry the arm64 slice and no other, and it must execute (`--version`, `-lc`).
# Signing/notarization is NOT done here — the artifact is a bare Mach-O; it is signed by
# whatever bundles it (scripts/package-app.sh signs the Resources/macvm copy with the
# app's identity).
#
# Distribution: GHCR OCI single-blob artifact `nucleic-nash-darwin`, same pattern as
# nucleic-linux-vm-kernel (oras). Tagged with the crate version AND `latest` (or the
# workflow_dispatch tag). After the FIRST publish, set the GHCR package to Public so it
# can be pulled anonymously while the repo stays private, like nucleic-kernel.

on:
  workflow_dispatch:
    inputs:
      tag:
        description: "Extra GHCR tag for the published binary (besides the crate version)"
        required: true
        default: "latest"
      publish:
        description: "Push to GHCR (else just build + upload the workflow artifact)"
        type: boolean
        default: true
  push:
    branches: [main, dev]
    paths:
      - shell/**
      - third_party/brush/**
      - scripts/build-nash-macos.sh
      - .github/workflows/nash.yml

jobs:
  darwin:
    name: nash arm64 → GHCR
    runs-on: macos-15 # arm64, matching the only architecture we build for
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: aarch64-apple-darwin

      - name: Test (nash + nash-observe, native arm64)
        working-directory: shell
        run: cargo test --release -p nash -p nash-observe

      - name: Build binary
        run: ./scripts/build-nash-macos.sh dist/nash-macos

      - name: Sanity-check slice + execution
        run: |
          # Assert the two properties independently rather than string-equalling lipo's
          # whole output: arm64 present, x86_64 absent (a stray slice means the build
          # regressed back to a lipo). Substring matching can't false-fail on however
          # `lipo -archs` chooses to space or order its output for a thin Mach-O.
          archs="$(lipo -archs dist/nash-macos/nash)"
          echo "slices: $archs"
          case "$archs" in *arm64*) ;; *) echo "✗ no arm64 slice: $archs" >&2; exit 1 ;; esac
          case "$archs" in *x86_64*) echo "✗ stray x86_64 slice: $archs" >&2; exit 1 ;; esac
          dist/nash-macos/nash --version
          test "$(dist/nash-macos/nash -lc 'echo ok')" = ok

      - name: Upload workflow artifact
        uses: actions/upload-artifact@v4
        with:
          name: nucleic-nash-darwin-arm64
          path: dist/nash-macos/nash
          if-no-files-found: error

      - name: Resolve GHCR owner + crate version
        id: ref
        run: |
          echo "owner=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
          ver="$(sed -n 's/^version = "\(.*\)"/\1/p' shell/nash/Cargo.toml | head -1)"
          test -n "$ver"
          echo "version=$ver" >> "$GITHUB_OUTPUT"

      - uses: oras-project/setup-oras@v1
        if: ${{ github.event_name == 'push' || inputs.publish }}
      - name: Log in to GHCR
        if: ${{ github.event_name == 'push' || inputs.publish }}
        run: oras login ghcr.io -u '${{ github.actor }}' -p '${{ secrets.GITHUB_TOKEN }}'
      - name: Push as an OCI artifact
        if: ${{ github.event_name == 'push' || inputs.publish }}
        working-directory: dist/nash-macos
        run: |
          img="ghcr.io/${{ steps.ref.outputs.owner }}/nucleic-nash-darwin"
          ver="${{ steps.ref.outputs.version }}"
          oras push "$img:$ver" \
            --artifact-type application/vnd.nucleic.shell \
            nash:application/octet-stream
          oras tag "$img:$ver" "${{ inputs.tag || 'latest' }}"
