Skip to content
Open
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
56 changes: 0 additions & 56 deletions .maintenance/clone-all-repositories.php

This file was deleted.

110 changes: 110 additions & 0 deletions .maintenance/clone-all-repositories.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/usr/bin/env bash

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

if ! command -v jq &>/dev/null; then
echo "Required command 'jq' is not installed or not available in PATH." >&2
exit 1
fi

SKIP_LIST=(
"autoload-splitter"
"composer-changelogs"
"dash-docset-generator"
"ideas"
"package-index"
"regenerate-readme"
"sample-plugin"
"wp-cli-dev"
"wp-cli-roadmap"
)

# Detect number of CPU cores, defaulting to 4.
if command -v nproc &>/dev/null; then
DETECTED_CORES=$(nproc)
elif command -v sysctl &>/dev/null; then
DETECTED_CORES=$(sysctl -n hw.logicalcpu 2>/dev/null || echo 4)
else
DETECTED_CORES=4
fi

MAX_CORES=8
CORES="${CLONE_JOBS:-${WPCLI_DEV_JOBS:-${DETECTED_CORES}}}"

if ! [[ "${CORES}" =~ ^[1-9][0-9]*$ ]]; then
CORES=4
elif [[ -z "${CLONE_JOBS:-}" && -z "${WPCLI_DEV_JOBS:-}" && "${CORES}" -gt "${MAX_CORES}" ]]; then
CORES=${MAX_CORES}
fi

# Fetch repository list from the GitHub API.
CURL_OPTS=(-fsS)
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
CURL_OPTS+=(--header "Authorization: Bearer ${GITHUB_TOKEN}")
fi

if ! RESPONSE=$(curl "${CURL_OPTS[@]}" 'https://api.github.com/orgs/wp-cli/repos?per_page=100'); then
echo "Failed to fetch repository list from the GitHub API." >&2
exit 1
fi

# Validate the response shape and detect API errors such as rate limiting.
if ! jq -e 'type == "array"' >/dev/null <<< "${RESPONSE}"; then
if jq -e '.message' >/dev/null <<< "${RESPONSE}"; then
MESSAGE=$(jq -r '.message' <<< "${RESPONSE}")
echo "GitHub responded with: ${MESSAGE}" >&2
echo "If you are running into a rate limiting issue during large events please set GITHUB_TOKEN environment variable." >&2
echo "See https://github.com/settings/tokens" >&2
else
echo "GitHub API returned an unexpected response; expected a JSON array of repositories." >&2
fi
exit 1
fi

is_skipped() {
local name="$1"
for skip in "${SKIP_LIST[@]}"; do
[[ "${skip}" == "${name}" ]] && return 0
done
return 1
}

get_destination() {
local name="$1"
if [[ "${name}" == ".github" ]]; then
echo "dot-github"
else
echo "${name}"
fi
}

CLONE_LIST=()
UPDATE_FOLDERS=()

while IFS=$'\t' read -r name clone_url ssh_url; do
if is_skipped "${name}"; then
continue
fi

destination=$(get_destination "${name}")

if [[ ! -d "${destination}" ]]; then
if [[ -n "${GITHUB_ACTION:-}" ]]; then
CLONE_LIST+=("${destination}"$'\t'"${clone_url}")
else
CLONE_LIST+=("${destination}"$'\t'"${ssh_url}")
fi
fi

UPDATE_FOLDERS+=("${destination}")
done < <(echo "${RESPONSE}" | jq -r '.[] | [.name, .clone_url, .ssh_url] | @tsv')

if [[ ${#CLONE_LIST[@]} -gt 0 ]]; then
printf '%s\n' "${CLONE_LIST[@]}" | xargs -n2 -P"${CORES}" bash "${SCRIPT_DIR}/clone-repository.sh"
fi

if [[ ${#UPDATE_FOLDERS[@]} -gt 0 ]]; then
printf '%s\n' "${UPDATE_FOLDERS[@]}" | xargs -P"${CORES}" -I% php "${SCRIPT_DIR}/refresh-repository.php" %
fi
14 changes: 14 additions & 0 deletions .maintenance/clone-repository.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

set -euo pipefail

if [[ $# -ne 2 ]]; then
echo "Usage: clone-repository.sh <destination> <clone_url>" >&2
exit 1
fi

destination="$1"
clone_url="$2"

printf "Fetching \033[32m%s\033[0m...\n" "${destination}"
git clone "${clone_url}" "${destination}"
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,8 @@
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"pre-install-cmd": "php .maintenance/clone-all-repositories.php",
"pre-update-cmd": "php .maintenance/clone-all-repositories.php",
"pre-install-cmd": "bash .maintenance/clone-all-repositories.sh",
"pre-update-cmd": "bash .maintenance/clone-all-repositories.sh",
Comment on lines +322 to +323
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching Composer hooks from PHP to bash introduces new runtime prerequisites during composer install/update (at least bash, plus curl/jq used by the script). If this repo is expected to work in environments without these tools (e.g., some Windows setups or minimal CI images), consider adding a clearer failure message in the script and/or documenting the dependencies (or keeping a PHP fallback).

Suggested change
"pre-install-cmd": "bash .maintenance/clone-all-repositories.sh",
"pre-update-cmd": "bash .maintenance/clone-all-repositories.sh",
"pre-install-cmd": "php -r \"$required = ['bash', 'curl', 'jq']; $missing = []; foreach ($required as $command) { $finder = stripos(PHP_OS, 'WIN') === 0 ? 'where' : 'command -v'; @exec($finder . ' ' . escapeshellarg($command) . ' 2>' . (stripos(PHP_OS, 'WIN') === 0 ? 'NUL' : '/dev/null'), $output, $status); if ($status !== 0) { $missing[] = $command; } } if ($missing) { fwrite(STDERR, 'Missing required tools for Composer pre-install-cmd: ' . implode(', ', $missing) . PHP_EOL . 'The .maintenance/clone-all-repositories.sh hook requires bash, curl, and jq. Please install the missing dependencies and re-run composer install/update.' . PHP_EOL); exit(1); } passthru('bash .maintenance/clone-all-repositories.sh', $exitCode); exit($exitCode);\"",
"pre-update-cmd": "php -r \"$required = ['bash', 'curl', 'jq']; $missing = []; foreach ($required as $command) { $finder = stripos(PHP_OS, 'WIN') === 0 ? 'where' : 'command -v'; @exec($finder . ' ' . escapeshellarg($command) . ' 2>' . (stripos(PHP_OS, 'WIN') === 0 ? 'NUL' : '/dev/null'), $output, $status); if ($status !== 0) { $missing[] = $command; } } if ($missing) { fwrite(STDERR, 'Missing required tools for Composer pre-update-cmd: ' . implode(', ', $missing) . PHP_EOL . 'The .maintenance/clone-all-repositories.sh hook requires bash, curl, and jq. Please install the missing dependencies and re-run composer install/update.' . PHP_EOL); exit(1); } passthru('bash .maintenance/clone-all-repositories.sh', $exitCode); exit($exitCode);\"",

Copilot uses AI. Check for mistakes.
"post-install-cmd": [
"php .maintenance/symlink-vendor-folders.php",
"php .maintenance/phpstorm.exclude-recursive-folders.php"
Expand Down