原可靠GitHub Action工作流部署Azure Function Apps后无法运行
曾可靠运行的GitHub Action工作流,现在部署Windows版Azure Function Apps时无报错,但Azure门户无法显示函数列表,偶尔提示:We were not able to load some functions in the list due to errors. Refresh the page to try again. See details,详情仅显示An unexpected error has occurred.。Application Insights未捕获到失败详情,但通过Visual Studio手动部署可正常显示所有函数。
工作流脚本
on: workflow_call: inputs: client_config_dir: required: true type: string functionapp_name: required: true type: string functionapp_config_source_filename: required: true type: string functionapp_config_dest_filename: required: true type: string functionapp_csproj_name: required: true type: string dotnet_version: required: true type: string secrets: publish_profile: required: true jobs: build-test: name: Build & Test runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Copy client specific configs run: | cp "source/Config/${{ inputs.client_config_dir }}/test.settings.json" "source/Config/test.settings.json" cp "source/Config/${{ inputs.client_config_dir }}/shared.settings.json" "source/Config/shared.settings.json" cp "source/Config/${{ inputs.client_config_dir }}/${{ inputs.functionapp_config_source_filename }}" "source/Config/${{ inputs.functionapp_config_dest_filename }}" - name: Setup .NET uses: actions/setup-dotnet@v3 with: dotnet-version: ${{ inputs.dotnet_version }} - name: NuGet package cache uses: actions/cache@v3 with: path: ~/.nuget/packages key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} restore-keys: | ${{ runner.os }}-nuget- - name: Restore dependencies run: dotnet restore source/LogisticsAutomation.sln - name: Build full solution run: dotnet build source/LogisticsAutomation.sln --no-restore --configuration Release - name: Test full solution run: dotnet test source/LogisticsAutomation.sln --no-build --configuration Release --verbosity normal - name: Generate function app artifacts run: dotnet publish source/${{ inputs.functionapp_csproj_name }}/${{ inputs.functionapp_csproj_name }}.csproj --no-build --configuration Release --output ./deploy - name: Store artifacts uses: actions/upload-artifact@v3 with: name: deploy path: deploy deploy: name: Deploy needs: build-test runs-on: ubuntu-latest steps: - name: Retrieve artifacts uses: actions/download-artifact@v3 with: name: deploy path: deploy - name: Deploy function app uses: azure/functions-action@v1 with: app-name: ${{ inputs.functionapp_name }} package: deploy publish-profile: ${{ secrets.publish_profile }}
注意:工作流使用
ubuntu-latest,但目标Function Apps为Windows版,多个应用(含应用服务/消费计划)均出现此问题。
关键差异点
- GitHub Action部署后,根目录生成包含
win和unix子目录的runtimes文件夹,且runtime下出现net6.0目录(项目实际基于net8.0) - Visual Studio部署后,生成
.azurefunctions文件夹,其下runtimes仅包含win子目录,无多余框架版本目录
在工作目录中发现自动生成的\obj\Debug\net8.0\WorkerExtensions\WorkerExtensions.csproj文件,内容如下:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <Configuration>Release</Configuration> <AssemblyName>Microsoft.Azure.Functions.Worker.Extensions</AssemblyName> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.NETCore.Targets" Version="3.0.0" PrivateAssets="all" /> <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.3.0" /> </ItemGroup> <Target Name="_VerifyTargetFramework" BeforeTargets="Build"> <!-- It is possible to override our TFM via global properties. This can lead to successful builds, but runtime errors due to incompatible dependencies being brought in. --> <Error Condition="'$(TargetFramework)' != 'net6.0'" Text="The target framework '$(TargetFramework)' must be 'net6.0'. Verify if target framework has been overridden by a global property." /> </Target> </Project>
已尝试的实验
- 启用Oryx构建:设置
scm-do-build-during-deployment和enable-oryx-build,问题依旧 - 更新Action版本:将所有Action升级至最新版(如
actions/setup-dotnet@v4),未解决 - 本地构建测试:本地执行
dotnet build和dotnet publish时,根目录同时生成.azurefunctions和runtimes文件夹,推测缺失.azurefunctions是问题根源
可能的原因及修复方案
1. 跨平台构建导致运行时冗余
GitHub Action使用Linux环境构建Windows函数应用,dotnet publish默认生成跨平台运行时文件,Windows函数应用不需要unix相关文件,导致Azure Functions Runtime加载混乱。
修复:
在dotnet publish命令中指定Windows目标运行时:
dotnet publish source/${{ inputs.functionapp_csproj_name }}/${{ inputs.functionapp_csproj_name }}.csproj --no-build --configuration Release --output ./deploy --runtime win-x64 --self-contained false
2. WorkerExtensions.csproj框架版本冲突
自动生成的WorkerExtensions.csproj强制使用net6.0,与项目net8.0目标框架不兼容,导致部署后版本冲突。
修复:
更新Microsoft.NET.Sdk.Functions包至兼容net8.0的最新版本(如v4.28.1),在函数项目的csproj中修改:
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.28.1" />
3. 缺失.azurefunctions元数据文件夹
该文件夹包含函数元数据,Azure门户依赖它加载函数列表,GitHub Action构建过程未生成此文件夹。
修复:
在生成构建产物后手动创建元数据文件夹,在Generate function app artifacts步骤后添加:
- name: Generate .azurefunctions metadata run: | mkdir -p ./deploy/.azurefunctions echo '{"schemaVersion": "2.0.0"}' > ./deploy/.azurefunctions/metadata.json
同时确保项目已正确引用Microsoft.Azure.Functions.Worker.Sdk包,该包负责生成函数元数据。
4. 部署方式或权限问题
尝试使用Azure登录替代发布配置文件部署,避免权限或配置遗漏:
- name: Azure Login uses: azure/login@v2 with: creds: ${{ secrets.AZURE_CREDENTIALS }} - name: Deploy function app uses: azure/functions-action@v1 with: app-name: ${{ inputs.functionapp_name }} package: deploy
内容的提问来源于stack exchange,提问作者Gavin

