version: 0.2
phases:
  # install:
  #   runtime-versions:
  #     docker: 19
  pre_build:
    commands:
      # ECRのリポジトリにログイン
      # - $(aws ecr get-login --no-include-email --region ${AWS_REGION})
      - aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

      ##### 環境変数の定義 ###################################
      # APP_NAME, APP_ENV はcodeBuildの環境変数を設定している。
      # envディレクティブで設定していないのはスクリプトで定義している部分があるため。
      # AWSのアカウントIDを$CODEBUILD_BUILD_ARNから取得
#      - OLDIFS=$IFS && IFS=':' && set -- ${CODEBUILD_BUILD_ARN} && AWS_ACCOUNT_ID=$5 && IFS=$OLDIFS
      - ROOT_DIR=`pwd`
      - REPOSITORY_URI_BASE=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${APP_NAME}-${APP_ENV}
      # gitのコミットID
      - COMMIT_HASH=`echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-9`
      - IMAGE_TAG=${COMMIT_HASH:=latest}
      - PROJECT_DIR=${ROOT_DIR}
      - SRC_DIR=${ROOT_DIR}/src
      - DOCKER_COMPOSE_FILE=${ROOT_DIR}/environments/ecs/docker-compose.${APP_ENV}.yml
      - DOCKER_DIR=${ROOT_DIR}/docker
      # 下記のDockerfileが変更されていたらイメージをビルドしてECRへpushする
      - DOCKERFILES="nginx php-fpm"
      - CACHE_DIR=${ROOT_DIR}/cache
      - IMGDEF_JSON_FILE=${ROOT_DIR}/environments/ecs/imagedefinitions.json
      # 環境変数初期値表示
      - |
        echo ">>> ENVs ->"
        echo ">>>     APP_NAME: ${APP_NAME}"
        echo ">>>     APP_ENV: ${APP_ENV}"
        echo ">>>     AWS_ACCOUNT_ID: ${AWS_ACCOUNT_ID}"
        echo ">>>     ROOT_DIR: ${ROOT_DIR}"
        echo ">>>     REPOSITORY_URI_BASE: ${REPOSITORY_URI_BASE}"
        echo ">>>     COMMIT_HASH: ${COMMIT_HASH}"
        echo ">>>     IMAGE_TAG: ${IMAGE_TAG}"
        echo ">>>     PROJECT_DIR: ${PROJECT_DIR}"
        echo ">>>     DOCKER_COMPOSE_FILE: ${DOCKER_COMPOSE_FILE}"
        echo ">>>     DOCKER_DIR: ${DOCKER_DIR}"
        echo ">>>     CACHE_DIR: ${CACHE_DIR}"
        echo ">>>     IMGDEF_JSON_FILE: ${IMGDEF_JSON_FILE}"
        echo ">>>     PRODUCTION_APP_ENV: ${PRODUCTION_APP_ENV}"
        echo ">>>     DOCKERHUB_USER: ${DOCKERHUB_USER}"
        echo ">>>     DOCKERHUB_PASSWORD: ${DOCKERHUB_PASSWORD}"

  build:
    commands:
      # node16をインストール
      - n 16.14
      - IMGDEF_JSON=""
      - cd ${PROJECT_DIR}; echo ">>> [dir] `pwd`"
      - CACHE_DIR_FOR_DOCKER=${CACHE_DIR}/docker
      - mkdir -p ${CACHE_DIR_FOR_DOCKER} 2>/dev/null
      ##### dockerイメージのビルド ###################################
      # Dockerfileが更新されていたらイメージをビルドしてECRへpush、されていなければlatestをpull
      - |
        set -e
        for target in ${DOCKERFILES}; do
          target_file=${target}/Dockerfile
          cached_dockerfile=${CACHE_DIR_FOR_DOCKER}/${target_file}
          original_dockerfile=${DOCKER_DIR}/${target_file}
          docker_image_on_ecr=${REPOSITORY_URI_BASE}/${target}
          docker_image_on_local=${APP_NAME}.${APP_ENV}/${target}
          IMGDEF_JSON=${IMGDEF_JSON}$(printf '{"name":"%s", "imageUri": "%s"},' ${target} ${docker_image_on_ecr}:${IMAGE_TAG})
          if [ -e ${cached_dockerfile} ]; then
            set -- $(sha256sum ${original_dockerfile});original_hash=$1;
            set -- $(sha256sum ${cached_dockerfile});cached_hash=$1;
            if [ $original_hash = $cached_hash ]; then
              # 更新されていなかったら
              echo ">>> ${original_dockerfile} is not updated."
              # テストやビルドに使うためにイメージをpull。
              docker pull ${docker_image_on_ecr}:latest
              docker tag ${docker_image_on_ecr}:latest ${docker_image_on_ecr}:${IMAGE_TAG}
              # 新しいタグをつける（これだと更新する度にタグが増えるので改善の余地あり）
              docker push ${docker_image_on_ecr}:${IMAGE_TAG}
              # ここでループ終わり
              continue
            fi
          fi
          # 更新されていたらもしくは初めてだったら
          echo ">>> ${original_dockerfile} is updated."
          docker-compose -f ${DOCKER_COMPOSE_FILE} build ${target}
          docker tag ${target} ${docker_image_on_ecr}:latest
          docker tag ${target} ${docker_image_on_ecr}:${IMAGE_TAG}
          docker push ${docker_image_on_ecr}:latest
          docker push ${docker_image_on_ecr}:${IMAGE_TAG}

          # キャッシュにDockerfileを保存
          [ ! -e ${CACHE_DIR_FOR_DOCKER}/${target} ] && mkdir -p ${CACHE_DIR_FOR_DOCKER}/${target}
          cp ${original_dockerfile} ${cached_dockerfile}
        done
      - cd ${PROJECT_DIR}; echo ">>> [dir] `pwd`"

      ##### appイメージのビルド ###################################
      - echo ">>> Composer version check ..."
      - COMPOSER_UPDATED=1
      - cd ${SRC_DIR}; echo ">>> [dir] `pwd`"
      # キャッシュがあってcomposer.lockに変更が無ければキャッシュからvendorを配置
      - |
        if [ -e ${CACHE_DIR}/composer.lock ] && [ -e ${CACHE_DIR}/vendor.tar ]; then
          diff ${CACHE_DIR}/composer.lock ./composer.lock
          if [ $? -eq 0 ]; then
            COMPOSER_UPDATED=0
            tar zxf ${CACHE_DIR}/vendor.tar
          fi
        fi
      - echo ">>> COMPOSER_UPDATED ${COMPOSER_UPDATED}"
      - cd ..; echo ">>> [dir] `pwd`"
      - docker ps
      - docker images
