pact-foundation / pact-js-core

Core binaries for pact-js, a Contract Testing Framework. NOTE: If you are looking to do Pact contract testing in node, you almost certainly want pact-js, not pact-node.
https://docs.pact.io
MIT License
150 stars 79 forks source link

Support installation on Mac M1 ARM (using rosetta2) #264

Closed pedropaf closed 2 years ago

pedropaf commented 3 years ago

I'm trying to install PACT for testing, I get the following error:

arch -x86_64 npm install @pact-foundation/pact-node
npm ERR! code EBADPLATFORM
npm ERR! notsup Unsupported platform for @pact-foundation/pact-node@10.11.8: wanted {"os":"darwin,linux,win32","arch":"x64,ia32"} (current: {"os":"darwin","arch":"arm64"})
npm ERR! notsup Valid OS:    darwin,linux,win32
npm ERR! notsup Valid Arch:  x64,ia32
npm ERR! notsup Actual OS:   darwin
npm ERR! notsup Actual Arch: arm64

I have tried with node 12 and node 15. / I have tried to specify arch x86_64 to run on rosseta2, but I think the issue is the call to the binary form js, would need to specify that flag if the architecture is darwin / arm64 pass the arch flag when calling the binary file to run it through rosetta2.

Any other workarounds that you suggest?

Thanks, Pedro

TimothyJones commented 3 years ago

So, we don’t currently have M1 binaries (or an M1 machine to test on, but I’m sure that will change). Travelling ruby has just been updated, so we might be able to make M1 binaries with that.

I think this error is coming from npm, not from pact-node (although it is following the restriction in pact-node’s package.json). From the npm docs, it looks like you’re running the arm version of npm. I think you’ll need to run the x86 version of node to install it- sounds like this is possible/easiest through running your terminal through Rosetta (although I may be wrong, I have only just started reading about it).

TimothyJones commented 3 years ago

It's very possible that there will be issues with the way we are invoking the binary at the moment, but I am pretty sure the error you're currently getting is from npm deciding whether or not to let you install the package, based on comparing the value of process.arch to pact-node's cpu field in package.json.

If you have the time, it might be easiest to jump on slack together and see what we can do to get this going- I'm around tomorrow morning AEDT (UTC+11) -and plenty of other times if that doesn't work.

pedropaf commented 3 years ago

Thanks, @TimothyJones for the update, I'm happy to jump into a call on GMT timezone.

fimak commented 3 years ago

@pedropaf @TimothyJones How it was, did you find a solution?

obiSerra commented 3 years ago

hello, there is any news on this issue? I'm having the same problem

TimothyJones commented 3 years ago

We haven't had a chance to look at it yet. My gut says it's an npm configuration issue, rather than a pact-node issue, but I don't have an M1 machine to test it on.

obiSerra commented 3 years ago

@TimothyJones I managed to investigate a bit more on this and the problem seems to be on pact-js-core where there are some checks to install the ruby binaries. The binaries work fine on my Apple m1, but the package.json configuration and the checksum performed on install.ts prevent the installation

obiSerra commented 3 years ago

I opened a PR with a possible fix https://github.com/pact-foundation/pact-js-core/pull/271

TimothyJones commented 3 years ago

Thanks for looking in to this!

I think the checksums should be included in the package, so there should be no need to download them as part of the install (if we did, I think we’d lose some of the value of the checksum).

We don’t have arm64 binaries yet, so unless I am missing something, I’m not sure it’s right to set that key in package json either- if we do need to set that key, I think it is an indication that npm is not checking with the appropriate value when Rosetta is used.

On 16 Mar 2021, at 3:32 am, Roberto Serra @.***> wrote:  I opened a PR with a possible fix #271

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

obiSerra commented 3 years ago

