Cách duy nhất để tránh sai lầm là đừng có ý tưởng mới.
Albert Einstein
1. Trong rails
version: 2
jobs:
test:
docker:
- image: circleci/ruby:2.6.0-node
environment:
BUNDLE_JOBS: 3
BUNDLE_RETRY: 3
BUNDLE_PATH: vendor/bundle
RAILS_ENV: test
RACK_ENV: test
- image: circleci/postgres:9.6-ram
environment:
POSTGRES_USER: test
POSTGRES_DB: test
POSTGRES_PASSWORD: ""
- image: redis
steps:
- checkout
# Which version of bundler?
- run:
name: Which bundler?
command: bundle -v
# Restore bundle cache
- restore_cache:
keys:
- project-v1-{{ checksum "Gemfile.lock" }}
- project-v1-
- run:
name: Bundle Install
command: bundle check || bundle install
# Store bundle cache
- save_cache:
key: project-v1-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:5432 -timeout 1m
- run: |-
mkdir -p config && echo 'test:
adapter: postgresql
database: test
username: test
host: 127.0.0.1
' > config/database.yml
- run:
name: Prepare DB
command: bundle exec rake db:create db:schema:load --trace
- store_artifacts:
path: coverage
deploy_ssh:
docker:
- image: circleci/ruby:2.6-node
steps:
- add_ssh_keys:
fingerprints:
- "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1"
- run:
name: Deploy
command: |
ssh -o StrictHostKeyChecking=no ec2-user@deploy.server.com deploy.sh "$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME" $CIRCLE_BRANCH $CIRCLE_SHA1
workflows:
version: 2
test-deploy:
jobs:
- test
- deploy_ssh:
requires:
- test
filters:
branches:
only:
- deploy_test
- develop
- master
2. React
version: 2
jobs:
test:
docker:
# 3.6.5-stretch-node has NodeJS 8.11.1 and yarn 1.5.1 installed
- image: circleci/python:3.6.5-stretch-node
working_directory: ~/project/
steps:
- checkout
- save_cache:
key: v1-repo-{{ .Environment.CIRCLE_SHA1 }}
paths: ~/project/
- restore_cache:
key: v1-node-build-deps-{{ .Branch }}
- run:
name: Install node dependencies
command: npm install --no-progress
- save_cache:
key: v1-node-build-deps-{{ .Branch }}
paths:
- "~/project/node_modules"
- run:
name: Run tests and coverage
command: npm run test-coverage
deploy:
docker:
- image: circleci/python:3.6.5-stretch-node
working_directory: ~/project/
steps:
- restore_cache:
key: v1-repo-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
key: v1-node-build-deps-{{ .Branch }}
- run:
name: Prepare environment variables
command: |
commit_msg=$(git log -n 1 --pretty=format:"%B" ${CIRCLE_SHA1})
if [[ $commit_msg = *"__DEPLOY_TO_PRODUCTION__"* ]]; then
CONTAINS_PRODUCTION_DEPLOY=1
else
CONTAINS_PRODUCTION_DEPLOY=0
fi
case $CIRCLE_BRANCH in
"master")
if [[ $CONTAINS_PRODUCTION_DEPLOY = "1" ]]; then
DEPLOY_ENV=production
else
DEPLOY_ENV=staging
fi
;;
"develop")
DEPLOY_ENV=dev
;;
*)
esac
echo "export CONTAINS_PRODUCTION_DEPLOY=\"${CONTAINS_PRODUCTION_DEPLOY}\"" | tee -a "$BASH_ENV"
echo "export DEPLOY_ENV=\"${DEPLOY_ENV}\"" | tee -a "$BASH_ENV"
case $DEPLOY_ENV in
"production")
CF_DISTRIBUTION_ID=ABCDEFGHJIK
NPM_ENV='production'
REACT_APP_SENTRY_DSN_URL='https://1234567890987654322@sentry.io/12345678'
REACT_APP_ENV='production'
;;
"staging")
CF_DISTRIBUTION_ID=ABCDEFGHJIK
NPM_ENV='staging'
REACT_APP_SENTRY_DSN_URL='https://123456789009876543222@sentry.io/123456'
REACT_APP_ENV='staging'
;;
"dev")
CF_DISTRIBUTION_ID=ABCDEFGHJIK
NPM_ENV='dev'
REACT_APP_SENTRY_DSN_URL='https://12345678900987654323@sentry.io/123456'
REACT_APP_ENV='dev'
;;
*)
esac
echo "export CF_DISTRIBUTION_ID=\"${CF_DISTRIBUTION_ID}\"" | tee -a "$BASH_ENV"
echo "export S3_DIRECTORY=\"s3://bucket-name-${DEPLOY_ENV}\"" | tee -a "$BASH_ENV"
echo "export NPM_ENV=\"${NPM_ENV}\"" | tee -a "$BASH_ENV"
echo "export REACT_APP_SENTRY_DSN_URL=\"${REACT_APP_SENTRY_DSN_URL}\"" | tee -a "$BASH_ENV"
echo "export REACT_APP_ENV=\"${REACT_APP_ENV}\"" | tee -a "$BASH_ENV"
source "$BASH_ENV"
- restore_cache:
key: v1-deploy-deps-{{ .Branch }}
- run:
name: Install deployment Python deps in venv
command: |
python3 -m venv venv
. venv/bin/activate
pip install awscli
- save_cache:
key: v1-deploy-deps-{{ .Branch }}
paths:
- "~/project/venv"
- run:
name: Build
command: |
CI=false npm run build:${NPM_ENV}
- run:
name: Deploy to S3
command: |
. venv/bin/activate
echo "> Removing old files..."
aws s3 rm "${S3_DIRECTORY}"/project-rollback/ --recursive
echo "> Creating rollback..."
aws s3 cp "${S3_DIRECTORY}"/project/ "${S3_DIRECTORY}"/projtect-rollback/ --recursive
echo "> Uploading new files..."
aws s3 sync ./build "${S3_DIRECTORY}"/project/ --delete --exact-timestamps
echo "> Creating CloudFront invalidation"
aws cloudfront create-invalidation --distribution-id "$CF_DISTRIBUTION_ID" --paths "/project/*"
workflows:
version: 2
test-and-deploy:
jobs:
- test
- deploy:
requires:
- test
filters:
branches:
only:
- develop
- master
Comments
