WerckerCI + CodeDeployでGolangのCI環境を整える

結構ハマってしまったので設定ファイルを残しておきます。
① Werckerでビルドし、
② CodeDeployでEC2にデプロイ
という流れにしています。

develop環境ではCodeDeployを使わずにscpを使ってデプロイしてます。頻繁にビルド＆デプロイを行うので、毎回S3にビルド成果物を置くのがもったいないと考えたのでそうしました。（大した金額にならないと思うので置くのもありですが）

CodeDeployはAutoScaleグループに対してローリングデプロイができ、便利です。

## wercker.yml

```yaml
box: golang

build:
  steps:
    - setup-go-workspace

    # Check go and gb version
    - script:
        name: check go version
        code: |
          go version

    # Build the project
    - script:
        name: gb build
        code: |
          go get github.com/constabulary/gb/...
          gb vendor restore
          gb build

    # Test the project
    - script:
        name: gb test
        code: |
          gb test -v

    - script:
        name: artifacts copy
        code: |
          cp -a ./bin ./conf ./resources ./server ./appspec.yml ./deploy_script $WERCKER_OUTPUT_DIR

  # slack notification
  after-steps:
    - slack-notifier:
        url: $SLACK_URL
        channel: wercker
        username: wercker
        icon_url: $SLACK_ICON_URL
        notify_on: "failed"

deploy:
  development:
    - script:
        name: show archive files
        code: |
          find .

    - script:
        name: archive
        code: |
          FILE_DATE=$(date +"%Y%m%d_%H%M")
          FILE_NAME=${FILE_DATE}.tgz
          tar zcvf $FILE_NAME *
          mkdir artifact
          mv $FILE_NAME artifact

    - add-ssh-key:
        keyname: WERCKER_SSH_KEY_PRIVATE

    # deploy to development server
    - script:
        name: scp deploy to development server
        code: |
          ssh -o "StrictHostKeyChecking=no" ec2-user@$SERVER_DEVELOPMENT 'rm -rf /opt/app/api/*'
          scp -o "StrictHostKeyChecking=no" -r artifact/* ec2-user@$SERVER_DEVELOPMENT:/opt/app/api/
          ssh -o "StrictHostKeyChecking=no" ec2-user@$SERVER_DEVELOPMENT 'cd /opt/app/api && tar zxvf *tgz'
          ssh -o "StrictHostKeyChecking=no" ec2-user@$SERVER_DEVELOPMENT 'sudo /usr/local/bin/supervisorctl restart all && sudo /usr/local/bin/supervisorctl status'

  production:
    - script:
        name: show archive files
        code: |
          find .

    - script:
        name: archive
        code: |
          FILE_DATE=$(date +"%Y%m%d_%H%M")
          FILE_NAME=${FILE_DATE}.tgz
          tar zcvf $FILE_NAME *
          mkdir artifact
          mv $FILE_NAME artifact

    - s3sync:
        key-id: $AWS_ACCESS_KEY_ID
        key-secret: $AWS_SECRET_ACCESS_KEY
        bucket-url: s3://$AWS_BUCKET_NAME/$AWS_BUCKET_PATH/
        source-dir: artifact/
        delete-removed: false

    - script:
        name: install pyinstaller
        code: |
          python --version
          which python
          wget https://bootstrap.pypa.io/get-pip.py
          python get-pip.py
          sudo pip install awscli

    - script:
        name: CodeDeploy
        code: |
          aws deploy create-deployment \
           --application-name app-api \
           --s3-location bucket=$AWS_BUCKET_NAME,key=$AWS_BUCKET_PATH/$FILE_NAME,bundleType=tgz \
           --deployment-group-name deploy-group-app-api \
           --region ap-northeast-1

  # slack notification
  after-steps:
    - slack-notifier:
        url: $SLACK_URL
        channel: wercker
        username: wercker
        icon-url: $SLACK_ICON_URL
```

## appspec.yml
```yaml
version: 0.0
os: linux

files:
  - source: /
    destination: /opt/app/api

hooks:
  # アプリケーションを停止
  ApplicationStop:
    - location: deploy_script/stop_application.sh
      timeout: 300
      runas: root

  # ビルド先のフィルを削除する
  BeforeInstall:
    - location: deploy_script/before_install.sh
      timeout: 300
      runas: root

  # アプリケーションを起動
  ApplicationStart:
    - location: deploy_script/start_application.sh
      timeout: 300
      runas: root
```

## deploy_script/stop_application.sh
```bash
#!/bin/sh
/usr/local/bin/supervisorctl stop unisize-api
```

## deploy_script/stop_application.sh
```bash
#!/bin/sh
rm -rf /opt/unisize/unisize-api/*
```

## deploy_script/start_application.sh
```bash
#!/bin/sh
service supervisord start
/usr/local/bin/supervisorctl start unisize-api
```


golangはテスト＆ビルドが早くていい！