| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.2//EN" |
| "http://forrest.apache.org/dtd/document-v12.dtd"> |
| <document> |
| <header> |
| <title>Forrestbot - automated building and deploying</title> |
| </header> |
| <body> |
| <section> |
| <title>Overview</title> |
| <p> |
| Forrestbot lets you automate building and deploying websites. The whole |
| process gets the source docs, builds the site, then deploys it where you |
| want it to go. Forrestbot can also notify you afterwards, and it keeps a |
| log of the build process. To accomplish these tasks, Forrestbot uses |
| four "workstages" (getsrc, build, deploy, notify). Each workstage has |
| various implementations (e.g., getsrc has getsrc.cvs or getsrc.svn or |
| getsrc.local implementations), which have various properties that may be |
| set, depending upon the implementations chosen. |
| </p> |
| </section> |
| <section> |
| <title>Using Forrestbot</title> |
| <p> |
| You need to create a customized buildfile directing Forrestbot's work |
| and then simply execute: |
| </p> |
| <source>forrest -f mybuildfile.xml</source> |
| <p> |
| This project buildfile is simply an Ant buildfile with specific targets |
| that control Forrestbot's operation. The next section explains how to |
| create such a buildfile. For details on the syntax of Ant buildfiles and |
| the operation of Ant itself consult the <link |
| href="ext:ant">Ant |
| documentation</link>. |
| </p> |
| </section> |
| <section> |
| <title>Creating a Forrestbot Project Buildfile</title> |
| <p> |
| Within the new buildfile, you need to first set properties needed by the |
| workstages you are going to use and then specify which implementations |
| will be used by each workstage. Note that the properties need to be set |
| at the global scope (as children of <code><project></code>, i.e., |
| outside of <code><target></code> elements) in order for your |
| settings to override the defaults in the Forrestbot implementation. |
| Other than that, the property definitions can appear anywhere before the |
| <code><import></code> task. |
| </p> |
| <p> |
| This sample buildfile can be used as a base from which to customize your |
| own buildfile. The file starts with the project name and default target, |
| then sets the specific properties we need to get the source, indicate |
| the deployment location, and set up notification. It then specifies |
| which implementations we will use and finishes up with importing the |
| <code>forrestbot.xml</code> file. The 'main' target, which is specified |
| as the default here, is a convenience target (defined in |
| <code>forrestbot.xml</code>) that executes the four workstages (getsrc, |
| build, deploy, notify) sequentially. |
| </p> |
| <source> |
| <![CDATA[ |
| <project name="mysampleproject" default="main"> |
| <property name="notify.email.host" value="smtp.myhost.com"/> |
| <property name="notify.email.to" value="me@domain.com"/> |
| <property name="notify.administrator" value="Your Name"/> |
| <property name="getsrc.cvs.user" value="anoncvs"/> |
| <property name="getsrc.cvs.password" value="anoncvs"/> |
| <property name="getsrc.cvs.root" value="/home/cvspublic"/> |
| <property name="getsrc.cvs.host" value="cvs.myhost.com"/> |
| <property name="getsrc.cvs.module" value="myproject"/> |
| <property name="deploy.scp.dest" |
| value="username@myhost.com:/var/www/mydomain/htdocs"/> |
| |
| <!-- here we declare the ssh keyfile and passphrase in an external file --> |
| <import file="../deploy-settings.xml" optional="true"/> |
| |
| <!-- here we specify to use two notification implementations --> |
| <target name="notify" depends="notify.local, notify.email"/> |
| |
| <!-- here we specify to deploy with the scp implementation --> |
| <target name="deploy" depends="deploy.scp"/> |
| |
| <!-- the default implementation for getsrc is getsrc.cvs, |
| which is what we want --> |
| |
| <!-- assumes FORREST_HOME has been set as an environment variable --> |
| <property environment="env"/> |
| <import file="${env.FORREST_HOME}/tools/forrestbot/core/forrestbot.xml"/> |
| </project> |
| ]]> |
| </source> |
| <section> |
| <title>Workstages</title> |
| <p> |
| It is only necessary to include specific target implementations in the |
| buildfile if we want to override the default implementations. The |
| following table shows the various workstages, which implementations |
| may be used for each, and which one is the default. |
| </p> |
| <table> |
| <tr> |
| <th>Workstage</th> |
| <th>Implementations</th> |
| </tr> |
| <tr> |
| <td>getsrc</td> |
| <td> |
| <ul> |
| <li><link href="#getsrc.local">getsrc.local</link></li> |
| <li><link href="#getsrc.cvs">getsrc.cvs</link> (default)</li> |
| <li><link href="#getsrc.svn">getsrc.svn</link></li> |
| </ul> |
| </td> |
| </tr> |
| <tr> |
| <td>build</td> |
| <td> |
| <ul> |
| <li><link href="#build.forrest">build.forrest</link></li> |
| </ul> |
| </td> |
| </tr> |
| <tr> |
| <td>deploy</td> |
| <td> |
| <ul> |
| <li><link href="#deploy.local">deploy.local</link> |
| (default)</li> |
| <li><link href="#deploy.scp">deploy.scp</link></li> |
| <li><link href="#deploy.cvs">deploy.cvs</link></li> |
| <li><link href="#deploy.svn">deploy.svn</link></li> |
| <li><link href="#deploy.ftp">deploy.ftp</link></li> |
| </ul> |
| </td> |
| </tr> |
| <tr> |
| <td><link href="#notify">notify</link> |
| </td> |
| <td> |
| <ul> |
| <li><link href="#notify.local">notify.local</link> |
| (default)</li> |
| <li><link href="#notify.email">notify.email</link></li> |
| </ul> |
| </td> |
| </tr> |
| </table> |
| <p> |
| If you want to do more advanced processing for your project, you can |
| override the 'main' target, which by default is <code><target |
| name="main" depends="getsrc, build, deploy, notify"/></code>, |
| create your own implementation of a workstage, or use any other ant |
| tasks to do additional work. In order to create your own workstage |
| implementation, define the workstage target in question in your |
| <code>mybuildfile.xml</code> anywhere before the |
| <code><import></code> task. This will override the default |
| implementation provided by Forrestbot. |
| </p> |
| <p> |
| Also, you can choose a different target as the default by changing the |
| <code>default</code> attribute of <code><project></code>. For |
| example, you will much more frequently do a 'build' without a 'deploy' |
| during the development of your website, and only at the end do an |
| actual 'deploy', so you might want to choose 'build' as your default |
| target. |
| </p> |
| <section id="checksums"> |
| <title>Deploying only modified files</title> |
| <p> |
| Use the <link href="site:faq/checksums">checkums</link> feature of |
| the Cocoon CLI. This enables Forrest to keep track of which |
| generated files have actually been changed. The Ant tasks used by |
| Forrestbot will then deploy only the modified files. Ant keeps a |
| <code>cache.properties</code> file. If you need to deploy all files |
| then remove this file and let it be re-generated. |
| </p> |
| <p> |
| Note that the deplo.svn and deploy.cvs workstages handle modified |
| files with their own mechanism. |
| </p> |
| </section> |
| <section> |
| <title>Correct Use of getsrc.local</title> |
| <p> |
| There is a wrinkle when using the 'getsrc.local' implementation of |
| the 'getsrc' workstage. If you define your own 'getsrc.local' |
| target, make sure it starts with the <code><property></code> |
| task given here: |
| </p> |
| <source><target name="getsrc.local"> |
| <property name="build.home-dir" location="${getsrc.local.root-dir}"/> |
| [...] |
| </target></source> |
| <p> |
| Alternatively (and preferably), define your 'getsrc' target like |
| this: |
| </p> |
| <source><target name="getsrc" depends="getsrc.clean-workdir, getsrc.get, getsrc.local"/></source> |
| <p> |
| and then implement the actual fetching of the sources in the |
| 'getsrc.get' target. This latter approach is safer since it is more |
| likely to be forward-compatible with future versions of Forrestbot. |
| </p> |
| </section> |
| </section> |
| <section> |
| <title>Workstage Properties</title> |
| <p> |
| Each workstage implementation is configurable with properties. The |
| following tables describe each property and whether or not you are |
| required to set it in your buildfile. |
| </p> |
| <p> |
| Many workstage properties use usernames and passwords. You may want to |
| keep them out of your project's Ant buildfile (especially if you store |
| that file in CVS or SVN). A nice way to do this is to create a |
| separate properties file (e.g., <code>auth.properties</code>) that |
| just sets those properties (don't include it in CVS/SVN). Then, at the |
| top of your project buildfile, have <code><property |
| file="auth.properties"/></code>. |
| </p> |
| <section> |
| <title>Misc. Properties</title> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>ant.project.name (you specify this by <project |
| name="____"> in your buildfile)</td> |
| <td>This must be unique for each project.</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| </table> |
| </section> |
| <section> |
| <title>getsrc.clean-workdir</title> |
| <p> |
| This should be executed before a getsrc implementation is executed, |
| e.g., <code><target name="getsrc" depends="getsrc.clean-workdir, |
| getsrc.svn"/></code>. |
| </p> |
| </section> |
| <section id="getsrc.local"> |
| <title>getsrc.local</title> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>getsrc.local.root-dir</td> |
| <td>Absolute path to the project's root directory on the local |
| computer. Use <strong>location=</strong> instead of |
| <strong>value=</strong> for this <property></td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| </table> |
| </section> |
| <section id="getsrc.cvs"> |
| <title>getsrc.cvs</title> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>getsrc.cvs.user</td> |
| <td>CVS username</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>getsrc.cvs.password</td> |
| <td>CVS password</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>getsrc.cvs.root</td> |
| <td>CVS root directory</td> |
| <td>/home/cvsroot</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>getsrc.cvs.host</td> |
| <td>CVS host</td> |
| <td>cvs.apache.org</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>getsrc.cvs.module</td> |
| <td>CVS module name (an alias for or the full path to the |
| directory that contains forrest.properties)</td> |
| <td>${ant.project.name}</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>getsrc.cvs.tag</td> |
| <td>CVS tag or branch name</td> |
| <td></td> |
| <td>No</td> |
| </tr> |
| </table> |
| </section> |
| <section id="getsrc.svn"> |
| <title>getsrc.svn</title> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>getsrc.svn.url</td> |
| <td>Full repository URL for project (this directory must contain |
| forrest.properties)</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>getsrc.svn.revision</td> |
| <td>Revision number to fetch</td> |
| <td>HEAD</td> |
| <td>No</td> |
| </tr> |
| </table> |
| </section> |
| <section id="build.forrest"> |
| <title>build.forrest</title> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>build.work-dir</td> |
| <td>Directory to temporarily hold working files</td> |
| <td>work/${ant.project.name}</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>build.log-dir</td> |
| <td>Directory to hold log files</td> |
| <td>logs</td> |
| <td>No</td> |
| </tr> |
| </table> |
| </section> |
| <section id="deploy.local"> |
| <title>deploy.local</title> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>deploy.local.dir</td> |
| <td>Path to deploy site to - the dir that would be the |
| equivalant of build/site dir. Relative paths are relative to |
| ${basedir}, which defaults to the dir containing the Forrestbot |
| project buildfile (mybuildfile.xml).</td> |
| <td>sites/${ant.project.name}</td> |
| <td>No</td> |
| </tr> |
| </table> |
| </section> |
| <section id="deploy.scp"> |
| <title>deploy.scp</title> |
| <p> |
| The <code>${user.home}/.ssh/known_hosts</code> must properly |
| recognize the host, so you should manually make an ssh connection to |
| the host if you never have before. |
| </p> |
| <p> |
| If <code>${deploy.scp.keyfile}</code>is defined, then it will use |
| key-based authentication in preference. Otherwise it will use |
| <code>${deploy.scp.password}</code> |
| </p> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>deploy.scp.dest</td> |
| <td>Full destination reference in the format |
| user@host:/directory/path</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>deploy.scp.keyfile</td> |
| <td>Location of the local file holding the private key. |
| Usually /home/me/.ssh/id_dsa or /home/me/.ssh/id_rsa |
| <br /> |
| Note that the deploy.scp.passphrase must also be supplied. |
| </td> |
| <td></td> |
| <td>No. However, if this is not supplied then scp will fallback |
| to use the less secure deploy.scp.password</td> |
| </tr> |
| <tr> |
| <td>deploy.scp.passphrase</td> |
| <td>Local passphrase for your private key.</td> |
| <td></td> |
| <td>No. You will be prompted if it is not set.</td> |
| </tr> |
| <tr> |
| <td>deploy.scp.password</td> |
| <td>Password for user@host</td> |
| <td></td> |
| <td>No. You will be prompted if it is not set. |
| <br /> |
| Not needed if using the preferred |
| deploy.scp.keyfile/deploy.scp.passphrase |
| </td> |
| </tr> |
| </table> |
| </section> |
| <section id="deploy.cvs"> |
| <title>deploy.cvs</title> |
| <p> |
| This is only available on *nix operating systems. |
| </p> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>deploy.cvs.user</td> |
| <td>CVS username to use when committing changes</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>deploy.cvs.password</td> |
| <td>CVS password</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>deploy.cvs.root</td> |
| <td>CVS root</td> |
| <td>/home/cvs</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>deploy.cvs.host</td> |
| <td>CVS host</td> |
| <td>cvs.apache.org</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>deploy.cvs.module</td> |
| <td>CVS module</td> |
| <td>${ant.project.name}</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>deploy.cvs.commit-message</td> |
| <td>Message to use when committing. You probably want to put a |
| machine name or person's name here.</td> |
| <td>Automatic publish from forrestbot</td> |
| <td>No</td> |
| </tr> |
| </table> |
| </section> |
| <section id="deploy.svn"> |
| <title>deploy.svn</title> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>deploy.svn.user</td> |
| <td>SVN username to use when committing changes</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>deploy.svn.password</td> |
| <td>SVN password</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>deploy.svn.url</td> |
| <td>Full repository URL</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>deploy.svn.commit-message</td> |
| <td>Message to use when committing. You probably want to put a |
| machine name or person's name here.</td> |
| <td>Automatic publish from forrestbot</td> |
| <td>No</td> |
| </tr> |
| </table> |
| </section> |
| <section id="deploy.ftp"> |
| <title>deploy.ftp</title> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>deploy.ftp.server</td> |
| <td>FTP server to upload files to</td> |
| <td>localhost</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>deploy.ftp.user</td> |
| <td>FTP username to use for authenticating with the server</td> |
| <td>anonymous</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>deploy.ftp.password</td> |
| <td>Password for the FTP user</td> |
| <td>forrestbot@</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>deploy.ftp.remotedir</td> |
| <td>The directory to upload to (this can be an absolute path or |
| relative to the FTP user's default directory)</td> |
| <td>incoming</td> |
| <td>No</td> |
| </tr> |
| </table> |
| </section> |
| <section id="notify"> |
| <title>notify</title> |
| <p> |
| These settings are used by all notify implementations. |
| </p> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>notify.administrator</td> |
| <td>Name and email address of the forrestbot administrator</td> |
| <td></td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>notify.on.failure</td> |
| <td>On a build failure, notification will happen if this is |
| true.</td> |
| <td>true</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>notify.on.success</td> |
| <td>On a succesful build, notification will happen if this is |
| true.</td> |
| <td>true</td> |
| <td>No</td> |
| </tr> |
| <tr> |
| <td>notify.log</td> |
| <td>Log file</td> |
| <td></td> |
| <td>No. Set by other workstage(s).</td> |
| </tr> |
| <tr> |
| <td>notify.deploy-location</td> |
| <td>Deployed location</td> |
| <td></td> |
| <td>No. Set by other workstage(s).</td> |
| </tr> |
| <tr> |
| <td>notify.completion-status</td> |
| <td>Result of the build</td> |
| <td></td> |
| <td>No. Set by other workstage(s).</td> |
| </tr> |
| </table> |
| </section> |
| <section id="notify.local"> |
| <title>notify.local</title> |
| <p> |
| No properties. |
| </p> |
| </section> |
| <section id="notify.email"> |
| <title>notify.email</title> |
| <table> |
| <tr> |
| <th>Property</th> |
| <th>Description</th> |
| <th>Default Value</th> |
| <th>Required?</th> |
| </tr> |
| <tr> |
| <td>notify.email.host</td> |
| <td>SMTP host through which the email will be sent.</td> |
| <td>localhost</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>notify.email.to</td> |
| <td>Email address to send notification to.</td> |
| <td>${user.name}@localhost</td> |
| <td>Yes</td> |
| </tr> |
| <tr> |
| <td>notify.email.from</td> |
| <td>From: address in the email</td> |
| <td>Forrestbot</td> |
| <td>No, but some mailers may require a valid email address.</td> |
| </tr> |
| </table> |
| </section> |
| </section> |
| </section> |
| <section> |
| <title>Forrestbot Design</title> |
| <p> |
| Forrest and Forrestbot use Ant buildfiles extensively. Ant 1.6's |
| <code><import></code> task is used to import multiple buildfiles |
| into a single build. The following is the flow of control when running |
| Forrestbot: |
| </p> |
| <ul> |
| <li>Your project buildfile (<code>mybuildfile.xml</code>)<ul> |
| <li><code>$FORREST_HOME/tools/forrestbot/core/forrestbot.xml</code> |
| <ul> |
| <li>Workstage buildfiles |
| (<code>$FORREST_HOME/tools/forrestbot/core/{getsrc,build,deploy,notify}.xml</code>)</li> |
| <li><code>$FORREST_HOME/main/forrest.build.xml</code></li> |
| </ul></li> |
| </ul></li> |
| </ul> |
| <p> |
| The workstage buildfiles define the default workstage implementations |
| and set up the properties and files so that targets in the main Forrest |
| buildfile (<code>forrest.build.xml</code>) will run. After those targets |
| are executed, the targets in the workstage buildfiles can perform |
| reporting, deployment, or other post-build activities. |
| </p> |
| <p> |
| Your project buildfile specifies the workstages you want to use, sets |
| properties for them, and does any additional pre- and post-processing. |
| In addition, you can override the default workstage implementations by |
| defining the relevant targets in your project buildfile before the |
| <code><import></code> task (see the example above). |
| </p> |
| </section> |
| </body> |
| </document> |