Add folder support to Azure blob storage commands

This change adds a --folder parameter to both 'vpk upload az' and 'vpk download az' commands, allowing users to organize releases in subdirectories within their Azure blob containers.

Key changes:
- Added Folder property to AzureUploadOptions and AzureDownloadOptions
- Modified AzureRepository to prepend folder paths to all blob operations
- Updated upload, download, and delete operations to work with folder paths
- Retention policy (--keepMaxReleases) correctly handles files in folders
- Release index and legacy release files are stored in the specified folder

This enables multiple applications or environments to share a single Azure container by using folders as isolated namespaces. For example:
- vpk upload az --folder "releases/v1" ...
- vpk download az --folder "releases/v1" ...

The implementation is backward compatible - existing deployments without folders continue to work as before.
This commit is contained in:
azegallo
2025-07-25 23:24:16 -04:00
committed by Caelan
parent 09f9df1d11
commit 095567789a
5 changed files with 177 additions and 11 deletions

View File

@@ -6,6 +6,11 @@ namespace Velopack.CommandLine.Tests.Commands;
public abstract class AzureCommandTests<T> : BaseCommandTests<T>
where T : AzureBaseCommand, new()
{
protected override string GetRequiredDefaultOptions()
{
return "--account \"test-account\" --key \"test-key\" --container \"test-container\" ";
}
[Fact]
public void Command_WithRequiredEndpointOptions_ParsesValue()
{
@@ -23,20 +28,37 @@ public abstract class AzureCommandTests<T> : BaseCommandTests<T>
}
public class AzureDownloadCommandTests : AzureCommandTests<AzureDownloadCommand>
{ }
{
[Fact]
public void Folder_WithPath_ParsesValue()
{
var command = new AzureDownloadCommand();
string cli = GetRequiredDefaultOptions() + " --folder \"releases/v1\"";
ParseResult parseResult = command.ParseAndApply(cli);
Assert.Equal("releases/v1", command.Folder);
}
}
public class AzureUploadCommandTests : AzureCommandTests<AzureUploadCommand>
{
public override bool ShouldBeNonEmptyReleaseDir => true;
protected override string GetRequiredDefaultOptions()
{
return base.GetRequiredDefaultOptions() + "--releaseDir \"./releases\" ";
}
//[Fact]
//public void KeepMaxReleases_WithNumber_ParsesValue()
//{
// var command = new S3UploadCommand();
[Fact]
public void Folder_WithPath_ParsesValue()
{
var command = new AzureUploadCommand();
// string cli = GetRequiredDefaultOptions() + "--keepMaxReleases 42";
// ParseResult parseResult = command.ParseAndApply(cli);
string cli = GetRequiredDefaultOptions() + " --folder \"releases/v1\"";
ParseResult parseResult = command.ParseAndApply(cli);
Assert.Equal("releases/v1", command.Folder);
}
// Assert.Equal(42, command.KeepMaxReleases);
//}
}