From 6723f3a51e0e5d898474a5f37b8883cc6797ea13 Mon Sep 17 00:00:00 2001 From: Ben Word Date: Fri, 25 Jul 2025 22:23:58 -0400 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=9A=A7=20Bedrock=20v2=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roles/deploy/tasks/bedrock-detection.yml | 38 ++++++ roles/deploy/tasks/prepare.yml | 3 + .../tasks/bedrock-detection.yml | 109 ++++++++++++++++++ roles/wordpress-setup/tasks/main.yml | 3 + 4 files changed, 153 insertions(+) create mode 100644 roles/deploy/tasks/bedrock-detection.yml create mode 100644 roles/wordpress-setup/tasks/bedrock-detection.yml diff --git a/roles/deploy/tasks/bedrock-detection.yml b/roles/deploy/tasks/bedrock-detection.yml new file mode 100644 index 0000000000..97ec183a49 --- /dev/null +++ b/roles/deploy/tasks/bedrock-detection.yml @@ -0,0 +1,38 @@ +--- +# Bedrock version detection for deployment +# This detects whether the deployed code uses Bedrock v1 (web/) or v2 (public/) structure + +- name: Check for Bedrock v2 structure in deployment (public directory) + stat: + path: "{{ deploy_helper.new_release_path }}/public" + register: deploy_bedrock_v2_check + +- name: Check for Bedrock v1 structure in deployment (web directory) + stat: + path: "{{ deploy_helper.new_release_path }}/web" + register: deploy_bedrock_v1_check + +- name: Set public_path based on detected Bedrock version in deployment + set_fact: + detected_public_path: "{{ + deploy_bedrock_v2_check.stat.exists | ternary('public', + deploy_bedrock_v1_check.stat.exists | ternary('web', + site_env.public_path | default('web'))) + }}" + detected_upload_path: "{{ + deploy_bedrock_v2_check.stat.exists | ternary('uploads', + deploy_bedrock_v1_check.stat.exists | ternary('app/uploads', + project.upload_path | default('app/uploads'))) + }}" + +- name: Update site environment with detected public path + set_fact: + site_env: "{{ site_env | combine({'public_path': detected_public_path}) }}" + +- name: Update project configuration with detected paths + set_fact: + project: "{{ project | combine({'public_path': detected_public_path, 'upload_path': detected_upload_path}) }}" + +- name: Debug detected Bedrock structure for deployment + debug: + msg: "Deployment for {{ site }}: Using {{ detected_public_path }} directory (Bedrock {{ 'v2' if detected_public_path == 'public' else 'v1' }}), uploads: {{ detected_upload_path }}" diff --git a/roles/deploy/tasks/prepare.yml b/roles/deploy/tasks/prepare.yml index 33ae769999..c2c8ff107d 100644 --- a/roles/deploy/tasks/prepare.yml +++ b/roles/deploy/tasks/prepare.yml @@ -48,6 +48,9 @@ executable: /bin/bash when: project.repo_subtree_path is defined +- import_tasks: bedrock-detection.yml + tags: bedrock-detection + - name: write unfinished file file: path: "{{ deploy_helper.new_release_path }}/{{ deploy_helper.unfinished_filename }}" diff --git a/roles/wordpress-setup/tasks/bedrock-detection.yml b/roles/wordpress-setup/tasks/bedrock-detection.yml new file mode 100644 index 0000000000..e3de52e3c8 --- /dev/null +++ b/roles/wordpress-setup/tasks/bedrock-detection.yml @@ -0,0 +1,109 @@ +--- +# This task detects whether the project uses Bedrock v1 (web/) or v2 (public/) structure +# and automatically adjusts paths accordingly + +- name: Check for Bedrock v2 structure (public directory) - Development + stat: + path: "{{ item.value.local_path }}/public" + register: bedrock_v2_local_check + delegate_to: localhost + become: false + loop: "{{ wordpress_sites | dict2items }}" + loop_control: + label: "{{ item.key }}" + when: + - ansible_connection != 'winrm' + - item.value.local_path is defined + - ansible_hostname == 'vagrant' or inventory_hostname in groups['development'] + +- name: Check for Bedrock v1 structure (web directory) - Development + stat: + path: "{{ item.value.local_path }}/web" + register: bedrock_v1_local_check + delegate_to: localhost + become: false + loop: "{{ wordpress_sites | dict2items }}" + loop_control: + label: "{{ item.key }}" + when: + - ansible_connection != 'winrm' + - item.value.local_path is defined + - ansible_hostname == 'vagrant' or inventory_hostname in groups['development'] + +- name: Check for Bedrock v2 structure (public directory) - Remote/Deployed + stat: + path: "{{ www_root }}/{{ item.key }}/{{ item.value.current_path | default('current') }}/public" + register: bedrock_v2_remote_check + loop: "{{ wordpress_sites | dict2items }}" + loop_control: + label: "{{ item.key }}" + when: + - ansible_connection != 'winrm' + - not (ansible_hostname == 'vagrant' or inventory_hostname in groups['development']) + +- name: Check for Bedrock v1 structure (web directory) - Remote/Deployed + stat: + path: "{{ www_root }}/{{ item.key }}/{{ item.value.current_path | default('current') }}/web" + register: bedrock_v1_remote_check + loop: "{{ wordpress_sites | dict2items }}" + loop_control: + label: "{{ item.key }}" + when: + - ansible_connection != 'winrm' + - not (ansible_hostname == 'vagrant' or inventory_hostname in groups['development']) + +- name: Set public_path based on detected Bedrock version - Development + set_fact: + wordpress_sites: "{{ wordpress_sites | combine({ + item.key: item.value | combine({ + 'public_path': ( + bedrock_v2_local_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('public', + bedrock_v1_local_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('web', + item.value.public_path | default('web'))), + 'upload_path': ( + bedrock_v2_local_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('uploads', + bedrock_v1_local_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('app/uploads', + item.value.upload_path | default('app/uploads')))) + }) + }) + }) }}" + loop: "{{ wordpress_sites | dict2items }}" + loop_control: + label: "{{ item.key }}" + extended: true + when: + - ansible_connection != 'winrm' + - ansible_hostname == 'vagrant' or inventory_hostname in groups['development'] + - bedrock_v2_local_check.results is defined + +- name: Set public_path based on detected Bedrock version - Remote/Deployed + set_fact: + wordpress_sites: "{{ wordpress_sites | combine({ + item.key: item.value | combine({ + 'public_path': ( + bedrock_v2_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('public', + bedrock_v1_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('web', + item.value.public_path | default('web'))), + 'upload_path': ( + bedrock_v2_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('uploads', + bedrock_v1_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('app/uploads', + item.value.upload_path | default('app/uploads')))) + }) + }) + }) }}" + loop: "{{ wordpress_sites | dict2items }}" + loop_control: + label: "{{ item.key }}" + extended: true + when: + - ansible_connection != 'winrm' + - not (ansible_hostname == 'vagrant' or inventory_hostname in groups['development']) + - bedrock_v2_remote_check.results is defined + +- name: Debug detected Bedrock structure + debug: + msg: "Site {{ item.key }}: Using {{ item.value.public_path }} directory (Bedrock {{ 'v2' if item.value.public_path == 'public' else 'v1' }}), uploads: {{ item.value.upload_path | default('app/uploads') }}" + loop: "{{ wordpress_sites | dict2items }}" + loop_control: + label: "{{ item.key }}" + when: ansible_connection != 'winrm' diff --git a/roles/wordpress-setup/tasks/main.yml b/roles/wordpress-setup/tasks/main.yml index 890d7078aa..0d55d5938d 100644 --- a/roles/wordpress-setup/tasks/main.yml +++ b/roles/wordpress-setup/tasks/main.yml @@ -39,6 +39,9 @@ when: disable_default_pool | default(true) notify: reload php-fpm +- import_tasks: bedrock-detection.yml + tags: bedrock-detection + - import_tasks: nginx-includes.yml tags: [nginx-includes, wordpress-setup-nginx] From ca4814e700d602114fbaff0224d90d824dcb7ecc Mon Sep 17 00:00:00 2001 From: Ben Word Date: Fri, 1 Aug 2025 12:45:10 -0400 Subject: [PATCH 2/3] syntax --- roles/wordpress-setup/tasks/bedrock-detection.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/wordpress-setup/tasks/bedrock-detection.yml b/roles/wordpress-setup/tasks/bedrock-detection.yml index e3de52e3c8..9f08f74a47 100644 --- a/roles/wordpress-setup/tasks/bedrock-detection.yml +++ b/roles/wordpress-setup/tasks/bedrock-detection.yml @@ -83,7 +83,7 @@ 'public_path': ( bedrock_v2_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('public', bedrock_v1_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('web', - item.value.public_path | default('web'))), + item.value.public_path | default('web')))), 'upload_path': ( bedrock_v2_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('uploads', bedrock_v1_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('app/uploads', From a43dec372fe9dd8b6543e669b4bde9efec72ec42 Mon Sep 17 00:00:00 2001 From: Ben Word Date: Fri, 1 Aug 2025 12:55:27 -0400 Subject: [PATCH 3/3] better --- .../tasks/bedrock-detection.yml | 118 +++++++----------- 1 file changed, 45 insertions(+), 73 deletions(-) diff --git a/roles/wordpress-setup/tasks/bedrock-detection.yml b/roles/wordpress-setup/tasks/bedrock-detection.yml index 9f08f74a47..a88a1aa101 100644 --- a/roles/wordpress-setup/tasks/bedrock-detection.yml +++ b/roles/wordpress-setup/tasks/bedrock-detection.yml @@ -2,108 +2,80 @@ # This task detects whether the project uses Bedrock v1 (web/) or v2 (public/) structure # and automatically adjusts paths accordingly -- name: Check for Bedrock v2 structure (public directory) - Development +- name: Check for Bedrock v2 config file stat: - path: "{{ item.value.local_path }}/public" - register: bedrock_v2_local_check - delegate_to: localhost - become: false + path: "{{ site_path }}/config.php" + register: bedrock_v2_config_check + vars: + site_path: "{{ item.value.local_path | default(www_root + '/' + item.key + '/' + (item.value.current_path | default('current'))) }}" loop: "{{ wordpress_sites | dict2items }}" loop_control: label: "{{ item.key }}" - when: - - ansible_connection != 'winrm' - - item.value.local_path is defined - - ansible_hostname == 'vagrant' or inventory_hostname in groups['development'] -- name: Check for Bedrock v1 structure (web directory) - Development +- name: Check for Bedrock v1 config file stat: - path: "{{ item.value.local_path }}/web" - register: bedrock_v1_local_check - delegate_to: localhost - become: false + path: "{{ site_path }}/config/application.php" + register: bedrock_v1_config_check + vars: + site_path: "{{ item.value.local_path | default(www_root + '/' + item.key + '/' + (item.value.current_path | default('current'))) }}" loop: "{{ wordpress_sites | dict2items }}" loop_control: label: "{{ item.key }}" - when: - - ansible_connection != 'winrm' - - item.value.local_path is defined - - ansible_hostname == 'vagrant' or inventory_hostname in groups['development'] -- name: Check for Bedrock v2 structure (public directory) - Remote/Deployed +- name: Check for public directory stat: - path: "{{ www_root }}/{{ item.key }}/{{ item.value.current_path | default('current') }}/public" - register: bedrock_v2_remote_check + path: "{{ site_path }}/public" + register: public_dir_check + vars: + site_path: "{{ item.value.local_path | default(www_root + '/' + item.key + '/' + (item.value.current_path | default('current'))) }}" loop: "{{ wordpress_sites | dict2items }}" loop_control: label: "{{ item.key }}" - when: - - ansible_connection != 'winrm' - - not (ansible_hostname == 'vagrant' or inventory_hostname in groups['development']) -- name: Check for Bedrock v1 structure (web directory) - Remote/Deployed +- name: Check for web directory stat: - path: "{{ www_root }}/{{ item.key }}/{{ item.value.current_path | default('current') }}/web" - register: bedrock_v1_remote_check + path: "{{ site_path }}/web" + register: web_dir_check + vars: + site_path: "{{ item.value.local_path | default(www_root + '/' + item.key + '/' + (item.value.current_path | default('current'))) }}" loop: "{{ wordpress_sites | dict2items }}" loop_control: label: "{{ item.key }}" - when: - - ansible_connection != 'winrm' - - not (ansible_hostname == 'vagrant' or inventory_hostname in groups['development']) -- name: Set public_path based on detected Bedrock version - Development +- name: Set public_path and upload_path based on detected Bedrock version set_fact: wordpress_sites: "{{ wordpress_sites | combine({ item.key: item.value | combine({ - 'public_path': ( - bedrock_v2_local_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('public', - bedrock_v1_local_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('web', - item.value.public_path | default('web'))), - 'upload_path': ( - bedrock_v2_local_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('uploads', - bedrock_v1_local_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('app/uploads', - item.value.upload_path | default('app/uploads')))) - }) + 'public_path': detected_public_path, + 'upload_path': detected_upload_path }) }) }}" + vars: + site_results: "{{ bedrock_v2_config_check.results | selectattr('item.key', 'equalto', item.key) | first }}" + has_v2_config: "{{ site_results.stat.exists | default(false) }}" + site_results_v1: "{{ bedrock_v1_config_check.results | selectattr('item.key', 'equalto', item.key) | first }}" + has_v1_config: "{{ site_results_v1.stat.exists | default(false) }}" + site_results_public: "{{ public_dir_check.results | selectattr('item.key', 'equalto', item.key) | first }}" + has_public_dir: "{{ site_results_public.stat.exists | default(false) }}" + site_results_web: "{{ web_dir_check.results | selectattr('item.key', 'equalto', item.key) | first }}" + has_web_dir: "{{ site_results_web.stat.exists | default(false) }}" + detected_public_path: "{{ 'public' if (has_v2_config and has_public_dir) else ('web' if (has_v1_config and has_web_dir) else ('public' if has_public_dir else 'web')) }}" + detected_upload_path: "{{ 'uploads' if (has_v2_config and has_public_dir) else 'app/uploads' }}" loop: "{{ wordpress_sites | dict2items }}" loop_control: label: "{{ item.key }}" - extended: true - when: - - ansible_connection != 'winrm' - - ansible_hostname == 'vagrant' or inventory_hostname in groups['development'] - - bedrock_v2_local_check.results is defined -- name: Set public_path based on detected Bedrock version - Remote/Deployed - set_fact: - wordpress_sites: "{{ wordpress_sites | combine({ - item.key: item.value | combine({ - 'public_path': ( - bedrock_v2_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('public', - bedrock_v1_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('web', - item.value.public_path | default('web')))), - 'upload_path': ( - bedrock_v2_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('uploads', - bedrock_v1_remote_check.results[ansible_loop.index0].stat.exists | default(false) | ternary('app/uploads', - item.value.upload_path | default('app/uploads')))) - }) - }) - }) }}" - loop: "{{ wordpress_sites | dict2items }}" - loop_control: - label: "{{ item.key }}" - extended: true +- name: Validate Bedrock structure + fail: + msg: "Ambiguous Bedrock structure detected: Both v1 and v2 config files exist for {{ item.key }}" + vars: + site_results: "{{ bedrock_v2_config_check.results | selectattr('item.key', 'equalto', item.key) | first }}" + has_v2_config: "{{ site_results.stat.exists | default(false) }}" + site_results_v1: "{{ bedrock_v1_config_check.results | selectattr('item.key', 'equalto', item.key) | first }}" + has_v1_config: "{{ site_results_v1.stat.exists | default(false) }}" when: - - ansible_connection != 'winrm' - - not (ansible_hostname == 'vagrant' or inventory_hostname in groups['development']) - - bedrock_v2_remote_check.results is defined - -- name: Debug detected Bedrock structure - debug: - msg: "Site {{ item.key }}: Using {{ item.value.public_path }} directory (Bedrock {{ 'v2' if item.value.public_path == 'public' else 'v1' }}), uploads: {{ item.value.upload_path | default('app/uploads') }}" + - has_v2_config + - has_v1_config loop: "{{ wordpress_sites | dict2items }}" loop_control: - label: "{{ item.key }}" - when: ansible_connection != 'winrm' + label: "{{ item.key }}" \ No newline at end of file