CodePipelineでnpmにパッケージ公開する

2019.07.05

先日こんなブログを書きました。

textlintのAWS用ルールを作ってみた

かなり自分のブログ執筆には役立っているんですが、ルールの変更が多くなれば(要は俺が頑張れば)パッケージの更新が大変になります。
なのでCodePipelineを使用して、npmにパッケージをリリースすれば楽になるんじゃないかなぁと思い、パイプラインを作ってみました。

このブログではCodePipeline、というよりかはCodeBuildを使用してどうやってnpmに公開するかを紹介します。

パイプラインを作る

パイプライン職人の朝は早いです。私はこの日8時少し過ぎぐらいに起きました。
初めてのパイプラインだったのでマネジメントコンソールを開いてCodePipelineを選択しました。

そしたら必要な情報を埋めて作成していきます。

次にソースステージを選択していきます。
今回はリポジトリがGitHubにあるのでCodePipelineからGitHubへアクセスできる権限を払い出します。

権限払い出しが終わったら、リポジトリとブランチを選択します。
masterにマージが掛かったらパイプラインを使うイメージだったので、画像のような設定にしています。

ここまでできたら、ビルドステージに進んでいきます。
CodeBuildのプロジェクトは何もできていないので、「プロジェクトを作成する」を選択します。

適当にこんな感じでデフォルトのままの設定を書いていきます。
説明することもないのでペタペタと画像をはっつけていきます。パイプライン職人は寡黙なんです。

デプロイステージは設定しません。
AWSリソースにしかデプロイできないため、今回のデプロイ先である、npmに関しては対象外だからです。
パイプライン職人の割には期待してプロバイダーを開いてちょっとしょげてました。

ここまで設定できたらだいたいパイプラインの完成です。
作成時にはパイプラインが1回実行されます。
この段階でbuildspec.ymlを追加してなかったのでCodeBuildでこけてます。

Systems Manager パラメータストアの設定

パイプライン職人はCodeBuildのビルドステージでnpmの認証トークンを使用したくなりました。
buildspec.ymlにベタ書きしたりするのよくないって、職人の直感がそう訴えかけてきたので、パラメータストアを使うことにしました。

パラメータストアを開いて設定していきます。

NPM_TOKENという名前で作成していきます。

パラメータストアに値を入れたので今度はCodeBuildから値を参照できるようにIAM ロールを変更していきます。
まずはポリシーを作りっていきます。

こんな感じのポリシーを書きました。
ドキュメントをしっかりと見れば"ssm:GetParameters"しか書いてないので"ssm:GetParameter"はいらないと思います。

{
  "Version": "2012-10-17",
  "Statement": [
    "Effect": "Allow",
    "Action": [
      "ssm:GetParameters",
      "ssm:GetParameter"
    ],
    "Resource": "arn:aws::ssm:ap-northeast-1:xxxxxxxxx:parameter/NPM_TOKEN"
  ]
}

最後にポリシーに名前を丹精込めてつけます。

出来上がったポリシーをロールにアタッチしたら作業は完了です。

buildspec.ymlを書く

masterブランチで直接作業したくないので、とりあえずブランチを変更しました。
そしてこんな感じの作業をしました。

$ git checkout -b codebuild
$ vi buildspec.yml
$ git add buildspec.yml
$ git commit
$ git push -u origin codebuild
version: 0.2
env:
  parameter-store:
    NPM_TOKEN: "NPM_TOKEN"

phases:
  install:
    runtime-versions:
      nodejs: 10
    commands:
      - npm ci
      - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
  build:
    commands:
      - npm run prepublish
      - npm publish

buildspec.ymlについて説明します。
まずこの部分で、パラメータストアからNPM_TOKENを取り出しています。

env:
  parameter-store:
    NPM_TOKEN: "NPM_TOKEN"

そして、installフェーズで先ほど取得した、TOKENを~/.npmrcに入れます。
"//registry.npmjs.org/:_authToken=${NPM_TOKEN}" といった形で挿入すると、npmコマンドが参照してくれます。
後はbuildフェーズでビルドをして、パッケージを公開させています。

ついでにGitHubのブランチ設定についても触れます。
masterブランチのみ保護して、masterへのpushをできないようにしています。
プルリクのレビュー必須とかにはしてないです。パイプライン職人は孤独なのです。

コードを適当に変更してからmasterにマージするとパイプラインが正常に動いていることが確認できます。

さいごに

はじめてのパイプライン作成でしたが思ったより簡単に作ることができました。
またパイプラインの作成を通じて、自動化の前に手作業を必ず把握する重要性を理解できました。