Skip to content

Commit f3b7923

Browse files
Copilotaishwaryabhliliankasemhallvictoria
authored
Fix func pack command for C# in-process projects and add basic functionality tests for other languages (#4529)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: aishwaryabh <37918412+aishwaryabh@users.noreply.github.com> Co-authored-by: liliankasem <2198905+liliankasem@users.noreply.github.com> Co-authored-by: Aishwarya Bhandari <aibhandari@microsoft.com> Co-authored-by: hallvictoria <59299039+hallvictoria@users.noreply.github.com>
1 parent e963a76 commit f3b7923

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1239
-17
lines changed

eng/ci/templates/steps/run-e2e-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ steps:
2929
3030
Write-Host "##vso[task.setvariable variable=DURABLE_FUNCTION_PATH]$(Build.SourcesDirectory)/test/Azure.Functions.Cli.Tests/Resources/DurableTestFolder"
3131
Write-Host "##vso[task.setvariable variable=INPROC_RUN_SETTINGS]$(Build.SourcesDirectory)/test/Cli/Func.E2ETests/.runsettings/start_tests/ci_pipeline/dotnet_inproc.runsettings"
32+
Write-Host "##vso[task.setvariable variable=TEST_PROJECT_PATH]$(Build.SourcesDirectory)/test/TestFunctionApps"
3233
displayName: 'Set environment variables for E2E tests'
3334

3435

eng/scripts/artifact-assembler/test-vs-artifacts.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ $runtimeSettings = ".\test\Cli\Func.E2ETests\.runsettings\start_tests\artifact_c
1313
[System.Environment]::SetEnvironmentVariable("FUNCTIONS_WORKER_RUNTIME", "dotnet", "Process")
1414

1515
# Path for Visual Studio test projects (convert to absolute paths)
16-
$net8VsProjectPath = ".\test\TestFunctionApps\VisualStudioTestProjects\TestNet8InProcProject"
17-
$net6VsProjectPath = ".\test\TestFunctionApps\VisualStudioTestProjects\TestNet6InProcProject"
16+
$net8VsProjectPath = ".\test\TestFunctionApps\TestNet8InProcProject"
17+
$net6VsProjectPath = ".\test\TestFunctionApps\TestNet6InProcProject"
1818

1919
# Resolve paths to absolute paths
2020
$absoluteNet8VsProjectPath = (Resolve-Path -Path $net8VsProjectPath -ErrorAction SilentlyContinue).Path

release_notes.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
#### Changes
99

