Once our quality checks have passed, we want to look at deploying the application. Again, we have an opportunity to codify some practices to make sure your team performs the same actions time and time again.
Let's set out a typical process that represents a deployment to production:
Number one was taken care of by our before-init
step. Minification and optimization is taken care of by Sencha Cmd's build-in tasks. We're left with three tasks that we'd like to complete before pushing to production, so we'll look at them in turn, but first, let's have a brief interlude and talk about Ant.
In effect, the next few pages are a tutorial for Ant, rather than Sencha Cmd or application architecture. There are many, many resources for Ant online and in print form, so why go over old ground?
Remember that this book isn't a list of facts and figures or code listings to type in line by line. It's supposed to get the brain thinking about the application from a top-down perspective and see how you can help your team build a strong product for your client.
An architect isn't just there to draw pictures of the house. They are there to make sure a beautiful house is built and the homeowner walks away happy.
Back to Ant. There are multiple reasons why you want to label an application with a build or version number—a key one is to let stakeholders know the version they're reviewing to see whether it contains the bug fixes they'd expect.
Versioning the application is a two-step process:
Ant provides a task to make step one fairly simple:
<propertyfile file="app.properties"> <entry key="build.number" type="int" operation="+" value="1"/> </propertyfile>
We use the propertyfile
task to specify that a file called app.properties
will contain an entry called build.number
. Every time we run the task, it triggers an operation to increment thisentry
by one as follows:
<property file="app.properties"/> <replace file="${build.classes.file}" token="{VERSION}" value="${build.number}"/>
Next, we read the app.properties
file to understand how to use the property task, which makes the properties it contains available to further tasks.
Finally, we do a search and replace in the generated JS for a {VERSION}
token and replace it with the build.number
property. Let's see it as a full build.xml
:
<?xml version="1.0" encoding="utf-8"?> <project name="MyApp" default=".help"> <import file="${basedir}/.sencha/app/build-impl.xml"/> <target name="-after-page"> <propertyfile file="app.properties"> <entry key="build.number" type="int" operation="+" value="1"/> </propertyfile> <property file="app.properties"/> <replace file="${build.classes.file}" token="{VERSION}" value="${build.number}"/> </target> </project>
Note that we're using the after-page
target as a hook. This fires after Sencha Cmd has assembled all of the application's dependencies and created a single file to contain them. This is the file we do our search and replace on, which means that our original source files remain intact. You could have a JavaScript file such as this:
// app/Application.js Ext.define('MyApp.Application', { extend: 'Ext.app.Application', name: MyApp', version: '{VERSION}' });
Also, the {VERSION}
token would be replaced, enabling you to use the version number across your application, perhaps in a footer or an About screen.
Our code is neat and tidy, we know what version we're releasing. The next step is to push it to a production server. We'll use SFTP to transfer files to a remote server:
<target name="-after-build"> <input message="Please enter SFTP username:" addproperty="scp.user" /> <input message="Please enter SFTP password:" addproperty="scp.password" /> <scp remoteTodir="${scp.user}@sftp.mysite.com:/path/to/myapp/dir" password="${scp.password}"> <fileset dir="build/production"/> </scp> </target>
We use the afterbuild
target, which means that all other aspects of the build are complete and the final production files have been built. As it's a really bad idea to hardcode security credentials, we use the input task to request input from the user on the command line. The resulting input gets assigned to the property specified in addproperty
.
The scp
task's remoteToDir
attribute should be customized according to your needs, but the scp.username
and scp.password
values will be filled with the previous user input. In the fileset
task, we specify that the whole build/production
directory will be pushed up to the remote server.
We've shown how we can leverage the power of Ant to hook into key aspects of the Sencha Cmd build process, converting error-prone manual tasks to automated ones that can be easily shared with your development team.