Code Monkey home page Code Monkey logo

Comments (5)

privatenumber avatar privatenumber commented on May 29, 2024 1

In a few of my projects, I test multiple Node.js versions in one job like this:
https://github.com/esbuild-kit/tsx/blob/f8837b72793131042f7fc58e2282ac2dc1a86184/tests/index.ts#L34

It's possible to move the logic to setup-node, but I'd have to move the testing logic to the GitHub Actions yml file, and it would complicate testing locally.

Personally, I like that I can see all the testing logic in JS, and run them between CI and local with one command.

Since it's a major change and the Github distribution isn't a true mirror, I think it's completely reasonable to close this issue. I really appreciate your thorough evaluation nonetheless!

from get-node.

ehmicky avatar ehmicky commented on May 29, 2024 1

Yes, that's exactly it! Thanks for sharing the setup @privatenumber.

from get-node.

ehmicky avatar ehmicky commented on May 29, 2024

Hi @privatenumber,

Thanks for reaching out.

The main difference with the GitHub actions is that they use the following manifest file instead of the official Node.js one, with the same Node.js binary files but hosted on GitHub.

Some difference: it does not support less mainstream architectures (AIX, x86, ARM, PPC64, s390). It also only goes back to Node 6.17.1.

It is possible that raw.githubusercontent.com has a lower latency than nodejs.org/dist, especially from a GitHub action. More importantly, those Node versions files are cached and retrieved using @actions/tool-cache.

I agree this would result in a better experience (faster and fewer download errors) when using get-node inside GitHub actions. However, implementing this would require significant changes to multiple repositories. Also, most of the logic would duplicate the implementation from setup-node.

Which leads me to ask you: can you tell me more about how you use get-node inside GitHub actions?
Also: why not use setup-node instead?

from get-node.

ehmicky avatar ehmicky commented on May 29, 2024

Thanks a lot for the information and link to your code @privatenumber.

This seems to be a good use case. For most users, I would recommend using @actions/setup-node instead of get-node and putting the logic in the GitHub Actions workflow file. However, I can see why you might want to put it in the tests instead, as it gives you additional flexibility.

Checksums

One small detail: using GitHub node-versions would remove the automatic integrity check get-node is performing.

get-node/src/checksum.js

Lines 24 to 26 in 0e7f4cb

if (actualChecksum !== expectedChecksum) {
return `Could not download Node.js ${version}: checksum did not match`
}

That's because the checksums are provided by nodejs.org/dist, and the Node.js archives provided by GitHub have an additional file in them (some small Bash script), i.e. have different checksums. So you'd be losing this feature, although that might arguably not be critical for most users.

Download speed

I ran some benchmarks trying to fetch(nodeUrl) using either nodejs.org/dist or the URL from GitHub node-versions. (For more details, here are the links to the code and results).

The following shows the mean duration per download, after fetching the Node.js 20.7.0 archive 10 times in a row.

  • When run locally with nodejs.org/dist: Linux: 62ms, macOS: 45ms, Windows: 52ms
  • When run in GitHub actions with nodejs.org/dist: Linux: 58ms, macOS: 92ms, Windows: 62ms
  • When run locally with the URL from GitHub node-versions: Linux: 286ms, macOS: 239ms, Windows: 243ms
  • When run in GitHub actions with the URL from GitHub node-versions: Linux: 137ms, macOS: 130ms, Windows: 132ms

So, surprisingly, it turns out fetching Node.js from nodejs.org/dist is much faster than using GitHub node-versions even inside GitHub actions!

Caching

GitHub node-versions also uses the GitHub actions cache to remove the need to download the Node.js binary. From previous experience, I remembered it not to be as fast as one might expect. I think this might be due to the need to download the cached assets at the beginning of the workflow, and to run the additional caching logic.

That being said, caching also provides with resilience. Namely, nodejs.org/dist can be a little unstable and sometimes fails.

However, get-node provides some solutions to this. First, download failures are automatically retried twice.

Also, get-node has some built-in caching logic: when running it multiple times with the same output path, only the first call will download the Node.js binary. More precisely, if the specific Node.js version already exists in the output path, it is used instead of re-downloading the Node.js binary.

get-node/src/download.js

Lines 16 to 20 in 0e7f4cb

const nodePath = join(output, version, archA, NODE_FILENAME)
if (await pathExists(nodePath)) {
return nodePath
}

Recommendations

I am wondering whether a good approach for your case would be to edit your GitHub actions workflow file to make it cache the Node.js binaries output path? In other words fixture.path in:

https://github.com/esbuild-kit/tsx/blob/f8837b72793131042f7fc58e2282ac2dc1a86184/tests/index.ts#L34

What are your thoughts on this?

from get-node.

privatenumber avatar privatenumber commented on May 29, 2024

Very interesting investigation! Thanks for gathering this data. I'm surprised downloading from GitHub releases is slower even for GitHub Actions.

Node's server is generally fast for me, but what prompted me to investigate this was locally downloading from Node's server was really slow a few times last week (maybe it was PST work hours and congested?) and I was speculating it to cause the tests to freeze.

I started caching the nve cache directory like this, which seems effective:
https://github.com/esbuild-kit/tsx/blob/f8837b72793131042f7fc58e2282ac2dc1a86184/.github/workflows/test.yml#L44-L46

from get-node.

Related Issues (6)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.