I was able to successfully deploy two web APIs to the same web service using virtual paths using GitHub actions. Here are the steps I took.
Create virtual applications
If you wanted your application to be named test then the Virtual path would be /test and the Physical Path value would be site\wwwroot_test. Having the physical path be site\wwwroot\test is also possible, however, this is the way I have gotten it to work. I also did not check either of the Directory or Preload enabled checkboxes.
Modify the publish profile
The destinationAppUrl's value needs to add the path. See Doris Lv's answer.
Add OutOfProcess AspNetCoreHostingModel
For each of the web projects you want to host on the same web app, you need to add the following to each .csproj file
<PropertyGroup>
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
</PropertyGroup>
Modify app service url
Next since these applications are going to be in a different path than the root directory, you need to change the app service url to include the virtual path.
Example: instead of www.https://yoursite.azurewebsites.net/ it will now be https://yoursite.azurewebsites.net/test if /test is the virtual path you created.
Add deployment target step to GitHub action
To deploy to the correct directory, you will need to add a step into your GitHub workflow. Here is a snippet of code from my workflow that sets the DEPLOYMENT_TARGET environment variable in the web service prior to the deploy composite action that I have setup.
Here is a snippet of the GitHub workflow:
# .github/workflows/cd.yml
jobs:
# ...
target:
needs: [set_environment, build, test, publish]
runs-on: windows-latest
environment:
name: ${{ needs.set_environment.outputs.my_env }}
steps:
- uses: actions/checkout@v4
- name: Run Composite Action Target
uses: ./.github/actions/target
with:
Service-Principal: ${{ secrets.SPN }}
deploy:
needs: [set_environment, build, test, publish, target]
runs-on: windows-latest
environment:
name: ${{ needs.set_environment.outputs.my_env }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: echo_environment
run: |
echo "The environment value is:
${{needs.set_environment.outputs.my_env}}"
- name: Run Composite Action Deploy
uses: ./.github/actions/deploy
with:
Publish-Profile: ${{ secrets.TEST_PUBLISH_PROFILE }}
Service-Principal: ${{ secrets.SPN }}
Has-Api-Management-Service: true
Here is the composite action.
# .github/actions/target/action.yml
runs:
using: 'composite'
steps:
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ inputs.Service-Principal }}
- name: Configure Azure Deployment Target
run: az webapp config appsettings set --name ${{ env.AZURE_WEBAPP_NAME }} --resource-group ${{ env.AZURE_APIM_RESOURCEGROUP }} --settings DEPLOYMENT_TARGET=${{ env.DEPLOYMENT_TARGET }} --output none
shell: pwsh
- name: logout
run: >
az logout
shell: pwsh
Add concurrency to GitHub actions
Since these deployment workflows are relying on the DEPLOYMENT_TARGET value being the correct site\wwwroot_app path, if two cd.yml GitHub actions run together, the builds may end up in the wrong directory. Therefore, to avoid this I added the same concurrency group to each of the cd workflows that deploy to the same web app.
name: Test Continuous Deployment
on:
push:
branches: TEST
paths:
- .github/**
- TestDirectory/**
concurrency:
group: webapp-deploy
Some of the resources that helped me: