Today I want to talk about the time you spend in your debug cycle.
Simply put, developers spend a lot of time repeating the same cycle.
As the linked Brian Armstrong blog entry puts it, a debug cycle is doing this:
1 – Try something
2 – See if it works
3 – Repeat
The Infinity Platform is really an amazing thing to work with, and I have tremendous respect for the many engineers who have made it the performant, highly extensible system it is today.
Having said that, one of the more frustrating aspects of working in BBCRM can be the duration of the debug cycle.
Imagine this scenario:
1 – You found a bug in the code for a form extension’s UIModel.
2 – You fix the bug in your source code.
3 – You deploy the fix to your local or test installation
4 – You observe the fix in CRM
If you are like me, steps 3 and 4 of that process can be painfully slow – especially if #4 involves resetting IIS or generally shaking the magic 8 ball that is IIS caching.
When you have to repeat this many times a day, it can be a real productivity drain.
Because of this problem, I’m always looking for ways to shorten my debug cycle.
One powerful tool in that never-ending battle is the post build script.
What is a post-build script, you ask? I’m so glad you did.
A post build script is a set of commands that get executed after a project successfully builds.
Imagine that visual studio is asking you: “Ok, your project has built. Now if you’d like me to, I can open up a command prompt window and do anything you want.”
That’s the point of view that the post build has – the command prompt.
If you haven’t already, you should check out the post build option in Visual Studio.
You can get there by following these steps:
1 – Open your solution
2 – Right click on a project and choose “Properties”
3 – Go to the “Compile” tab of the project
4 – Click on “Build Events”
5 – You should see a dialog like this one:
In fact, if you create a new UIModel project, you’ll get a default post build event that looks like this:
rem xcopy UIModel1.* ..\Blackbaud.AppFx.Server\Deploy\bin\ /y
But I always replace whatever default postbuild it gives me with a single line:
What does this do?
Well without going into way too much detail, this is like saying “Ok command prompt. Run the postbuild.bat file that lives in at the root level of my project.”
For this to work, you need to (surprise!) have a postbuild script at the root level of your project.
You can do that by right-clicking on your project, adding a new item, choosing “Text File”, and naming it “postbuild.bat”.
Here is an example of a rather simple post build script in action:
The key to designing a good post build script is to ask yourself “What things do I do manually every time I build my project?”.
Typical answers include “Copy and paste a DLL to vroot\bin\custom”, or “Copy HTML files to my vroot\browser folder”
You might also like to clear out the IIS temp files, or even reset IIS, depending on how heavily your customization is cached.
Here are some examples of post build scripts that can do all of these things:
::A script to copy a DLL to a local deployment location
::copy the dll to vroot\bin for bizproc functionality to be exposed
copy “C:\dev\src\Emerging Markets\Clients\29442_UMichigan\Dev\Customizations\Blackbaud.CustomFx.BBISParts.Catalog\bin\Debug\Blackbaud.CustomFx.BBISParts.Catalog.dll” “C:\infinity\uofm\bbappfx\vroot\bin” /y
::A script to copy HTML to a deployment location
copy “C:\dev\src\Emerging Markets\Clients\29442_UMichigan\Dev\Customizations\Blackbaud.CustomFx.BBISParts.UIModel\htmlforms\*.html” “C:\infinity\uofm\bbappfx\vroot\browser\htmlforms\custom\bbis” /y
A script to purge IIS temp files:
::A script to clear out all IIS temporary files
::Stop IIS first, so the files won’t be in use
::Go to the root temp folder
cd “C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files”
::Remove all of the subfolders within it
FOR /D %%g IN (*) DO rmdir /q /s %%g
::Repeat for the .NET 4 files
cd “C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files”
FOR /D %%g IN (*) DO rmdir /q /s %%g
::Pick up where we left off
LoadSpec is a command line utility. You could load all the specs in your “Add forms” folder:
::go to the folder whose specs I want to load
cd “C:\dev\src\Emerging Markets\Clients\29442_UMichigan\dev\Customizations\Blackbaud.CustomFx.BBISParts.Catalog\Add Forms”
::call the LoadSpec Utility on every file in that folder
FOR %%g IN (*.xml) DO “C:\infinity\uofm\bbappfx\sdk\Tools\LoadSpec.exe” /s=(local) /db=UOFM_DEV /spec=”%%g” /nodepends
Obviously your local paths will be different. But you get the idea.
You can also do more sophisticated things. Let’s say, for example, that your project relies on BBMetalWeb to generate code based on the specs you’ve created.
You could re-generate all of that in a post build event with something like this:
::Regenerate bbmetalweb code into a temp folder
set crm_role_name=BBIS Feature Owner
set proj_codegen_loc=”C:\dev\src\Emerging Markets\Clients\29442_UMichigan\Dev\Customizations\Blackbaud.CustomFx.BBISParts.Web\bbmetalweb output”
::remove previous output from bbmetalweb, get ready for new stuff
::rmdir /s /q %dump_folder%
ping 0 > nul
if not exist %dump_folder% mkdir %dump_folder%
::create codegen files
::generate more commands with this query:
::select ‘”%metal_exe%” /wsuri=”http://localhost/uofm_bbec/appfxwebservice.asmx” /db=”bbinfinity” /targetpath=”%dump_folder%” /v /a /rt=”‘+name+’” /inputrolename=”%crm_role_name%” /nodbcheck /silent > nul’ from RECORDTYPE where name like ‘%BBIS%’
“%metal_exe%” /wsuri=”http://localhost/uofm_bbec/appfxwebservice.asmx” /db=”bbinfinity” /targetpath=”%dump_folder%” /v /rt=”MLE Guest Attribute” /inputrolename=”%crm_role_name%” /nodbcheck /silent > nul
If this looks scary, then look harder.
Command line syntax looks like something only uber-geeks would touch. But I have news for you. You are a CRM developer. Welcome to the uber-geek crowd.
Besides, once you get past the unfamiliar syntax, command line statements are almost always very simple.
Effective post-build scripts can reduce the time you spend in your debug cycle in a few ways.
Firstly, the mindless pushing of files from one place to another will happen instantly. Your local deployment will stay up to date without any special effort on your part.
Secondly, you’ll avoid the inevitable errors that occur when you manually copy a file to the wrong place, or forget to deploy one piece of a customization (ohhh vroot\bin\custom…).
Thirdly, you’ll have an artifact that shows other people exactly how you deploy your files, so that “setting up a new machine” becomes just that much easier.
On a related note, another useful tool in reducing your debug cycle is the visual studio macro.
You can find some good macros in this post by Chris Whisenhunt.
Similar to the post-build event, macros can be run any time, not just after building a project.
And they have the full power of the .NET framework behind them. Heady stuff.
In my next post, I’ll cover some more advanced ways to use postbuild scripts.
Some of the topics I have in mind are:
Generalization through the use of variables
Only execute when running on **my** machine
Calling custom executables to do fancy things
Manipulating your own project from the command line
Pitfalls of using post-build scripts