Example #1
0
        /// <summary>
        /// Deploy local directory to KuduWebsite as read only Zip file system
        /// </summary>
        /// <param name="client">The Kudu client.</param>
        /// <param name="localPath">The local directory path.</param>
        /// <param name="skipPostDeploymentValidation">Flag for if post deployment validation should be done.</param>
        /// <param name="relativeValidateUrl">The relative url used for validation (default: "KuduClientZipRunFromDirectoryVersion.txt").</param>
        /// <param name="expectedValidateValue">The expected value returned from validation url (default zip file name).</param>
        /// <returns>The path of deployed Zip.</returns>
        /// <example>
        /// <code>
        /// git teUrl             = $"/api/GetVersion?version={expectedValidateValue}";
        ///
        /// FilePath deployFilePath = kuduClient.ZipRunFromDirectory(
        ///                                         sourceDirectoryPath,
        ///                                         skipPostDeploymentValidation,
        ///                                         relativeValidateUrl,
        ///                                         expectedValidateValue);
        ///
        /// Information("Deployed to {0}", deployFilePath);
        /// </code>
        /// </example>
        /// <remarks>
        /// You app service needs to have the setting WEBSITE_RUN_FROM_ZIP set to 1 for Kudu to pickup your publish.
        /// </remarks>
        public static FilePath ZipRunFromDirectory(
            this IKuduClient client,
            DirectoryPath localPath,
            bool skipPostDeploymentValidation,
            string relativeValidateUrl   = null,
            string expectedValidateValue = null)
        {
            DirectoryPath sitePackagesPath = "d:/home/data/SitePackages";
            FilePath
                siteVersionPath = sitePackagesPath.CombineWithFilePath("packagename.txt"),
                deployFilePath  = sitePackagesPath
                                  .CombineWithFilePath(FormattableString.Invariant($"{DateTime.UtcNow:yyyyMMdd_HHmmss}_{Guid.NewGuid():N}.zip"));
            var relativeDeployFilePath = deployFilePath.GetFilename().FullPath;

            const string kuduClientVersionFile = "KuduClientZipRunFromDirectoryVersion.txt";

            relativeValidateUrl   = relativeValidateUrl ?? kuduClientVersionFile;
            expectedValidateValue = expectedValidateValue ?? relativeDeployFilePath;

            client.ZipDirectoryToMemoryStream(
                localPath,
                sourceStream => client.VFSUploadStream(
                    sourceStream,
                    deployFilePath),
                archive =>
            {
                var entry = archive.CreateEntry(kuduClientVersionFile, CompressionLevel.Optimal);
                using (var entryStream = entry.Open())
                {
                    using (var sw = new StreamWriter(entryStream, Encoding.ASCII))
                    {
                        sw.Write(relativeDeployFilePath);
                    }
                }
            });

            client.VFSUploadString(
                relativeDeployFilePath,
                siteVersionPath);

            if (skipPostDeploymentValidation)
            {
                return(deployFilePath);
            }

            var commandResult = client.ExecuteCommand(
                "powershell",
                "site",
                $"-Command \"$ProgressPreference = 'SilentlyContinue';Invoke-RestMethod https://%WEBSITE_HOSTNAME%/{relativeValidateUrl};exit $LastExitCode\"");

            client.Log.Debug(
                "Output:\r\n{0}\r\nError:\r\n{1}\r\nExitCode: {2}",
                commandResult.Output,
                commandResult.Error,
                commandResult.ExitCode);

            var commandOutput = commandResult.Output?.TrimEnd();

            if (expectedValidateValue != commandOutput)
            {
                throw new Exception($"Deployment failed expected \"{expectedValidateValue}\" got \"{commandOutput}\"");
            }

            return(deployFilePath);
        }