#      - docker run --rm -v ${SRC_DIR}:/var/www ${REPOSITORY_URI_BASE}/php-fpm composer install --no-dev --optimize-autoloader
      - docker run --rm -v ${SRC_DIR}:/var/www ${REPOSITORY_URI_BASE}/php-fpm composer install
#      - docker-compose -f ${DOCKER_COMPOSE_FILE} up -d php-fpm
#      - docker-compose -f ${DOCKER_COMPOSE_FILE} ps
#      - docker-compose -f ${DOCKER_COMPOSE_FILE} exec -T php-fpm composer install


       # キャッシュがあってpackage-lock.jsonに変更が無ければキャッシュからnode_modulesを配置
      - echo ">>> package-lock.json check ..."
      - YARN_UPDATED=1
      - cd ${SRC_DIR}; echo ">>> [dir] `pwd`"
      - |
        if [ -e ${CACHE_DIR}/package-lock.json ] && [ -e ${CACHE_DIR}/node_modules.tar ]; then
          diff ${CACHE_DIR}/package-lock.json ./package-lock.json
          if [ $? -eq 0 ]; then
            YARN_UPDATED=0
            tar zxf ${CACHE_DIR}/node_modules.tar
          fi
        fi
      - echo ">>> YARN_UPDATED ${YARN_UPDATED}"
      - cd ..; echo ">>> [dir] `pwd`"

      # Vueのコンパイル。
      - cd ${SRC_DIR}; echo ">>> [dir] `pwd`"
      - node -v
      - echo -e "${JS_CONFIG}" > resources/js/config.js
#      - yarn install
#      - yarn lint-fix:config
#      - yarn lint
#      - yarn prod
      - npm install
      - npm run prod
      # フロントをビルド。sassで4万行くらいDeprecatedがでるのでログを圧縮してある。
      # https://stackoverflow.com/questions/67675422/deprecation-warning-in-bootstrap-scss
#      - cd ${SRC_DIR}; echo ">>> [dir] `pwd`"
#      - npm cache verify
#      - npm ci
#      - |
#        if [ ${APP_ENV} != "production" ] || [ ${APP_ENV} != "prod" ]; then
#          npm run prod 2>&1 | gzip > ${ROOT_DIR}/environments/ecs/node.build.log.gz
#        else
#          npm run dev 2>&1 | gzip > ${ROOT_DIR}/environments/ecs/node.build.log.gz
#        fi
      # キャッシュを保存。 node_modulesをappへコピーしてしまうのでキャッシュしたら削除する。
      - cd ${SRC_DIR}; echo ">>> [dir] `pwd`"
      - |
        if [ ${COMPOSER_UPDATED} -eq 1 ]; then
          echo ">>> Caching vendor ..."
          cp composer.lock ${CACHE_DIR}/
          tar zcf ${CACHE_DIR}/vendor.tar vendor
        fi
        if [ ${YARN_UPDATED} -eq 1 ]; then
          echo ">>> Caching node_modules ..."
          cp package-lock.json ${CACHE_DIR}/
          tar zcf ${CACHE_DIR}/node_modules.tar node_modules
        fi
      - rm -rf node_modules

      # appのイメージを作成
      - cd ${PROJECT_DIR}; echo ">>> [dir] `pwd`"
      - |
        set -e
        docker-compose -f ${DOCKER_COMPOSE_FILE} build app
        docker tag app ${REPOSITORY_URI_BASE}/app:latest
        docker tag app ${REPOSITORY_URI_BASE}/app:${IMAGE_TAG}
        docker push ${REPOSITORY_URI_BASE}/app:latest
        docker push ${REPOSITORY_URI_BASE}/app:${IMAGE_TAG}
        IMGDEF_JSON=${IMGDEF_JSON}$(printf '{"name":"%s", "imageUri": "%s"},' 'app' ${REPOSITORY_URI_BASE}/app:${IMAGE_TAG})

      - cd ${ROOT_DIR}; echo ">>> [dir] `pwd`"

      ##### imagedefinitions.jsonの書き込み ###################################
      - IMGDEF_JSON="["${IMGDEF_JSON:0:${#IMGDEF_JSON}-1}"]"
      - echo ${IMGDEF_JSON}
      - echo ${IMGDEF_JSON} > ${IMGDEF_JSON_FILE}

artifacts:
  files:
    - '**/*'
  discard-paths: no
  base-directory: environments/ecs

cache:
  paths:
    - './cache/**/*'
