Continuous deployment & delivery

2019-04-16 07:22发布

问题:

We have a solution that contains +10 projects, from whom 2 are websites. Now i need to setup a build definition(s) linked to our TFS server, that builds the solution and deploys the 2 sites to the right Azure website. I've tried a few different approaches, but the delivery seems to fail every time. Building the project on the TFS server is no problem, but when azure needs to deliver the right asp project, to the correct Azure website, it fails... Can anybody point me in the right direction on how to create such a build definition, and where to specify the delivery options?

EDIT:

To illustrate with an image from our build.

So we have 2 websites in this folder:

I'd like to publish those two websites in this folder to the correct azure location. Does anybody know a good approach to achieve a succesfull constant delivery with 2 websites?

回答1:

We use the Azure Service Managetment API for this during a TFS build. We adapted this sample code - Windows Azure ServiceManagement Sample - as a command line tool to run in a build task.

HostedServiceList hostedServices = new HostedServiceList();
Dictionary<string, IServiceManagement> servicesOperations = new Dictionary<string, IServiceManagement>();

ParseArguments(args);
ProcessCheckServerCertificate();

// upload the package created during the build to Azure BLOB
var packageUrl = UploadFileToBlob(package);
var services = new ListHostedServicesCommand();
services.Run();
hostedServices = services.HostedServices;
.
.
.
foreach (var hostedService in hostedServices)
{
    Console.WriteLine("updating: " + hostedService.ServiceName);
    // get the deployment unique name - required for upgrade
    AzureCommand.HostedServiceName = hostedService.ServiceName;
    AzureCommand.DeploymentName = null;
    var getDeployment = new GetDeploymentCommand();
    getDeployment.Run();
    AzureCommand.DeploymentName = getDeployment.Deployment.Name;

    // upgrade the existing deployment    
    var upgradeDeployment = new UpgradeDeploymentCommand();
    upgradeDeployment.Run();
    servicesOperations.Add(upgradeDeployment.TrackingId, upgradeDeployment.ServiceManagement);
}
.
.
.
// check status of all operations submitted
foreach (var servicesOperation in servicesOperations)
{
    // check status of operations
    AzureCommand.WaitForAsyncOperation(servicesOperation.Value, servicesOperation.Key);
}

Here's the UploadFileToBlob code...

private string UploadFileToBlob(string file)
{
    // Retrieve storage account from connection string
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));

    // Create the blob client
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    // Retrieve reference to a previously created container
    CloudBlobContainer container = blobClient.GetContainerReference("mydeployments");

    // Retrieve reference to a blob
    var date = DateTime.UtcNow.ToString("yyyyMMdd-hhmmss-");
    var fileinfo = new FileInfo(file);
    if (fileinfo.Exists)
    {
        var fileToUpload = new FileInfo(file).Name;
        var filename = date + fileToUpload;
        try
        {
            CloudBlob blob = container.GetBlobReference(filename);

            // Create or overwrite the blob with contents from a local file
            using (var fileStream = System.IO.File.OpenRead(file))
            {
                blob.UploadFromStream(fileStream);
            }

            return blob.Uri.AbsoluteUri;
        }
        catch (Exception ex)
        {
            LogError("Error uploading file to blog: ", ex.Message);
            return "";
        }
    }

    LogError("Error - specified file does not exist: ", file);
    return "";
}

And add the build task in the .proj file for the cloud service, pointed to "YourCommandLineTool.exe":

  <Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" />
  <Target Name="AzureDeploy" AfterTargets="CorePublish" DependsOnTargets="CorePublish" Condition="$(DeployToAzure) == 'true'">
    <Exec WorkingDirectory="$(MSBuildProjectDirectory)" Command="C:\WindowsAzure\Deploy\YourCommandLineTool.exe /log:$(MSBuildProjectDirectory)\AzureDeploy.log /package:$(MSBuildProjectDirectory)\$(PublishDir)$(AssemblyName).cspkg /config:$(MSBuildProjectDirectory)\$(PublishDir)ServiceConfiguration.$(Configuration).cscfg" />
  </Target>