Skip to content
Merged
Show file tree
Hide file tree
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
with:
dotnet-version: '8.0.x'
dotnet-version: '10.0.x'
- run: dotnet build
- run: dotnet test tests

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
python-version: '3.11'
- uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
with:
dotnet-version: '8.0.x'
dotnet-version: '10.0.x'
- name: Test JavaScript
working-directory: javascript
run: |
Expand Down
4 changes: 2 additions & 2 deletions TECHNICAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ and choose the newest stable tag ending in your language ID. Each language relea
| Language | Release tag | Contents |
| --- | --- | --- |
| JavaScript | `epp-packages-<run>-<attempt>-javascript` | Node.js 22 application and production dependencies |
| .NET | `epp-packages-<run>-<attempt>-dotnet` | Framework-dependent .NET 8 Linux x64 publish output, including Azure Functions metadata and extensions |
| .NET | `epp-packages-<run>-<attempt>-dotnet` | Framework-dependent .NET 10 Linux x64 publish output, including Azure Functions metadata and extensions |
| Python | `epp-packages-<run>-<attempt>-python` | Python 3.11 application with Linux x64 dependencies in `.python_packages/lib/site-packages` |

Deploy the ZIP to an Azure Functions v4 app on Linux x64 with the matching language runtime.
Expand All @@ -93,7 +93,7 @@ Run one packaging script from the repository root. It creates a local ZIP withou
| Language | Root-level script | Prerequisites | ZIP in `artifacts/` |
| --- | --- | --- | --- |
| JavaScript | [package-javascript.ps1](package-javascript.ps1) | PowerShell 7+, Node.js 20 or 22 with npm, npm registry access | `javascript/released-package.zip` |
| .NET | [package-dotnet.ps1](package-dotnet.ps1) | PowerShell 7+, .NET 8 SDK, and NuGet feed access to build the ZIP | `dotnet/released-package.zip` |
| .NET | [package-dotnet.ps1](package-dotnet.ps1) | PowerShell 7+, .NET 10 SDK, and NuGet feed access to build the ZIP | `dotnet/released-package.zip` |
| Python | [package-python.ps1](package-python.ps1) | Linux x64, PowerShell 7+, Python 3.11 with pip, and PyPI access to build the ZIP | `python/released-package.zip` |

