Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support tagged releases in Travis, Ansible #656

Merged
merged 1 commit into from
Dec 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,20 @@ before_deploy:
- export PATH="$PATH:$HOME/.rvm/bin"
- export PHANTOMJS_CDNURL=http://cnpmjs.org/downloads
deploy:
provider: script
script: ".travis/deploy.sh"
skip_cleanup: true
on:
repo: WorldBank-Transport/DRIVER
branch: develop
- provider: script
script: ".travis/deploy_staging.sh"
skip_cleanup: true
on:
repo: WorldBank-Transport/DRIVER
branch: develop
- provider: script
script: ".travis/deploy.sh"
skip_cleanup: true
on:
repo: WorldBank-Transport/DRIVER
branch: master
tags: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may lead to two deployments that race, at least if we use git-flow. I think that the completion of a release branch will trigger a build for the merge into master, but also a build for the tagged commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding from the docs is that branch and tags are AND-ed together such that a build is only kicked off if it satisfies both conditions:

When all conditions specified in the on: section are met, your build will deploy.

https://docs.travis-ci.com/user/deployment#Conditional-Releases-with-on%3A

But I have no experience with this aspect of travis so it's definitely possible that that's not quite how it works.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. This may be true then. I was basing my understanding off of visually seeing builds get triggered for master and tagged commits whenever a release gets finalized (merges into master, develop, and tagged commit). It is possible that at the end of a build it ANDs these conditions together to make a decision.


after_deploy:
- rm deployment/driver.pem
- rm gradle/data/driver.keystore
Expand Down
34 changes: 3 additions & 31 deletions .travis/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,7 @@ set -x

for image in app editor web gradle analysis;
do
docker push "quay.io/azavea/driver-${image}:${TRAVIS_COMMIT:0:7}"
docker tag "quay.io/azavea/driver-${image}:${TRAVIS_COMMIT:0:7}" "quay.io/azavea/driver-${image}:latest"
docker push "quay.io/azavea/driver-${image}:latest"
docker push "quay.io/azavea/driver-${image}:${TRAVIS_TAG}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that if we remove on: master above, this will work. Otherwise, I think the TRAVIS_TAG environment variable will be unset when a build is triggered due to changes to master.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above; my understanding from the docs is that tags: true will prevent this from running if TRAVIS_TAG is unset.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this seems to back that up too:

tags: true: deployment is triggered if and only if $TRAVIS_TAG is set. Depending on your workflow, you may set $TRAVIS_TAG explicitly, even if this is a non-tag build when it was initiated. This causes the branch condition to be ignored.

docker tag "quay.io/azavea/driver-${image}:${TRAVIS_TAG}" "quay.io/azavea/driver-${image}:${TRAVIS_TAG}"
docker push "quay.io/azavea/driver-${image}:${TRAVIS_TAG}"
done

# TODO: The below was for deploying to our staging environment, which we no longer have.
# If staging is ever resurrected, we can re-enable this.
# Set up group vars
#echo "setting up group vars..."
#set +x
#grep -v nominatim_key deployment/ansible/group_vars/all.example \
# > deployment/ansible/group_vars/all
#echo "web_js_nominatim_key: \"${NOMINATIM_API_KEY}\"" \
# >> deployment/ansible/group_vars/all
#echo "oauth_client_id: \"${OAUTH_CLIENT_ID}\"" \
# >> deployment/ansible/group_vars/all
#echo "oauth_client_secret: \"${OAUTH_CLIENT_SECRET}\"" \
# >> deployment/ansible/group_vars/all
#echo "forecast_io_api_key: \"${FORECAST_IO_API_KEY}\"" \
# >> deployment/ansible/group_vars/all
#echo "keystore_password: \"${DRIVER_KEYSTORE_PASSWORD}\"" \
# >> deployment/ansible/group_vars/all
#set -x

#ansible-galaxy install -f -r deployment/ansible/roles.yml -p deployment/ansible/roles

#chmod 0600 deployment/driver.pem

#ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook \
# -i deployment/ansible/inventory/staging \
# --private-key="${TRAVIS_BUILD_DIR}/deployment/driver.pem" \
# deployment/ansible/database.yml deployment/ansible/app.yml deployment/ansible/celery.yml
39 changes: 39 additions & 0 deletions .travis/deploy_staging.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash

