ようへいの日々精進XP

よかろうもん

AWS CodeArtifact を使ってみた (2) 〜 特定のパッケージだけ CodeArtifact 経由でパッケージをインストールしたい 〜

これは

YAMAP エンジニア Advent Calendar 2021 の第四日目の記事になる予定です。

qiita.com

経緯

特定のパッケージだけ、AWS CodeArtifact (以後、CodeArtifact) からインストールして、他のパブリックなパッケージは既存のパッケージレジストリからインストールしたい場合、どうしたらいいんだろうなあと試行錯誤したのでメモしておきます。

前回に引き続き、オレオレ npm パッケージを用意して試行錯誤します。

inokara.hateblo.jp

パッケージを登録する

スコープ

npm パッケージの場合、以下のようにパッケージ名を指定することで、スコープを定義出来るとのことです。

@somescope/somepackagename

ドキュメント によると、以下のように書かれています。

docs.npmjs.com

スコープは、パッケージ名の通常のルール(URLセーフな文字、先頭にドットやアンダースコアを付けない)に従います。パッケージ名に使用する場合、スコープの前に@マークを付け、その後にスラッシュを付けます。

前回の記事では、サンプルで作ったオレオレパッケージは、以下のような名前でした。

oreno-sample

ここに、@oreno-repo というスコープを設定します。(本当は @oreno-pkg が良かったかな)

@oreno-repo/oreno-sample

パッケージの登録

スコープを付与した名前で CodeArtifact に Publish してみたいと思います。

$ cat package.json
{
  "name": "@oreno-repo/oreno-sample",
  "version": "0.0.2",
  "description": "sample",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "inokappa",
  "license": "ISC"
}

$ npm publish
npm notice
npm notice 📦  @oreno-repo/oreno-sample@0.0.2
npm notice === Tarball Contents ===
npm notice 63B  index.js
npm notice 234B package.json
npm notice === Tarball Details ===
npm notice name:          @oreno-repo/oreno-sample
npm notice version:       0.0.2
npm notice filename:      @oreno-repo/oreno-sample-0.0.2.tgz
npm notice package size:  326 B
npm notice unpacked size: 297 B
npm notice shasum:        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
npm notice integrity:     sha512-kDGgkiOmOcvvL[...]nXPlCFy/YAKlw==
npm notice total files:   2
npm notice
+ @oreno-repo/oreno-sample@0.0.2

ちゃんと、登録されているでしょうか。

$ aws codeartifact list-packages --domain=oreno-codeartifact --repository=oreno-repo
{
    "packages": [
        {
            "format": "npm",
            "package": "oreno-sample"
        },
        {
            "format": "npm",
            "namespace": "oreno-repo",
            "package": "oreno-sample"
        }
    ]
}

ちゃんと、namepace として oreno-repo が登録されていて、パッケージは oreno-sample が登録されています。

パッケージを利用する

package.json を修正

前の記事で、サンプルプロジェクトで利用していた package.json は以下のような内容でした。オレオレパッケージ (oreno-sample) と aws-sdkmocha に依存したプロジェクトです。

{
  "name": "sample-project",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "oreno-sample": "^0.0.1",
    "aws-sdk": "^2.1041.0",
    "mocha": "^9.1.3"
  }
}

この package.json を以下のように修正します。

{
  "name": "sample-project",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@oreno-repo/oreno-sample": "^0.0.1",
    "aws-sdk": "^2.1041.0",
    "mocha": "^9.1.3"
  }
}

$HOME/.npmrc を修正

前回の記事では、CodeArtifact を利用する為に、以下のような AWS CLI コマンドを実行しました。

$ aws codeartifact login \
  --tool npm \
  --repository oreno-repo \
  --domain oreno-codeartifact \
  --domain-owner ${AWS_ACCOUNT_ID}

このコマンドを実行すると、$HOME/.npmrc は、以下のような内容で上書きされます。

$ cat $HOME/.npmrc
registry=https://oreno-codeartifact-${AWS_ACCOUNT_ID}.d.codeartifact.ap-northeast-1.amazonaws.com/npm/oreno-repo/
//oreno-codeartifact-${AWS_ACCOUNT_ID}.d.codeartifact.ap-northeast-1.amazonaws.com/npm/oreno-repo/:_authToken=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

