actions / toolkit

The GitHub ToolKit for developing GitHub Actions.
https://github.com/features/actions
MIT License
5.02k stars 1.45k forks source link

@actions/core version 1.11.0 has error ReferenceError: crypto is not defined #1841

Closed jessecollier closed 1 month ago

jessecollier commented 1 month ago

Describe the bug We have a github action that runs in the following environment:

Current runner version: '2.319.1'
Operating System
  Ubuntu
  [2](https://github.com/dynamic-labs/dynamic-auth/actions/runs/11149638521/job/30988996400#step:1:2)2.04.5
  LTS
Runner Image
  Image: ubuntu-22.04
  Version: 20240922.1.0
  Included Software: https://github.com/actions/runner-images/blob/ubuntu22/20240922.1/images/ubuntu/Ubuntu2204-Readme.md
  Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu22%2F20240922.1
Runner Image Provisioner
  2.0.[3](https://github.com/dynamic-labs/dynamic-auth/actions/runs/11149638521/job/30988996400#step:1:3)84.1

To Reproduce Steps to reproduce the behavior:

  1. Create a js file that imports const core = require('@actions/core');
  2. Add it to your github action
/home/runner/work/_actions/<redacted>/main/.github/actions/release-helper/node_modules/@actions/core/lib/file-command.js:47
    const delimiter = `ghadelimiter_${crypto.randomUUID()}`;
                                      ^

ReferenceError: crypto is not defined
    at prepareKeyValueMessage (/home/runner/work/_actions/<redacted>/main/.github/actions/release-helper/node_modules/@actions/core/lib/file-command.js:47:39)
    at Object.setOutput (/home/runner/work/_actions/<redacted>/main/.github/actions/release-helper/node_modules/@actions/core/lib/core.js:168:105)
    at setOutput (/home/runner/work/_actions/<redacted>/main/.github/actions/release-helper/util.js:8:8)
    at Object.<anonymous> (/home/runner/work/_actions/<redacted>/main/.github/actions/release-helper/getVersion.js:20:1)
    at Module._compile (node:internal/modules/cjs/loader:1364:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
    at Module.load (node:internal/modules/cjs/loader:1203:32)
    at Module._load (node:internal/modules/cjs/loader:1019:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:[128](https://github.com/<redacted>/actions/runs/11149638521/job/30988996400#step:2:139):12)
    at node:internal/main/run_main_module:28:49

Expected behavior Should not throw an error

Additional context Add any other context about the problem here.

MarioUhrikTakeda commented 1 month ago

On my end, this problem appeared while we were using Node 18.x, and upgrade to Node 20.x fixed the problem E.g. by adding this into the GHA Workflow:

    - name: Set Node.js 20.x
      uses: actions/setup-node@v4
      with:
        node-version: 20.x

This is further apparent from how this PR was tested, because the build pipeline uses the same: https://github.com/actions/toolkit/actions/runs/10707564967/workflow#L27-L30

joshmgross commented 1 month ago

@jessecollier which version of Node are you using for that action?

Both Node 16 actions and Node 20 should work with this function.

https://nodejs.org/docs/latest-v16.x/api/crypto.html#cryptorandomuuidoptions

https://docs.github.com/en/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#runs-for-javascript-actions

aeisenberg commented 1 month ago

We are seeing the same problem. Using node v18.20.4, and image version 20240922.1.0.

Here's the failing job: https://github.com/github/codeql-action/actions/runs/11152388670/job/31043230806?pr=2518

Interestingly, when I run this locally using the same version of node, the tests pass (and crypto is indeed available in globalThis). Is it possible that the default node version in the action image is using a version of node that was not compiled with the crypto class?

According to the node docs:

It is possible for Node.js to be built without including support for the node:crypto module. In such cases, attempting to import from crypto or calling require('node:crypto') will result in an error being thrown.

joshmgross commented 1 month ago

I will look into reverting the addition of crypto, need to investigate a bit more.

In the meantime, I would recommend pinning to an earlier version of @actions/core.

Bo98 commented 1 month ago

Is it possible that the default node version in the action image is using a version of node that was not compiled with the crypto class?

Prior to Node 19, crypto needs an explicit require (or import given it's TypeScript), which seems to be what's missing here.

$ /opt/homebrew/opt/node@20/bin/node - <<<"console.log(crypto.randomUUID())"
df14bf83-0951-4296-a0a9-44f57230e56d

$ /opt/homebrew/opt/node@18/bin/node - <<<"console.log(crypto.randomUUID())" 
[stdin]:1
console.log(crypto.randomUUID())
            ^

ReferenceError: crypto is not defined

$ /opt/homebrew/opt/node@18/bin/node - <<<"const crypto = require('crypto'); console.log(crypto.randomUUID())"
477f9e75-369a-4a88-b7ee-6f1ab9bcbeba

$ /opt/homebrew/opt/node@20/bin/node - <<<"const crypto = require('crypto'); console.log(crypto.randomUUID())"
7e78649d-c0bb-4d28-b474-3700c6ce04a1

(not using -e here as that does some auto-require magic)

jessecollier commented 1 month ago

Yea we're using node 18. Pinning to the previous version of the package resolved the issue for us.

joshmgross commented 1 month ago

Thanks for the info @Bo98!

Confirmed that crypto works as expected when explicitly required/imported in Node 16, 18, 20, and the default Node version on ubuntu-latest (currently Node 18).

https://github.com/joshmgross/node-crypto-testing/blob/main/.github/workflows/validate-node-crypto.yaml

https://nodejs.org/en/blog/announcements/v19-release-announce#stable-webcrypto

joshmgross commented 1 month ago

This should be fixed in 1.11.1

https://www.npmjs.com/package/@actions/core/v/1.11.1

joshmgross commented 1 month ago

Marking as resolved! Thanks for reporting this and thanks again to @Bo98 for helping find the solution.

Feel free to reopen or file a new issue if you're still seeing this problem.