Continuous Integration - TeamCity (linux)

This sets up a TeamCity build integration environment on Linux.

Prerequisites

After meeting the preparation steps for your specific environment, log on to your teamcity interface at http://<your server>:8111/.

Create a new project named “Evennia” and in it construct a new template called continuous-integration.

A Quick Overview

Templates are fancy objects in TeamCity that allow an administrator to define build steps that are shared between one or more build projects. Assigning a VCS Root (Source Control) is unnecessary at this stage, primarily you’ll be worrying about the build steps and your default parameters (both visible on the tabs to the left.)

Template Setup

In this template, you’ll be outlining the steps necessary to build your specific game. (A number of sample scripts are provided under this section below!) Click Build Steps and prepare your general flow. For this example, we will be doing a few basic example steps:

  • Transforming the Settings.py file - We do this to update ports or other information that make your production environment unique from your development environment.

  • Making migrations and migrating the game database.

  • Publishing the game files.

  • Reloading the server.

For each step we’ll being use the “Command Line Runner” (a fancy name for a shell script executor).

Create a build step with the name: “Transform Configuration” and add the script:

#!/bin/bash
# Replaces the game configuration with one 
# appropriate for this deployment.

CONFIG="%system.teamcity.build.checkoutDir%/server/conf/settings.py"
MYCONF="%system.teamcity.build.checkoutDir%/server/conf/my.cnf"

sed -e 's/TELNET_PORTS = [4000]/TELNET_PORTS = [%game.ports%]/g' "$CONFIG" > "$CONFIG".tmp && mv
"$CONFIG".tmp "$CONFIG"
sed -e 's/WEBSERVER_PORTS = [(4001, 4002)]/WEBSERVER_PORTS = [%game.webports%]/g' "$CONFIG" >
"$CONFIG".tmp && mv "$CONFIG".tmp "$CONFIG"
# settings.py MySQL DB configuration
echo Configuring Game Database...
echo "" >> "$CONFIG"
echo "######################################################################" >> "$CONFIG"
echo "# MySQL Database Configuration" >> "$CONFIG"
echo "######################################################################" >> "$CONFIG"

echo "DATABASES = {" >> "$CONFIG"
echo "   'default': {" >> "$CONFIG"
echo "       'ENGINE': 'django.db.backends.mysql'," >> "$CONFIG"
echo "       'OPTIONS': {" >> "$CONFIG"
echo "           'read_default_file': 'server/conf/my.cnf'," >> "$CONFIG"
echo "       }," >> "$CONFIG"
echo "   }" >> "$CONFIG"
echo "}" >> "$CONFIG"

# Create the My.CNF file.
echo "[client]" >> "$MYCONF"
echo "database = %mysql.db%" >> "$MYCONF"
echo "user = %mysql.user%" >> "$MYCONF"
echo "password = %mysql.pass%" >> "$MYCONF"
echo "default-character-set = utf8" >> "$MYCONF"

If you look at the parameters side of the page after saving this script, you’ll notice that some new parameters have been populated for you. This is because we’ve included new teamcity configuration parameters that are populated when the build itself is ran. When creating projects that inherit this template, we’ll be able to fill in or override those parameters for project-specific configuration.

Go ahead and create another build step called “Make Database Migration” If you’re using Sqlite3 for your game (default database), it’s prudent to change working directory on this step to your game dir.

#!/bin/bash
# Update the DB migration

LOGDIR="server/logs"

. %evenv.dir%/bin/activate

# Check that the logs directory exists.
if [ ! -d "$LOGDIR" ]; then
  # Control will enter here if $LOGDIR doesn't exist.
  mkdir "$LOGDIR"
fi

evennia makemigrations

Create yet another build step, this time named: “Execute Database Migration”: If you’re using Sqlite3 for your game (default database), it’s prudent to change working directory on this step to your game dir.

#!/bin/bash
# Apply the database migration.
    
LOGDIR="server/logs"
    
. %evenv.dir%/bin/activate
    
# Check that the logs directory exists.
if [ ! -d "$LOGDIR" ]; then
  # Control will enter here if $LOGDIR doesn't exist.
  mkdir "$LOGDIR"
fi
    
evennia migrate

Our next build step is where we actually publish our build. Up until now, all work on game has been done in a ‘work’ directory on TeamCity’s build agent. From that directory we will now copy our files to where our game actually exists on the local server.

Create a new build step called “Publish Build”. If you’re using SQlite3 on your game, be sure to order this step ABOVE the Database Migration steps. The build order will matter!

#!/bin/bash
# Publishes the build to the proper build directory.
    
DIRECTORY="<game_dir>"
    
if [ ! -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY doesn't exist.
  mkdir "$DIRECTORY"
fi
    
# Copy all the files.
cp -ruv %teamcity.build.checkoutDir%/* "$DIRECTORY"
chmod -R 775 "$DIRECTORY"
 

Finally the last script will reload our game for us.

Create a new script called “Reload Game”: The working directory on this build step will be: %game.dir%

#!/bin/bash
# Apply the database migration.

LOGDIR="server/logs"
PIDDIR="server/server.pid"

. %evenv.dir%/bin/activate

# Check that the logs directory exists.
if [ ! -d "$LOGDIR" ]; then
  # Control will enter here if $LOGDIR doesn't exist.
  mkdir "$LOGDIR"
fi

# Check that the server is running.
if [ -d "$PIDDIR" ]; then
  # Control will enter here if the game is running.
  evennia reload
fi

Now the template is ready for use! It would be useful this time to revisit the parameters page and set the evenv parameter to the directory where your virtualenv exists: IE “/srv/mush/evenv”.

Creating the Project

Now it’s time for the last few steps to set up a CI environment.

  • Return to the Evennia Project overview/administration page.

  • Create a new Sub-Project called “Production”. This will be the category that holds our actual game.

  • Create a new Build Configuration in Production with the name of your MUSH. Base this configuration off of the continuous-integration template we made earlier.

  • In the build configuration, enter VCS roots and create a new VCS root that points to the branch/version control that you are using.

  • Go to the parameters page and fill in the undefined parameters for your specific configuration.

  • If you wish for the CI to run every time a commit is made, go to the VCS triggers and add one for “On Every Commit”.

And you’re done! At this point, you can return to the project overview page and queue a new build for your game. If everything was set up correctly, the build will complete successfully. Additional build steps could be added or removed at this point, adding some features like Unit Testing or more!