My Script for Auto WordPress Upgrade

I like posting scripts. I am proud of most of them. I mentioned before that I run WordPress trunk and that every day, the auto upgrade script runs, upgrades this blog and sends me a detailed email regarding the upgrade. Not only does this help me keep track of changes from revision to revision without having to go browsing the repository, it gives me a handy reference in case I have to roll back.

Here is the script I run. It is a PHP command line script (I do most of my CLI scripting in PHP as I’m fluent in it).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/php
< ?php
/* Get info from the WordPress repository regarding trunk. We will use this to parse out the latest revision number */
$svninfo = shell_exec('svn info /root/working_copies/wptrunk/trunk/');
$lines = explode("n", $svninfo);
$bits = explode(' ', $lines[7]);
$oldrev = $bits[3];

/* I use shell_exec() because the output of the CLI commands will be returned. I'll be able to add this to the email */
$log = "PROCESS LOGn---------------nn";
$log .= shell_exec('svn up /root/working_copies/wptrunk/trunk/');
$log .= shell_exec('svn export --force /root/working_copies/wptrunk/trunk /home/techno/public_html/');

/* Get the revision number of the working copy. This is the new revision number */
$svninfo = shell_exec('svn info /root/working_copies/wptrunk/trunk/');
$lines = explode("n", $svninfo);
$bits = explode(' ', $lines[7]);
$newrev = $bits[3];

/* Pass the revision info along to be included in the email */
$details = "nnOld Revision: $oldrevnNew Revision: $newrevnnn";

/* Use the revision numbers to determine the log of changes between them. Add for email.  */
$history = "SVN LOGn---------------nn";
$history .= shell_exec("svn log -r $oldrev:$newrev /root/working_copies/wptrunk/trunk/");
$history .= "nn";

/* Grab detailed changes (diff) between revisions. Add to email. */
$history .= "SVN DIFFn---------------nn";
$history .= shell_exec("svn diff -r $oldrev:$newrev http://svn.automattic.com/wordpress/trunk/");
$history .= "nn";

/* Put the pieces together for the email, then send */
$message = $details . $history . $log;
mail('aaron@technosailor.com','WordPress SVN Update', $message, 'From: aaron@technosailor.com');
?>

This sends me an email like the one I got the other night:

 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
Old Revision: 4863
New Revision: 4871

SVN LOG
---------------

------------------------------------------------------------------------
r4863 | ryan | 2007-02-02 11:38:26 -0500 (Fri, 02 Feb 2007) | 1 line

Check page ID only if is_page.  fixes #3049
------------------------------------------------------------------------
r4865 | ryan | 2007-02-02 19:56:23 -0500 (Fri, 02 Feb 2007) | 1 line

Typo fix from charleshooper.  fixes #3743
------------------------------------------------------------------------
r4866 | ryan | 2007-02-05 16:29:39 -0500 (Mon, 05 Feb 2007) | 1 line

Disambiguate queries.  Props mhyk25.  fixes #3747
------------------------------------------------------------------------
r4867 | ryan | 2007-02-05 16:37:47 -0500 (Mon, 05 Feb 2007) | 1 line

Make DB_COLLATE blank by default so that MySQL will choose the default collation for the charset. #3517
------------------------------------------------------------------------
r4870 | ryan | 2007-02-05 20:44:23 -0500 (Mon, 05 Feb 2007) | 1 line

XMLRPC changes from Joseph.
------------------------------------------------------------------------
r4871 | ryan | 2007-02-06 15:12:53 -0500 (Tue, 06 Feb 2007) | 1 line

Send content type header. Props nbachiyski.  fixes #3754
------------------------------------------------------------------------

SVN DIFF
---------------

Index: wp-includes/query.php
===================================================================
--- wp-includes/query.php   (revision 4863)
+++ wp-includes/query.php   (revision 4871)
@@ -794,16 +794,16 @@
            $in_cats = substr($in_cats, 0, -2);
            $out_cats = substr($out_cats, 0, -2);
            if ( strlen($in_cats) > 0 )
-               $in_cats = " AND category_id IN ($in_cats)";
+               $in_cats = " AND $wpdb->post2cat.category_id IN ($in_cats)";
            if ( strlen($out_cats) > 0 ) {
-               $ids = $wpdb->get_col("SELECT post_id FROM $wpdb->post2cat WHERE category_id IN ($out_cats)");
+               $ids = $wpdb->get_col("SELECT post_id FROM $wpdb->post2cat WHERE $wpdb->post2cat.category_id IN ($out_cats)");
                if ( is_array($ids) && count($ids > 0) ) {
                    foreach ( $ids as $id )
                        $out_posts .= "$id, ";
                    $out_posts = substr($out_posts, 0, -2);
                }
                if ( strlen($out_posts) > 0 )
-                   $out_cats = " AND ID NOT IN ($out_posts)";
+                   $out_cats = " AND $wpdb->posts.ID NOT IN ($out_posts)";
                else
                    $out_cats = '';
            }
