Skip to content

Commit

Permalink
Improve Git deployment strategy with git archive
Browse files Browse the repository at this point in the history
Currently the deployment process looks like this:

1. Clone the repo into the `source` dir
2. Copy the `source` dir into a new release dir
3. Optionally move the `repo_subtree_path` directory to the release root
4. Optionally remove unwanted dirs in the new release

This process leads to some complications and bugs. By copying the entire
repo into the release dir and then moving the subtree, other directories
are left behind that you manually need to clean up.

There can also be conflicts if your subtree directory contains
directories with the same name as directories in the repo's root.

The new process looks like this:

1. Clone the repo into the `source` dir
2. Run `git archive` to populate the new release dir

`git archive` already supports subtrees and through `.git_attributes`,
other files/folders can be excluded.
  • Loading branch information
swalkinshaw committed Dec 30, 2015
1 parent fd9a69d commit fde4bea
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
### HEAD
* Improve Git deploy implementation via `git archive` ([#451](https://github.com/roots/trellis/pull/451))
* Replace strip_www with optional redirect to www/non-www ([#452](https://github.com/roots/trellis/pull/452))
* Accommodate file encryption via ansible vault ([#317](https://github.com/roots/trellis/pull/317))
* Fixes #353 - Allow insecure curl reqs for cron ([#450](https://github.com/roots/trellis/pull/450))
Expand Down
2 changes: 1 addition & 1 deletion group_vars/production/wordpress_sites.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ wordpress_sites:
local_path: ../site # path targeting local Bedrock site directory (relative to Ansible root)
repo: [email protected]:roots/bedrock.git
branch: master
# subtree_path: site # relative path to your Bedrock/WP directory in your repo (above) if it is not the root (like the roots-example-project structure)
# repo_subtree_path: site # relative path to your Bedrock/WP directory in your repo (above) if it is not the root (like the roots-example-project structure)
permalink_structure: "/%postname%/"
multisite:
enabled: false
Expand Down
2 changes: 1 addition & 1 deletion group_vars/staging/wordpress_sites.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ wordpress_sites:
local_path: ../site # path targeting local Bedrock site directory (relative to Ansible root)
repo: [email protected]:roots/bedrock.git
branch: master
# subtree_path: site # relative path to your Bedrock/WP directory in your repo (above) if it is not the root (like the roots-example-project structure)
# repo_subtree_path: site # relative path to your Bedrock/WP directory in your repo (above) if it is not the root (like the roots-example-project structure)
permalink_structure: "/%postname%/"
multisite:
enabled: false
Expand Down
5 changes: 1 addition & 4 deletions roles/deploy/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
# If you use the "git" strategy:
# - you must set a repository (no default)
project_git_repo: "{{ project.repo }}"
project_subtree_path: "{{ project.subtree_path | default(false) }}"
project_subtree_path: "{{ project.repo_subtree_path | default(false) }}"
# - you can set the git ref to deploy (can be a branch, tag or commit hash)
project_version: "{{ project.branch | default('master') }}"

# The source_path is used to fetch the tags from git, or synchronise via rsync. This way
# you do not have to download/sync the entire project on every deploy
project_source_path: "{{ project_root }}/shared/source"

# Files or folders to remove from the source when deploying
project_unwanted_items: ['.git']

# There are certain folders you'll want to copy from release to release to speed up deploys.
# Examples: Composer's `vendor` folder, npm's `node_modules`.
# These should not be part of project_shared_children since dependencies need to be atomic and tied to a deploy.
Expand Down
2 changes: 1 addition & 1 deletion roles/deploy/hooks/build-after.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

- 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."
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 `repo_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
Expand Down
34 changes: 19 additions & 15 deletions roles/deploy/tasks/prepare.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,32 @@
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
- name: Check for project repo subtree
stat:
path: "{{ deploy_helper.new_release_path }}/{{ project_subtree_path }}"
path: "{{ project_source_path }}/{{ project_subtree_path }}"
register: project_subtree_full_path
when: project_subtree_path != 'False'

- name: Fail if project_subtree_path is set incorrectly
- name: Fail if repo_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`."
msg: "repo subtree is set to '{{ project_subtree_path }}' but that path does not exist in the repo. Edit `repo_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
- name: Create new release dir
file:
path: "{{ deploy_helper.new_release_path }}/{{ item }}"
state: absent
with_items: project_unwanted_items
path: "{{ deploy_helper.new_release_path }}"
state: directory

- name: Run git archive to populate new build dir
shell: git archive {{ project_version }} | tar xf - -C {{ deploy_helper.new_release_path }}
args:
chdir: "{{ project_source_path }}"
when: project_subtree_path == 'False'

- name: Run git archive with subdirectory to populate new build dir
shell: git archive {{ project_version }} {{ project_subtree_path }} | tar -x --strip-components {{ project_subtree_path.split('/') | count }} -f - -C {{ deploy_helper.new_release_path }}
args:
chdir: "{{ project_source_path }}"
when: project_subtree_path != 'False'

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

0 comments on commit fde4bea

Please sign in to comment.