private async Task UploadPackageToStorage()

in src/Cli/func/Actions/AzureActions/PublishFunctionAppAction.cs [1183:1245]


        private async Task<string> UploadPackageToStorage(Stream package, string blobName, IDictionary<string, string> appSettings)
        {
            return await RetryHelper.Retry(
                async () =>
                {
                    // Setting position to zero, in case we retry, we want to reset the stream
                    package.Position = 0;
                    var packageMD5 = SecurityHelpers.CalculateMd5(package);

                    const string containerName = "function-releases";

                    CloudBlobContainer blobContainer = null;

                    try
                    {
                        var storageConnection = appSettings["AzureWebJobsStorage"];
                        var storageAccount = CloudStorageAccount.Parse(storageConnection);
                        var blobClient = storageAccount.CreateCloudBlobClient();
                        blobContainer = blobClient.GetContainerReference(containerName);
                        await blobContainer.CreateIfNotExistsAsync();
                    }
                    catch (Exception ex)
                    {
                        if (StaticSettings.IsDebug)
                        {
                            ColoredConsole.Error.WriteLine(ErrorColor(ex.ToString()));
                        }

                        throw new CliException($"Error creating a Blob container reference. Please make sure your connection string in \"AzureWebJobsStorage\" is valid");
                    }

                    var blob = blobContainer.GetBlockBlobReference(blobName);
                    using (var progress = new StorageProgressBar($"Uploading {Utilities.BytesToHumanReadable(package.Length)}", package.Length))
                    {
                        await blob.UploadFromStreamAsync(
                            package,
                            AccessCondition.GenerateEmptyCondition(),
                            new BlobRequestOptions(),
                            new OperationContext(),
                            progress,
                            CancellationToken.None);
                    }

                    var cloudMd5 = blob.Properties.ContentMD5;

                    if (!cloudMd5.Equals(packageMD5))
                    {
                        throw new CliException("Upload failed: Integrity error: MD5 hash mismatch between the local copy and the uploaded copy.");
                    }

                    var sasConstraints = new SharedAccessBlobPolicy();
                    sasConstraints.SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5);
                    sasConstraints.SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddYears(10);
                    sasConstraints.Permissions = SharedAccessBlobPermissions.Read;

                    var blobToken = blob.GetSharedAccessSignature(sasConstraints);

                    return blob.Uri + blobToken;
                },
                3,
                TimeSpan.FromSeconds(1),
                displayError: true);
        }