Created
March 6, 2026 11:28
-
-
Save ErHaWeb/037ab7b1d65a2781c2d830d0cf60359d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| ## TYPO3 Core Contribution Setup Script | |
| ## | |
| ## This script automates the setup of a TYPO3 Core development environment | |
| ## including Git, Gerrit configuration and a fully working DDEV instance. | |
| ## | |
| ## It prepares a local TYPO3 Core checkout on the "main" branch and configures | |
| ## everything required for TYPO3 Core contribution development. | |
| ## | |
| ## | |
| ## INSTALLATION | |
| ## ---------------------------------------------------------------------- | |
| ## Place the script for example in: | |
| ## | |
| ## ~/.shellscripts/typo3/install-core-contribution.sh | |
| ## | |
| ## Optionally create an alias in your shell configuration (~/.bashrc or ~/.zshrc): | |
| ## | |
| ## alias install-typo3-core="bash ~/.shellscripts/typo3/install-core-contribution.sh" | |
| ## | |
| ## | |
| ## USAGE | |
| ## ---------------------------------------------------------------------- | |
| ## Pass one or more target directories as parameters. A TYPO3 Core repository | |
| ## will be cloned into each directory and fully prepared for TYPO3 Core | |
| ## contribution development. | |
| ## | |
| ## Multiple installations can be created in a single command: | |
| ## | |
| ## install-typo3-core t3core1 t3core2 t3core3 | |
| ## | |
| ## Supported path variants: | |
| ## | |
| ## 1. Relative path (created in the current working directory) | |
| ## | |
| ## install-typo3-core t3coredev | |
| ## | |
| ## 2. Path relative to the user's home directory | |
| ## | |
| ## install-typo3-core ~/work/t3coredev | |
| ## | |
| ## 3. Absolute path | |
| ## | |
| ## install-typo3-core /var/www/t3coredev | |
| ## | |
| ## The target directory will be created automatically if it does not exist. | |
| ## If the directory already exists and is not empty, the script aborts. | |
| ## | |
| ## | |
| ## REQUIREMENTS | |
| ## ---------------------------------------------------------------------- | |
| ## The following tools must be installed and available in PATH: | |
| ## | |
| ## - git | |
| ## - ssh | |
| ## - ddev | |
| ## - docker (required by ddev) | |
| ## | |
| ## The script verifies SSH access to TYPO3 Gerrit before setup starts: | |
| ## | |
| ## ssh -p 29418 <your-typo3-username>@review.typo3.org | |
| ## | |
| ## Your Git email must match an email address registered in Gerrit. | |
| ## Otherwise Gerrit may reject pushes with: | |
| ## | |
| ## invalid committer | |
| ## | |
| ## | |
| ## TYPO3 BACKEND LOGIN | |
| ## ---------------------------------------------------------------------- | |
| ## After installation the TYPO3 backend can be accessed at: | |
| ## | |
| ## https://<ddev-project>.ddev.site/typo3/ | |
| ## | |
| ## Default credentials: | |
| ## | |
| ## Username : admin | |
| ## Password : Password1% | |
| ## | |
| ## The default password is intended for local development environments only. | |
| ## | |
| ## | |
| ## COPYRIGHT | |
| ## ---------------------------------------------------------------------- | |
| ## © 2026 Eric Harrer | |
| ## | |
| ## This script is intended to simplify TYPO3 Core contribution setup and | |
| ## may be adapted for personal or team development environments. | |
| ## | |
| set -Eeuo pipefail | |
| IFS=$'\n\t' | |
| readonly T3CORE_RED='\033[0;31m' | |
| readonly T3CORE_GREEN='\033[0;32m' | |
| readonly T3CORE_YELLOW='\033[1;33m' | |
| readonly T3CORE_NC='\033[0m' | |
| readonly T3CORE_START_DIR="$PWD" | |
| readonly T3CORE_DEFAULT_ADMIN_USERNAME='admin' | |
| readonly T3CORE_DEFAULT_ADMIN_PASSWORD='Password1%' | |
| readonly T3CORE_MIN_DDEV_VERSION='1.16.5' | |
| readonly T3CORE_GITHUB_SSH_URL='git@github.com:typo3/typo3.git' | |
| readonly T3CORE_GITHUB_HTTPS_URL='https://github.com/typo3/typo3.git' | |
| readonly T3CORE_GERRIT_SSH_KEYS_URL='https://review.typo3.org/settings/web-identities#SSHKeys' | |
| readonly T3CORE_GERRIT_IDENTITIES_URL='https://review.typo3.org/settings/web-identities#Identities' | |
| readonly T3CORE_GERRIT_EMAIL_ADDRESSES_URL='https://review.typo3.org/settings/web-identities#EmailAddresses' | |
| T3CORE_CLONED_TARGET_DIR="" | |
| T3CORE_CONFIRMED_TYPO3_USERNAME="" | |
| T3CORE_CONFIRMED_GIT_USER_NAME="" | |
| T3CORE_CONFIRMED_GIT_USER_EMAIL="" | |
| t3core_print_error() { | |
| printf "%b[ERROR]%b %s\n" "$T3CORE_RED" "$T3CORE_NC" "$1" >&2 | |
| } | |
| t3core_print_warning() { | |
| printf "%b[WARNING]%b %s\n" "$T3CORE_YELLOW" "$T3CORE_NC" "$1" | |
| } | |
| t3core_print_success() { | |
| printf "%b[OK]%b %s\n" "$T3CORE_GREEN" "$T3CORE_NC" "$1" | |
| } | |
| t3core_print_headline() { | |
| printf "\n============================================================\n" | |
| printf " %s\n" "$1" | |
| printf "============================================================\n" | |
| } | |
| t3core_cleanup() { | |
| cd "$T3CORE_START_DIR" >/dev/null 2>&1 || true | |
| } | |
| trap t3core_cleanup EXIT | |
| t3core_error_trap() { | |
| local exit_code="$?" | |
| local line_no="$1" | |
| local command="$2" | |
| t3core_print_error "Command failed in line $line_no with exit code $exit_code: $command" | |
| exit "$exit_code" | |
| } | |
| trap 't3core_error_trap "$LINENO" "$BASH_COMMAND"' ERR | |
| t3core_require_command() { | |
| local cmd="$1" | |
| local hint="${2:-}" | |
| if ! command -v "$cmd" >/dev/null 2>&1; then | |
| t3core_print_error "$cmd is not installed. $hint" | |
| exit 1 | |
| fi | |
| } | |
| t3core_trim() { | |
| local value="$1" | |
| value="${value#"${value%%[![:space:]]*}"}" | |
| value="${value%"${value##*[![:space:]]}"}" | |
| printf '%s' "$value" | |
| } | |
| t3core_prompt_with_default() { | |
| local prompt="$1" | |
| local default_value="${2:-}" | |
| local input | |
| if [ -n "$default_value" ]; then | |
| read -r -p "$prompt [$default_value]: " input | |
| input="$(t3core_trim "$input")" | |
| if [ -z "$input" ]; then | |
| input="$default_value" | |
| fi | |
| else | |
| while true; do | |
| read -r -p "$prompt: " input | |
| input="$(t3core_trim "$input")" | |
| if [ -n "$input" ]; then | |
| break | |
| fi | |
| t3core_print_warning "This field must not be empty." | |
| done | |
| fi | |
| printf '%s' "$input" | |
| } | |
| t3core_confirm_yes_no() { | |
| local prompt="$1" | |
| local answer | |
| while true; do | |
| read -r -p "$prompt [y/N]: " answer | |
| answer="$(t3core_trim "$answer")" | |
| case "$answer" in | |
| [Yy]|[Yy][Ee][Ss]) return 0 ;; | |
| [Nn]|[Nn][Oo]|'') return 1 ;; | |
| *) t3core_print_warning "Please answer with y or n." ;; | |
| esac | |
| done | |
| } | |
| t3core_expand_target_path() { | |
| local input_path="$1" | |
| if [[ $input_path == ~/* ]]; then | |
| printf '%s\n' "${HOME}/${input_path#~/}" | |
| else | |
| printf '%s\n' "$input_path" | |
| fi | |
| } | |
| t3core_guard_target_path() { | |
| local target_dir="$1" | |
| case "$target_dir" in | |
| ""|"/"|"$HOME"|"$HOME/"|"."|"./"|".."|"../"|"/var/www"|"/var/www/") | |
| t3core_print_error "Refusing unsafe target path: '$target_dir'" | |
| return 1 | |
| ;; | |
| esac | |
| return 0 | |
| } | |
| t3core_get_version_number() { | |
| local raw_version="$1" | |
| printf '%s' "$raw_version" | grep -Eo '[0-9]+(\.[0-9]+)+' | head -n1 | |
| } | |
| t3core_version_ge() { | |
| local installed="$1" | |
| local required="$2" | |
| local i | |
| local installed_part required_part | |
| local -a installed_parts required_parts | |
| local IFS='.' | |
| read -r -a installed_parts <<<"$installed" | |
| read -r -a required_parts <<<"$required" | |
| local max_len="${#installed_parts[@]}" | |
| if [ "${#required_parts[@]}" -gt "$max_len" ]; then | |
| max_len="${#required_parts[@]}" | |
| fi | |
| for ((i = 0; i < max_len; i++)); do | |
| installed_part="${installed_parts[i]:-0}" | |
| required_part="${required_parts[i]:-0}" | |
| if ((10#$installed_part > 10#$required_part)); then | |
| return 0 | |
| fi | |
| if ((10#$installed_part < 10#$required_part)); then | |
| return 1 | |
| fi | |
| done | |
| return 0 | |
| } | |
| t3core_require_min_version() { | |
| local cmd="$1" | |
| local min_version="$2" | |
| local version_output | |
| local installed_version | |
| version_output="$("$cmd" --version 2>/dev/null || true)" | |
| installed_version="$(t3core_get_version_number "$version_output")" | |
| if [ -z "$installed_version" ]; then | |
| t3core_print_error "Could not determine version of $cmd." | |
| exit 1 | |
| fi | |
| if ! t3core_version_ge "$installed_version" "$min_version"; then | |
| t3core_print_error "$cmd version $installed_version detected but >= $min_version is required." | |
| exit 1 | |
| fi | |
| t3core_print_success "$cmd version $installed_version OK" | |
| } | |
| t3core_require_docker_running() { | |
| if ! docker info >/dev/null 2>&1; then | |
| t3core_print_error "Docker is installed but not running." | |
| exit 1 | |
| fi | |
| t3core_print_success "Docker daemon is running" | |
| } | |
| t3core_check_requirements() { | |
| printf "\n--- Checking required tools\n" | |
| t3core_require_command git "Please install Git." | |
| t3core_require_command ssh "Please install OpenSSH." | |
| t3core_require_command ddev "Please install DDEV." | |
| t3core_require_command docker "Please install Docker." | |
| t3core_require_min_version ddev "$T3CORE_MIN_DDEV_VERSION" | |
| t3core_require_docker_running | |
| } | |
| t3core_get_gerrit_push_url() { | |
| local typo3_username="$1" | |
| printf '%s\n' "ssh://${typo3_username}@review.typo3.org:29418/Packages/TYPO3.CMS.git" | |
| } | |
| t3core_validate_typo3_username() { | |
| local typo3_username="$1" | |
| if [[ ! "$typo3_username" =~ ^[a-zA-Z0-9._-]+$ ]]; then | |
| t3core_print_error "Invalid TYPO3 username format: '$typo3_username'" | |
| t3core_print_error "Allowed characters are: letters, digits, dot, underscore and hyphen." | |
| exit 1 | |
| fi | |
| } | |
| t3core_validate_git_email() { | |
| local git_user_email="$1" | |
| if [[ ! "$git_user_email" =~ ^[^[:space:]@]+@[^[:space:]@]+\.[^[:space:]@]+$ ]]; then | |
| t3core_print_error "Invalid Git email format: '$git_user_email'" | |
| t3core_print_error "Please enter a valid email address." | |
| exit 1 | |
| fi | |
| } | |
| t3core_collect_confirmed_identity() { | |
| local global_name | |
| local global_email | |
| local typo3_username | |
| local git_user_name | |
| local git_user_email | |
| global_name="$(git config --global user.name 2>/dev/null || true)" | |
| global_email="$(git config --global user.email 2>/dev/null || true)" | |
| while true; do | |
| printf "\n--- Please enter your TYPO3 and Git identity\n" | |
| typo3_username="$(t3core_prompt_with_default 'YOUR_TYPO3_USERNAME' '')" | |
| git_user_name="$(t3core_prompt_with_default 'git config user.name' "$global_name")" | |
| git_user_email="$(t3core_prompt_with_default 'git config user.email' "$global_email")" | |
| printf "\n--- Please confirm the information\n" | |
| printf "YOUR_TYPO3_USERNAME : %s\n" "$typo3_username" | |
| printf "git user.name : %s\n" "$git_user_name" | |
| printf "git user.email : %s\n" "$git_user_email" | |
| if t3core_confirm_yes_no "Are these values correct?"; then | |
| t3core_validate_typo3_username "$typo3_username" | |
| t3core_validate_git_email "$git_user_email" | |
| T3CORE_CONFIRMED_TYPO3_USERNAME="$typo3_username" | |
| T3CORE_CONFIRMED_GIT_USER_NAME="$git_user_name" | |
| T3CORE_CONFIRMED_GIT_USER_EMAIL="$git_user_email" | |
| return 0 | |
| fi | |
| printf "\n--- Input will be requested again.\n" | |
| done | |
| } | |
| t3core_print_gerrit_ssh_setup_help() { | |
| local typo3_username="$1" | |
| printf "\n--- Gerrit SSH setup required\n" | |
| printf "To continue, set up SSH access for review.typo3.org:\n" | |
| printf "\n" | |
| printf "1. Create an SSH key if you do not have one yet:\n" | |
| printf " ssh-keygen -t ed25519 -C \"%s\"\n" "$T3CORE_CONFIRMED_GIT_USER_EMAIL" | |
| printf "\n" | |
| printf "2. Open Gerrit account settings:\n" | |
| printf " SSH keys : %s\n" "$T3CORE_GERRIT_SSH_KEYS_URL" | |
| printf " Identities : %s\n" "$T3CORE_GERRIT_IDENTITIES_URL" | |
| printf " Email addresses : %s\n" "$T3CORE_GERRIT_EMAIL_ADDRESSES_URL" | |
| printf "\n" | |
| printf "3. Add your public key, for example:\n" | |
| printf " %s/.ssh/id_ed25519.pub\n" "$HOME" | |
| printf "\n" | |
| printf "4. Test the connection:\n" | |
| printf " ssh -p 29418 %s@review.typo3.org\n" "$typo3_username" | |
| printf "\n" | |
| printf "Expected result:\n" | |
| printf " Welcome to Gerrit Code Review\n" | |
| printf " ... you have successfully connected over SSH.\n" | |
| printf "\n" | |
| printf "5. If your SSH client does not pick the correct key automatically,\n" | |
| printf " add this to %s/.ssh/config:\n" "$HOME" | |
| printf "\n" | |
| printf " Host review.typo3.org\n" | |
| printf " User %s\n" "$typo3_username" | |
| printf " IdentityFile %s/.ssh/id_ed25519\n" "$HOME" | |
| printf " Port 29418\n" | |
| printf "\n" | |
| printf "After that, run the script again.\n" | |
| } | |
| t3core_verify_gerrit_ssh_access() { | |
| local typo3_username="$1" | |
| local ssh_output | |
| printf "\n--- Checking Gerrit SSH access\n" | |
| ssh_output="$( | |
| ssh \ | |
| -p 29418 \ | |
| -o BatchMode=yes \ | |
| -o StrictHostKeyChecking=accept-new \ | |
| "${typo3_username}@review.typo3.org" \ | |
| 2>&1 || true | |
| )" | |
| if printf '%s' "$ssh_output" | grep -Eq 'Welcome to Gerrit Code Review|successfully connected over SSH'; then | |
| t3core_print_success "Gerrit SSH access is working." | |
| return 0 | |
| fi | |
| t3core_print_error "SSH access to review.typo3.org is not configured or not working for user '${typo3_username}'." | |
| printf "\nSSH output:\n%s\n" "$ssh_output" | |
| t3core_print_gerrit_ssh_setup_help "$typo3_username" | |
| exit 1 | |
| } | |
| t3core_clone_repository() { | |
| local target_dir_input="$1" | |
| local target_dir | |
| local resolved_target_dir | |
| local ssh_clone_exit_code | |
| local ssh_clone_output | |
| target_dir="$(t3core_expand_target_path "$target_dir_input")" | |
| t3core_guard_target_path "$target_dir" | |
| printf "\n--- Cloning TYPO3 Core repository into: %b%s%b\n" "$T3CORE_GREEN" "$target_dir" "$T3CORE_NC" | |
| mkdir -p "$target_dir" | |
| cd -P "$target_dir" || { | |
| t3core_print_error "Failed to change directory to $target_dir" | |
| exit 1 | |
| } | |
| resolved_target_dir="$(pwd -P)" | |
| t3core_guard_target_path "$resolved_target_dir" | |
| if [ -n "$(find . -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null)" ]; then | |
| t3core_print_error "Target directory '$resolved_target_dir' already exists and is not empty. Aborting to protect existing files." | |
| return 1 | |
| fi | |
| set +e | |
| ssh_clone_output="$(git clone "$T3CORE_GITHUB_SSH_URL" . 2>&1)" | |
| ssh_clone_exit_code="$?" | |
| set -e | |
| if [ "$ssh_clone_exit_code" -eq 0 ]; then | |
| t3core_print_success "Clone via GitHub SSH successful." | |
| else | |
| t3core_print_warning "GitHub SSH clone failed. Falling back to HTTPS." | |
| printf "%s\n" "$ssh_clone_output" >&2 | |
| t3core_print_warning "GitHub SSH is optional. Gerrit SSH access remains required for pushes." | |
| find . -mindepth 1 -maxdepth 1 -exec rm -rf {} + | |
| git clone "$T3CORE_GITHUB_HTTPS_URL" . | |
| t3core_print_success "Clone via GitHub HTTPS successful." | |
| fi | |
| T3CORE_CLONED_TARGET_DIR="$resolved_target_dir" | |
| t3core_print_success "Repository ready in: $T3CORE_CLONED_TARGET_DIR" | |
| } | |
| t3core_configure_git_repository() { | |
| local typo3_username="$1" | |
| local git_user_name="$2" | |
| local git_user_email="$3" | |
| local gerrit_push_url | |
| printf "\n--- Configuring local Git repository\n" | |
| gerrit_push_url="$(t3core_get_gerrit_push_url "$typo3_username")" | |
| git config --local user.name "$git_user_name" | |
| git config --local user.email "$git_user_email" | |
| git config --local branch.autosetuprebase remote | |
| git config --local pull.rebase true | |
| git config --local remote.origin.pushurl "$gerrit_push_url" | |
| git config --local remote.origin.push "+refs/heads/main:refs/for/main" | |
| t3core_print_success "Local Git and Gerrit configuration applied." | |
| } | |
| t3core_install_git_hooks() { | |
| printf "\n--- Installing TYPO3 Git hooks for Gerrit\n" | |
| mkdir -p .git/hooks | |
| if [ ! -f Build/git-hooks/commit-msg ]; then | |
| t3core_print_error "Required Gerrit hook not found: Build/git-hooks/commit-msg" | |
| exit 1 | |
| fi | |
| cp Build/git-hooks/commit-msg .git/hooks/commit-msg | |
| chmod +x .git/hooks/commit-msg | |
| if [ -f Build/git-hooks/unix+mac/pre-commit ]; then | |
| cp Build/git-hooks/unix+mac/pre-commit .git/hooks/pre-commit | |
| chmod +x .git/hooks/pre-commit | |
| t3core_print_success "commit-msg and pre-commit hooks installed." | |
| else | |
| t3core_print_warning "Optional pre-commit hook not found. Installed commit-msg hook only." | |
| t3core_print_success "commit-msg hook installed." | |
| fi | |
| } | |
| t3core_configure_commit_template() { | |
| local commit_template_file | |
| commit_template_file='.git/info/typo3-commit-template.txt' | |
| printf "\n--- Configuring TYPO3 commit message template\n" | |
| mkdir -p .git/info | |
| cat > "$commit_template_file" <<'EOF' | |
| [BUGFIX|TASK|FEATURE|DOCS] | |
| Resolves: # | |
| Releases: main | |
| EOF | |
| git config --local commit.template "$commit_template_file" | |
| t3core_print_success "Commit message template configured: $commit_template_file" | |
| } | |
| t3core_configure_local_git_excludes() { | |
| local exclude_file | |
| exclude_file='.git/info/exclude' | |
| printf "\n--- Configuring local Git excludes\n" | |
| mkdir -p .git/info | |
| touch "$exclude_file" | |
| if ! grep -Fxq '.ddev/' "$exclude_file" 2>/dev/null; then | |
| printf "\n.ddev/\n" >> "$exclude_file" | |
| t3core_print_success "Added .ddev/ to .git/info/exclude" | |
| else | |
| t3core_print_success ".ddev/ already present in .git/info/exclude" | |
| fi | |
| } | |
| t3core_ensure_ddev_project_name_is_available() { | |
| local project_name="$1" | |
| if ddev list 2>/dev/null | tail -n +2 | awk '{print $1}' | grep -Fxq "$project_name"; then | |
| t3core_print_error "A DDEV project named '$project_name' already exists." | |
| t3core_print_error "The target directory name maps to the DDEV project name '$project_name'." | |
| t3core_print_error "Please choose a different target directory name or remove the existing DDEV project first." | |
| exit 1 | |
| fi | |
| } | |
| t3core_configure_ddev() { | |
| local project_name="$1" | |
| printf "\n--- Configuring DDEV\n" | |
| ddev config \ | |
| --project-name="$project_name" \ | |
| --project-type=typo3 \ | |
| --docroot=. \ | |
| --database='mariadb:10.11' \ | |
| --php-version=8.2 \ | |
| --composer-version='stable' \ | |
| --webserver-type=apache-fpm \ | |
| --nodejs-version=22 \ | |
| --web-environment='TYPO3_CONTEXT=Development' \ | |
| --webimage-extra-packages='build-essential,locales-all' | |
| t3core_print_success "DDEV configuration created." | |
| } | |
| t3core_setup_instance() { | |
| local git_user_email="$1" | |
| local project_label="$2" | |
| printf "\n--- Installing Composer dependencies via runTests.sh\n" | |
| if [ ! -x ./Build/Scripts/runTests.sh ]; then | |
| t3core_print_error "Required script not found or not executable: ./Build/Scripts/runTests.sh" | |
| exit 1 | |
| fi | |
| ./Build/Scripts/runTests.sh -s composerInstall | |
| printf "\n--- Starting DDEV\n" | |
| ddev start -y | |
| printf "\n--- Creating FIRST_INSTALL file\n" | |
| ddev exec touch FIRST_INSTALL | |
| printf "\n--- Running TYPO3 setup\n" | |
| ddev typo3 setup \ | |
| --driver=mysqli \ | |
| --host=db \ | |
| --port=3306 \ | |
| --dbname=db \ | |
| --username=db \ | |
| --password=db \ | |
| --admin-username="$T3CORE_DEFAULT_ADMIN_USERNAME" \ | |
| --admin-user-password="$T3CORE_DEFAULT_ADMIN_PASSWORD" \ | |
| --admin-email="$git_user_email" \ | |
| --project-name="$project_label" \ | |
| --no-interaction \ | |
| --server-type=apache \ | |
| --force | |
| printf "\n--- Running extension:setup and activating extensions\n" | |
| ddev typo3 extension:setup | |
| ddev typo3 extension:activate indexed_search | |
| ddev typo3 extension:activate styleguide | |
| printf "\n--- Creating default backend user groups\n" | |
| ddev typo3 setup:begroups:default --groups=Both | |
| printf "\n--- Generating Styleguide page trees\n" | |
| printf "# Note: 'frontend-systemplate' is the official TYPO3 identifier.\n" | |
| ddev typo3 styleguide:generate --create -- tca | |
| ddev typo3 styleguide:generate --create -- frontend-systemplate | |
| printf "\n--- Flushing TYPO3 caches\n" | |
| ddev typo3 cache:flush || true | |
| t3core_print_success "TYPO3 Core contribution setup completed." | |
| } | |
| t3core_show_result() { | |
| local project_name="$1" | |
| local typo3_username="$2" | |
| local target_dir="$3" | |
| local gerrit_push_url | |
| gerrit_push_url="$(t3core_get_gerrit_push_url "$typo3_username")" | |
| printf "\n--- TYPO3 Backend Login\n" | |
| printf "URL : https://%s.ddev.site/typo3/\n" "$project_name" | |
| printf "Username : %s\n" "$T3CORE_DEFAULT_ADMIN_USERNAME" | |
| printf "Password : %s\n" "$T3CORE_DEFAULT_ADMIN_PASSWORD" | |
| printf "\n--- Gerrit push configuration\n" | |
| printf "Push URL : %s\n" "$gerrit_push_url" | |
| printf "Push ref : +refs/heads/main:refs/for/main\n" | |
| printf "Note : This default targets main. Adjust remote.origin.push manually for other target branches.\n" | |
| printf "\n--- Gerrit account setup\n" | |
| printf "SSH keys : %s\n" "$T3CORE_GERRIT_SSH_KEYS_URL" | |
| printf "Identities : %s\n" "$T3CORE_GERRIT_IDENTITIES_URL" | |
| printf "Email addresses : %s\n" "$T3CORE_GERRIT_EMAIL_ADDRESSES_URL" | |
| printf "\n--- Important before your first push\n" | |
| printf "1. Add your SSH public key in Gerrit:\n" | |
| printf " %s\n" "$T3CORE_GERRIT_SSH_KEYS_URL" | |
| printf "\n" | |
| printf "2. Ensure your Git email address is registered in Gerrit.\n" | |
| printf " If Gerrit rejects your push with 'invalid committer', add the email at:\n" | |
| printf " %s\n" "$T3CORE_GERRIT_EMAIL_ADDRESSES_URL" | |
| printf "\n" | |
| printf "3. Verify your connected identities at:\n" | |
| printf " %s\n" "$T3CORE_GERRIT_IDENTITIES_URL" | |
| printf "\n--- Test Gerrit SSH connection\n" | |
| printf "ssh -p 29418 %s@review.typo3.org\n" "$typo3_username" | |
| printf "\n--- Git behavior in this repository\n" | |
| printf "git pull : rebases by default\n" | |
| printf "git push : pushes to Gerrit for main by default\n" | |
| printf "\n--- Suggested first contribution workflow\n" | |
| printf "cd %s\n" "$target_dir" | |
| printf "git status\n" | |
| printf "git add <changed-files>\n" | |
| printf "git commit\n" | |
| printf "git push\n" | |
| printf "\n--- Rebase your checkout onto latest main\n" | |
| printf "git pull\n" | |
| printf "\n--- Update an existing review\n" | |
| printf "git add <changed-files>\n" | |
| printf "git commit --amend\n" | |
| printf "git push\n" | |
| printf "\n--- DDEV information\n" | |
| ddev describe || true | |
| printf "\n--- Opening TYPO3 backend in browser\n" | |
| ddev launch /typo3/ || true | |
| } | |
| t3core_execute_setup() { | |
| local target_dir_input="$1" | |
| local project_name | |
| local project_label | |
| t3core_clone_repository "$target_dir_input" | |
| project_name="$(basename "$T3CORE_CLONED_TARGET_DIR" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9-' '-')" | |
| project_name="${project_name#-}" | |
| project_name="${project_name%-}" | |
| if [ -z "$project_name" ]; then | |
| t3core_print_error "A valid DDEV project name could not be derived from the target path." | |
| return 1 | |
| fi | |
| project_label="TYPO3 Contribution (${project_name})" | |
| t3core_configure_git_repository \ | |
| "$T3CORE_CONFIRMED_TYPO3_USERNAME" \ | |
| "$T3CORE_CONFIRMED_GIT_USER_NAME" \ | |
| "$T3CORE_CONFIRMED_GIT_USER_EMAIL" | |
| t3core_install_git_hooks | |
| t3core_configure_commit_template | |
| t3core_ensure_ddev_project_name_is_available "$project_name" | |
| t3core_configure_ddev "$project_name" | |
| t3core_configure_local_git_excludes | |
| t3core_setup_instance \ | |
| "$T3CORE_CONFIRMED_GIT_USER_EMAIL" \ | |
| "$project_label" | |
| t3core_show_result "$project_name" "$T3CORE_CONFIRMED_TYPO3_USERNAME" "$T3CORE_CLONED_TARGET_DIR" | |
| cd "$T3CORE_START_DIR" >/dev/null 2>&1 || true | |
| } | |
| t3core_main() { | |
| local target_dir | |
| t3core_check_requirements | |
| if [ "$#" -lt 1 ]; then | |
| t3core_print_error "Please provide at least one repository path as parameter." | |
| printf "Example: %s t3coredev\n" "${0##*/}" >&2 | |
| exit 1 | |
| fi | |
| t3core_collect_confirmed_identity | |
| t3core_verify_gerrit_ssh_access "$T3CORE_CONFIRMED_TYPO3_USERNAME" | |
| for target_dir in "$@"; do | |
| t3core_print_headline "TYPO3 Core Contribution Setup: $target_dir" | |
| t3core_execute_setup "$target_dir" | |
| done | |
| } | |
| t3core_main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment