Update (04-30-2012): Since being featured on the Windows Azure blog for my WordPress post the hits to this post have exploded. Automated deployment is a hot issue with Windows Azure, however this is probably not the post you are looking for as it deals with the outdated command-line tools project, which has been officially depreciated. I do, however, have another possible solution for you, the WAZ-PHP-Utils project that can be found on Github. With this project you do not ever have to touch a scaffolder and can package and deploy in one command. There is a full wiki on installing and using the project on the Github page. Be sure to check it out.
Windows Azure PHP Utilities Github project page
Newer Note: The Interoperability Team at Microsoft has annouced a new version of the Windows Azure SDK for PHP which contains a set of shiny new command line tools and has deprecated the Windows Azure PHP Command-line Tools project. This post is not valid for the SDK and in fact the new tools make it so easy to create a package that it is almost not worth using a build script. See http://azurephp.interoperabilitybridges.com for documentation on the new SDK tools
One of the main goals in any developer’s mind is how to streamline processes to make development faster and easier. Quite often we will spend a significant amount of time building a tool to solve a problem that could have been implemented much quicker if we just solved the problem. However by building that tool in the future we will not have to think about that problem again, nor take any time to solve it. Simply pull up the tool and go.
Coming from that mindset it irked me to remember all the step and parameters needed to build a PHP project for Windows Azure with the Windows Azure PHP Command-line Tools in Windows. I built a fairly flexible build script that allows me to forget about all those pesky details and instead focus on building my app. Being primarily a Linux user I am very comfortable at the console and usually have several open, even on Windows, therefore this tool requires you to use the console and be in the project directory.
Here is the typical work flow:
- Build your app
- Open a terminal and change directories to the root of your app
- Run ‘wazbuild’
- Do something with the output (testing, uploading, whatever)
This works great for me and I will share my build script with you below. First you need to take note of my directory structure though and to get a clear grasp you need some Windows Azure background. Windows Azure allows developers to setup many roles. Roles do the actual running of your application and there are two types of roles you may choose: Web Role or Worker Role. A Web Role runs IIS and provides your users with a place to interact with your data and application. A Worker Role is a background process without an interface that is designed to simply do tasks you specify. Since a lot of the projects I build use both I have elected to use a predetermined folder structure for my projects that clearly delineates between the two. Here is my typical folder structure:
\ProjectFolder
\ProjectFolder\Web
\ProjectFolder\Worker
\ProjectFolder\Worker\worker.php
The structure should be self-explanatory from the information given above, however there is one file I did not mention, the worker.php file. When building a worker with the Windows Azure Command-line Tools you must provide an entry point for the worker. This file will get run when the worker role starts. That is the worker.php file in my case.
Enough blabbing, here is my build script. Edit it to your specific Windows development environment an put it somewhere safe.
ECHO OFF
REM Automated build script for Windows Azure Projects
REM To use this script you must be in the root of the WAZ project directory
REM Builds Windows Azure projects based on the structure
REM \ProjDir
REM \ProjDir\Web
REM \ProjDir\Worker
REM \ProjDir\Worker\worker.php
set PROJNAME="WAZProj"
set OUTPUT_DIR="%CD%\deploy"
set WACMDDIR="C:\wacmd"
set PHPRUNTIME="C:\Program Files (x86)\PHP"
set PROJ=%CD%
REM Make sure the files that are required exists
IF NOT EXIST %WACMDDIR% (
ECHO Command-line tools directory does not exist
GOTO:EOF
)
IF NOT EXIST %WACMDDIR%\res\php\runtime (
set ADDRUNTIME=--phpRuntime=%PHPRUNTIME%
ECHO %RUNME%
)
IF NOT EXIST %PHPRUNTIME% (
ECHO Could not find PHP Runtime!!!
GOTO:EOF
)
IF NOT EXIST %PROJ%\Web (
ECHO Invalid Project Directory Structure. Missing 'Web' folder
GOTO:EOF
)
IF NOT EXIST %PROJ%\Worker (
ECHO Invalid Project Directory Structure. Missing 'Worker' folder
GOTO:EOF
)
IF NOT EXIST %PROJ%\Worker\worker.php (
ECHO Invalid Project Directory Structure. Missing 'Worker\worker.php'
GOTO:EOF
)
ECHO %RUNTIMEPARAM%
csrun /devfabric:shutdown && rm -rf %PROJ%\deploy
cd %WACMDDIR%
%PHPRUNTIME%\php.exe package.php --source="%PROJ%\Web" --project="%PROJNAME%" --runDevFabric -f --target="%OUTPUT_DIR%" --worker-role-startup-script="worker.php" --worker-role="%PROJ%\Worker" %ADDRUNTIME%
cd %PROJ%
Now you have the script, great but it does not do anything just yet. You still need to edit your system path settings and add the location of your build script. I tend to keep mine in “C:\scripts” so that is what I added to my path.
Now open a terminal, change directories to your project, and type ‘wazbuild’ into your terminal. If you did everything correctly you will see the script kick the Windows Azure Command-line Tools into action and shortly your browser will pop up with your project running and you will find a ‘deploy’ folder inside your project root with the files needed to upload your project to the Windows Azure Portal.
If you are interested in developing with PHP on Windows Azure be sure to check out the Azure PHP website from the folks on the Microsoft Interoperability team. They have a collection of tutorials available that will guide you through the process of setting up of your development environment in Windows to actual deployment of your code. Their tutorials are great and full of many step-by-step coding examples.
Update (05-19-2011): Added conditional check to ensure the tool has a PHP runtime available to put in the package. Thanks for the idea @CraigKitterman!