Index: wp-includes/functions.php
===================================================================
--- wp-includes/functions.php   (revision 4863)
+++ wp-includes/functions.php   (revision 4871)
@@ -329,7 +329,7 @@

    $alloptions = wp_load_alloptions();
    if ( isset($alloptions[$option_name]) ) {
-       $alloptions[$options_name] = $newvalue;
+       $alloptions[$option_name] = $newvalue;
        wp_cache_set('alloptions', $alloptions, 'options');
    } else {
        wp_cache_set($option_name, $newvalue, 'options');
Index: xmlrpc.php
===================================================================
--- xmlrpc.php  (revision 4863)
+++ xmlrpc.php  (revision 4871)
@@ -228,7 +228,7 @@
                "wp_page_parent_title"  => $parent_title,
                "wp_page_order"         => $page->menu_order,
                "wp_author_id"          => $author->ID,
-               "wp_author_display_username"    => $author->display_name
+               "wp_author_display_name"    => $author->display_name
            );

            return($page_struct);
Index: wp-config-sample.php
===================================================================
--- wp-config-sample.php    (revision 4863)
+++ wp-config-sample.php    (revision 4871)
@@ -5,7 +5,7 @@
 define('DB_PASSWORD', 'password'); // ...and password
 define('DB_HOST', 'localhost');    // 99% chance you won't need to change this value
 define('DB_CHARSET', 'utf8');
-define('DB_COLLATE', 'utf8_general_ci');
+define('DB_COLLATE', '');

 // You can have multiple installations in one database if you give each a unique prefix
 $table_prefix  = 'wp_';   // Only numbers, letters, and underscores please!
Index: wp-admin/index-extra.php
===================================================================
--- wp-admin/index-extra.php    (revision 4863)
+++ wp-admin/index-extra.php    (revision 4871)
@@ -2,6 +2,8 @@
 require_once('admin.php');
 require_once (ABSPATH . WPINC . '/rss.php');

+@header('Content-type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
+
 switch ( $_GET['jax'] ) {

 case 'incominglinks' :

PROCESS LOG
---------------

U  /root/working_copies/wptrunk/trunk/wp-includes/query.php
U  /root/working_copies/wptrunk/trunk/wp-includes/functions.php
U  /root/working_copies/wptrunk/trunk/xmlrpc.php
U  /root/working_copies/wptrunk/trunk/wp-config-sample.php
U  /root/working_copies/wptrunk/trunk/wp-admin/index-extra.php

Fetching external item into '/root/working_copies/wptrunk/trunk/wp-content/plugins/akismet'
Updated external to revision 7886.

Updated to revision 4871.
Export complete.

Nice huh?

Update: Use this script at your own risk. The WordPress trunk is not supported by WordPress. If you use this script without understanding how to roll back, it’s all on you. If you break your blog, no one is going to help you!

Commenter Rick explains the systems requirements:

  • Shell access; the command “php wordpress-update-cli.php” would otherwise be unable to run.
  • Crontab; if you wanted to automate the running of the script on a regular basis.
  • php 4.0.1+ or 5+; shell_exec() would otherwise be unavailable. The other prominent function call, explode(), is available from 4+. Safe mode must be set to Off to use shell_exec().
  • SVN installed on the server in order to use svn command from the shell.

Aaron Brazell

Aaron Brazell is a Baltimore, MD-based WordPress developer, a co-founder at WP Engine, WordPress core contributor and author. He wrote the book WordPress Bible and has been publishing on the web since 2000. You can follow him on Twitter, on his personal blog and view his photography at The Aperture Filter.

24 thoughts on “My Script for Auto WordPress Upgrade

  1. As asked before what are the requirements and also what if the hosting provider upgrades wordpress automatically. Wont it interfere with this script then.

  2. This may be a silly question, but wouldn’t it be a neat idea to build this into some sort of upgrade application that one could use without having to be on the bleeding edge? The problem with WordPress is that the installation process is from the 1980’s. If your script will work, it’s a great starting point.

    Peace,
    Gene

  3. I’m not sure what the exact server requirements would be, but I can take a guess:

    1) Shell access; the command “php wordpress-update-cli.php” would otherwise be unable to run.

    2) Crontab; if you wanted to automate the running of the script on a regular basis.

    3) php 4.0.1+ or 5+; shell_exec() would otherwise be unavailable. The other prominent function call, explode(), is available from 4+. Safe mode must be set to Off to use shell_exec().

    4) SVN installed on the server in order to use svn command from the shell. (Not too sure about this one, though it seems reasonable. I’m not sure how native the svn command, whether it needs extra software or not, etc.)

  4. Ajay: Rick nailed them.

    Anshuk: If your host auto upgrades anything of yours, it’s time to find a new host.

    BloggingPro China: Uh…. ;)

    Gene: Sure, it’s called FTP. :)

  5. Why would you do that, Jonathon? If you want stable just go and download the thing from wordpress.org. Stable is only released ever so often, not something you’d want to put on cron and upgrade every night.

  6. It’s stable today! Can’t guarantee tomorrow! :) It’s definitely not supported! It’s definitely for advanced users who understand the ins and outs of WordPress and SVN.

  7. Pingback: Akkam’s Razor
  8. Pingback: The Best of 2007

Comments are closed.