npm install in GitHub 操作失败并显示 "ENOENT: no such file or directory" - 在其他地方工作正常

npm install in GitHub Action fails with "ENOENT: no such file or directory" - Works fine elsewhere

我目前正在努力用 GitHub Actions 替换我们的 Drone CI 安装。

到目前为止,我的 Action Workflow 归结为以下 .github/workflows/ci.yml 文件:

on: [ push, pull_request ]

name: CI
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Install Node
        uses: actions/setup-node@v1
        with:
          node-version: '13.x'

      - name: Install Dependencies
        run: npm install

日志本身是一长串 npm WARN tar ENOENT: no such file or directory ala 下面的截断列表。

2020-04-29T21:15:31.7899082Z npm install
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/acorn-26d8ba97/dist/acorn.js.map'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/coffeescript-acee515b/lib/coffee-script/register.js'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/coffeescript-acee515b/lib/coffee-script/repl.js'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/coffeescript-acee515b/lib/coffee-script/rewriter.js'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/tslint-c216b578/LICENSE'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/eslint-cd3dbe58/LICENSE'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/eslint-cd3dbe58/README.md'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/typescript-b4b55d18/lib/diagnosticMessages.generated.json'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/jquery-1794793b/dist/jquery.min.js'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/lodash-05c1df31/fp/_convertBrowser.js'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/lodash-70e4a396/fp/_convertBrowser.js'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/lodash-79f5ae17/fp/_convertBrowser.js'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/lodash-e49b02f6/fp/_convertBrowser.js'
npm WARN tar ENOENT: no such file or directory, open '/home/runner/work/project/project/node_modules/.staging/lodash-16fa050d/fp/_convertBrowser.js'

我在网上找到的建议是 rm package-lock.json 但这不是一个可接受的解决方案,因为我需要使用我们锁定的依赖项的确切版本来测试我们的代码。

此外,我不认为我们的 package-lock.json 文件有任何问题,因为它仍然 npm install 在本地和我们的 Drone [=29] 上都符合预期=] 安装.

在漫长的等待中,我在这里找到了解决方案:

Install an npm module from a private GitHub repository using GitHub Actions

      - uses: actions/checkout@v2
        with:
          persist-credentials: false
      - uses: actions/setup-node@v1
        with:
          node-version: 12.x
      - run: git config --global url."https://${{ secrets.PAT }}@github.com/".insteadOf ssh://git@github.com/
      - run: npm ci
      ...

我基本上自己尝试了所有这些,但缺少最重要的部分:

        with:
          persist-credentials: false

actions/checkout@v2 默认情况下会扰乱 Git 的某些设置并阻止 insteadOf 正常工作。

如果您使用的是私有 npm 包,并且只是忘记将秘密添加到存储库,也会发生此错误情况。

例如如果您的 GitHub 操作工作流程中有这样的内容:

- name: Add token for private package access to .npmrc
  run: echo "//npm.pkg.github.com/:_authToken=$ACME_CORP_TOKEN" > ~/.npmrc
  env:
    ACME_CORP_TOKEN: ${{ secrets.ACME_CORP_TOKEN }}

...如果 $ACME_CORP_TOKEN 不存在,像上面这样的操作不会失败(尽管这样做会更好),所以如果您忘记实际添加ACME_CORP_TOKEN secret 到存储库(在存储库设置的 Secrets 选项卡中),然后你会遇到同样的问题。

node_modules 中看起来正常的依赖项的大量 npm WARN tar ENOENT 错误列表不会使问题实际上是缺少私有注册表访问令牌变得显而易见。

我们遇到了这个问题。在无休止的 tar ENOENT 错误流中,我们发现了另一个错误(为简洁起见进行了编辑):

npm ERR! Error while executing:
npm ERR! /usr/bin/git ls-remote -h -t ssh://git@github.com/fivetran/doctrine.git
npm ERR! git@github.com: Permission denied (publickey).
npm ERR! fatal: Could not read from remote repository.
npm ERR! exited with error code: 128

在我们的例子中,有问题的存储库是 public 但出于某种原因 npm 仍然试图通过 ssh 而不是 https 获取它(与我们所有其他依赖项不同)。

我们通过在工作流程中添加一个额外的步骤来配置 npm 以改为使用 https 来解决这个问题:

    steps:
    - uses: actions/checkout@v2
      with:
        persist-credentials: false

    - name: Reconfigure git to use HTTP authentication
      run: >
        git config --global url."https://github.com/".insteadOf
        ssh://git@github.com/

    # etc.