Edited at

CIでLerna publishするまで

絶対に忘れる自信があるので今のうちにメモっておく。


Lerna is 何



  • Lerna はmonorepoを管理するためのツール

  • Babelのように、単一レポジトリで複数のnpmパッケージを管理できる

  • レポジトリ内パッケージ間の依存関係をsimlinkにより解決してくれる(勝手に npm link してくれるイメージ)


やりたいこと


  1. 開発者がmasterへコード修正commit(PRのmergeなど)

  2. CIでテスト実行

  3. 開発者がリリース意思表示

  4. CIでリリース実行



    • lerna publish が実行されて、npmへpublish完了!



今回はCIサービスにはCircleCI(2.x)を選択。

特にCircleCIにこだわっているわけでもなく、workflow的な仕組みが備わっているCI Serviceであれば問題ないはず。WerckerCIとか。


準備

lerna publish は下記を逐次的に実行していく。


  1. リリースバージョンの決定(デフォルトでは、質問に答えることでインタラクティブに決定される)

  2. publishが必要なパッケージの選定

  3. lerna.json, publish対象パッケージのpackage.jsonのversion番号を書き換えて git commit

  4. 決定したバージョンで git tag 実行

  5. 対象パッケージを npm publish 実行


  6. git push origin master --tags 実行

lernaは、各個のコマンド呼び出しにはchild_process.execSync を叩いているだけなので、CIでも上記の個別コマンドが動くようになっていれば問題ない。


GitHub deploy key

CircleCIからGitHubへgit pushできるようにする必要がある。ここでは、Deploy key(SSH公開鍵認証)を使う。

下記コマンドで、パスフレーズ空の鍵ペアを生成。

ssh-keygen -t rsa -b 4096 -P "" -C "<GitHubのメアド>" -f ${HOME}/.ssh/gh_dep_rsa

秘密鍵(~/.ssh/gh_dep_rsa)をコピって、CircleCI設定画面の、Permissions -> SSH Permissions -> Add SSH keyから登録。

Project_settings_-_Quramy_reg-suit_-_CircleCI.png

公開鍵(~/.ssh/gh_dep_rsa.pub)をコピって、GitHubレポジトリの Setting -> Deploy keys -> Add deploy key に登録。"Allow write access" を忘れずに。

Deploy_keys.png

Deploy_keys_2.png

fingerprintをコピっておいて、CircleCIの設定ファイルに追記.


circleci/config.yml

    steps:

- add-ssh-keys:
fingerprints:
# 上記でコピったfingerprintをここに貼り付け
- "a1:a2:a3:a4:a5:a6:a7:a8:a1:a2:a3:a4:a5:a6:a7:a8"


Git user config

地味に忘れがちなのがこれ。 package.jsonやらをcommitする際に必要になるので。


circleci/config.yml

    steps:

- run:
name: Setup git user
command: |
git config --global user.email "<メアド>"
git config --global user.name "<ユーザー名>"


NPM token

npmにpublishするために必要。

ローカルで、npm adduserを実行してnpmにログインしておいてから、


~/.npmrc

//registry.npmjs.org/:_authToken=xxxxxx-yyyyyy-wwwwww-zzzzzz


_authToken=... の値をコピー。

Build settings -> Environment Variables -> Add variableを選択して、コピーした値を NPM_AUTH_TOKEN という名前で保存しておく。

これで、環境変数としてnpmの認証トークンを取り出せるようになったので、この値を使ってCI側でログインするようにしておく。


circleci/config.yml

      - run:

name: Login npm
command: |
echo "//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}" > ~/.npmrc
npm whoami

なお、 npm whoami はログインの確認用。


実行

これで準備が整った。最後はlerna publishをstepに加えるだけだ。


circleci/config.yml

      - run:

name: Publish
command: |
./node_modules/.bin/lerna --cd-version="patch" --yes --registry="https://registry.npmjs.org/" publish

--cd-version="patch"--yes でリリースバージョンが自動的に決定されるようにしておく。

--registryhttps://github.com/lerna/lerna/issues/896 のworkaround。多分そのうち不要になるだろうけど、最初はコイツを忘れたお陰で、npm whoamiが正常終了なのに、lernaから実行される npm publish でauth errorとなって悲しい思いをした。


追記 (2019.03.21)

久々にドキュメント読み返していたら、 --cd-version の記載が消えていた。

lerna publish patch --yes

のように書くか、または、手元で lerna version patch などを実行後に、CI側で

lerna publish from-package --yes

を叩くと良さそう(CIまでは未検証)