1010
- Fix dotnet templates installation (#4538)
11-
- Disable diagnostic events in local development by replacing the `IDiagnosticEventRepository` with a `DiagnosticEventNullRepository` (#4542)
11+
- Disable diagnostic events in local development by replacing the `IDiagnosticEventRepository` with a `DiagnosticEventNullRepository` (#4542)
12+
- Add `func pack` support for in-proc functions (#4529)

src/Cli/func/Actions/AzureActions/PublishFunctionAppAction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ private async Task PublishFunctionApp(Site functionApp, GitIgnoreParser ignorePa
573573
TelemetryHelpers.AddCommandEventToDictionary(TelemetryCommandEvents, "UseGoZip", useGoZip.ToString());
574574

575575
ColoredConsole.WriteLine(GetLogMessage("Starting the function app deployment..."));
576-
Func<Task<Stream>> zipStreamFactory = () => ZipHelper.GetAppZipFile(functionAppRoot, BuildNativeDeps, PublishBuildOption, NoBuild, ignoreParser, AdditionalPackages, ignoreDotNetCheck: true);
576+
Func<Task<Stream>> zipStreamFactory = () => ZipHelper.GetAppZipFile(functionAppRoot, BuildNativeDeps, PublishBuildOption, NoBuild, ignoreParser, AdditionalPackages);
577577

578578
bool shouldSyncTriggers = true;
579579
bool shouldDeferPublishZipDeploy = false;

src/Cli/func/Actions/LocalActions/PackAction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public override async Task RunAsync()
109109
bool useGoZip = EnvironmentHelper.GetEnvironmentVariableAsBool(Constants.UseGoZip);
110110
TelemetryHelpers.AddCommandEventToDictionary(TelemetryCommandEvents, "UseGoZip", useGoZip.ToString());
111111

112-
var stream = await ZipHelper.GetAppZipFile(functionAppRoot, BuildNativeDeps, noBuild: false, buildOption: BuildOption.Default, additionalPackages: AdditionalPackages);
112+
var stream = await ZipHelper.GetAppZipFile(functionAppRoot, BuildNativeDeps, BuildOption.Default, noBuild: false, additionalPackages: AdditionalPackages);
113113

114114
if (Squashfs)
115115
{

src/Cli/func/Helpers/ZipHelper.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Azure.Functions.Cli.Helpers
1212
{
1313
public static class ZipHelper
1414
{
15-
public static async Task<Stream> GetAppZipFile(string functionAppRoot, bool buildNativeDeps, BuildOption buildOption, bool noBuild, GitIgnoreParser ignoreParser = null, string additionalPackages = null, bool ignoreDotNetCheck = false)
15+
public static async Task<Stream> GetAppZipFile(string functionAppRoot, bool buildNativeDeps, BuildOption buildOption, bool noBuild, GitIgnoreParser ignoreParser = null, string additionalPackages = null)
1616
{
1717
var gitIgnorePath = Path.Combine(functionAppRoot, Constants.FuncIgnoreFile);
1818
if (ignoreParser == null && FileSystemHelpers.FileExists(gitIgnorePath))
@@ -37,10 +37,6 @@ public static async Task<Stream> GetAppZipFile(string functionAppRoot, bool buil
3737
{
3838
return await PythonHelpers.GetPythonDeploymentPackage(FileSystemHelpers.GetLocalFiles(functionAppRoot, ignoreParser), functionAppRoot, buildNativeDeps, buildOption, additionalPackages);
3939
}
40-
else if (GlobalCoreToolsSettings.CurrentWorkerRuntime == WorkerRuntime.Dotnet && !ignoreDotNetCheck && !noBuild && buildOption != BuildOption.Remote)
41-
{
42-
throw new CliException("Pack command doesn't work for dotnet functions");
43-
}
4440
else if (GlobalCoreToolsSettings.CurrentWorkerRuntime == WorkerRuntime.Dotnet && buildOption == BuildOption.Remote)
4541
{
4642
// Remote build for dotnet does not require bin and obj folders. They will be generated during the oryx build

test/Cli/Func.E2ETests/BaseE2ETests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public abstract class BaseE2ETests(ITestOutputHelper log) : IAsyncLifetime
1717

1818
protected string WorkingDirectory { get; set; } = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
1919

20+
protected string TestProjectDirectory { get; set; } = Environment.GetEnvironmentVariable(Constants.TestProjectPath) ?? Path.GetFullPath(Path.Combine("..", "..", "..", "..", "test", "TestFunctionApps"));
21+
2022
public Task InitializeAsync()
2123
{
2224
if (string.IsNullOrEmpty(FuncPath))
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
using Azure.Functions.Cli.TestFramework.Assertions;
5+
using Azure.Functions.Cli.TestFramework.Commands;
6+
using FluentAssertions;
7+
using Xunit;
8+
using Xunit.Abstractions;
9+
10+
namespace Azure.Functions.Cli.E2ETests.Commands.FuncPack
11+
{
12+
internal static class BasePackTests
13+
{
14+
internal static void TestBasicPackFunctionality(string workingDir, string testName, string funcPath, ITestOutputHelper log, string[] filesToValidate)
15+
{
16+
// Run pack command
17+
var funcPackCommand = new FuncPackCommand(funcPath, testName, log);
18+
var packResult = funcPackCommand
19+
.WithWorkingDirectory(workingDir)
20+
.Execute([]);
21+
22+
// Verify pack succeeded
23+
packResult.Should().ExitWith(0);
24+
packResult.Should().HaveStdOutContaining("Creating a new package");
25+
26+
// Find any zip files in the working directory
27+
var zipFiles = Directory.GetFiles(workingDir, "*.zip");
28+
29+
// Verify at least one zip file exists
30+
Assert.True(zipFiles.Length > 0, $"No zip files found in {workingDir}");
31+
32+
// Log all found zip files
33+
foreach (var zipFile in zipFiles)
34+
{
35+
log?.WriteLine($"Found zip file: {Path.GetFileName(zipFile)}");
36+
}
37+
38+
// Verify the first zip file has some content (should be > 0 bytes)
39+
var zipFileInfo = new FileInfo(zipFiles.First());
40+
Assert.True(zipFileInfo.Length > 0, $"Zip file {zipFileInfo.FullName} exists but is empty");
41+
42+
// Validate the contents of the zip file
43+
packResult.Should().ValidateZipContents(zipFiles.First(), filesToValidate, log);
44+
45+
File.Delete(zipFiles.First()); // Clean up the zip file after validation
46+
}
47+
}
48+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
using Azure.Functions.Cli.E2ETests.Traits;
5+
using Xunit;
6+
using Xunit.Abstractions;
7+
8+
namespace Azure.Functions.Cli.E2ETests.Commands.FuncPack
9+
{
10+
[Trait(WorkerRuntimeTraits.WorkerRuntime, WorkerRuntimeTraits.Dotnet)]
11+
public class DotnetInProc6PackTests : BaseE2ETests
12+
{
13+
public DotnetInProc6PackTests(ITestOutputHelper log)
14+
: base(log)
15+
{
16+
}
17+
18+
private string Dotnet6ProjectPath => Path.Combine(TestProjectDirectory, "TestNet6InProcProject");
19+
20+
[Fact]
21+
public void Pack_Dotnet6InProc_WorksAsExpected()
22+
{
23+
var testName = nameof(Pack_Dotnet6InProc_WorksAsExpected);
24+
Log.WriteLine(Dotnet6ProjectPath);
25+
26+
BasePackTests.TestBasicPackFunctionality(
27+
Dotnet6ProjectPath,
28+
testName,
29+
FuncPath,
30+
Log,
31+
new[]
32+
{
33+
"host.json",
34+
"Dotnet6InProc.cs",
35+
"TestNet6InProcProject.csproj"
36+
});
37+
}
38+
}
39+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
using Azure.Functions.Cli.E2ETests.Traits;
5+
using Xunit;
6+
using Xunit.Abstractions;
7+
8+
namespace Azure.Functions.Cli.E2ETests.Commands.FuncPack
9+
{
10+
[Trait(WorkerRuntimeTraits.WorkerRuntime, WorkerRuntimeTraits.Dotnet)]
11+
public class DotnetInProc8PackTests : BaseE2ETests
12+
{
13+
public DotnetInProc8PackTests(ITestOutputHelper log)
14+
: base(log)
15+
{
16+
}
17+
18+
private string Dotnet8ProjectPath => Path.Combine(TestProjectDirectory, "TestNet8InProcProject");
19+
20+
[Fact]
21+
public void Pack_Dotnet8InProc_WorksAsExpected()
22+
{
23+
var testName = nameof(Pack_Dotnet8InProc_WorksAsExpected);
24+
25+
BasePackTests.TestBasicPackFunctionality(
26+
Dotnet8ProjectPath,
27+
testName,
28+
FuncPath,
29+
Log,
30+
new[]
31+
{
32+
"host.json",
33+
"Dotnet8InProc.cs",
34+
"TestNet8InProcProject.csproj"
35+
});
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)