monorepoでCircleCIを使ってherokuへのdeployをする
はじめに
かなり特殊な構成なので自分以外には役に立たないかもしれませんが...
個人開発のプロジェクトをmonorepoで開発しているのですが、apiサーバーがherokuなので単純にmasterをそのままherokuにpushするとめちゃ不要なファイルなどが含まれてしまうという問題がありました。
gitignoreすればいいとは思いつつも、heroku用のgitignoreとgithubで管理するコード用のgitignoreみたいなことをするのも辛いので、 git worktree
を使ってheroku用のブランチへのpushを行い、それをherokuにもpushするというアプローチにしました。(以下の図のようなイメージ)
herokuまでのdeployの流れ
CircleCIの各jobの説明
build
jobは普通にgolangのbuildやtestなどを行うgit_push
jobはdeploy.sh
を実行して、 heroku用のworktreeを作成しgithub
にpushします- 一度ここでCircleCIのworkflowは途切れてしまいます
heroku_deploy
jobによって herokuのgitリポジトリに対してpushを行います- このpushでheroku側でdeployが行われます
登場するファイル(参考までに
deploy.sh
#!/bin/bash set -x # shellcheck disable=SC2006 if [ "`git status -s`" ] then echo "The working directory is dirty. Please commit any pending changes." exit 1; fi echo "Deleting old publication" rm -rf heroku mkdir heroku git worktree prune rm -rf .git/worktrees/heroku/ echo "Checking out heroku branch into heroku" git worktree add -B heroku heroku origin/heroku echo "Removing existing files" rm -rf heroku/* echo "Generating site" sh ./deploy_generate_file.sh echo "Updating heroku branch" cd heroku && git add --all && git commit -m "Publishing to heroku (deploy.sh)" echo "Pushing to github" git push -u origin heroku
deploy_generate_file.sh
#!/bin/bash set -x cp -r .circleci heroku # circleCIが動くようにするため cp -r api heroku # このディレクトリにapiサーバーのコードが入ってます(main.goとかとか) cp go.mod go.sum heroku # 訳あってgo.modが上位階層にあるのでそれもコピー cp app.json Procfile heroku # herokuのdeployに必要なファイル cd heroku && go mod vendor # heroku側でfetchしなくていいように(deployを早くするため)にgo mod vendor
circleci/config.yml
# Golang CircleCI 2.1 configuration file version: 2.1 jobs: build: docker: - image: circleci/golang:1.13 environment: GO111MODULE: "on" working_directory: /go/src/github.com/kyokomi/webapp-sandbox steps: - checkout - run: go get -u golang.org/x/lint/golint - run: go get -u golang.org/x/tools/cmd/goimports - run: make test_all - run: make build_api git_push: docker: - image: circleci/golang:1.13 environment: GO111MODULE: "on" working_directory: /go/src/github.com/kyokomi/webapp-sandbox steps: - checkout - run: name: git settings command: | git config --global user.email kyokomidev@gmail.com git config --global user.name circleci - run: sh deploy.sh heroku_deploy: docker: - image: buildpack-deps:trusty environment: HEROKU_APP_NAME: "kyokomi-webapp-sandbox" steps: - checkout - run: name: Deploy Master to Heroku command: | git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git master workflows: api_build_and_deploy: jobs: - build: filters: branches: ignore: heroku - git_push: requires: - build filters: branches: only: - master - heroku_deploy: filters: branches: only: - heroku