Skip to content

Instantly share code, notes, and snippets.

@mortenson
Last active January 17, 2019 18:46
Show Gist options
  • Save mortenson/6cb964cccce76eaf6d3c57040637b613 to your computer and use it in GitHub Desktop.
Save mortenson/6cb964cccce76eaf6d3c57040637b613 to your computer and use it in GitHub Desktop.
Creates a patch of all security fixes (commits whose logs contain "SA-") between two Drupal tags
# This script attempts to create a patch file that includes all security fixes
# between two tags.
# Hypothetically, you could just apply the patch to your Drupal site after the
# script is finished successfully to be up to date.
# Biggest successful D7 patch - 7.36 => 7.58
# Biggest successful D8 patch - 8.4.0 => 8.4.7 / 8.6.0 => 8.6.7
# WARNING: This is an experimental patch generation method and may not be
# perfect. If you use this on production I take no responsibility for your
# site's security or lack there-of.
CURRENT_TAG=$1
FORWARD_TAG=$2
OUT_FILE=$3
if [ "$#" -ne 3 ]; then
echo "Missing arguments. Script syntax is ./secpatches.sh CURRENT_TAG FORWARD_TAG output.patch"
echo "For example, to create a patch with all security updates for 8.5.0, run:"
echo "./secpatches.sh 8.5.0 8.5.2 output.patch"
exit 1
fi
echo "Cloning Drupal core..."
tmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
git clone --quiet https://git.drupal.org/project/drupal.git $tmpdir
if [ $? -ne 0 ]; then
echo "Error encountered cloning Drupal core. Is Git working?"
exit 1
fi
cd $tmpdir
git checkout --quiet $CURRENT_TAG
# Get commits with "SA-" in the log message and create a long patch.
echo "Creating and testing a patch using commits:"
git --no-pager log --reverse --format="(%h) %s" --grep=SA- HEAD..$FORWARD_TAG
git --no-pager log --reverse --format=%h --grep=SA- HEAD..$FORWARD_TAG | xargs git show --oneline > tmp.patch
# Some files will fail to patch most of the time.
git apply --exclude=composer.* --exclude=core/composer.* --exclude=*Tests* --exclude=*tests* --exclude=*test --exclude=core/CHANGELOG.txt --exclude=CHANGELOG.txt --exclude=includes/bootstrap.inc tmp.patch
if [ $? -ne 0 ]; then
echo "Unable to apply $OUT_FILE to the $CURRENT_TAG tag."
echo "You may have to create a patch manually, or just update."
else
# Manually copy files that change every release to the working dir
if [ -f core/CHANGELOG.txt ]; then
git checkout $FORWARD_TAG -- core/CHANGELOG.txt composer.lock composer.json core/composer.json
else
git checkout $FORWARD_TAG -- CHANGELOG.txt includes/bootstrap.inc
fi
# Create the real patch
rm tmp.patch
git add .
git diff HEAD --binary . > $OUT_FILE
cd - > /dev/null
if [ -f $tmpdir/$OUT_FILE ]; then
cp $tmpdir/$OUT_FILE $OUT_FILE
fi
echo "Created $OUT_FILE, which applies to $CURRENT_TAG. Use at your own risk!"
fi
rm -rf $tmpdir
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment