Skip to content

Misc project updates, doc updates, docker updates & test fixes #4470

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/out/bin/Azure.Functions.Cli/debug_net8.0/func.dll",
"program": "${workspaceFolder}/out/bin/Azure.Functions.Cli/debug/func.dll",
"env": {
"CLI_DEBUG": "1"
},
15 changes: 11 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -8,16 +8,25 @@ To install the required dotnet packages navigate into the repository root and ru

## Compiling the CLI Tools

To build the project run `cd src/Azure.Functions.Cli; dotnet build` (note navigating into the src directory is required due to the test suite currently failing to compile on non-windows environments - see below)
To build the project run `dotnet build` from the root of the repository. This will build the project and all of its dependencies.
The output will be placed in the `out/bin/Azure.Functions.Cli/debug` directory.

`dotnet run --project src/Cli/func <command>` will run the CLI tool from the source directory.

### Running against a function app

To test this project against a local function app you can run from that function app's directory

`dotnet run --project PATH_TO_FUNCTIONS_CLI/src/Azure.Functions.Cli start`
- `cd myTestFunctionApp`
- `dotnet run --project PATH_TO_FUNCTIONS_CLI/src/Cli/func <command>`

where PATH_TO_FUNCTIONS_CLI is the absolute or relative path to the root of this repository.

Or you can add `out/bin/Azure.Functions.Cli/debug/func` to your `PATH` environment variable and run the command from anywhere.

- `export PATH=$PATH:/path/to/Azure.Functions.Cli/out/bin/Azure.Functions.Cli/debug/func`
- `func <command>`

### Running the Test Suite

- Build the solution `dotnet build Azure.Functions.Cli.sln`
@@ -64,5 +73,3 @@ Before we can accept your pull-request you'll need to sign a [Contribution Licen
When your pull-request is created, we classify it. If the change is trivial, i.e. you just fixed a typo, then the PR is labelled with `cla-not-required`. Otherwise it's classified as `cla-required`. In that case, the system will also also tell you how you can sign the CLA. Once you signed a CLA, the current and all future pull-requests will be labelled as `cla-signed`. Signing the CLA might sound scary but it's actually super simple and can be done in less than a minute.

Before submitting a feature or substantial code contribution please discuss it with the team and ensure it follows the product roadmap. Note that all code submissions will be rigorously reviewed and tested by the Azure Functions Core Tools team, and only those that meet the bar for both quality and design/roadmap appropriateness will be merged into the source.