I tested it on my computer and the mac binaries (https://github.com/pact-foundation/pact-ruby-standalone/releases/download/v1.88.41/pact-1.88.41-osx.tar.gz) seem to work fine; the problem was the check done by npm.

I added the checksum download because the install process was failing on that: the install process was checking for the checksum inside the standalone directory but wasn't able to find it there.

Unfortunately, I'm pretty new to pact-js and to the application we are using it on: I'm just picking up the project and I need to port it to our new Mac; so I'm not able to test it properly and to check against the version we used on the old machines

TimothyJones commented 3 years ago

I'll summarise what I think is happening - and forgive me if this is not how it works on M1, I don't have one to test, and I'm not really sure how rosetta works. Corrections welcome.

I think the issue is that when you are running npm through rosetta, it is incorrectly failing the check for os in package.json, because npm is reporting the wrong value of arm64.

To work around this, we can add arm64 to the package.json, but this would not be correct, because we don't have arm64 binaries. As I understand it, adding arm64 to package.json would mean that people running npm natively (without rosetta) would have failures when they try to use the package.

I think this is a bug in npm, which should not be rejecting a darwin compatible package when running through rosetta.

TimothyJones commented 3 years ago

Doing a bit more digging, I think that it looks like you need to install npm under rosetta. There are instructions here (although they are for cypress, this is the same issue). See: https://www.cypress.io/blog/2021/01/20/running-cypress-on-the-apple-m1-silicon-arm-architecture-using-rosetta-2/

TimothyJones commented 3 years ago

^ Could someone try the above, and let us know if it works? If so, I'll add it to the documentation until we have M1 binaries.

obiSerra commented 3 years ago

Thank you, I followed the instruction you sent to me, and it worked

erithmetic commented 3 years ago

Alternatively, you can run everything in docker, which can run it in amd64 mode: https://erica.works/docker-on-mac-m1/

konalegi commented 3 years ago

any updates here? Can I help somehow?

Alternatively, you can run everything in docker, which can run it in amd64 mode: https://erica.works/docker-on-mac-m1/\

Unfortunately, this is a bad option for my setup it's 4 times slower than in arm64 mode.

mefellows commented 3 years ago

I'm not across the problem, but if you're willing to look into the details for us that would be helpful.

None of the maintainers currently have access to an M1 machine. It seems that docker should be a workaround, albeit not ideal, as well as using some other intel based workaround as per the Cypress blog.

If we can codify this and hide some of it from users, this would be great.

The core of the problem is that we use Ruby binaries (and soon to be Rust libraries) as our shared core. These need to be able to support the M1 chip.

fidalgodev commented 3 years ago

Having the same issue. The fix was to delete the Node version the project was using with nvm, then run terminal in Rosetta mode inside the project folder, install the node version the project is using with the terminal in Rosetta mode (this will install node x64 instead of ARM version), and then I can run yarn fine.

Would be nice if this package could support node ARM tho.

johanneswuerbach commented 3 years ago

I've investigate a bit, how to build arm64 binaries, but there seems to be a lot of exploration and work left 😢 .

Therefor I think just allowing rosetta to run the current binaries would be a really good usability improvement https://github.com/pact-foundation/pact-js-core/pull/302 as it just works if you have rosetta2 installed. I agree its not ideal, but teaching the current workaround to our developers and every new one seems worse 🤔 .

johanneswuerbach commented 3 years ago

This should no longer be required since pact-node@10.13.1 / pact-core@11.1.0 as the cpu limitation was removed https://github.com/pact-foundation/pact-js-core/pull/302

Now pact should just work ™️ with an arm node and rosetta installed 🎉. Thanks @TimothyJones

TimothyJones commented 3 years ago

I think it’s still required, because allowing the arm64 install is a work around- we still don’t support that cpu yet. The workaround relies on the (currently) high probability that people with this cpu are on a mac that can translate the intel binary with Rosetta. It won’t work (I believe) for anyone (say) running Linux on that cpu.

I’d like to look at fixing this after the v3 release. It will be easier once we’re using the rust binaries, and hopefully at that point there will be M1 machines available in CI

iknowcss commented 2 years ago

@TimothyJones It won’t work (I believe) for anyone (say) running Linux on that cpu.

You're correct. One of the people on my team with an M1 Mac running a linux docker container without Rosetta gets this error during install:

Error: Error while installing binary: Cannot find binary for platform 'linux' with architecture 'arm64'.

Interestingly he is able to install and run the pact tests directly on the host without Rosetta :thinking:

iknowcss commented 2 years ago

Ah, sorry I just read the detail of #302. I guess the executable is running on Rosetta even though he is not running the node process under it.

lawrenceong commented 2 years ago

@iknowcss We are using Apple M1 as well. We usually run pact locally, either manually or on commit. To workaround the following error when building via docker:

Error: Error while installing binary: Cannot find binary for platform 'linux' with architecture 'arm64'.

We added the following to Dockerfile:

# Skipping pact binary install as it is not compatible with Apple M1 CPU
# See: https://github.com/pact-foundation/pact-js-core/issues/347
ENV PACT_SKIP_BINARY_INSTALL true

Can probably make it more comprehensive by detecting for CPU before setting it. Hope that helps.

mefellows commented 2 years ago

The latest version (13.x.x) should work on M1 natively as it ships an aarch64 shared module.

Previous versions (that bundle the Ruby core) can work under rosetta mode.