set -e
set -x

for image in app editor web gradle analysis;
do
docker push "quay.io/azavea/driver-${image}:${TRAVIS_COMMIT:0:7}"
docker tag "quay.io/azavea/driver-${image}:${TRAVIS_COMMIT:0:7}" "quay.io/azavea/driver-${image}:latest"
docker push "quay.io/azavea/driver-${image}:latest"
done

# TODO: The below was for deploying to our staging environment, which we no longer have.
# If staging is ever resurrected, we can re-enable this.
# Set up group vars
#echo "setting up group vars..."
#set +x
#grep -v nominatim_key deployment/ansible/group_vars/all.example \
# > deployment/ansible/group_vars/all
#echo "web_js_nominatim_key: \"${NOMINATIM_API_KEY}\"" \
# >> deployment/ansible/group_vars/all
#echo "oauth_client_id: \"${OAUTH_CLIENT_ID}\"" \
# >> deployment/ansible/group_vars/all
#echo "oauth_client_secret: \"${OAUTH_CLIENT_SECRET}\"" \
# >> deployment/ansible/group_vars/all
#echo "forecast_io_api_key: \"${FORECAST_IO_API_KEY}\"" \
# >> deployment/ansible/group_vars/all
#echo "keystore_password: \"${DRIVER_KEYSTORE_PASSWORD}\"" \
# >> deployment/ansible/group_vars/all
#set -x

#ansible-galaxy install -f -r deployment/ansible/roles.yml -p deployment/ansible/roles

#chmod 0600 deployment/driver.pem

#ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook \
# -i deployment/ansible/inventory/staging \
# --private-key="${TRAVIS_BUILD_DIR}/deployment/driver.pem" \
# deployment/ansible/database.yml deployment/ansible/app.yml deployment/ansible/celery.yml
6 changes: 6 additions & 0 deletions deployment/ansible/group_vars/all.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
---
# This is used ONLY when deploying to production to determine which docker image is used.
# To use a specific version locally, you'll need to `git checkout tags/<version>`
app_version: "1.0.0"
developing: "{{ 'development' in group_names }}"
developing_or_staging: "{{ 'development' in group_names or 'staging' in group_names }}"
not_developing: "{{ 'development' not in group_names }}"
Expand All @@ -9,6 +12,9 @@ production: "{{ 'production' in group_names }}"
docker_version: "1.10.*"
docker_py_version: "1.2.3"
docker_options: "--storage-driver=aufs"
# In local development, always use the 'latest' tag regardless of what app_version says;
# users need to checkout a tag in order to get a specific version.
docker_image_tag: "{% if developing %}latest{% else %}{{app_version}}{% endif %}"

python_version: "2.7.*"
pip_version: "1.*"
Expand Down
8 changes: 4 additions & 4 deletions deployment/ansible/roles/driver.app/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@
command: >
docker build
-f {{ root_app_dir }}/Dockerfile.base
-t quay.io/azavea/driver-app:latest
-t quay.io/azavea/driver-app:{{ docker_image_tag }}
{{ root_app_dir }}
when: developing

- name: Build application Docker image
- name: Build application Docker image (dev tools)
command: >
docker build
-f {{ root_app_dir }}/Dockerfile.development
-t quay.io/azavea/driver-app:latest
-t quay.io/azavea/driver-app:{{ docker_image_tag }}
{{ root_app_dir }}
when: developing

- name: Pull application Docker image
command: /usr/bin/docker pull quay.io/azavea/driver-app:latest
command: /usr/bin/docker pull quay.io/azavea/driver-app:{{ docker_image_tag }}
when: staging or production
notify:
- Restart driver-app
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pre-start script
/usr/bin/docker rm driver-app || true

{% if 'development' not in group_names -%}
/usr/bin/docker pull quay.io/azavea/driver-app:latest
/usr/bin/docker pull quay.io/azavea/driver-app:{{ docker_image_tag }}
{% endif %}
end script