Path: /opt/homebrew/Cellar/azure-functions-core-tools@4/4.0.7030/templates
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![Azure Functions Logo](https://raw.githubusercontent.com/Azure/azure-functions-core-tools/refs/heads/main/publish-scripts/npm/assets/azure-functions-logo-color-raster.png)
![Azure Functions Logo](https://raw.githubusercontent.com/Azure/azure-functions-core-tools/refs/heads/main/eng/res/functions.png)

|Branch|Status|
|---|---|
9 changes: 2 additions & 7 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -9,18 +9,13 @@ COPY *.props .
COPY stylecop.json .
COPY .editorconfig .
COPY NuGet.Config .
COPY tools/ tools/
COPY eng/*.props eng/
COPY src/*.props src/
COPY eng/ eng/
COPY src/Cli/func src/Cli/func
COPY AzureFunctions-CLI.ico .
COPY eng/scripts/download-templates.ps1 .
COPY src/GoZipTool src/GoZipTool

ARG TARGET_RUNTIME=linux-x64
RUN dotnet publish src/Cli/func /p:BuildNumber="9999" /p:CommitHash="N/A" -o /cli -c Release -f net8.0 --self-contained -r ${TARGET_RUNTIME}

RUN pwsh ./download-templates.ps1 -OutputPath "/cli"

FROM ${SDK_IMAGE} AS runtime

WORKDIR /cli
4 changes: 2 additions & 2 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -17,8 +17,8 @@ The default func runtime being built by the `Dockerfile` is linux x64.
- When you want to kill the container, run: `docker-compose down`

> [!IMPORTANT]
> If you are using a Mac with Apple silicon (M1, M2, etc.), you will need to use the `--platform linux/arm64`
> flag when building the image for non-ARM RIDs. You can also set this in the docker-compose file.
> If you are using a Mac with Apple silicon (M1, M2, etc.), you will need to use the `--platform linux/amd64`
> flag when building the image for non-ARM RIDs (e.g. linux-x64). You can also set this in the docker-compose file.

### Testing Different Runtimes

2 changes: 1 addition & 1 deletion docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ services:
dockerfile: docker/Dockerfile
args:
TARGET_RUNTIME: linux-x64
# platform: linux/arm64 # Uncomment if you are on a Mac with Apple silicon for non-ARM RID builds
# platform: linux/amd64 # Uncomment if you are on a Mac with Apple silicon for non-ARM RID builds
container_name: func-cli
image: func-cli
ports:
2 changes: 1 addition & 1 deletion eng/build/Packages.props
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
<!-- abstractions-->
<ItemGroup>
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.2" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.25071.2" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta5.25306.101" />
</ItemGroup>

<!-- func -->
11 changes: 11 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"sdk": {
"version": "9.0.106",
"allowPrerelease": true,
"rollForward": "latestFeature"
},
"msbuild-sdks": {
"Microsoft.Build.NoTargets": "3.7.56",
"Microsoft.Build.Traversal": "4.1.0"
}
}
3 changes: 3 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Azure Functions CLI <version>

- <entry>
4 changes: 3 additions & 1 deletion src/Cli/Abstractions/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Azure.Functions.Cli.Abstractions

This library represents the abstractions core tools uses for defining commands, environment, process reaper, etc.
The files within this library are based off the .NET sdk [here](https://github.com/dotnet/sdk).

Once the dotnet cli utils package is in a published consumable state, we will migrate over to use that.
Once the dotnet cli utils package is in a published consumable state, we will migrate over to use that.
File renamed without changes.
23 changes: 8 additions & 15 deletions src/Cli/func/Azure.Functions.Cli.csproj
Original file line number Diff line number Diff line change
@@ -19,17 +19,6 @@
<PublishReadyToRunShowWarnings>false</PublishReadyToRunShowWarnings>
</PropertyGroup>

<PropertyGroup>
<BuildNumber Condition=" '$(BuildNumber)' == '' ">1</BuildNumber>
<MajorMinorProductVersion>4.0</MajorMinorProductVersion>
<Version>$(MajorMinorProductVersion).$(BuildNumber)</Version>
<AssemblyVersion>$(MajorMinorProductVersion).$(BuildNumber)</AssemblyVersion>
<FileVersion>$(MajorMinorProductVersion).$(BuildNumber)</FileVersion>
<CommitHash Condition="$(CommitHash) == ''">N/A</CommitHash>
<IntegrationBuildNumberInfo Condition="$(IntegrationBuildNumber) != ''">Integration build number: $(IntegrationBuildNumber)</IntegrationBuildNumberInfo>
<InformationalVersion>$(FileVersion) Commit hash: $(CommitHash) $(IntegrationBuildNumberInfo)</InformationalVersion>
</PropertyGroup>

<ItemGroup>
<EmbeddedResource Include="StaticResources\stacks.json">
<LogicalName>$(AssemblyName).stacks.json</LogicalName>
@@ -262,7 +251,7 @@
</ItemGroup>

<ItemGroup>
<Content Include="$(RepoRoot)tools\python\packapp\__main__.py">
<Content Include="$(EngRoot)tools\python\packapp\__main__.py">
<Link>tools\python\packapp\__main__.py</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
@@ -296,9 +285,13 @@
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker.PS7.0" />
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker.PS7.2" />
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker.PS7.4" />
<!-- PythonWorker v4.35 introduced an error when being build for win-arm64. For now, we will not include this package when we build
core tools for win-arm64. This is a temporary measure as we figure out how we want this to go. -->
<PackageReference Include="Microsoft.Azure.Functions.PythonWorker" Condition="'$(RuntimeIdentifier)' != 'win-arm64'" />
<PackageReference Include="Microsoft.Azure.Functions.PythonWorker" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$(SrcRoot)GoZipTool\GoZipTool.csproj">
<Properties>ResolvedRuntimeIdentifier=$(RuntimeIdentifier)</Properties>
</ProjectReference>
</ItemGroup>

<ItemGroup>
6 changes: 0 additions & 6 deletions src/CoreToolsHost/global.json

This file was deleted.

27 changes: 25 additions & 2 deletions src/GoZipTool/GoZipTool.csproj
Original file line number Diff line number Diff line change
@@ -9,7 +9,25 @@
<GoZipSource Include="gozip\**\*.go" />
</ItemGroup>

<Target Name="MustProvideRIDOnPublish"
Condition="'$(_IsPublishing)' == 'true' and '$(ResolvedRuntimeIdentifier)' == ''"
BeforeTargets="AssignTargetPaths">
<Error Text="You must provide a 'RuntimeIdentifier' on publish to ensure GoZip is built for the right OS and architecture." />
</Target>

<Target Name="EnsureRuntimeIsSetOnBuild" Condition="'$(ResolvedRuntimeIdentifier)' == '' and '$(_IsPublishing)' != 'true'">
<Message Importance="high" Text="No RuntimeIdentifier specified. Defaulting to '$(NETCoreSdkPortableRuntimeIdentifier)'." />
<PropertyGroup>
<ResolvedRuntimeIdentifier>$(NETCoreSdkPortableRuntimeIdentifier)</ResolvedRuntimeIdentifier>
</PropertyGroup>
</Target>

<Target Name="SetGoZipPath">
<!-- Since we cannot transitively pass in the RID, we need to construct our own output path to ensure we have a path for each RID build of gozip -->
<PropertyGroup>
<ResolvedIntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration.ToLowerInvariant())_$(ResolvedRuntimeIdentifier)\</ResolvedIntermediateOutputPath>
</PropertyGroup>

<PropertyGroup>
<GoOS Condition="'$(ResolvedRuntimeIdentifier)' == 'win-x86'">windows</GoOS>
<GoArch Condition="'$(ResolvedRuntimeIdentifier)' == 'win-x86'">386</GoArch>
@@ -30,7 +48,7 @@
<GoArch Condition="'$(ResolvedRuntimeIdentifier)' == 'osx-arm64'">arm64</GoArch>

<ExeSuffix Condition="'$(GoOS)' == 'windows'">.exe</ExeSuffix>
<GoZipPath>$(IntermediateOutputPath)gozip$(ExeSuffix)</GoZipPath>
<GoZipPath>$(ResolvedIntermediateOutputPath)gozip$(ExeSuffix)</GoZipPath>
</PropertyGroup>

<Error Condition="'$(GoOS)' == '' Or '$(GoArch)' == ''"
@@ -39,16 +57,21 @@
</Target>

<Target Name="BuildGoZip" Condition="'$(NoBuild)' != 'true'" Inputs="@(GoZipSource)" Outputs="$(GoZipPath)">
<Message Importance="low" Text="Building 'gozip' for $(GoOS) - $(GoArch)..." />
<Exec
Command="go build -o $(GoZipPath) @(GoZipSource)"
EnvironmentVariables="GOOS=$(GoOS);GOARCH=$(GoArch);CGO_ENABLED=0" />
</Target>

<Target Name="CollectGoZipOutput" DependsOnTargets="SetGoZipPath;BuildGoZip" BeforeTargets="AssignTargetPaths" Condition="'$(ResolvedRuntimeIdentifier)' != ''">
<Target Name="CollectGoZipOutput" DependsOnTargets="EnsureRuntimeIsSetOnBuild;SetGoZipPath;BuildGoZip" BeforeTargets="AssignTargetPaths">
<Message Importance="low" Text="Collecting GoZip output: $(GoZipPath)" />
<ItemGroup>
<None Include="$(GoZipPath)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Target>

<Target Name="GoZipMissing" AfterTargets="Publish" Condition="'$(GoZipPath)' == ''">
<Error Text="⚠️ GoZip executable is missing. Make sure you publish with a 'RuntimeIdentifier' to ensure GoZip is built and packaged.'" />
</Target>

</Project>
Original file line number Diff line number Diff line change
@@ -48,5 +48,5 @@
<ItemGroup>
<ProjectReference Include="..\..\src\Cli\func\Azure.Functions.Cli.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
<None Include=".runsettings\start_tests\artifact_consolidation_pipeline\default.runsettings" />
<None Include=".runsettings\start_tests\artifact_consolidation_pipeline\dotnet_inproc.runsettings" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Moq" />
@@ -23,8 +23,8 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$(RepoSrcRoot)Cli\func\Azure.Functions.Cli.csproj" />
<ProjectReference Include="$(RepoTestRoot)Cli\TestFramework\Azure.Functions.Cli.TestFramework.csproj" />
<ProjectReference Include="$(SrcRoot)Cli\func\Azure.Functions.Cli.csproj" />
<ProjectReference Include="$(TestRoot)Cli\TestFramework\Azure.Functions.Cli.TestFramework.csproj" />
</ItemGroup>

<PropertyGroup>
Original file line number Diff line number Diff line change
@@ -26,10 +26,20 @@ public async Task Start_InProc_MissingHostJson_FailsWithExpectedError()
}

[Theory]
[InlineData("dotnet", "--worker-runtime None", "Use the up/down arrow keys to select a worker runtime:", false, false)] // Runtime parameter set to None, worker runtime prompt displayed
[InlineData("dotnet", "", $"Use the up/down arrow keys to select a worker runtime:", false, false)] // Runtime parameter not provided, worker runtime prompt displayed
public async Task Start_InProc_MissingLocalSettingsJson_BehavesAsExpected(string language, string runtimeParameter, string expectedOutput, bool invokeFunction, bool setRuntimeViaEnvironment)
[InlineData("dotnet", "--worker-runtime None", false, false)] // Runtime parameter set to None, worker runtime prompt displayed
[InlineData("dotnet", "", false, false)] // Runtime parameter not provided, worker runtime prompt displayed
public async Task Start_InProc_MissingLocalSettingsJson_BehavesAsExpected(string language, string runtimeParameter, bool invokeFunction, bool setRuntimeViaEnvironment)
{
string expectedOutput;
if (OperatingSystem.IsWindows())
{
expectedOutput = "Use the up/down arrow keys to select a worker runtime:";
}
else
{
expectedOutput = "Select a number for ";
}

await RunMissingLocalSettingsJsonTest(language, runtimeParameter, expectedOutput, invokeFunction, setRuntimeViaEnvironment, nameof(Start_InProc_MissingLocalSettingsJson_BehavesAsExpected));
}
}
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.

// Based off of: https://github.com/dotnet/sdk/blob/e793aa4709d28cd783712df40413448250e26fea/test/Microsoft.NET.TestFramework/Assertions/CommandResultAssertions.cs
using Azure.Functions.Cli.Abstractions;
using System.Text.RegularExpressions;
using FluentAssertions;
using FluentAssertions.Execution;

@@ -92,14 +92,14 @@ public AndConstraint<CommandResultAssertions> WriteDockerfile()

public AndConstraint<CommandResultAssertions> WriteVsCodeExtensionsJsonAndExitWithZero(string workingDirectory)
{
var pattern = $"Writing {workingDirectory}\\.vscode\\extensions.json";
var vsCodeExtPattern = @"Writing.*[\\/]\.vscode[\\/]*extensions\.json";
var gitInitPattern = "Initialized empty Git repository";

Execute.Assertion.ForCondition(_commandResult.ExitCode == 0)
.FailWith($"Expected command to exit with 0 but it did not. Error message: {_commandResult.StdErr}");

Execute.Assertion.ForCondition(_commandResult.StdOut is not null && _commandResult.StdOut.Contains(pattern))
.FailWith($"The command output did not contain expected result: {pattern}{Environment.NewLine}");
Execute.Assertion.ForCondition(_commandResult.StdOut is not null && Regex.IsMatch(_commandResult.StdOut, vsCodeExtPattern))
.FailWith($"The command output did not contain expected (using regex pattern): {vsCodeExtPattern}{Environment.NewLine}");

Execute.Assertion.ForCondition(_commandResult.StdOut is not null && !_commandResult.StdOut.Contains(gitInitPattern))
.FailWith($"The command output did contain unexpected result: {gitInitPattern}{Environment.NewLine}");
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$(RepoSrcRoot)Cli\Abstractions\Azure.Functions.Cli.Abstractions.csproj" />
<ProjectReference Include="$(SrcRoot)Cli\Abstractions\Azure.Functions.Cli.Abstractions.csproj" />
</ItemGroup>

</Project>