diff --git a/.ddev/commands/host/.utils b/.ddev/commands/host/.utils new file mode 100755 index 0000000..99a7b5c --- /dev/null +++ b/.ddev/commands/host/.utils @@ -0,0 +1,9 @@ +#!/bin/bash + +function verbose_output() { + if [ "$VERBOSE_INSTALL" = true ]; then + "$@" + else + "$@" > /dev/null + fi +} diff --git a/.ddev/commands/host/ibexa-setup b/.ddev/commands/host/ibexa-setup new file mode 100755 index 0000000..e858a62 --- /dev/null +++ b/.ddev/commands/host/ibexa-setup @@ -0,0 +1,164 @@ +#!/bin/bash + +## #ddev-generated +## Description: This script reads settings from `ddev ibexa-configurator` and sets up ddev +## Usage: ibexa-setup +## Example: ddev ibexa-setup + +source .ddev/commands/host/.utils + +[ -z "$SETTINGS_FILE" ] && SETTINGS_FILE="./.ddev/.ibexa-instance-settings" +[ -z "$PROVISION_FILE_GENERAL" ] && PROVISION_FILE_GENERAL="./.ddev/.ibexa-setup-general-provisioned" +[ -z "$PROVISION_FILE_SERVICES" ] && PROVISION_FILE_SERVICES="./.ddev/.ibexa-setup-services-provisioned" +[ -z "$VERBOSE_INSTALL" ] && VERBOSE_INSTALL=false + +if [ "$VERBOSE_INSTALL" != false ] && [ ! -f "$PROVISION_FILE_GENERAL" ] && [ ! -f "$PROVISION_FILE_SERVICES" ]; then + clear +fi + +if [ ! -f "$SETTINGS_FILE" ]; then + echo "Settings file does not exist, run ddev ibexa-configurator first." + exit 1 +fi + +source $SETTINGS_FILE + +if [ ! -f "$PROVISION_FILE_GENERAL" ]; then + # Project name + ddev config --project-name="$DDEV_SITENAME" + + # PHP + echo "php_version: $PHP_VERSION" > .ddev/config.php.yaml + echo "👷 Configured PHP version: $PHP_VERSION" + + # NodeJS + echo "nodejs_version: $NODE_VERSION" > .ddev/config.node.yaml + echo "👷 Configured Node version: $NODE_VERSION" + + # Web Server + if [ "$HTTP_SERVER" = "apache-fpm" ] + then + echo "webserver_type: $HTTP_SERVER" > .ddev/config.http.yaml + fi + echo "👷 Configured HTTP server: $HTTP_SERVER" + + # Database + echo "database: + type: $DATABASE + version: $DATABASE_VERSION" > .ddev/config.db.yaml + echo "👷 Configured Database: $DATABASE:$DATABASE_VERSION" + + # App env + echo "APP_ENV=$APP_ENV" >> .env.local + if [ "$APP_ENV" = "prod" ]; then + echo "APP_DEBUG=0" >> .env.local + else + echo "APP_DEBUG=1" >> .env.local + fi + echo "👷 Configured app environment: $APP_ENV" + + echo "👷 Restarting ddev project to reflect webserver and database changes" + + touch "$PROVISION_FILE_GENERAL" + + verbose_output ddev restart +fi + +if [ -f "$PROVISION_FILE_SERVICES" ]; then + exit 0 +fi + +DB_SCHEME=mysql +DB_USER=db +DB_PASS=db +DB_NAME=db +DB_HOST=db +DB_PORT=3306 +DB_VERSION=$DATABASE_VERSION +DB_CHARSET=utf8mb4 +DB_COLLATION=utf8mb4_unicode_520_ci + +if [ "$DATABASE" == "mariadb" ]; then + DB_VERSION=mariadb-`ddev exec -s db mysql -V | awk '{print $5}' | sed 's/-.*//'` +fi + +if [ "$DATABASE" == "postgres" ]; then + DB_PORT=5432 + DB_SCHEME=postgresql + DB_CHARSET=utf8 + DB_COLLATION=utf8_unicode_ci +fi + +echo "# " >> .env.local +echo "# dxp-installer generated" >> .env.local +echo "DATABASE_URL=${DB_SCHEME}://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}?serverVersion=${DB_VERSION}&charset=${DB_CHARSET}" >> .env.local +echo "DATABASE_VERSION=${DB_VERSION}" >> .env.local +echo "DATABASE_CHARSET=${DB_CHARSET}" >> .env.local +echo "DATABASE_COLLATION=${DB_COLLATION}" >> .env.local + +echo "👷 Saved database details in .env.local" + +if [ "$HTTP_CACHE" == "varnish" ]; then + echo "# " >> .env.local + echo "# dxp-installer generated" >> .env.local + echo "TRUSTED_PROXIES=REMOTE_ADDR" >> .env.local + echo "HTTPCACHE_PURGE_TYPE=varnish" >> .env.local + echo "HTTPCACHE_PURGE_SERVER=$DDEV_PRIMARY_URL" >> .env.local + + verbose_output ddev get reithor/ddev-varnish +fi + +echo "👷 Configured HTTP cache: $HTTP_CACHE" + +# Memcached +if [ "$APP_CACHE" == "memcached" ]; then + echo "# " >> .env.local + echo "# dxp-installer generated" >> .env.local + echo "CACHE_POOL=\"cache.memcached\"" >> .env.local + echo "CACHE_DSN=\"memcached:11211?weight=33\"" >> .env.local + + verbose_output ddev get ddev/ddev-memcached +fi + +# Redis +if [ "$APP_CACHE" == "redis" ]; then + echo "# " >> .env.local + echo "# dxp-installer generated" >> .env.local + echo "CACHE_POOL=cache.redis" >> .env.local + echo "CACHE_DSN=redis@redis:6379" >> .env.local + + verbose_output ddev get ddev/ddev-redis-7 + + echo "# " >> .ddev/redis/memory.conf + echo "# dxp-installer generated" >> .ddev/redis/memory.conf + echo "maxmemory-policy volatile-lfu" >> .ddev/redis/memory.conf +fi + +echo "👷 Configured app cache: $APP_CACHE" + +# Solr +if [ "$SEARCH_ENGINE" == "solr" ]; then + echo "# " >> .env.local + echo "# dxp-installer generated" >> .env.local + echo "SEARCH_ENGINE=solr" >> .env.local + echo "SOLR_CORE=collection1" >> .env.local + echo "SOLR_DSN=http://solr:8983/solr" >> .env.local + + verbose_output ddev get ibexa/ddev-solr +fi + +# Elasticsearch +if [ "$SEARCH_ENGINE" == "elasticsearch" ]; then + echo "# " >> .env.local + echo "# dxp-installer generated" >> .env.local + echo "SEARCH_ENGINE=elasticsearch" >> .env.local + echo "ELASTICSEARCH_DSN=http://elasticsearch:9200" >> .env.local + + verbose_output ddev get ddev/ddev-elasticsearch +fi + +echo "👷 Configured search engine: $SEARCH_ENGINE" + +echo "✅ Finished setting up ddev services. Restarting the environment..." +touch "$PROVISION_FILE_SERVICES" +ddev restart diff --git a/.ddev/commands/web/.utils b/.ddev/commands/web/.utils new file mode 100755 index 0000000..b1df791 --- /dev/null +++ b/.ddev/commands/web/.utils @@ -0,0 +1,94 @@ +#!/bin/bash + +# +# Default settings +# + +export PRIMARY_COLOR="#FF4713" +export GUM_SPIN_SPINNER_FOREGROUND="$PRIMARY_COLOR" +export GUM_CHOOSE_HEADER_FOREGROUND="$PRIMARY_COLOR" +export BORDER_FOREGROUND="$PRIMARY_COLOR" +export CLI_WIDTH=90 +export IBEXA_DXP_INSTALLED_LOCK_FILE=".ddev/.ibexa-dxp-installed" +export INSTANCE_SETTINGS_FILE=".ddev/.ibexa-instance-settings" + +# +# Helper functions +# + +function bold() { + gum style --bold "$@" +} + +function italic() { + gum style --italic "$@" +} + +function underline() { + gum style --underline "$@" +} + +function faint() { + gum style --faint "$@" +} + +function choose() { + local HEADER="$1" + shift + SELECT=$(gum choose --header "$HEADER" -- "$@") +} + +function execute_with_spinner() { + TITLE="$1" + shift + + if [ "$VERBOSE_INSTALL" = true ]; then + "$@" + else + gum spin --title "$TITLE" --timeout 0 -- "$@" + fi +} + +function banner() { + gum style \ + --foreground "#FF4713" \ + --align center --width 90 \ + "" \ + "#%%* =# " \ + "%%%+ -#%% " \ + "%#- #%%% " \ + ". . #%%% .... ... ..... ... " \ + " :** #%%%:+#%%%%%%#+: -+#%%%%%#+- -#%%%*. :=*%%%%%%#+- " \ + "+%%* #%%%%%%#*+++#%%%#- +%%%%#+++*%%%%+. :#%%%*: :*%%%%**+*#%%%%= " \ + "%%%* #%%%%+. .=%%%* .#%%#= .+%%%*..: -#%%%+: =%%%*: .+%%%# " \ + "%%%* #%%%- :%%%= *%%%. .+%%%*:.*%%*#%%%*. :%%%= :%%%+" \ + "%%%* #%%% #%%* %%%+ .+%%%*: -%%%%%#: +%%% *%%%" \ + "%%%* +%%%. %%%+ #%%# .+%%%*: -#%%%%%%*: =%%%. #%%%" \ + "%%%* .%%%#: .#%%#. -%%%*%%%*- -#%%%*:-*%%%*: #%%#: .*%%%%" \ + "%%%* :#%%%*=::.:=*%%%#. -%%%%%*:.:-+%%%%*. :*%%%*: *%%%*-:...-+%%%%%%" \ + "%%%* -*%%%%%%%%%%*- .=#%%%%%%%%%#+. -#%%%*: :*%%%%%%%%%%##%%=" \ + "" + + gum style \ + --foreground "#FFFFFF" --faint --align center --width 90 \ + "~==[ $1 ]==~" \ + "" +} + +# +# Custom error handling +# --- +# Exits on all errors occurred during runtime +# + +# Immediately stop the execution on error +set -e + +function error_handler() { + echo "" + echo "❌️ An error occurred. Exiting..." + exit 1 +} + +# Set custom error handler +trap 'error_handler' ERR diff --git a/.ddev/commands/web/README.txt b/.ddev/commands/web/README.txt new file mode 100755 index 0000000..e0c4a05 --- /dev/null +++ b/.ddev/commands/web/README.txt @@ -0,0 +1,4 @@ +#ddev-generated +Scripts in this directory will be executed inside the web container. + +See https://ddev.readthedocs.io/en/stable/users/extend/custom-commands/#environment-variables-provided for a list of environment variables that can be used in the scripts. diff --git a/.ddev/commands/web/gum b/.ddev/commands/web/gum new file mode 100755 index 0000000..84afe38 --- /dev/null +++ b/.ddev/commands/web/gum @@ -0,0 +1,10 @@ +#!/bin/bash + +#ddev-generated +## Description: Run gum in the web container +## Usage: gum +## Example: "ddev gum" +## ExecRaw: true +## HostWorkingDir: true + +gum "$@" diff --git a/.ddev/commands/web/ibexa-configurator b/.ddev/commands/web/ibexa-configurator new file mode 100755 index 0000000..8407587 --- /dev/null +++ b/.ddev/commands/web/ibexa-configurator @@ -0,0 +1,409 @@ +#!/bin/bash + +## #ddev-generated +## Description: Runs service configurator +## Usage: ibexa-configurator +## Example: ddev ibexa-configurator + +source .ddev/commands/web/.utils + +# +# Default settings +# + +LABEL_INSTALL_SAMPLE_DATA="Yes" +LABEL_INSTALL_PROFILER="Yes" +IBEXA_DXP_PRODUCTS=("oss" "headless" "experience" "commerce") + +[ -z "$PHP_VERSION" ] && PHP_VERSION="8.3" +[ -z "$DATABASE" ] && DATABASE="mariadb" +[ -z "$DATABASE_VERSION" ] && DATABASE_VERSION="10.11" +[ -z "$NODE_VERSION" ] && NODE_VERSION="20" +[ -z "$HTTP_CACHE" ] && HTTP_CACHE="varnish" +[ -z "$HTTP_SERVER" ] && HTTP_SERVER="nginx-fpm" +[ -z "$APP_CACHE" ] && APP_CACHE="redis" +[ -z "$SEARCH_ENGINE" ] && SEARCH_ENGINE="elasticsearch" +[ -z "$INSTALL_SAMPLE_DATA" ] && INSTALL_SAMPLE_DATA=true +[ -z "$INSTALL_PROFILER" ] && INSTALL_PROFILER=true +[ -z "$APP_ENV" ] && APP_ENV="prod" +[ -z "$INSTALL_CLOUD_CONFIG" ] && INSTALL_CLOUD_CONFIG=true + +if [ -f "$INSTANCE_SETTINGS_FILE" ]; then + # Nothing to do + exit 0 +fi + +function detect_version() { + if [ "$DXP_EDITION" != "website" ] && [ -f composer.lock ]; then + MIN_STABILITY="`(jq -r '."minimum-stability"' composer.lock)`" + PRODUCT_VERSION="`(jq -r '.packages[] | select(.name == "ibexa/oss") | .version' composer.lock | sed 's/^v//')`" + INSTALL_FROM_EDITION_SKELETON=true + else + MIN_STABILITY="`(jq -r '."minimum-stability"' composer.json)`" + PRODUCT_VERSION="`(jq -r '.extra."branch-alias"."dev-main"' composer.json)`" + INSTALL_FROM_EDITION_SKELETON=false + fi +} + +function detect_product() { + PROJECT_NAME=$(jq -r '.name' composer.json) + # Strip "ibexa/" and "-skeleton" parts from the value + DXP_EDITION=$(echo $PROJECT_NAME | sed 's/ibexa\///;s/-skeleton//') + case "$DXP_EDITION" in + "commerce") + PRODUCT_TYPE="Ibexa DXP Commerce" + ;; + "experience") + PRODUCT_TYPE="Ibexa DXP Experience" + ;; + "headless") + PRODUCT_TYPE="Ibexa DXP Headless" + ;; + "oss") + PRODUCT_TYPE="Ibexa OSS" + ;; + esac +} + +function configure_product() { + if [ "$DXP_EDITION" = "website" ]; then + choose "`(faint "[Product]")` `(bold "Select Ibexa product")`" "Ibexa OSS" "Ibexa DXP Headless" "Ibexa DXP Experience" "Ibexa DXP Commerce" + PRODUCT_TYPE="$SELECT" + case "$SELECT" in + "Ibexa DXP Commerce") + DXP_EDITION=commerce + ;; + "Ibexa DXP Experience") + DXP_EDITION=experience + ;; + "Ibexa DXP Headless") + DXP_EDITION=headless + ;; + "Ibexa OSS") + DXP_EDITION=oss + ;; + esac + fi +} + +function configure_php() { + choose "`(faint "[Setup]")` `(bold "Select PHP version")`" "8.3 (recommended)" "8.2" "8.1" + case "$SELECT" in + "8.3 (recommended)") + PHP_VERSION="8.3" + ;; + "8.2") + PHP_VERSION="8.2" + ;; + "8.1") + PHP_VERSION="8.1" + ;; + esac +} + +function configure_node() { + choose "`(faint "[Setup]")` `(bold "Select Node version")`" "20 (recommended)" "18" "21" "22" + case "$SELECT" in + "20 (recommended)") + NODE_VERSION="20" + ;; + "18") + NODE_VERSION="18" + ;; + "21") + NODE_VERSION="21" + ;; + "22") + NODE_VERSION="22" + ;; + esac +} + +function configure_http_server() { + choose "`(faint "[Setup]")` `(bold "Select HTTP server")`" "nginx (recommended)" "Apache" + case "$SELECT" in + "nginx (recommended)") + HTTP_SERVER="nginx-fpm" + ;; + "Apache") + HTTP_SERVER="apache-fpm" + ;; + esac +} + +function configure_http_cache() { + choose "`(faint "[Setup]")` `(bold "Select HTTP cache")`" "Varnish (recommended)" "Symfony" + case "$SELECT" in + "Varnish (recommended)") + HTTP_CACHE="varnish" + ;; + "Symfony") + HTTP_CACHE="symfony" + ;; + esac +} + +function configure_database() { + choose "`(faint "[Setup]")` `(bold "Select database platform")`" "MariaDB (recommended)" "MySQL" "PostgreSQL" + case "$SELECT" in + "MariaDB (recommended)") + DATABASE="mariadb" + configure_mariadb_version + ;; + "MySQL") + DATABASE="mysql" + DATABASE_VERSION="8.0" + ;; + "PostgreSQL") + DATABASE="postgres" + configure_postgres_version + ;; + esac +} + +function configure_mariadb_version() { + choose "`(faint "[Setup]")` `(bold "Select MariaDB version")`" "10.11 (recommended)" "10.3" + case "$SELECT" in + "10.11 (recommended)") + DATABASE_VERSION="10.11" + ;; + "10.3") + DATABASE_VERSION="10.3" + ;; + esac +} + +function configure_postgres_version() { + choose "`(faint "[Setup]")` `(bold "Select PostgreSQL version")`" "16 (recommended)" "15" "14" "13" "12" "11" "10" + case "$SELECT" in + "16 (recommended)") + DATABASE_VERSION="16" + ;; + "15") + DATABASE_VERSION="15" + ;; + "14") + DATABASE_VERSION="14" + ;; + "13") + DATABASE_VERSION="13" + ;; + "12") + DATABASE_VERSION="12" + ;; + "11") + DATABASE_VERSION="11" + ;; + "10") + DATABASE_VERSION="10" + ;; + esac +} + +function configure_app_cache() { + choose "`(faint "[Setup]")` `(bold "Select application cache")`" "Redis (recommended)" "Memcached" "Filesystem" + case "$SELECT" in + "Redis (recommended)") + APP_CACHE="redis" + ;; + "Memcached") + APP_CACHE="memcached" + ;; + "Filesystem") + APP_CACHE="filesystem" + ;; + esac +} + +function configure_search_engine() { + choose "`(faint "[Setup]")` `(bold "Select search engine")`" "Elasticsearch (recommended)" "Solr" "Legacy" + case "$SELECT" in + "Elasticsearch (recommended)") + SEARCH_ENGINE="elasticsearch" + ;; + "Solr") + SEARCH_ENGINE="solr" + ;; + "Legacy") + SEARCH_ENGINE="legacy" + ;; + esac +} + +function configure_sample_data() { + if [ "$DXP_EDITION" != "oss" ]; then + choose "`(faint "[Instance]")` `(bold "Install sample data?")`" "Yes (recommended)" "No" + case "$SELECT" in + "Yes (recommended)") + INSTALL_SAMPLE_DATA=true + LABEL_INSTALL_SAMPLE_DATA="Yes" + ;; + "No") + INSTALL_SAMPLE_DATA=false + LABEL_INSTALL_SAMPLE_DATA="No" + ;; + esac + else + # OSS is incompatible with ibexa/test-fixtures + INSTALL_SAMPLE_DATA=false + LABEL_INSTALL_SAMPLE_DATA="No" + fi +} + +function configure_profiler() { + choose "`(faint "[Instance]")` `(bold "Install Symfony profiler?")`" "No (recommended)" "Yes" + case "$SELECT" in + "No (recommended)") + INSTALL_PROFILER=false + LABEL_INSTALL_PROFILER="No" + ;; + "Yes") + INSTALL_PROFILER=true + LABEL_INSTALL_PROFILER="Yes" + ;; + esac +} + +function configure_app_env() { + choose "`(faint "[Instance]")` `(bold "Select app environment")`" "prod (recommended)" "dev" + case "$SELECT" in + "prod (recommended)") + APP_ENV=prod + ;; + "dev") + APP_ENV=dev + ;; + esac +} + +function configure_cloud() { + choose "`(faint "[Instance]")` `(bold "Install Ibexa Cloud configuration?")`" "Yes (recommended)" "No" + case "$SELECT" in + "Yes (recommended)") + INSTALL_CLOUD_CONFIG=true + ;; + "No") + INSTALL_CLOUD_CONFIG=false + ;; + esac +} + +function format_bool() { + if [ "$1" == true ]; then + echo "yes" + else + echo "no" + fi +} + +function info_table() { + gum style \ + --border double \ + --align center --margin "0" --padding "1 2" \ + "$@" +} + +function print_selected_settings() { + echo "${1}" # print title + + TABLE_APPLICATION=$(info_table "`(bold Application)`" \ + "" \ + "`(faint "Product:")` `(bold "$PRODUCT_TYPE")`" \ + "`(faint "Version:")` `(bold "$PRODUCT_VERSION")`" \ + "") + + TABLE_SERVICES=$(info_table --border-foreground "#F4B19B" "`(bold Services)`" \ + "" \ + "`(faint "HTTP Cache:")` `(bold "$HTTP_CACHE")`" \ + "`(faint "App Cache:")` `(bold "$APP_CACHE")`" \ + "`(faint "Search Engine:")` `(bold "$SEARCH_ENGINE")`") + + TABLE_ENVIRONMENT=$(info_table --border-foreground "#FFE6D7" "`(bold Environment)`" \ + "" \ + "`(faint "Web Server:")` `(bold "$HTTP_SERVER")`" \ + "`(faint "PHP:")` `(bold "$PHP_VERSION")`" \ + "`(faint "Node:")` `(bold "$NODE_VERSION")`" \ + "`(faint "Database:")` `(bold "$DATABASE")` `(faint "("$DATABASE_VERSION")")`") + + TABLE_EXTRAS=$(info_table --border-foreground "#78B1E0" "`(bold Extras)`" \ + "" \ + "`(faint "Install sample data:")` `(bold $(format_bool "$INSTALL_SAMPLE_DATA"))`" \ + "`(faint "Install Ibexa Cloud config:")` `(bold $(format_bool "$INSTALL_CLOUD_CONFIG"))`" \ + "`(faint "Install Symfony Profiler:")` `(bold $(format_bool "$INSTALL_PROFILER"))`" \ + "`(faint "App environment:")` `(bold "$APP_ENV")`") + + ROW_1=$(gum join "$TABLE_APPLICATION" "$TABLE_SERVICES") + ROW_2=$(gum join "$TABLE_ENVIRONMENT" "$TABLE_EXTRAS") + gum join --align center --vertical "$ROW_1" "$ROW_2" + echo "" +} + +function select_configuration() { + configure_php + configure_node + configure_http_server + configure_database + configure_http_cache + configure_app_cache + configure_search_engine + configure_sample_data + configure_profiler + configure_app_env + configure_cloud + + print_selected_settings "`gum style --bold --underline -- "Your configuration:"`" + + if ! gum confirm "Confirm these settings?" ; + then + select_configuration + fi +} + +function save_settings_file() { + { + declare -p DXP_EDITION + declare -p PRODUCT_TYPE + declare -p PRODUCT_VERSION + declare -p PHP_VERSION + declare -p NODE_VERSION + declare -p DATABASE + declare -p DATABASE_VERSION + declare -p HTTP_CACHE + declare -p APP_CACHE + declare -p SEARCH_ENGINE + declare -p INSTALL_SAMPLE_DATA + declare -p INSTALL_PROFILER + declare -p APP_ENV + declare -p HTTP_SERVER + declare -p INSTALL_CLOUD_CONFIG + declare -p INSTALL_FROM_EDITION_SKELETON + } > "$INSTANCE_SETTINGS_FILE" +} + +# +# Main +# + +clear + +banner "Interactive Installation Tool" + +bold "⚠️ This tool is experimental. Do not use on production servers." +echo "" + +detect_product +detect_version + +configure_product + +print_selected_settings "`gum style --bold --underline -- "Recommended configuration:"`" + +if ! gum confirm "Do you confirm these settings?" ; +then + select_configuration +fi + +save_settings_file + + + diff --git a/.ddev/commands/web/ibexa-installer b/.ddev/commands/web/ibexa-installer new file mode 100755 index 0000000..e25c5a4 --- /dev/null +++ b/.ddev/commands/web/ibexa-installer @@ -0,0 +1,155 @@ +#!/bin/bash + +## #ddev-generated +## Description: Runs interactive installer for Ibexa DXP +## Usage: ibexa-installer +## Example: ddev ibexa-installer + +source .ddev/commands/web/.utils + +if [ -f "$IBEXA_DXP_INSTALLED_LOCK_FILE" ] || [ ! -f "$INSTANCE_SETTINGS_FILE" ] +then + # Nothing to do + exit 0 +fi + +source "$INSTANCE_SETTINGS_FILE" + +# +# Default settings +# + +ADMIN_USERNAME=admin +ADMIN_PASSWORD=publish + +# +# Main +# + +function composer_auth_error() { + echo "❗️ Cannot access `(faint updates.ibexa.co)`" + echo "Please provide your composer auth details to ddev and re-run `(faint "ddev start")`. The process will continue using previously configured settings." + exit 1 +} + +if [ "$VERBOSE_INSTALL" == false ]; then + clear +fi + +# Workaround to the issue on Mac OS +git config --global --add safe.directory /var/www/html + +banner "Interactive Installation Tool" + +echo "🚀 Product to be installed: `(bold "$PRODUCT_TYPE v$PRODUCT_VERSION")`" + +# Configure updates.ibexa.co composer repository, check availability (composer auth file could not be linked to ddev) +if [ "$DXP_EDITION" != "oss" ]; then + trap 'composer_auth_error' ERR + if [ "$INSTALL_FROM_EDITION_SKELETON" == false ]; then + composer config repositories.ibexa composer https://updates.ibexa.co --quiet > /dev/null 2>&1 + fi + execute_with_spinner "Checking `(bold updates.ibexa.co)` authorization" composer require "ibexa/$DXP_EDITION:$PRODUCT_VERSION" -W --no-scripts --no-plugins --no-install --no-interaction --quiet + trap 'error_handler' ERR + + echo "✅ Repository `(bold updates.ibexa.co)` is reachable" +fi + +# PHP 8.x requires custom error handler to suppress deprecation warnings, it's already added to edition skeletons +if [ "$INSTALL_FROM_EDITION_SKELETON" == false ]; then + composer config extra.runtime.error_handler "\\Ibexa\\Contracts\\Core\\MVC\\Symfony\\ErrorHandler\\Php82HideDeprecationsErrorHandler" +fi + +# Installation steps between website-skeleton and edition skeletons are different +if [ "$INSTALL_FROM_EDITION_SKELETON" == true ]; then + if [ "$PHP_VERSION" == "8.1" ]; then + execute_with_spinner "Installing composer dependencies..." composer update -W --no-scripts --no-interaction + else + execute_with_spinner "Installing composer dependencies..." composer install --no-scripts --no-interaction + fi + echo "✅ Composer dependencies installed successfully" +else + execute_with_spinner "Installing `(bold ibexa/${DXP_EDITION})` package..." composer require "ibexa/$DXP_EDITION:$PRODUCT_VERSION" -W --no-scripts --no-interaction + echo "✅ Package `(bold ibexa/${DXP_EDITION})` installed successfully" + + execute_with_spinner "Initializing git repository..." git init > /dev/null && git add . > /dev/null && git commit -m "Installed Ibexa DXP" > /dev/null + echo "✅ Initialized git repository" + + execute_with_spinner "Installing Flex recipe..." composer recipes:install ibexa/${DXP_EDITION} --force --reset + echo "✅ Installed Flex recipe" +fi + +# Install test fixtures +if [ "$INSTALL_SAMPLE_DATA" == true ]; then + composer show --available ibexa/test-fixtures > /dev/null 2>&1 + + if [ "$?" == 0 ]; then + execute_with_spinner "Installing ibexa/test-fixtures package" composer require ibexa/test-fixtures --no-scripts --no-interaction + echo "✅ Installed ibexa/test-fixtures package" + else + echo "⚠️ `(bold "ibexa/test-fixtures")` package is unavailable. Cannot install sample data." + fi + +fi + +# Install profiler +if [ "$INSTALL_PROFILER" == true ]; then + execute_with_spinner "Installing Symfony Profiler" composer require symfony/profiler-pack --no-scripts --no-interaction + echo "✅ Installed Symfony Profiler" +fi + +execute_with_spinner "Running Composer scripts..." composer run post-update-cmd +echo "✅ Scripts finished successfully" + +execute_with_spinner "Installing database schema and data..." php bin/console ibexa:install +echo "✅ Database installed" + +if [ "$SEARCH_ENGINE" == "solr" ] || [ "$SEARCH_ENGINE" == "elasticsearch" ]; then + if [ "$SEARCH_ENGINE" = "elasticsearch" ]; then + execute_with_spinner "Putting Elasticsearch index template" php bin/console ibexa:elasticsearch:put-index-template + echo "✅ Put Elasticsearch index template" + fi + + execute_with_spinner "Reindexing search data" php bin/console ibexa:reindex + echo "✅ Reindexed search data" +fi + +# Setup sample data +if [ "$INSTALL_SAMPLE_DATA" == true ]; then + execute_with_spinner "Installing sample data" php bin/console ibexa:test-fixtures:setup + echo "✅ Installed sample data" +fi + +execute_with_spinner "Generating GraphQL schema" php bin/console ibexa:graphql:generate-schema +echo "✅ GraphQL schema generated" + +# Setup Ibexa Cloud +if [ "$INSTALL_CLOUD_CONFIG" == true ]; then + execute_with_spinner "Installing Ibexa Cloud configuration" composer ibexa:setup --platformsh + echo "✅ Installed Ibexa Cloud configuration" +fi + +echo "✅ All done! You can now access your new project using provided details:" + +gum style --border double --margin "1 1" --padding "1 1" --width 60 \ + "Website: ` bold --bold "$DDEV_PRIMARY_URL" `" \ + "Backoffice: ` bold --bold "$DDEV_PRIMARY_URL/admin" `" \ + "" \ + "Username: ` bold "admin" `" \ + "Password: ` bold "publish" `" \ + "" \ + "Run `(bold "ddev describe")` for more details" + +echo "📧 Run `(bold "ddev mailpit")` to launch Mailpit interface and see caught e-mails" +echo "🗄️ Run `(bold "ddev get ddev/ddev-phpmyadmin")` to install PHPMyAdmin" +echo "🗄️ Run `(bold "ddev querious|sequelace|tableplus|dbeaver")` to launch database client app" +echo "" +echo "📦️ Run `(bold "ddev composer ...")` to execute Composer commands" +echo "🐘️ Run `(bold "ddev php ...")` to execute PHP scripts" +echo "🐞️ Run `(bold "ddev xdebug on|off")` to control Xdebug" +echo "" +echo "🚀️ Run `(bold "ddev start")` to start containers" +echo "⛔️ Run `(bold "ddev stop")` to stop containers" +echo "🔄️ Run `(bold "ddev restart")` to restart containers" + +echo "`date`" > ./.ddev/.ibexa-dxp-installed diff --git a/.ddev/config.db.yaml b/.ddev/config.db.yaml new file mode 100644 index 0000000..1a4c2c0 --- /dev/null +++ b/.ddev/config.db.yaml @@ -0,0 +1,2 @@ +omit_containers: + - db diff --git a/.ddev/config.gum.yaml b/.ddev/config.gum.yaml new file mode 100644 index 0000000..cd60a9e --- /dev/null +++ b/.ddev/config.gum.yaml @@ -0,0 +1,4 @@ +#ddev-generated +webimage_extra_packages: [gum] +web_environment: + - COLORTERM=truecolor diff --git a/.ddev/config.http.yaml b/.ddev/config.http.yaml new file mode 100644 index 0000000..199c894 --- /dev/null +++ b/.ddev/config.http.yaml @@ -0,0 +1 @@ +webserver_type: "nginx-fpm" diff --git a/.ddev/config.node.yaml b/.ddev/config.node.yaml new file mode 100644 index 0000000..aba6299 --- /dev/null +++ b/.ddev/config.node.yaml @@ -0,0 +1 @@ +nodejs_version: "20" diff --git a/.ddev/config.php.yaml b/.ddev/config.php.yaml new file mode 100644 index 0000000..864a10e --- /dev/null +++ b/.ddev/config.php.yaml @@ -0,0 +1 @@ +php_version: "8.3" diff --git a/.ddev/config.yaml b/.ddev/config.yaml new file mode 100644 index 0000000..fa97fd1 --- /dev/null +++ b/.ddev/config.yaml @@ -0,0 +1,19 @@ +type: php +composer_version: "2" +nodejs_version: "18" +router_http_port: "80" +router_https_port: "443" +docroot: "public/" +use_dns_when_possible: true +additional_hostnames: [] +additional_fqdns: [] +xdebug_enabled: false +upload_dirs: + - var/storage +web_environment: + - VERBOSE_INSTALL=false # set to `true` to view verbose output during install +hooks: + post-start: + - exec-host: "ddev ibexa-configurator" + - exec-host: "ddev ibexa-setup" + - exec-host: "ddev ibexa-installer" diff --git a/.ddev/docker-compose.mounts.yaml b/.ddev/docker-compose.mounts.yaml new file mode 100644 index 0000000..9562408 --- /dev/null +++ b/.ddev/docker-compose.mounts.yaml @@ -0,0 +1,20 @@ +#services: +# web: +# volumes: +# - "~/Projects/Web/ibexa/core:/var/www/html/vendor/ibexa/core:ro" + +# +# If you are using Mutagen, you also need to modify .ddev/mutagen/mutagen.yml file. +# Remove first line containing "#ddev-generated" and add container paths to the list. +# +# Example: +# +# sync: +# defaults: +# (...) +# ignore: +# paths: +# - ".idea" +# - "/public/var/storage" +# - "/vendor/ibexa/core" # Added new path +# \ No newline at end of file diff --git a/.ddev/web-build/pre.Dockerfile.gum b/.ddev/web-build/pre.Dockerfile.gum new file mode 100644 index 0000000..390b8b8 --- /dev/null +++ b/.ddev/web-build/pre.Dockerfile.gum @@ -0,0 +1,5 @@ +#ddev-generated +# https://github.com/charmbracelet/gum#installation +RUN mkdir -p /etc/apt/keyrings +RUN curl -fsSL https://repo.charm.sh/apt/gpg.key | gpg --dearmor -o /etc/apt/keyrings/charm.gpg +RUN echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | tee /etc/apt/sources.list.d/charm.list