hyme

CircleCIでpnpmを利用するためのconfig.ymlを書いた

pnpmのCI設定を書くのに若干手間取ったため、その備忘録です。

とはいえ、公式のドキュメントに .circleci/config.yml の設定が書いてあるため、ベースはほとんどこれで問題ないです。 https://pnpm.io/ja/continuous-integration#circleci

しかし、実際に動かしてみると↓のようなエラーがでます。

Internal Error: EACCES: permission denied, unlink '/usr/local/bin/pnpm'
    at async Object.unlink (node:internal/fs/promises:1066:10)
    at async EnableCommand.generatePosixLink (/usr/local/lib/node_modules/corepack/dist/lib/corepack.cjs:23517:9)
    at async EnableCommand.execute (/usr/local/lib/node_modules/corepack/dist/lib/corepack.cjs:23506:11)
    at async EnableCommand.validateAndExecute (/usr/local/lib/node_modules/corepack/dist/lib/corepack.cjs:20726:22)
    at async _Cli.run (/usr/local/lib/node_modules/corepack/dist/lib/corepack.cjs:21701:18)
    at async Object.runMain (/usr/local/lib/node_modules/corepack/dist/lib/corepack.cjs:24002:18)

Exited with code exit status 1

/usr/local/bin への権限がないようです。 sudo コマンドをCIでつけるのも作法としてあまりよくなさそうなので、今回は corepack でインストールするパッケージマネージャーのインストール先を ~/bin に変更しました。 詳しくはREADME.mdをご参考ください。

corepack enable --install-directory ~/bin

また、ドキュメントに記載しているDockerをcimg/nodeの方に変更しました。 本当はNode.jsのOrbsを利用したかったのですが、install-packages のコマンドやドキュメントを見る限りでは、pnpmには対応していませんでした(2024/07/30時点)。

最終的には以下のような .circleci/config.yml が完成しました。

version: 2.1

commands:
  setup-frontend:
    steps:
      - checkout
      - restore_cache:
          name: Restore pnpm Package Cache
          keys:
            - pnpm-packages-{{ checksum "pnpm-lock.yaml" }}
      - run:
          name: Install pnpm package manager
          command: |
            corepack enable --install-directory ~/bin
            corepack prepare pnpm@latest-9 --activate
            pnpm config set store-dir .pnpm-store
      - run:
          name: Install Dependencies
          command: |
            pnpm install
      - save_cache:
          name: Save pnpm Package Cache
          key: pnpm-packages-{{ checksum "pnpm-lock.yaml" }}
          paths:
            - .pnpm-store

jobs:
  pnpm:
    docker:
      - image: cimg/node:<< parameters.node-version >>
    parameters:
      node-version:
        type: string
        default: '20.16.0'
      command:
        type: string
      parallelism:
        type: integer
        default: 1
    parallelism: << parameters.parallelism >>
    steps:
      - setup-frontend
      - run:
          command: pnpm run << parameters.command >>

workflows:
  setup-and-test:
    jobs:
      - pnpm:
          matrix:
            parameters:
              command:
                - lint
                - build