circleciã®build/test/deployãgithub actions(beta)ã«ç§»è¡ãã
ã¾ã æ©è½çã«è¶³ããªãã¨ãããããããé å¼µã£ãã使ããæè¦ã ã£ãã
githubã«ãfeedbackãéããæãããã°éããã¨æãã
circleciã§ãã£ã¦ãããã¨ã¯ãã£ããæ¸ãã¨ä»¥ä¸ã
- testç³»
- buildç³»(only master)
- base imageã®build & push
- k8sä¸ã§åããprod imageã®build & push
- deployç³»(only master)
- GKEä¸ã«helm secrets upgrade
ãããgithub actionsã«ç§»è¡ããéã«circleciã¨ã®å·®åãæããæ©è½ã¯ä»¥ä¸ã
- slackéç¥
- èªåã®ãªãã¸ããªã§ã¯æªå®è£ ãããã©ã«ãã¯å¤±æããã¨ã¡ã¼ã«éç¥ãæ¥ã
- æªç¢ºèªã ãå¤åãããããªäººãbetaåãã®slackéç¥actionsãæ¸ãã¦ããã®ã§ã¯ãªãããã
- ãã®ãã¡è¯ãããªactionsãããã°æ¡ç¨ãããã¨æãããéè¯ã極å使ããããªãã®ã§ã§ããã°å ¬å¼orgã®ä¸ã§ãµãã¼ããã¦ã»ãã
- ç¾ç¶ã§ä½¿ããããªã®ã¯ https://github.com/pullreminders/slack-action
- ãã ãèªåã§payloadãstringå½¢å¼ã®jsonã§è¨è¿°ãããã¨ã«ãªãå人çã«ã¯è¾ãã®ã§å¾ ã¡
- ã¨è¨ããªããèªçãã GitHub Actions(beta)向けにslack通知プラグインを作った - 839の日記
- filteræ©è½
- ymlåä½ã§ããbranchã®filteræ©è½ãåå¨ããªã
- 1ã¤ã®workflowã«è¤æ°jobãå®ç¾©ãã¦ãjobã®ä¾åé¢ä¿ãæããã¦ããã¨ãã«å°ã
- e.g. featureãã©ã³ãã§ã¯test jobã ãèµ°ãããããmasterãã©ã³ãã§ã¯test/buildã並åãã¦èµ°ããã両æ¹ã¨ãæåãããdeployãè¡ã
- circleciã®ããã«jobåä½ã§branch filterãè¡ããããã«ãªã£ã¦ãã¦ã»ãã
- workflow(yml)ãåããå ´åã¯å¥workflowã®jobã®ç¶æ æ¤ç¥ãã§ããªããã¨ã¯ç¢ºèª
- ymlåä½ã§ããbranchã®filteræ©è½ãåå¨ããªã
- cacheæ©è½
- azure pipelineã®æ¹ã«ã¯ä¸å¿ããããã ããgithub actionsã«ã¯ããã¥ã¡ã³ããèªãã æãã ã¨è¦å½ãããªãã£ã
- circleciã¯freeãã¤privateã ã¨ä¸¦åã«èµ°ãããããªãããgithub actionsã¯ä¸¦åå®è¡ã§ããã®ã§çµæçã«ãã³ãã³ãããã®é度ã§çµãã£ã¦ãã
- circleciã§ã¯build/testãç´åã ã£ãããgithub actionsã«ãªã£ã¦ä¸¦åå®è¡ã«ãªã£ããããã¼ã¿ã«ã®å¾ ã¡æéãæ¸ã£ãããã£ãã·ã¥ããªãã®ã§jobåä½ã®å®è¡é度ã¯ä¼¸ã³ã
dirty hackãããã°ãããããã£ãã·ã¥ãå¯è½- https://github.com/actions/toolkit/tree/master/packages/tool-cache
- setup-goã¨ãã¯å
é¨çã«ä¸è¨ã使ã£ã¦ãã£ãã·ã¥ãã¦ãã
- ã¨æã£ã¦ããããå®ã¯ãã£ãã·ã¥ããã¦ããªãã£ãã®ã§issueãç«ã¦ã*1ãæåã®åéãã§ä»æ§ã ã£ã
- artifacts
- ã¢ãããã¼ãããæ¹æ³ã¯ããããã ã*2ãæ¹æ³ã«ã¤ãã¦ããã¥ã¡ã³ããè¦ã¤ããããªãã£ã*3
- å ¬å¼ãã©ã°ã¤ã³ã¨ãã¦æä¾ããã¦ãã https://github.com/actions/upload-artifact
- ã¢ãããã¼ãããæ¹æ³ã¯ããããã ã*2ãæ¹æ³ã«ã¤ãã¦ããã¥ã¡ã³ããè¦ã¤ããããªãã£ã*3
- environment variable
- stepåä½ã§ããæå®ã§ããªãã®ã§å ¨ã¦ã®stepã§æå®ãããenvironment variableãããã¨è¨è¿°ãåé·ã«ãªã
- secrets
- env keyã§ã®ã¿æå®ã§ãã模æ§
- circleciã¯envã¨secretãåä¸ã®ãããªæ±ã(envã¯ç®¡çç»é¢ã§ãfilterããã)ã ããgithub actionsã¯ããæ±ããç°ãªã
- è¤æ°å使ãsteps.ifã®æ¯è¼å¤ãsecretsçµç±ã§ä¸å 管çã«ãããã¨ãããã使ããªããããå¼¾ããã
- env keyã§ã®ã¿æå®ã§ãã模æ§
- dockerã®prepare
- circleciã§ã¯æ示çã«æå®ããå¿ è¦ããã£ãããgithub actionsã§ã¯ç¹ã«ãã¦ããªã使ããã®ã¯DXãããã£ã
- mergeæã®æå
- github actionsã¯mergeããéã¯2åactionãèµ°ã模æ§
ããã¯ä¸å ·åããï¼ã¨æã£ããä½ãçç±ãããã®ãããããªããèªåã§ä½¿ãéã¯2åèµ°ãã¨å®å ¨ã«ç¡é§ãªã®ã§steps.ifã§filterãã¦ãã
ymlèªä½ã®æ¸ãå³ã®éãã¯ãã£ããã¨æ¸ãã¨ä»¥ä¸ã®æãã
circleci
version: 2.1 orbs: gcr: circleci/[email protected] gke: circleci/[email protected] docker: circleci/[email protected] jobs: test-job: working_directory: /go/src/github.com/8398a7/app docker: - image: circleci/golang:1.12.6-stretch environment: CI: "true" GO111MODULE: "on" steps: - checkout - restore_cache: key: prepare-ci-tools-{{ checksum "scripts/prepare-ci-tools.sh" }} - run: name: prepare ci tools command: scripts/prepare-ci-tools.sh - save_cache: key: prepare-ci-tools-{{ checksum "scripts/prepare-ci-tools.sh" }} paths: - ./bin - run: name: helm-lint command: scripts/helm-lint.sh - run: name: kubeval command: scripts/kubeval.sh - restore_cache: key: go-mod-{{ checksum "go.mod" }} - run: name: go mod download command: go mod download - save_cache: key: go-mod-{{ checksum "go.mod" }} paths: - /go/pkg/mod/cache - run: name: golangci-lint run command: bin/golangci-lint run - run: name: test command: make test - run: name: build command: make build - store_artifacts: path: /go/src/github.com/8398a7/app/cover.html build-job: working_directory: /go/src/github.com/8398a7/app docker: - image: google/cloud-sdk steps: - checkout - setup_remote_docker - docker/check - run: name: pull app-base command: docker pull 8398a7/app-base:latest - docker/build: image: 8398a7/app-base dockerfile: build/Dockerfile extra_build_args: --cache-from 8398a7/app-base:latest tag: latest - docker/push: image: 8398a7/app-base tag: latest - gcr/build-image: image: app dockerfile: build/app/Dockerfile tag: $(get tag) - gcr/gcr-auth - gcr/push-image: image: app tag: $(get tag) deploy-job: machine: true environment: HELM_HOME: /home/circleci/.helm GOOGLE_APPLICATION_CREDENTIALS: /home/circleci/gcloud-service-key.json steps: - checkout - restore_cache: key: prepare-cd-tools-{{ checksum "scripts/prepare-cd-tools.sh" }} - run: name: prepare cd tools command: scripts/prepare-cd-tools.sh - save_cache: key: prepare-cd-tools-{{ checksum "scripts/prepare-cd-tools.sh" }} paths: - ./bin - gke/install - gke/init - run: name: get credentials command: gcloud container clusters get-credentials $GKE_CLUSTER - run: name: upgrade app command: bin/helm secrets upgrade prod-app ./deployments/app --install --wait --namespace app -f ./deployments/values.yaml -f ./deployments/secrets.yaml --set app.image.tag=$(get tag) workflows: version: 2 test-build-deploy-workflow: jobs: - test-job - build-job: filters: branches: only: master - deploy-job: requires: - test-job - build-job filters: branches: only: master
github actions
name: CI on: [push] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - uses: actions/setup-go@v1 with: version: 1.12.6 id: go - run: scripts/prepare-ci-tools.sh - run: scripts/helm-lint.sh env: CI: true - run: scripts/kubeval.sh env: CI: true - run: go mod download - run: bin/golangci-lint run - run: make test - run: make build - uses: actions/upload-artifact@master with: name: coverage path: cover.html build: runs-on: ubuntu-latest steps: - uses: actions/checkout@master if: contains(github.ref, 'master') - name: docker login run: echo $DOCKER_PASSWORD | docker login -u 8398a7 --password-stdin docker.io if: contains(github.ref, 'master') env: DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - name: pull app-base run: docker pull 8398a7/app-base:latest if: contains(github.ref, 'master') - name: build app-base run: docker build -t 8398a7/app-base:latest --cache-from 8398a7/app-base:latest -f build/Dockerfile . if: contains(github.ref, 'master') - name: push app-base run: docker push 8398a7/app-base:latest if: contains(github.ref, 'master') - name: build gcr.io/gcp_project/app run: docker build -t gcr.io/gcp_project/app:$(get tag) -f build/app/Dockerfile . if: contains(github.ref, 'master') - name: install gcloud sdk run: | export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - sudo apt-get update && sudo apt-get install -y google-cloud-sdk if: contains(github.ref, 'master') - name: initialize gcloud sdk run: | echo $GCLOUD_SERVICE_KEY > ${HOME}/gcloud-service-key.json gcloud auth activate-service-account --key-file=${HOME}/gcloud-service-key.json gcloud --quiet config set project gcp_project gcloud --quiet config set compute/zone gcp_zone gcloud auth configure-docker --quiet --project gcp_project env: GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }} if: contains(github.ref, 'master') - name: push gcr.io/gcp_project/app run: docker push gcr.io/gcp_project/app:$(get tag) if: contains(github.ref, 'master') deploy: runs-on: ubuntu-latest needs: [test, build] steps: - uses: actions/checkout@master if: contains(github.ref, 'master') - name: install gcloud sdk run: | export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - sudo apt-get update && sudo apt-get install -y google-cloud-sdk if: contains(github.ref, 'master') - name: initialize gcloud sdk run: | echo $GCLOUD_SERVICE_KEY > ${HOME}/gcloud-service-key.json gcloud auth activate-service-account --key-file=${HOME}/gcloud-service-key.json gcloud --quiet config set project gcp_project gcloud --quiet config set compute/zone gcp_zone env: GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }} if: contains(github.ref, 'master') - run: scripts/prepare-cd-tools.sh env: HELM_HOME: /home/runner/.helm if: contains(github.ref, 'master') - name: get credentials run: gcloud container clusters get-credentials gke_cluster if: contains(github.ref, 'master') - name: upgrade app run: bin/helm secrets upgrade prod-app ./deployments/app --install --wait --namespace app -f ./deployments/values.yaml -f ./deployments/secrets.yaml --set app.image.tag=$(get tag) env: HELM_HOME: /home/runner/.helm GOOGLE_APPLICATION_CREDENTIALS: /home/runner/gcloud-service-key.json if: contains(github.ref, 'master')
è¦ã¦ã®éããcircleciã®jobåä½branch filteræ©è½ããªãã®ã§ããã«è©²å½ãããã®ã¯å ¨ã¦ã«steps.ifã§ãã©ã³ãã®filterãããã¦ããã
ã¾ããmasterãã¼ã¸æã®2åçºç«ãé²ãããgithub.event.afterã§ãæ¡ä»¶ãæ¸ãã¦ãããã¾ããmasteræã«branch delete eventã§jobãèµ°ãããªãããã«github.event.deletedãè¦ã¦æ¡ä»¶ãæ¸ãã¦ããã- 8/17é ããbranch delete eventã§ã¯çºç«ããªããªã£ããããªã®ã§æ¡ä»¶ãæ¸ãå¿ è¦ããªããªã£ã
æ£ç´å
¨ã¦ã®stepã§åãifãä½åº¦ãæ¸ãã®ã¯è¦æ ããã¡ã³ããã³ã¹æ§ãæªãã®ã§ãjobåä½branch filterã¯ã»ãããªãã¨æããã
ã¡ãªã¿ã«workflowãrerunãããã¨ãã«ã¯githubã§åå¾ã§ããå¤ãã¡ãã£ã¨éãããã§ãdeployç³»ããã¾ãåä½ããªãã£ãã
"ref": "refs/heads/master", "sha": "dd47c626ef90ca4ee193d02a1cc0a253a5ba53a6", "repository": "8398a7/app", "repositoryUrl": "git://github.com/8398a7/app.git", "actor": "8398a7", "workflow": "CI", "head_ref": "", "base_ref": "", "event_name": "push", "event": *** "action": "rerequested", "check_suite": *** "after": "dd47c626ef90ca4ee193d02a1cc0a253a5ba53a6", "app": ***
event.check_suiteã®ä¸ã«afterãçããããã«ãªã£ã¦ããã
"description": "Powers your .github/main.workflow.",
ã¨ãæ¸ããã¦ãããã¾ã HCLã®ãã®ã®æåãå¼ããã£ã¦ããããã®ãããããªãâ¦ã
ä¸è¨ã®ãããªæãã§ç§»è¡ãã¦ã¿ãããcircleciã®free planä¸éãå²ã¨å³ããæãããã®ã§github actionsã«ç§»è¡ãã¦ãã®ãããã¯è§£æ¶ãããããªã®ãããã£ãã
GAã«ãªãã¾ã§ã«æ¹è¯ããããå¤æ´ããããããã¨æãã®ã§ç¶ç¶çã«æ´æ°ãã¦ããããã¨æãã