```powershell
Expand Down
6 changes: 5 additions & 1 deletion dotnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[Documentation](../docs/README.md) | [Settings](#environment-configuration) | [Request behavior](#request-behavior) | [Source](#source)

Implements the shared [contract](../docs/CONTRACT.md) with one provider per deployment.
Target: .NET 8 isolated worker, Azure Functions v4.
Target: .NET 10 isolated worker, Azure Functions v4.

## Setup and deployment

Expand All @@ -14,6 +14,10 @@ Target: .NET 8 isolated worker, Azure Functions v4.

**Custom package development:** follow these steps from `dotnet/`:

Install the .NET 10 SDK and current Azure Functions Core Tools v4.
On Linux, use Flex Consumption or Premium hosting; .NET 10 is not supported on the legacy
Linux Consumption plan.

1. Create the [local settings below](#environment-configuration). Select an adapter's fixed `Name`
from [Providers/](Src/Providers/), configure it, and complete
[provider authentication](../docs/ONBOARDING.md#complete-provider-authentication).
Expand Down
2 changes: 1 addition & 1 deletion dotnet/dotnet.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
3 changes: 1 addition & 2 deletions dotnet/tests/Epp.Otp.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
Expand All @@ -16,7 +16,6 @@
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageReference Include="Azure.Identity" Version="1.13.1" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
<PackageReference Include="jose-jwt" Version="5.1.0" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion package-dotnet.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ try {
[IO.Compression.ZipFile]::CreateFromDirectory($stage, $zip)
New-Item -ItemType Directory -Path (Split-Path $archive) -Force | Out-Null
[IO.File]::Move($zip, $archive)
Write-Host 'Framework-dependent .NET 8 Linux x64 ZIP created.'
Write-Host 'Framework-dependent .NET 10 Linux x64 ZIP created.'
Get-Item -LiteralPath $archive | Select-Object FullName, Length
} finally {
if (Test-Path -LiteralPath $temporary) { Remove-Item -LiteralPath $temporary -Recurse -Force }
Expand Down
2 changes: 1 addition & 1 deletion setup/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ Interactive setup can install missing Bicep.
| Choice | Azure runtime | Package contents |
| --- | --- | --- |
| JavaScript | Node.js 22, Functions v4 | Application and production dependencies |
| C# | .NET 8 isolated, Functions v4 | Framework-dependent Linux x64 publish output, Function metadata, and extensions |
| C# | .NET 10 isolated, Functions v4 | Framework-dependent Linux x64 publish output, Function metadata, and extensions |
| Python | Python 3.11, Functions v4 | Application and Linux x64 dependencies in `.python_packages/lib/site-packages` |

Setup verifies and publishes the selected ZIP, recording its SHA-256 in the deployment summary.
Expand Down
4 changes: 2 additions & 2 deletions setup/docs/Troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ a full SHA avoids branch-resolution API rate limits. Private raw downloads are u
<a id="net-build-fails"></a>
## .NET package fails to load

**Expected:** guided setup downloads `released-package.zip` from the `-dotnet` release, containing framework-dependent .NET 8
**Expected:** guided setup downloads `released-package.zip` from the `-dotnet` release, containing framework-dependent .NET 10
Linux x64 publish output, Function metadata, and `.azurefunctions` extension assemblies.
Confirm the Function uses .NET 8 isolated and align the selected
Confirm the Function uses .NET 10 isolated on Flex Consumption or Premium, not legacy Linux Consumption, and align the selected
[source/package versions](README.md#source-versioning). For custom packaging errors, see
[build prerequisites and commands](../../TECHNICAL.md#build-zips-locally).

Expand Down
4 changes: 2 additions & 2 deletions setup/infra/resources.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ var runtimes = {
}
dotnet: {
worker: 'dotnet-isolated'
stack: 'DOTNET-ISOLATED|8.0'
version: '8.0'
stack: 'DOTNET-ISOLATED|10.0'
version: '10.0'
}
python: {
worker: 'python'
Expand Down
5 changes: 5 additions & 0 deletions setup/tests/ServicePlans.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ try {
$inner = ($template.resources | Where-Object type -eq 'Microsoft.Resources/deployments').properties.template
Assert (($inner.parameters.servicePlan.allowedValues -join ',') -ceq 'FC1,EP1') 'Bicep must restrict service plans to the two offered SKUs.'
Assert ($inner.variables.isFlexConsumption -ceq "[equals(parameters('servicePlan'), 'FC1')]") 'The Flex condition must use the selected SKU.'
$dotnetRuntime = $inner.variables.runtimes.dotnet
Assert ($dotnetRuntime.worker -ceq 'dotnet-isolated' -and $dotnetRuntime.stack -ceq 'DOTNET-ISOLATED|10.0' -and
$dotnetRuntime.version -ceq '10.0') 'Both hosting plans must target .NET 10 isolated.'
$plan = $inner.resources | Where-Object type -eq 'Microsoft.Web/serverfarms'
Assert ($plan.sku -ceq "[if(variables('isFlexConsumption'), createObject('name', 'FC1', 'tier', 'FlexConsumption'), createObject('name', 'EP1', 'tier', 'ElasticPremium', 'capacity', 1))]") 'Bicep must deploy the selected SKU, tier, and Premium capacity.'
$settings = ($inner.resources | Where-Object { $_.type -eq 'Microsoft.Web/sites/config' -and $_.name -like '*appsettings*' }).properties
Expand All @@ -305,9 +308,11 @@ try {
Assert ($site.serverFarmId -ceq "[resourceId('Microsoft.Web/serverfarms', parameters('resourceNames').hostingPlan)]") 'The hosting-plan ID must be explicit without a runtime reference.'
Assert ($site.httpsOnly -eq $true -and $site.publicNetworkAccess -ceq 'Disabled') 'The Function must retain HTTPS-only access and initially disabled public ingress.'
Assert ($site.keyVaultReferenceIdentity -ceq 'SystemAssigned') 'Certificate references must use the Function system identity, not the outbound identity.'
Assert ($site.siteConfig.Contains("'linuxFxVersion', variables('runtime').stack")) 'Premium must use the selected runtime stack.'
$functionAppConfig = $site.functionAppConfig
Assert ($functionAppConfig -is [string] -and $functionAppConfig.StartsWith("[if(variables('isFlexConsumption'), ") -and $functionAppConfig.EndsWith(', null())]')) 'Only functionAppConfig must be conditional on FC1, with no Flex configuration for EP1.'
Assert ($functionAppConfig.Contains("'deployment', createObject('storage', createObject('type', 'blobContainer'") -and $functionAppConfig.Contains("reference(resourceId('Microsoft.Storage/storageAccounts', parameters('resourceNames').storageAccount), '2023-05-01').primaryEndpoints.blob")) 'Flex must retain its deployment container and storage endpoint lookup.'
Assert ($functionAppConfig.Contains("'runtime', createObject('name', variables('runtime').worker, 'version', variables('runtime').version)")) 'Flex must use the selected runtime name and version.'
Assert ($functionAppConfig.Contains("'instanceMemoryMB', 2048, 'maximumInstanceCount', 40, 'alwaysReady', createArray()") -and $functionAppConfig.Contains("'type', 'SystemAssignedIdentity'")) 'Flex must retain 2048 MB, up to 40 on-demand instances, zero always-ready instances, and managed-identity deployment storage.'
}
} $directory $TemplatePath
Expand Down
Loading