Github Actionsを全く使ったことがなかったので、学習がてらlambdaにzipを上げてみました。
なお、私はおひとりさま開発なので、チーム開発で参考にならないところがあったらごめんなさい。
また、現在も試行錯誤中なので、この記事がベストというわけではないです。
開発用ブランチはdevelop、マジ用ブランチはmain、lambdaの関数名はarea_information_city
とします。
roleのarnも適宜読み替えてください。
Github Actionsとは?
Githubが提供するCI/CDツールです。
利用にお金かかりそう...と思いましたが、ここに書いてある通り、パブリックリポジトリでは無料です。
準備すること
リポジトリに.github/workflows
というディレクトリを作り、その中にxxxx.yaml(yml)を作ります。
このyamlファイルはワークフローファイルと呼びます。
yaml拡張子について蛇足ですが、YAML公式はyaml推しだったようなので、Githubの例ではymlとなっていますが、我が家ではyamlで統一してます。
ワークフローの計画を立てる
次に、ワークフローの計画を立てます。今回やりたいのは以下です。
開発用ブランチのプッシュ時
開発ブランチではプッシュを検知してmypyとpylintと実行して、コード品質を担保します。
- python3.10の環境を準備する
- poetryをインストールする
- mypyとpylintを実行する
マジ用ブランチのプッシュ時
マジブランチではプッシュを検知してビルドとデプロイを行います。
- python3.10の環境を準備する
- AWSの認証情報をロードする
- poetryをインストールする
- poetryでビルドする
- ビルドしたパッケージを一旦ローカルに展開した上でzip化する
- lambdaにデプロイする
開発用ブランチのワークフローファイルを作成する
完成したものがこちらです。各項目の意味はコメントを参照。
# nameにワークフロー名を設定する。これがGithubリポジトリの[Actions]に表示される。
# なお、書かないと表示がフルパスのファイル名になってわかりにくい。
name: Test
on: # 実行のトリガーアクションを書く。
push: # pushでトリガーされる。
branches: # トリガー対象のブランチ。
- develop
jobs: # 複数ジョブをグルーピング。
test: # 単一ジョブをグルーピング。ここが[Actions]でジョブ名として表示される。
runs-on: ubuntu-latest # どの仮想マシン上でジョブを動かすかを決める。なんとMacOSもある...。
steps: # ジョブ内の処理(ステップ)をグルーピング。
- name: update python # ステップ名。[Actions]でステップ名として表示される。
# usesで、Githubやコミュニティが用意してくれているワークフローを使うことができる。
uses: actions/setup-python@v2
with: # この例では、ubuntuのpythonを3.10にしている。
python-version: '3.10'
architecture: 'x64'
- name: install poetry
# コマンドの実行はrunで行う。
run: curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
- name: set env
# 環境変数の設定はやや癖があり、以下のような設定をしないといけない。
run: echo "PATH=${PATH}:$HOME/.poetry/bin" >> $GITHUB_ENV
- name: checkout branch
uses: actions/checkout@v2 # このリポジトリをチェックアウトする
- name: install packages via poetry
run: poetry install
- name: check type annotation
run: poetry run mypy
- name: check lint
run: poetry run pylint area_information_city
マジ用ブランチのワークフローファイルを作成する
こちらも完成品を提示します。
name: Build Deploy
on:
push:
branches:
- main
workflow_dispatch:
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- name: update python
uses: actions/setup-python@v2
with:
python-version: '3.10'
architecture: 'x64'
- name: aws credential
# AWS公式のワークフローで、認証周りをよしなにやってくれるっぽいです。
# が、ENVへの設定でも良いのではという気も若干してます。
# secretsはGithubのSettings->Secrets->Actionsから登録します。
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: us-west-2
- name: install poetry
run: curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
- name: set env
run: echo "PATH=${PATH}:$HOME/.poetry/bin" >> $GITHUB_ENV
- name: checkout branch
uses: actions/checkout@v2
- name: build package
run: poetry build
- name: install package to local
run: pip install --upgrade -t package dist/*.whl
- name: copy lambda_function
run: cp lambda_function.py package/.
- name: zip local package for lambda
run: (cd package ; zip -r ../artifact.zip . -x '*.pyc')
# lambdaデプロイは、まず関数があるかどうかをチェック
# →あるならupdate、ないならcreate、という感じで実行します。
- name: check function
# idを付与することにより、後続でステップの終了ステータスを扱えるようになります。
# https://docs.github.com/ja/actions/learn-github-actions/contexts#steps-context
id: check-function
# continue-on-errorで失敗した場合でもジョブを継続するようにします。
continue-on-error: true
run: > # このyaml記法(>)は、最終行意外の行末がスペースに変換されます
aws lambda get-function
--function-name area_information_city
- name: create function
id: create-function
# ifを利用し、check-functionの結果がfailureだった場合(=関数が存在しない場合)に、
# このステップを実行するようにします。
if: steps.check-function.outcome == 'failure'
run: >
aws lambda create-function
--function-name area_information_city
--zip-file fileb://artifact.zip
--handler lambda_function.lambda_handler
--runtime python3.9
--role arn:aws:iam::999989709999:role/lambda-ex
--timeout 10
- name: update function
# ifを利用し、create-functionがskipされた場合(=関数が存在する場合)に、
# このステップを実行するようにします。(check-function.outcome == 'success'でも多分OK)
# なお、continue-on-errorを利用するとconclusionは必ずsuccessになってしまうので、
# create-functionではoutcomeを使いました。
# (outcome=continue-on-error適用前の結果 conclusion=continue-on-error的用語の結果)
if: steps.create-function.conclusion == 'skipped'
run: >
aws lambda update-function-code
--function-name area_information_city
--zip-file fileb://artifact.zip
おわりに
ざっくりと備忘がてらGithub Actionsの使用例を提示しました。
どなたかの参考になれば幸いです。
にしても、こんな機能がタダで使えるとは、すごい世の中になったものですね...。