この状態で、npm i を実行すると、以下のようなエラーとなります。

$ npm i
npm ERR! code E404
npm ERR! 404 Not Found - GET https://oreno-codeartifact-${AWS_ACCOUNT_ID}.d.codeartifact.ap-northeast-1.amazonaws.com/npm/oreno-repo/aws-sdk - Package, 'aws-sdk', not found.
npm ERR! 404
npm ERR! 404  'aws-sdk@^2.1041.0' is not in this registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

npm ERR! A complete log of this run can be found in:
npm ERR!     /path/to/.npm/_logs/2021-12-04T02_13_47_618Z-debug.log

この問題を回避する為に、手動で $HOME/.npmrc をセットアップします。尚、セットアップ手順は、マネジメントコンソールから確認することが出来ます。

f:id:inokara:20211204115430p:plain

見切れてしまっているので、以下にも転載します。

以下のコマンドを実行して、環境変数に CodeArtifact の認証トークンをセットします。

export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain oreno-codeartifact --domain-owner ${AWS_ACCOUNT_ID} --query authorizationToken --output text`

そして、$HOME/.npmrc に以下を追記するようです。

registry=https://oreno-codeartifact-${AWS_ACCOUNT_ID}.d.codeartifact.ap-northeast-1.amazonaws.com/npm/oreno-repo/
//oreno-codeartifact-${AWS_ACCOUNT_ID}.d.codeartifact.ap-northeast-1.amazonaws.com/npm/oreno-repo/:always-auth=true
//oreno-codeartifact-${AWS_ACCOUNT_ID}.d.codeartifact.ap-northeast-1.amazonaws.com/npm/oreno-repo/:_authToken=${CODEARTIFACT_AUTH_TOKEN}

ただ、このままをセットすると、全てのパッケージの取得は、CodeArtifact から行おうとしてしまいます。

これを回避する為、以下のように修正します。

@oreno-repo:registry=https://oreno-codeartifact-${AWS_ACCOUNT_ID}.d.codeartifact.ap-northeast-1.amazonaws.com/npm/oreno-repo/
//oreno-codeartifact-${AWS_ACCOUNT_ID}.d.codeartifact.ap-northeast-1.amazonaws.com/npm/oreno-repo/:always-auth=true
//oreno-codeartifact-${AWS_ACCOUNT_ID}.d.codeartifact.ap-northeast-1.amazonaws.com/npm/oreno-repo/:_authToken=${CODEARTIFACT_AUTH_TOKEN}

パッケージをインストール

CodeArtifact の認証トークンを環境変数にセットして、npm i でパッケージをインストールします。

$ export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain oreno-codeartifact --domain-owner ${AWS_ACCOUNT_ID} --query authorizationToken --output text`
$ npm i

以下のように出力され、全てのパッケージのインストールが完了しました。

$ npm i
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated uuid@3.3.2: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.

added 95 packages, and audited 96 packages in 4s

20 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

$ npm list
sample-project@0.0.1 /path/to/project
├── @oreno-repo/oreno-sample@0.0.1
├── aws-sdk@2.1043.0
└── mocha@9.1.3

オレオレパッケージのバージョンは 0.0.2 にアップグレードしていたので、package.json を書き換えて、上書きインストールなんかしちゃいます。

{
  "name": "sample-project",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@oreno-repo/oreno-sample": "^0.0.2",
    "aws-sdk": "^2.1041.0",
    "mocha": "^9.1.3"
  }
}

インストール、パッケージの確認。

$ npm i

changed 1 package, and audited 96 packages in 2s

20 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

$  npm list
sample-project@0.0.1 /path/to/project
├── @oreno-repo/oreno-sample@0.0.2
├── aws-sdk@2.1043.0
└── mocha@9.1.3

いい感じです。

今回は、特定のパッケージだけを CodeArtifact 経由でインストールする方法を確認しました。CodeArtifact はあまり関係なくて、CodeArtifact がサポートしているパッケージレジストリの使い方を調べるような感じになってしまいましたが、やりたいことが 実現出来て良かったです。

ということで、引き続き、CI/CD サービスを利用した、オレオレパッケージを CodeArtifact に登録するオペレーションの自動化等をやっていきたいとお見ます。

引き続き、よろしくお願い致します。