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

Deploy Hooks: use task files #378

Merged
merged 1 commit into from
Oct 9, 2015
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
### HEAD
* Add proper hooks for task files during deploys ([#378](https://github.com/roots/trellis/pull/378))
* Fix logrotate's Nginx postrotate script ([#377](https://github.com/roots/trellis/pull/377))
* Add static HTML files as fallbacks for Nginx's `index` directive ([#376](https://github.com/roots/trellis/pull/376))
* Use Windows environment variable to determine number of CPUs ([#366](https://github.com/roots/trellis/pull/366))
Expand Down
2 changes: 2 additions & 0 deletions deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
remote_user: "{{ web_user }}"

vars:
deploy_build_after: "{{ playbook_dir }}/roles/deploy/hooks/build-after.yml"
deploy_finalize_after: "{{ playbook_dir }}/roles/deploy/hooks/finalize-after.yml"
project: "{{ wordpress_sites[site] }}"
project_root: "{{ www_root }}/{{ site }}"

Expand Down
1 change: 1 addition & 0 deletions group_vars/all/users.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ users:
web_user: web
web_group: www-data
web_sudoers:
- "/usr/sbin/service hhvm *"
- "/usr/sbin/service php5-fpm *"
33 changes: 1 addition & 32 deletions roles/deploy/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,40 +56,9 @@ project_shared_children:
- path: web/app/uploads
src: uploads

# The project_environment is a list of environment variables added to the various *_commands
# The project_environment is a list of environment variables that can be used in hooks
# Example:
# project_environment:
# WP_ENV: "production"
project_environment:
WP_ENV: "{{ project.env.wp_env }}"

# There are a few moments in this role where arbitrary command(s) can be run. These commands receive
# the "project_environment" so deploys for different stages can be done by changing this.
# Each command is a dict with a `cmd` and an optional `path`. The `path` is relative to the
# local Trellis directory (for `project_pre_build_commands_local`) or relative to the
# `new_release_path` on the remote server (for `project_pre_build_commands` and `project_post_build_commands`).
# Examples:
# project_pre_build_commands_local:
# - path: "{{ project.local_path }}/web/app/themes/sage"
# cmd: gulp --production
# project_post_build_commands:
# - path: web/app/themes/mytheme
# cmd: npm install && gulp --production
# - cmd: wp db import posts.sql
project_pre_build_commands_local: []
project_pre_build_commands: []
project_post_build_commands:
- cmd: "composer install --no-ansi --no-dev --no-interaction --no-progress --optimize-autoloader --no-scripts"

# Post finalize commands are run with Ansible's `shell` module.
# These are meant primarily for service restarts such as php5-fpm or memcached.
project_post_finalize_commands:
- if wp core is-installed; then wp eval 'wp_clean_themes_cache(); switch_theme(get_stylesheet());'; fi
- sudo service php5-fpm reload

# At the end of the role, the unfinished_filename is removed and the "current" symlink is set to
# the release. If you need to perform your own actions before this happens, set "project_finalize"
# to false, and when you're ready, perform these tasks yourself:
# - file: path="{{ deploy.new_release_path }}/{{ deploy.unfinished_filename }}" state=absent
# - file: src="{{ deploy.new_release_path }} dest={{ deploy.current_path }}" state=link
project_finalize: true
15 changes: 15 additions & 0 deletions roles/deploy/hooks/build-after.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
- name: Check for composer.json in project root or project_subtree_path
stat:
path: "{{ deploy_helper.new_release_path }}/composer.json"
register: composer_json

- name: Fail if composer.json not found
fail:
msg: "Unable to find a `composer.json` file in the root of '{{ deploy_helper.new_release_path }}'. Make sure your repo has a `composer.json` file in its root or edit `subtree_path` for '{{ site }}' in `wordpress_sites.yml` so it points to the directory with a `composer.json` file."
when: not composer_json.stat.exists

- name: Install Composer dependencies
command: composer install --no-ansi --no-dev --no-interaction --no-progress --optimize-autoloader --no-scripts
args:
chdir: "{{ deploy_helper.new_release_path }}"
20 changes: 20 additions & 0 deletions roles/deploy/hooks/example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This is a placeholder example hook file
# To use deploy hooks, please refer to the docs at https://roots.io/trellis/docs/deploys
#
# tl;dr
# 1. create a tasks file you wish to include on a certain hook
# 2. set one of the below hook variables to "{{ playbook_dir }}/path/to/tasks-file.yml" in `deploy.yml`
#
# Available hooks:
# - deploy_initialize_before
# - deploy_initialize_after
# - deploy_update_before
# - deploy_update_after
# - deploy_prepare_before
# - deploy_prepare_after
# - deploy_build_before
# - deploy_build_after
# - deploy_share_before
# - deploy_share_after
# - deploy_finalize_before
# - deploy_finalize_after
26 changes: 26 additions & 0 deletions roles/deploy/hooks/finalize-after.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
- name: WordPress Installed?
command: wp core is-installed
args:
chdir: "{{ deploy_helper.new_release_path }}"
register: wp_installed
changed_when: false
failed_when: wp_installed.stderr != ""

- name: Update WP theme paths
command: wp eval 'wp_clean_themes_cache(); switch_theme(get_stylesheet());'
args:
chdir: "{{ deploy_helper.new_release_path }}"
when: wp_installed.rc == 0

- name: Reload php5-fpm
shell: sudo service php5-fpm reload
args:
chdir: "{{ deploy_helper.new_release_path }}"
when: not hhvm

- name: Restart HHVM
shell: sudo service hhvm restart
args:
chdir: "{{ deploy_helper.new_release_path }}"
when: hhvm
31 changes: 31 additions & 0 deletions roles/deploy/tasks/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
- include: "{{ deploy_build_before | default('../hooks/example.yml') }}"

- name: Copy project local files
synchronize:
src: "{{ item.src }}"
dest: "{{ deploy_helper.new_release_path }}/{{ item.dest }}"
group: no
owner: no
rsync_opts: --chmod=Du=rwx,--chmod=Dg=rx,--chmod=Do=rx,--chmod=Fu=rw,--chmod=Fg=r,--chmod=Fo=r
with_items: project_local_files

- name: Copy project templates
template:
src: "{{ item.src }}"
dest: "{{ deploy_helper.new_release_path }}/{{ item.dest }}"
mode: "{{ item.mode | default('0644') }}"
with_items: project_templates

- name: Check if project folders exist
stat:
path: "{{ deploy_helper.current_path }}/{{ item }}"
register: project_folder_paths
with_items: project_copy_folders

- name: Copy project folders
command: cp -rp {{ deploy_helper.current_path }}/{{ item.item }} {{ deploy_helper.new_release_path }}
with_items: project_folder_paths.results
when: item.stat.exists

- include: "{{ deploy_build_after | default('../hooks/example.yml') }}"
13 changes: 13 additions & 0 deletions roles/deploy/tasks/finalize.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- include: "{{ deploy_finalize_before | default('../hooks/example.yml') }}"

- name: Finalize the deploy
deploy_helper:
path: "{{ project_root }}"
release: "{{ deploy_helper.new_release }}"
state: finalize

- include: "{{ deploy_finalize_after | default('../hooks/example.yml') }}"

- debug:
msg: "{{ project_version }}@{{ git_commit.after | truncate(7, True, '') }} deployed as release {{ deploy_helper.new_release }}"
9 changes: 9 additions & 0 deletions roles/deploy/tasks/initialize.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
- include: "{{ deploy_initialize_before | default('../hooks/example.yml') }}"

- name: Initialize
deploy_helper:
path: "{{ project_root }}"
state: present

- include: "{{ deploy_initialize_after | default('../hooks/example.yml') }}"
123 changes: 6 additions & 117 deletions roles/deploy/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,118 +1,7 @@
---
- name: Initialize
deploy_helper: path="{{ project_root }}" state=present

- name: Check whether project source path is a git repo
stat: path={{ project_source_path }}/.git
register: git_project

- name: Get current git remote URL
command: git config --get remote.origin.url
args:
chdir: "{{ project_source_path }}"
register: remote_origin_url
when: git_project.stat.exists
changed_when: false

- name: Update git remote URL
command: git remote set-url origin {{ project_git_repo }}
args:
chdir: "{{ project_source_path }}"
when: git_project.stat.exists and remote_origin_url.stdout != project_git_repo

- name: Clone project files
git: repo="{{ project_git_repo }}"
dest="{{ project_source_path }}"
version="{{ project_version }}"
accept_hostkey=yes
register: git_commit

- name: write unfinished file
file: path="{{ project_source_path }}/{{ deploy_helper.unfinished_filename }}" state=touch

- name: Copy files to new build dir
command: cp -pr {{ project_source_path }} {{ deploy_helper.new_release_path }}

- name: Check for project subtree
stat: path={{ deploy_helper.new_release_path }}/{{ project_subtree_path }}
register: project_subtree_full_path
when: project_subtree_path != 'False'

- name: Fail if project_subtree_path is set incorrectly
fail: msg="subtree is set to '{{ project_subtree_path }}' but that path does not exist in the repo. Edit `subtree_path` for '{{ site }}' in `wordpress_sites.yml`."
when: project_subtree_path != 'False' and not project_subtree_full_path.stat.exists

- name: Move project subtree into root folder
shell: mv {{ deploy_helper.new_release_path }}/{{ project_subtree_path }}/* {{ deploy_helper.new_release_path }}
when: project_subtree_path != 'False'

- name: Remove unwanted files/folders from new release
file: path="{{ deploy_helper.new_release_path }}/{{ item }}" state=absent
with_items: project_unwanted_items

- name: Run pre_build_commands_local on Ansible host
local_action: "command {{ item.cmd }}"
args:
chdir: "{{ item.path }}"
with_items: project_pre_build_commands_local

- name: Copy project local files
synchronize: src="{{ item.src }}"
dest="{{ deploy_helper.new_release_path }}/{{ item.dest }}"
group=no
owner=no
rsync_opts=--chmod=Du=rwx,--chmod=Dg=rx,--chmod=Do=rx,--chmod=Fu=rw,--chmod=Fg=r,--chmod=Fo=r
with_items: project_local_files

- name: Copy project templates
template: src="{{ item.src }}" dest="{{ deploy_helper.new_release_path }}/{{ item.dest }}" mode="{{ item.mode | default('0644') }}"
with_items: project_templates

- name: Run pre_build_commands in the new_release_path
command: "{{ item.cmd }}"
args:
chdir: "{{ [deploy_helper.new_release_path, item.path] | select('defined') | join('/') }}"
with_items: project_pre_build_commands
environment: project_environment

- name: Check if project folders exist
stat: path="{{ deploy_helper.current_path }}/{{ item }}"
register: project_folder_paths
with_items: project_copy_folders

- name: Copy project folders
command: cp -rp {{ deploy_helper.current_path }}/{{ item.item }} {{ deploy_helper.new_release_path }}
with_items: project_folder_paths.results
when: item.stat.exists == True

- name: Ensure shared sources are present
file: path="{{ deploy_helper.shared_path }}/{{ item.src }}" state="{{ item.type | default('directory') }}" mode="{{ item.mode | default('0755') }}"
with_items: project_shared_children

- name: Ensure shared paths are absent
file: path="{{ deploy_helper.new_release_path }}/{{ item.path }}" state=absent
with_items: project_shared_children

- name: Create shared symlinks
file: path="{{ deploy_helper.new_release_path }}/{{ item.path }}" src="{{ deploy_helper.shared_path }}/{{ item.src }}" state=link
with_items: project_shared_children

- name: Run post_build_commands in the new_release_path
command: "{{ item.cmd }}"
args:
chdir: "{{ [deploy_helper.new_release_path, item.path] | select('defined') | join('/') }}"
with_items: project_post_build_commands
environment: project_environment

- name: Finalize the deploy
deploy_helper: path="{{ project_root }}" release="{{ deploy_helper.new_release }}" state=finalize
when: project_finalize

- name: Run post_finalize_commands
shell: "{{ item }}"
args:
chdir: "{{ deploy_helper.new_release_path }}"
with_items: project_post_finalize_commands

- debug:
msg: "{{ project_version }}@{{ git_commit.after | truncate(7, True, '') }} deployed as release {{ deploy_helper.new_release }}"
- include: initialize.yml
- include: update.yml
- include: prepare.yml
- include: build.yml
- include: share.yml
- include: finalize.yml
33 changes: 33 additions & 0 deletions roles/deploy/tasks/prepare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
- include: "{{ deploy_prepare_before | default('../hooks/example.yml') }}"

- name: write unfinished file
file:
path: "{{ project_source_path }}/{{ deploy_helper.unfinished_filename }}"
state: touch

- name: Copy files to new build dir
command: cp -pr {{ project_source_path }} {{ deploy_helper.new_release_path }}

- name: Check for project subtree
stat:
path: "{{ deploy_helper.new_release_path }}/{{ project_subtree_path }}"
register: project_subtree_full_path
when: project_subtree_path != 'False'

- name: Fail if project_subtree_path is set incorrectly
fail:
msg: "subtree is set to '{{ project_subtree_path }}' but that path does not exist in the repo. Edit `subtree_path` for '{{ site }}' in `wordpress_sites.yml`."
when: project_subtree_path != 'False' and not project_subtree_full_path.stat.exists

- name: Move project subtree into root folder
shell: mv {{ deploy_helper.new_release_path }}/{{ project_subtree_path }}/* {{ deploy_helper.new_release_path }}
when: project_subtree_path != 'False'

- name: Remove unwanted files/folders from new release
file:
path: "{{ deploy_helper.new_release_path }}/{{ item }}"
state: absent
with_items: project_unwanted_items

- include: "{{ deploy_prepare_after | default('../hooks/example.yml') }}"
24 changes: 24 additions & 0 deletions roles/deploy/tasks/share.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
- include: "{{ deploy_share_before | default('../hooks/example.yml') }}"

- name: Ensure shared sources are present
file:
path: "{{ deploy_helper.shared_path }}/{{ item.src }}"
state: "{{ item.type | default('directory') }}"
mode: "{{ item.mode | default('0755') }}"
with_items: project_shared_children

- name: Ensure shared paths are absent
file:
path: "{{ deploy_helper.new_release_path }}/{{ item.path }}"
state: absent
with_items: project_shared_children

- name: Create shared symlinks
file:
path: "{{ deploy_helper.new_release_path }}/{{ item.path }}"
src: "{{ deploy_helper.shared_path }}/{{ item.src }}"
state: link
with_items: project_shared_children

- include: "{{ deploy_share_after | default('../hooks/example.yml') }}"
31 changes: 31 additions & 0 deletions roles/deploy/tasks/update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
- include: "{{ deploy_update_before | default('../hooks/example.yml') }}"

- name: Check whether project source path is a git repo
stat:
path: "{{ project_source_path }}/.git"
register: git_project

- name: Get current git remote URL
command: git config --get remote.origin.url
args:
chdir: "{{ project_source_path }}"
register: remote_origin_url
when: git_project.stat.exists
changed_when: false

- name: Update git remote URL
command: git remote set-url origin {{ project_git_repo }}
args:
chdir: "{{ project_source_path }}"
when: git_project.stat.exists and remote_origin_url.stdout != project_git_repo

- name: Clone project files
git:
repo: "{{ project_git_repo }}"
dest: "{{ project_source_path }}"
version: "{{ project_version }}"
accept_hostkey: yes
register: git_commit

- include: "{{ deploy_update_after | default('../hooks/example.yml') }}"