vercel / pkg

Package your Node.js project into an executable
https://npmjs.com/pkg
MIT License
24.33k stars 1.02k forks source link

Latest arm64 macOS binary does not work when built on Ubuntu #2004

Closed olafurpg closed 1 year ago

olafurpg commented 1 year ago

What version of pkg are you using?

5.8.1

What version of Node.js are you using?

v20.4.0

What operating system are you using?

macOS and Ubuntu

What CPU architecture are you using?

arm64 on macOS, x86_64 on Ubuntu

What Node versions, OSs and CPU architectures are you building for?

arm64 macOS

Describe the Bug

I've been using pkg successfully from my local Apple M1 computer for an open source project. Here is where we invoke pkg

https://github.com/sourcegraph/cody/blob/43bad53c540eec46eaa6e39a9efeb6a62534b635/agent/package.json#L20

I recently added CI automation to trigger releases so that I don't have to build the project from my local computer. The macOS arm64 binary does not work when it's created by the ubuntu-latest runner from GitHub actions. I confirmed that all the other binaries work as expected (x86 macOS, x86 Linux, x86 Windows).

 ./agent-macos-x64 # works OK via Rosetta
Starting Cody Agent...
^C
❯ ./agent-macos-arm64
[1]    20895 killed     ./agent-macos-arm64

Expected Behavior

My expected behavior is that ./agent-macos-arm64 prints the same output as ./agent-macos-x86 when these binaries are built on Ubuntu.

To Reproduce

olafurpg commented 1 year ago

Closing since this seems to be unsupported according to the docs https://github.com/vercel/pkg#targets

macos-arm64 is experimental. Be careful about the mandatory code signing requirement. The final executable has to be signed (ad-hoc signature is sufficient) with codesign utility of macOS (or ldid utility on Linux). Otherwise, the executable will be killed by kernel and the end-user has no way to permit it to run at all. pkg tries to ad-hoc sign the final executable. If necessary, you can replace this signature with your own trusted Apple Developer ID.

I'm sorry for the noise. Thank you for creating a super helpful tool! 🙏🏻

olafurpg commented 1 year ago

For anyone Googling, we managed to get the macos-arm64 binary working even if it was created on an ubuntu-latest runner with GitHub Actions. The solution was twofold. First, setup QEMU and binfmt

      # See note about QEMU and binfmt requirement here https://github.com/vercel/pkg#targets
      - name: Set up QEMU
        id: qemu
        uses: docker/setup-qemu-action@v1
        with:
          image: tonistiigi/binfmt:latest
          platforms: all

Next, sign the macos-arm64 with ldid. Here is a script we use to install ldid

#!/usr/bin/env bash

# Script to install `ldid2` on Linux computers to codesign the macos-arm64 binary for the agent.

set -eux

# Check if ldid is installed
if command -v ldid &>/dev/null; then
  echo "ldid is already installed."
  exit 0
fi

curl -Lo ldid.zip https://github.com/xerub/ldid/archive/refs/heads/master.zip
unzip ldid.zip
cd ldid-master
./make.sh
cp ldid /usr/local/bin/

After installing, run `ldid -S PATH_TO-macos-arm64