Expand All @@ -41,7 +41,7 @@ exec /usr/bin/docker run \
--env DRIVER_ADMIN_GROUP='{{ driver_admin_group }}' \
--log-driver syslog \
{% if celery %} --entrypoint '/bin/bash -c' \
{% endif %} quay.io/azavea/driver-app:latest {% if celery %} \
{% endif %} quay.io/azavea/driver-app:{{ docker_image_tag }} {% if celery %} \
celery -A driver worker --queue=path --loglevel=info --concurrency=4
{% endif %}

Expand Down
8 changes: 4 additions & 4 deletions deployment/ansible/roles/driver.celery/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
command: >
docker build
-f {{ root_app_dir }}/Dockerfile.base
-t quay.io/azavea/driver-app:latest
-t quay.io/azavea/driver-app:{{ docker_image_tag }}
{{ root_app_dir }}
when: developing

- name: Build application Docker image
- name: Build application Docker image (dev tools)
command: >
docker build
-f {{ root_app_dir }}/Dockerfile.development
-t quay.io/azavea/driver-app:latest
-t quay.io/azavea/driver-app:{{ docker_image_tag }}
{{ root_app_dir }}
when: developing

- name: Pull application Docker image
command: /usr/bin/docker pull quay.io/azavea/driver-app:latest
command: /usr/bin/docker pull quay.io/azavea/driver-app:{{ docker_image_tag}}
when: staging or production
notify:
- Restart driver-celery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pre-start script
/usr/bin/docker rm driver-celery || true

{% if 'development' not in group_names -%}
/usr/bin/docker pull quay.io/azavea/driver-app:latest
/usr/bin/docker pull quay.io/azavea/driver-app:{{ docker_image_tag }}
{% endif %}
end script

Expand All @@ -36,7 +36,7 @@ exec /usr/bin/docker run \
{% endfor -%}
--log-driver syslog \
--entrypoint 'celery' \
quay.io/azavea/driver-app:latest \
quay.io/azavea/driver-app:{{ docker_image_tag }} \
-A driver worker --queue=taskworker \
--loglevel={% if 'development' in group_names %}debug{% else %}info{% endif %} \
--concurrency=4 \
Expand Down
4 changes: 2 additions & 2 deletions deployment/ansible/roles/driver.gradle/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
command: >
docker build
-f {{ gradle_dir }}/Dockerfile
-t quay.io/azavea/driver-gradle:latest
-t quay.io/azavea/driver-gradle:{{ docker_image_tag }}
{{ gradle_dir }}
when: developing

- name: Pull gradle Docker image
command: /usr/bin/docker pull quay.io/azavea/driver-gradle:latest
command: /usr/bin/docker pull quay.io/azavea/driver-gradle:{{ docker_image_tag }}
when: staging or production

- name: Configure gradle service definition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pre-start script
/usr/bin/docker rm driver-gradle || true

{% if 'development' not in group_names -%}
/usr/bin/docker pull quay.io/azavea/driver-gradle:latest
/usr/bin/docker pull quay.io/azavea/driver-gradle:{{ docker_image_tag }}
{% endif %}
end script

Expand All @@ -28,7 +28,7 @@ exec /usr/bin/docker run \
--env {{ k }}="{{ v }}" \
{% endfor -%}
--log-driver syslog \
quay.io/azavea/driver-gradle:latest
quay.io/azavea/driver-gradle:{{ docker_image_tag }}

post-stop script
/usr/bin/docker kill driver-gradle
Expand Down
4 changes: 2 additions & 2 deletions deployment/ansible/roles/driver.r-docker/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
command: >
docker build
-f {{ root_analysis_dir }}/Dockerfile
-t quay.io/azavea/driver-analysis:latest
-t quay.io/azavea/driver-analysis:{{ docker_image_tag }}
{{ root_analysis_dir }}
when: developing

- name: Pull application Docker image
command: /usr/bin/docker pull quay.io/azavea/driver-analysis:latest
command: /usr/bin/docker pull quay.io/azavea/driver-analysis:{{ docker_image_tag }}
when: staging or production
8 changes: 4 additions & 4 deletions deployment/ansible/roles/driver.web/tasks/development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
command: >
/usr/bin/docker build
-f {{ editor_dir }}/Dockerfile
-t quay.io/azavea/driver-editor:latest
-t quay.io/azavea/driver-editor:{{ docker_image_tag }}
{{ editor_dir }}

