System requirements:
- User uploads
$wgUploadDirectory
are stored offsite - Non-Docker MediaWiki with normal setup
- Composor installed (Can be installed automatically during updating)
Goals:
- Update MediaWiki with nearly zero downtime
- Download and install latest tagged MediaWiki from tarball package
- Update extensions and skins from latest git tagged branch
- Install extension-specific dependencies during updating
First create a script name it mw-update.sh
and make sure the script exits if anything goes wrong:
# Exit the whole script if anything goes wrong
set -e
Create a config file mw-update.conf
with the following content:
version=1.35.1
tmp="/tmp"
dest_base="/srv/www/wikiroot"
dest="/public_html"
permissions="nginx.nginx"
extensions="
BetaFeatures
CheckUser
CommonsMetadata
MobileFrontend
cldr
Flow
ContributionScores
intersection
"
skins="
MinervaNeue
"
Switch back to your script. Add more variables to use later:
MWU_START=`date +%s`
# Set the current working directory to the directory of this script
cd ${0%/*}
# Check if config exists
if [ ! -f ./mw-update.conf ]; then
echo -e "Config not found, run the following command first:"
echo -e "\n$ cp mw-update.sample.yml mw-update.yml"
exit 1
fi
# Parse config
. mw-update.conf
# MediaWiki uses git tag for latest stable version
MW_VER=$version
# Decoration
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Production dir
PROD_BASE="$dest_base"
PROD_DIR="$PROD_BASE$dest"
# `MW_VER_MAIN` is for the stupid download URL
MW_VER_MAIN=$(echo $MW_VER | sed -E 's/\.[0-9]+$//g')
# Temp dir prepare for update
TMP_BASE="$tmp/mediawiki-update"
TMP_DIR="$TMP_BASE/mediawiki-$MW_VER"
# Extensions dir
EXT_DIR="$TMP_DIR/extensions"
SKIN_DIR="$TMP_DIR/skins"
# Extensions use git branch for latest stable version
EXT_VER=$(echo REL$MW_VER_MAIN | sed -E 's/\./_/g')
# List of custom extensions
EXTENSIONS="$extensions"
SKINS="$skins"
Then print the setup info for confirmation:
# Prompt before executing anything
echo -e "${BLUE}MediaWiki Auto Updater${NC}"
echo -e "Tunghsiao Liu ([email protected])\n"
echo -e " Core version: ${BLUE}$MW_VER${NC}"
echo -e " Branch version: ${BLUE}$MW_VER_MAIN${NC}"
echo -e "Extension version: ${BLUE}$EXT_VER${NC}"
echo -e " Temp directory: ${BLUE}$TMP_BASE${NC}"
echo -e " Destination base: ${BLUE}$PROD_BASE${NC}"
echo -e " Destination: ${BLUE}$PROD_DIR${NC}"
echo -e " Permissions: ${BLUE}$permissions${NC}"
echo -e "Custom extensions: ${BLUE}$EXTENSIONS${NC}"
echo -e " Custom skins: ${BLUE}$SKINS${NC}"
Continue executing if user confirms:
read -p "Press enter to continue..."
echo -e "\n"
Check if PHP Composor installed:
function check_composer() {
# Allow running Composer with root
export COMPOSER_ALLOW_SUPERUSER=1
if command -v composer >/dev/null 2>&1 ; then
echo -e "${BLUE}PHP Composer found: $(composer --version | head -n 1)${NC}"
else
echo -e "PHP Composer not found, trying to install it..."
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
echo -e "Move PHP Composer to /usr/local/bin/composer for global use"
mv composer.phar /usr/local/bin/composer
fi
}
Begin to update MediaWiki cores:
# Update core files
echo -e "${BLUE}Creating essential directories${NC}"
mkdir -p $TMP_BASE
echo -e "${BLUE}Updating MediaWiki core files${NC}"
cd $TMP_BASE
wget -c https://releases.wikimedia.org/mediawiki/$MW_VER_MAIN/mediawiki-$MW_VER.tar.gz
tar -zxf mediawiki-$MW_VER.tar.gz
echo -e "${BLUE}Backing up LocalSettings.php${NC}"
cd $TMP_DIR
cp $PROD_DIR/LocalSettings.php $TMP_DIR/
Update extensions:
# Update extensions
for extension in $EXTENSIONS
do
echo -e "${BLUE}Updating extension $extension...${NC}"
cd $EXT_DIR
if [ ! -d "$EXT_DIR/$extension" ]; then
echo -e "${EXT_DIR}/${extension} git repo does not exists!"
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/$extension.git
fi
cd $EXT_DIR/$extension
git reset --hard
git clean -f -d
git pull
git checkout $EXT_VER
echo ""
done
Some extensions need special setup process like update git submodules or install dependencies with Composor:
if [[ ${extensions} =~ "Flow" ]]; then
echo -e "${BLUE}Updating composer for Flow (StructuredDiscussions)...${NC}"
cd $EXT_DIR/Flow
check_composer
composer update --no-dev
echo ""
fi
Update skins:
# Update skins
for skin in $SKINS
do
echo -e "${BLUE}Updating skin $skin...${NC}"
cd $SKIN_DIR
if [ ! -d "$SKIN_DIR/$skin" ]; then
git clone https://gerrit.wikimedia.org/r/mediawiki/skins/$skin.git
fi
cd $SKIN_DIR/$skin
git reset --hard
git clean -f -d
git pull
git checkout $EXT_VER
echo ""
done
Please note that all the above process are done in $TMP_BASE
directory. The website is still untouched at the moment. Now lets go into $TMP_BASE
to finalize the prepare process:
cd $TMP_BASE
echo -e "${BLUE}Backing up old files...${NC}"
# tar mediawiki-$MW_VER-update-backup.tar.gz -C $PROD_DIR .
mv $PROD_DIR $PROD_BASE/mediawiki-$MW_VER-backup-$(date +%F-%H:%M)
echo -e "${BLUE}Moving updated files to production...${NC}"
cp -R $TMP_DIR $PROD_DIR
echo -e "${BLUE}Fixing directory permissions...${NC}"
chown -R $permissions $PROD_DIR
echo -e "${BLUE}Running MediaWiki maintenance...${NC}"
php $PROD_DIR/maintenance/update.php --quick
MWU_END=`date +%s`
MWU_RUNTIME=$((MWU_END - MWU_START))
echo -e "${BLUE}Done! Time took: ${MWU_RUNTIME}s${NC}"