Flex Builder and CVS

I've got my commonly used classes all neatly organized in a single library project, but just to be safe I want backup and the ability to revert to a previous version when I break something. Sometimes you gotta take a step back to build quickly; there'll be plenty of time to break it again after the demo is over... so here's how I got my Library into CVS.

Set up a cvs server. I'm not going to get too deep into this; essentially on a mac all you do is create a folder somewhere (I put mine in my user directory to get it up and running quickly) and then tell CVS where that folder is (export CVSROOT=[path to folder]), then call cvs init from terminal. Start ssh, point port 22 on your router at your mac, and now you have access to your repository from anywhere. I'm sure similarly simple instructions are available for Windows and Linux; I don't remember having too much trouble getting a repository running on Vista a few months ago, although I didn't try to set up ssh on that one.

Let Flex know that the repository exists. Use File, New, Other, and select CVS Repository Location (it's under the CVS tab). Give Flex Builder all the required information: domain name (or ip) of the repository, path to the repository on the remote machine, maybe save password. If you're using ssh make sure to enter your username and password from the remote machine and choose extssh as the connection type. If you make it past this screen your connection has been validated.

Tell Flex to put your project(s) in the repository. If you just set up a new location you should be in the CVS Repository perspective. Click the double arrow in the upper right to get back to Flex Development view. Now, in Flex Navigator, right-click the project you want to add to the repository. Under Team select Share Project. Select the repository location you just set up, then tell Flex Builder to use the project name as module name. Otherwise you'll end up in the same situation I was in: using the existing CVSROOT put a /src folder in the CVSROOT. I realized that all of my other projects were going to have a /src folder, too, and I didn't want them to get all mixed together. Project name for module name solves this problem.

Tell Flex not to version your 47 meg comps. On the next screen you tell Flex Builder to ignore files for versioning. Make sure you aren't versioning huge files; it'll eat space on your server. There's a difference between versioning and just placing, though; if you know your huge psd isn't going to change, go ahead and put it in the CVS. For my part, though, I'm using sftp if I want to back up files and CVS for my scripts and documentation.

Correct file types. Flex Builder, for some reason, doesn't know that the file .flexProperties is a text file. Seems like it should. Anyhow, go through the list of files it's not sure of the type and figure out which are ascii and which are binary. A good rule of thumb for this is select ascii if it opens in a text editor... 'cept BBEdit doesn't seem to care about filetypes; it'll open just about anything.

Commit your project. I usually set the first commit comment to initial commit, although I could see something else like first commit or starting point. Just make sure you're actually commenting when you commit; it'll help you remember which version had a red background and which version had the background change to light maroon.

And that's it. From now on, whenever you edit one of your sources in the synced project you'll see a > symbol in Flex Navigator leading you to the changed file. That means you need to right-click the file, then select Team, Commit... in order to update the changes on the remote file.

There are much more comprehensive notes on the process here, although I deviated some from their instructions to give the repository a structure that will allow multiple projects.

One other note, sort of off topic but related to organizing classes into libraries. Once I had my library set up I could no longer run aasdoc on my project to make documentation for my coworkers. Turns out that the parameter -library-path is synonymous with "this path and ONLY this path". The parameter you want to use to build documentation using asdoc or aasdoc is -external-library-path, which means something more like "and if you can't find a class definition anywhere else, try here." Just what the doctor ordered. And now my coworkers get documentation. Thanks to this page for the correct parameter.

Addendum, 25 July: Opening port 22 seemed like a good idea when I wanted to get this working, but I actually had a freeze on my server a day ago. Thanks a lot, password-spewing bots. The solution was a bit difficult, so I'm documenting it here in case I need to set it up for other machines. First, set up key-based authentication for the server.

  • On the server, edit /etc/sshd_config (sudo pico /etc/sshd_config). Uncomment PasswordAuthentication and set its value to no, uncomment ChallengeResponseAuthentication and set its value to no. While you're in there, why not change PermitRootLogin to no? You'll still be able to sudo once you connect to the server
  • On the client machine, from terminal, browse to your ~/.ssh folder (create it if it doesn't exist with permissions 700).
  • Create a keypair (ssh-keygen -t rsa -f ~/.ssh/id_rsa -C "[yourUserName@yourComputer"]).
  • Put the public key on your cvs server (scp id_rsa.pub [serverUserName]@[serverAddress]:~/.ssh/authorized_keys2); note that this overwrites authorized_keys2, so if you are doing this for multiple users you'll want to copy and paste your key into the file rather than uploading the single key file.
  • Change permissions on the server's authorized_keys2 to 600
  • Restart sshd on the server; easiest way on a mac is to deselect and select remote login in system preferences under Sharing
  • Check that you can now login without being prompted for a password (ssh [serverUserName]@[serverAddress]). If you are asked for a password something went wrong and cvs probably isn't going to work right, either. Go through these instructions again or, like me, dig through page after page of "helpful" advice until you get it working.
  • Now, in terminal on the client machine, point your cvs client at the server (export CVS_RSH="ssh" ; export CVSROOT=":ext:[serverUserName]@[serverAddress]:[pathToRepository]"). Add these to your client machine's .bash_profile as well so you won't have to keep typing it (pico ~/.bash_profile, then add these lines at the end of what's already there).
  • Check that things are going well... from terminal on the client machine, type 'cvs version'. You should get 2 lines, one with your local cvs version, then a second line with the server's cvs version. If you get this response you're almost there...
  • In Flex Builder (yeah, that program that we're going through all this pain for), switch to your CVS perspective. If you already set up a cvs connection by the previous instructions, edit that connection (right-click, properties). Otherwise just set up a new connection.
  • Settings for the connection should be: Connection Type: ext, User: [serverUserName], Host: [serverAddress], Repository Path: [pathToRepository]. Don't enter a password; that's for ssh password authentication and we turned that off.
  • Switch back to Flex Development perspective and, if you had previously set up a repository association with one of your projects you should be back in business. Just add a comment to a versioned file and try to commit it to verify.