- name: Build production editor app
Expand All @@ -13,14 +13,14 @@
--name driver-editor
--volume {{ editor_dir }}:{{ editor_dir }}
--log-driver syslog
quay.io/azavea/driver-editor:latest
quay.io/azavea/driver-editor:{{ docker_image_tag }}
build

- name: Build web Docker image
command: >
/usr/bin/docker build
-f {{ web_dir }}/Dockerfile
-t quay.io/azavea/driver-web:latest
-t quay.io/azavea/driver-web:{{ docker_image_tag }}
{{ web_dir }}

- name: Build production web app
Expand All @@ -31,5 +31,5 @@
--volume {{ editor_dir }}:{{ editor_dir }}
--volume {{ web_dir }}:{{ web_dir }}
--log-driver syslog
quay.io/azavea/driver-web:latest
quay.io/azavea/driver-web:{{ docker_image_tag }}
build
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
- name: Pull editor Docker image
command: /usr/bin/docker pull quay.io/azavea/driver-editor:latest
command: /usr/bin/docker pull quay.io/azavea/driver-editor:{{ docker_image_tag }}

- name: Build production editor app
command: >
Expand All @@ -10,18 +10,18 @@
--volume {{ editor_scripts_dir }}/config.js:{{ editor_scripts_dir }}/config.js
--volume {{ editor_build_dir }}:{{ editor_build_dir }}
--log-driver syslog
quay.io/azavea/driver-editor:latest
quay.io/azavea/driver-editor:{{ docker_image_tag }}
build

- name: Create editor data container
command: >
/usr/bin/docker create
--volume {{ editor_dir }}
--name driver-editor
quay.io/azavea/driver-editor:latest
quay.io/azavea/driver-editor:{{ docker_image_tag }}

- name: Pull web Docker image
command: /usr/bin/docker pull quay.io/azavea/driver-web:latest
command: /usr/bin/docker pull quay.io/azavea/driver-web:{{ docker_image_tag }}

- name: Build production web app
command: >
Expand All @@ -34,7 +34,7 @@
--volume {{ web_dir }}/app/index.html:{{ web_dir }}/app/index.html
--volume {{ web_build_dir }}:{{ web_build_dir }}
--log-driver syslog
quay.io/azavea/driver-web:latest
quay.io/azavea/driver-web:{{ docker_image_tag }}
build

- name: Remove editor data container
Expand Down
4 changes: 3 additions & 1 deletion doc/system-administration.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ Each of these servers also includes:

## Deploying updates

Deploying updates to production is done using [Ansible](https://www.ansible.com/) (version must be at minimum 1.8). An `ansible-playbook` command is run, which uses the local configuration of the application files in the `deployment` directory to deploy updates to the remote servers. It is not necessary to have the application running locally, but it is necessary to have the latest source code, so make sure to pull down the latest version via `git pull`. In addition to the latest source code, there are four files not checked in to the repository that are needed in order to successfully deploy. These files are as follows
Deploying updates to production is done using [Ansible](https://www.ansible.com/) (version must be at minimum 1.8). An `ansible-playbook` command is run, which uses the local configuration of the application files in the `deployment` directory to deploy updates to the remote servers. It is not necessary to have the application running locally, but it is necessary to have the source code for the version you want to deploy, so make sure to pull down the latest version via `git pull` and then `git checkout tags/<version>`. In addition to the latest source code, there are four files not checked in to the repository that are needed in order to successfully deploy. These files are as follows

1. `production` group_vars - Defines the configured settings for the system. Must be placed in: `deployment/ansible/group_vars/`.
- Make sure to edit the `app_version` flag at the top of the `production` group_vars file to specify the version of the app you want to deploy
- Check out that tag with `git checkout tags/<version>`
2. `production` inventory - Defines the remote servers where code will be deployed. Must be placed in: `deployment/ansible/inventory/`.
3. `driver.keystore` - The signing keystore required for building Android APKs. Must be placed in: `gradle/data/`.
4. ssh identity file - The private key used for logging into the servers. This does not need to be placed in a particular location, but must be added via `ssh-add` before starting the deploy, so commands may be run on remote machines.
Expand Down