Question

I'm using Teamcity to automate (single click) deploys into our QA environment. At the moment content items are being deployed, but the QA guys then have to go and manually trigger a re-publish of the site.

Is there anyway using either TDS, Sitecore Rocks or A.N.Other tool to automate the re-publish at the end of the deploy process.

I know I can configure Sitecore to automatically publish every x minutes, but I would rather leave that deactivated as QA will also be performing load tests and I don't want the scheduler getting in the way.

Was it helpful?

Solution

We have done this by setting up an ASPX on our daily build and QA websites that triggers a publish. The build then has a Powershell call to trigger this. We've done this with CruiseControl, TeamCity, and Team Build.

TeamCity Configuration

The configuration for TeamCity uses an additional build step after you've deployed files and TDS:

  1. Runner Type: Powershell
  2. Step name: Trigger Publish to Web DB
  3. Powershell run mode: x64
  4. Working Directory: [no value]
  5. Script: Source code
  6. Script Source:

    $r = [System.Net.WebRequest]::Create('http://myqasite/SomePath/Publish.aspx'); $resp = $r.GetResponse();

  7. Script execution mode: Put script into Powershell stdin with "-Command -" arguments

Publish.aspx

The code for our Publish page is something like this:

    string full = Request.QueryString["full"];

    // Set up the publish mode
    PublishMode publishMode = PublishMode.Smart;
    if (!string.IsNullOrWhiteSpace(full) && (full == "1" || full.Equals("true", StringComparison.InvariantCultureIgnoreCase)) ) {
        publishMode = PublishMode.Full;
    }

    using (new Sitecore.SecurityModel.SecurityDisabler()) {
        //We need the target database
        var webDb = Sitecore.Configuration.Factory.GetDatabase("web");

        //source db
        var masterDb = Sitecore.Configuration.Factory.GetDatabase("master");

        try {
            foreach (Language language in masterDb.Languages) {
                //loops on the languages and do a full republish on the whole sitecore content tree
                var options = new PublishOptions(masterDb, webDb, publishMode, language, DateTime.Now)
                              {RootItem = masterDb.Items["/sitecore"], RepublishAll = true, Deep = true};
                        var myPublisher = new Publisher(options);
                        myPublisher.Publish();
            }
        }
        catch (Exception ex) {
            Sitecore.Diagnostics.Log.Error("Could not publish the master database to the web", ex);
        }

    }

OTHER TIPS

While waiting for an answer I shared the question on twitter, this resulted being given a guiding hand by Stephen Pope (his response) He suggested using the PowerShell enhancements offered by Sitecore Rocks, it took a while (documentation is thin on the ground) but I have achieved the result I was after :)

As a record of what I found, the following is provided as a potential answer to my own question, though big thanks to Jay S who's solution I would have used if not for this..

Anyway.. Using an additional build step in the Teamcity build, I have the following:

  • Runner type: Powershell
  • Step name: Publish site
  • Powershell run mode: x64
  • script: Source code
  • script execution mode: Put script into powershell stdin with "-Command -" arguments
  • Additional command line parameters: -ExecutionPolicy Unrestricted
  • Script source:

    import-module '.\build-modules\sitecore\sitecore.psd1';
    new-psdrive -name "rocks" -psp SitecoreRocks -root "" -host "%QA.Url%" -usr "%QA.sitecore.user%" -pwd "%QA.sitecore.password%" -databasename "master" -scope "Script";
    set-location rocks:
    Publish-SCDatabase;

The magic happens within the Publish-SCDatabase commandlet which when you run Get-Help shows a bunch of parameters, it turns out that only two of the parameters are usable -Name and -Mode

Finding documentation beyond the vs-plugins link above was impossible, so a bit of .net reflection and a good dose of patiense showes that the parameters have the following options:

  • -Name The name of the database to run the publish against (default is the psdrive database
  • -Mode Sets the publish mode of the comandlet with the following options available:
    • 0: Republish
    • 1: Incremental
    • 2: Smart
    • 3: Rebuild

Of course better documentation, and possibly additional info via the Get-Help commandlet would be nice.. if the rocks project was open source, I may well have forked the project to generate the additional help.

Now that there are two very good solutions to this question, I will let peoples votes decide on which is the best answer, in a few days I will check the votes and mark the most voted as the accepted answer.

Whist these are both good solutions (the custom aspx and the Powershell via Rocks one), they both have some shortcomings.

  1. Custom aspx page. Unless you "go to town" on your C# solution for publishing, in offering a very sophisticated way to change publishing targets, Root nodes and other options (e.g. smart, incremental), and allowing for invocation of these options in as flexible manner as possible, you would risk having to change your code to change deployment strategies periodically. The comment by Richard R below the Rocks answer concedes that. Contrast that with some kind of scripted solution. The fact it wouldn't be compiled code lends itself to being chopped and changed, and even proliferating into lots of different scripts for different purposes.

  2. Powershell via Rocks. Again there are shortcomings in terms of customization. You are limited to what commandlets (and ultimately CRUD operations) are supported by that particular implementation. Not to mention it being closed source and having limited documentation.

I probably need to elaborate a little about the use cases I have in mind that may need to be catered for. What if it is particularly important for us to publish only parts of the content tree on deploys (aspects like /templates, /system, /layouts)? In our deployments we have huge /content and /media library sections so being more granular about what gets published for certain deployments is essential to expedite deploys. Now, whilst it's perfectly feasible to create your own /Publish.aspx page which will specify the Root items and do these (deep) publishes for you, it would be much more elegant to do it via some kind of script. Not only that but consider the myriad other operations you may wish to automate on scripted deployments and environmental set-up such as adding content, applying workflows e.t.c.

Contrast both of these with Adam Najmanowicz's Powershell Console/Extensions. By allowing you to develop powershell scripts within sitecore, you can effectively create whatever you wish to by way of a scripted solution and even invoke it from an external tool in order to make that a step in a CI server or orchestrator: http://blog.najmanowicz.com/2011/12/19/continuous-deployment-in-sitecore-with-powershell/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top