クラウドワークス Advent Calendar 2020の10日目の記事となります。
今回は「DependabotとGithub Actionsで自動バージョンアップを実現する話」を書いていきます。
Dependabot について
Dependabot は Gemfile や package.json など、言語が持つパッケージ管理のマニフェストファイルを見て古かったり、安全ではないライブラリを発見してくれます。そして発見した依存関係を元に Pull Request(以下PR) を作成して通知してくれるツールです。
導入に関してはDependabot がGithubに買収されたことをきっかけにPreview 版から現在はGitHub公式のDependabot(Beta)が出来上がっているため今後はこれを使用していくことが推奨されます。
しかしGithub上でもまだBetaアイコンがついているためこれから・・・という感じかもしれませんが今の所問題なく使用できています。
なぜ使うのか
近年アプリケーション開発では、依存するライブラリの機能追加やセキュリティのアップデートに追従しておかないと気づいた時にはEOLになっていたり、致命的な脆弱性がでており個人情報が流出してしまうなど様々な問題が発生する可能性があります。
しかし、これらを全て把握し管理・運用していくのは並大抵の努力ではありません。
そこでDependabotを使うことで依存関係を管理し通知してもらい運用者の負荷を下げ、できるだけ早くバージョンアップを実現させていく事が重要となってきます。
Github Dependabot 導入の手順
Dependabot有効化の手順は下記に書いてありますが実際にやってみた結果や気になった点について触れてみます。
基本的には、.github/dependabot.yml
をリポジトリ上に設置すると動き出すと書かれていますが、ForkしたリポジトリでDependabotを有効にする場合はGUI上からも Enable Dependabot
を押して有効化を行わないといけません。(おそらくFork専用にGUI上に実装している感じもしますが初見だと少し紛らわしい感じがします)
さらに2020年12月現在GUI上でDependabotは、Insight
→ Dependency graph
の下にあるので、Setting
→Security & analysis
→ Dependency graph
のEnable
Dependency graph
を押せば使えるのかなと思っていたのですがこれも関係ありません。もう一度言いますが基本的にはファイルを設置するだけで使えます。
もう少し補足しておくと Dependency graph
はprivate repositoryでは default が Disable ですが、public repository では default が Enable になっていたりrepositoryによっても挙動が違っていますがまとめるとこんな感じです。
きちんとドキュメントを読めば簡単に理解できるのですが、Github上に思いの外Depend〇〇の機能が増えていてこれらの関連性がいまいちわかっていませんでした。
この辺りは最後のApendixにまとめておりますのでよければ見てください。
Dependabotの設定について
.github/dependabot.yml
を設置後、package-ecosystem
を使用して、監視するパッケージマネージャーを指定する必要があります。
選択できる対象はこちらにのっていますが今回はDockerを対象として実践していきます。
version: 2
updates:
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "daily"
time: "14:00"
timezone: "Asia/Tokyo"
target-branch: "develop"
パッケージマネージャーごとに、directory
と schedule.interval
を設定する必要があるため今回はdevelop branchを対象にdailyでチェックするようにファイルを作成しました。
その他、使用できるオプションはこちらに記載されていますのでご参考ください。
また、Dependabotはdefault branch にmergeしないと動かないのでファイルが完成したらPRを作成してください。
PR作成時、Github Actionsでのvalidationのcheckが入るのでおかしなところがあれば修正しておかないと動かない可能性があります。この辺りはうまく連携できていてすごくよさげです。
mergeすると設定したスケジュールでcheckが始まります。言語が持つパッケージ管理のマニフェストファイルなどを見て、新しいバージョンを見つけた場合は以下のようにPRを作成してくれます。
Dependabot Previewからの移行について
現在Dependabot Previewを使っていて移行したいという方はこちらにあるように下記2つの設定を有効にする必要があります。
- security updates
- version updates
security updates は Setting
→ Security & analysis
→ Dependabot security updates
の Enable
を押して有効化を(この時Dependabot alertsも有効化するように促されるのでこれも有効化する必要があります)
version updates は Dependabot Previewのコンソール上から Update config file を押してPRを作成する必要がありますが自分で .github/dependabot.yml
を作成して作り直しても構いません。
また、security updatesについてGithub上に取り込まれたことで設定箇所が分かれてしまいましたが、これから新規にDependabotを入れる方がいる場合は合わせて入れておく事をお勧めします。
Github Actionsと連携してCIを回していく
次に設定したDependabotをGithub Actionsと連携していきます。
と、言ってもPRを検知したらGithub Actionsでbuild&testを実行できるようにしておけば簡単に連携が可能となります。
こうすることで作業者はCHANGELOGやCommitを見て影響がなさそうであればmergeを押すだけの作業となり、作業時間の短縮につながります。
ただ以下のようなものも存在する場合があり全てが同じ仕組みで動かせるわけではありません。
- テストコードがないもの
- 開発(staging)環境のないもの
- テストが複雑でCI上でのテストが難しいもの
環境が不十分な場合はGithub Actionsの Comment on PR などを使用してPR作成時にどのように検証や確認を行うかなどコメントしてくれるようにしておくと便利になります。(Readmeに記載でも問題ないとは思いますが作業者が必ず全てを読んでくれているとは限りません)
name: Add checkout commands
on:
pull_request:
jobs:
comment:
name: Add checkout commands
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: harupy/comment-on-pr@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
filename: template.md
マージ後に以下の確認を行ってください。
- [ ] テスト1
- [ ] テスト2
稼働確認は別途Readmeを参照してください。
さらにmerge後deployの仕組みも入れておけばさらに自動化できるのでより便利になります。
簡単にこれらのSampleを載せておきます。
- PRがきたらgoとdockerのbuild&testを動かす
- Github Actions だと dcoker-composeがそのまま使えるのでこの辺りもすごく便利だなと感じました。
name: Test
on:
pull_request:
jobs:
gotest:
name: Go test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: 1.14.3
- uses: actions/cache@v2
id: cache
with:
path: |
~/go/pkg/mod/cache
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Install dependencies
run: go mod download
- name: Verify modules
run: go mod verify
- name: Tidy modules
run: go mod tidy
- name: go test
run: go test -v -cover ./...
connect_test:
name: Connect test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Docker pull
run: docker-compose pull
- name: Docker build
run: docker build -t hogehoge .
- name: Connect test
run: make test
- develop branchへのmerge時にAWSのECRにpushする
name: ECRPush
on:
push:
branches:
- develop
jobs:
ecr_push:
name: ECRPush
runs-on: ubuntu-latest
env:
AWS_REGION: ap-northeast-1
AWS_ACCOUNT: xxxxxxx
ECR_REPOSITORY: sample
IMAGE_TAG: latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ECR_REPOSITORY }}
IMAGE_TAG: ${{ env.IMAGE_TAG }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Logout of Amazon ECR
if: always()
run: docker logout ${{ steps.login-ecr.outputs.registry }}
そしてこれらを組み合わせることでDependabotとGithub Actionsで自動バージョンアップを実現させていきます。
自分が考えているフロー図を下記にまとめておきます。もちろんシステムや環境によって一概には言えませんが参考にしてみてください。
※青色の部分が人の手を介して作業を行う部分になります。
ということで今回DependabotとGithub Actionsで自動バージョンアップを実現する話を書きました。
Github Actionsはマーケットプレイスを見ると色んなworkflowが出てきているので、これから導入する方は必要なものを探し組み合わせよりよいCIを行なって行くことをお勧めします。
運用していく上での注意点について
Dependabotは非常に便利ですが、対応するリポジトリの量や依存するライブラリが多い場合はDependabotの通知ばかりきてしまい本来の業務に支障が出る場合もあります。最悪そのまま放置されるということもありがちなのでそれはあまり良くありません。
そのため入れるシステムの重要度や対象のパッケージマネージャーによってどういった頻度やバージョン単位(メジャーなのかマイナーなのかなど)でチェックしていくかも重要になってきます。
Appendix
始めに少し触れましたがDependa系は他にも色んな設定がありこれらも有効化しておくとさらに便利になりますが、ドキュメントなどをみてもひとつにまとまっている記事がなくそれぞれの関連性や機能を理解をするのに苦労をしました。
そのためここで簡単に紹介させていただきます。
Dependency graph
サポートされているファイル形式を使用して、サポートされているパッケージエコシステムの依存関係を定義するもの。サポート対象はこちら。
【Dependencies】
- Dependency graphによって、サポートされているエコシステムのマニフェストファイルとロックファイル、またはそれらに相当するものに詳細が示されている
- Dependency graph を有効化することで使用可能
【Dependents】
- public repositryの場合、リポジトリまたはパッケージに依存するリポジトリが報告される。
なお、private repositoryでは報告されない。
【Dependabot(Beta)】
- 本編で書いたので省略
Dependabot alerts
コードにセキュリティ脆弱性が発見されると、該当するコードがどのプロジェクトで利用されているかを追跡し、そのコードを利用しているユーザーに通知するもの
Dependabot security updates
Dependabotのセキュリティ更新により、リポジトリの依存関係グラフで脆弱な依存関係に対してDependabotアラートが発生すると、Dependabotは自動的にそれを修正しようとし、PRを発生させて、依存関係をパッチを含む最小バージョンに更新し、PRをDependabotアラートにリンクするか、アラートのエラーを報告する。
ただしこれはDependency graphとDependabot alertsを有効にしている場合のみ使用可能となる。
さいごに
GithubにはDependabotだけでなくDependenciesやDependabot security updatesなど様々な便利機能が備わっていました。
入れるのは比較的簡単なので、もし入れてないリポジトリがあれば入れてみて日々の運用に生かしてください。
ここまで読んでいただき、ありがとうございました。