Change variables in appsettings when deploying with github actions - c#

I am trying to deploy an app with github actions. I linked my azure account to my github repository and the following actions has been created:
name: Build and deploy ASP.Net Core app to Azure Web App - my_app_name
on:
push:
branches:
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#master
- name: Set up .NET Core
uses: actions/setup-dotnet#v1
with:
dotnet-version: '3.1.102'
- name: Build with dotnet
run: dotnet build --configuration Release
- name: dotnet publish
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp
- name: Deploy to Azure Web App
uses: azure/webapps-deploy#v1
with:
app-name: 'my_app_name'
slot-name: 'production'
publish-profile: ${{ secrets.AzureAppService_PublishProfile_xxxxxx }}
package: ${{env.DOTNET_ROOT}}/myapp
I have some variables in my appsettings.json file that I want to overwrite, but I don't find how to do it.

You may add the following action prior to deploying the artifacts to azure.
You can specify multiple files and it is supported with wildcard entries too.
The environment variable key must be specified with dot separated heirarchy.
#substitute production appsettings entries to appsettings json file
- name: App Settings Variable Substitution
uses: microsoft/variable-substitution#v1
with:
files: '${{env.DOTNET_ROOT}}/myapp/appsettings.json'
env:
ConnectionStrings.Default: ${{ secrets.SOME_CONNECTION_STRING }}
App.ServerRootAddress: ${{ env.SERVER_ROOT_ADDRESS }}
The above action can be used for xml and yaml file changes too.

Related

How to create Github actions to deploy a Blazor Server project on Azure targeting appsettings.Staging.json?

I have a C# Blazor server project deployed on Azure App Service using Github actions.
Deployment is OK, but the WebSite uses appsettings.json instead of appsettings.Staging.json.
I think the environment should be defined, but I cannot find how to do this.
I've tried to provide
/p:EnvironmentName parameter to "dotnet publish", without success.
env:
API_RESOURCE_NAME: myappapica
MYAPP_ASPNETCORE_ENVIRONMENT: Staging
jobs:
build:
environment:
name: staging
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- name: Set up .NET Core
uses: actions/setup-dotnet#v3
with:
dotnet-version: "6.0.x"
- name: Install wasm-tools
run: dotnet workload install wasm-tools
- uses: azure/login#v1
with:
creds: ${{ secrets.STAGING_AZURE_CREDENTIALS }}
- name: Set backend env variables
uses: azure/powershell#v1
with:
azPSVersion: "latest"
inlineScript: |
az extension add --source https://workerappscliextension.blob.core.windows.net/azure-cli-extension/containerapp-0.2.4-py2.py3-none-any.whl --yes
az provider register --namespace Microsoft.App
$apiUrl = "https://$(az resource show -g ${{ secrets.STAGING_AZURE_RESOURCE_GROUP_NAME }} -n ${{ env.API_RESOURCE_NAME }} --resource-type Microsoft.App/containerApps -o tsv --query properties.configuration.ingress.fqdn)"
echo "MYAPP_API_URL=$apiUrl" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
- name: Build
run: dotnet build src/Web/MyApp.Web --configuration Release
- name: Publish
run: dotnet publish --configuration Release src/Web/MyApp.Web /p:EnvironmentName=${{ env.MYAPP_ASPNETCORE_ENVIRONMENT }} --output web
- uses: actions/upload-artifact#v3
with:
name: drop
path: web
outputs:
MyAppApiUrl: ${{ env.MYAPP_API_URL }}
My appsettings:
{
...
"WebConfiguration": {
"EnvironmentCode": "PRODUCTION",
}
}
My appsettings.Staging.json :
{
...
"WebConfiguration": {
"EnvironmentCode": "STAGING",
}
}
My web site always shows EnvironmentCode="PRODUCTION" instead of "EnvironmentCode": "STAGING".
Any help would be great !
I found the solution by going back to fundamentals :
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-7.0
For Azure App Service, it requires to add an application settings "ASPNETCORE_ENVIRONMENT". As I didn't want to do it manually on Azure portal, I updated my deploy job to add a new App Service app settings variable.
app-settings-json: |
[
{
"name": "ASPNETCORE_ENVIRONMENT",
"value": "${{ env.MYAPP_ASPNETCORE_ENVIRONMENT }}"
}
]
Here is a large part of the yml file.
env:
API_RESOURCE_NAME: myappapica
# Warning : This is case sensitive !
MYAPP_ASPNETCORE_ENVIRONMENT: Staging
jobs:
build:
......[SOME CODE]......
deploy:
needs: build
environment:
name: staging
if: ${{ github.ref == 'refs/heads/develop' && (github.event_name == 'push' || github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch') }}
runs-on: ubuntu-lastaging
steps:
- uses: actions/checkout#v3
- uses: azure/login#v1
with:
creds: ${{ secrets.STAGING_AZURE_CREDENTIALS }}
- name: Deploy ARM
uses: azure/powershell#v1
with:
azPSVersion: "3.1.0"
inlineScript: |
az deployment group create -n ghaction -g ${{ secrets.STAGING_AZURE_RESOURCE_GROUP_NAME }} --template-file deploy/Web/staging.web.deployment.json --parameters webAppName=${{secrets.STAGING_WEBAPP_NAME}} servicePlanName=${{secrets.STAGING_SERVICE_PLAN_NAME}} servicePlanSku=${{secrets.STAGING_SERVICE_PLAN_SKU}}
- name: Download web artifacts
uses: actions/download-artifact#v3
with:
name: drop
path: web
- name: Collect App Service app settings variables
uses: azure/powershell#v1
with:
azPSVersion: "3.1.0"
inlineScript: |
az extension add --name application-insights
$applicationInsightConnectionString ="$(az monitor app-insights component show -g ${{ secrets.STAGING_AZURE_RESOURCE_GROUP_NAME }} --app ${{ secrets.STAGING_APPLICATION_INSIGHT_NAME }} -o tsv --query connectionString)"
echo "APPLICATION_INSIGHT_CONNECTION_STRING=$applicationInsightConnectionString" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
- name: Update App Service app settings variables
uses: Azure/appservice-settings#v1
with:
app-name: ${{ secrets.STAGING_WEBAPP_NAME }}
app-settings-json: |
[
{
"name": "ASPNETCORE_ENVIRONMENT",
"value": "${{ env.MYAPP_ASPNETCORE_ENVIRONMENT }}"
}
]
- name: Azure WebApp
uses: Azure/webapps-deploy#v2
with:
app-name: ${{ secrets.STAGING_WEBAPP_NAME }}
package: web
I have created a Blazor Server App and deployed to Azure App Service using GitHub Actions.
If we deploy the App using Deployment Center => GitHub Actions by default, the workflow file will be created with Production settings in the .yaml file.
Instead of using the Deployment Center => GitHub from Azure Portal, we need to create the workflow manually in GitHub Repository.
In Git Hub, add the new Environment.
Create a new Workflow with staging environment.
Refer MSDoc and Using AppSettings in Blazor WebAssembly for more details.

Upload build artifacts that have changed using GitHub actions

I am trying to establish a GitHub workflow with the help of GitHub Actions. Theoretically, the workflow would deploy any new changes to the web server each time a pull request is merged into the master branch.
This is my yaml file thus far:
name: .NET
on:
push:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Setup .NET
uses: actions/setup-dotnet#v1
with:
dotnet-version: 3.1.x
- name: Restore dependencies
run: dotnet restore src/my.Web.sln
- name: Build application
run: dotnet build src/my.Web.sln --no-restore
- name: Test application
run: dotnet test src/my.Web.sln --no-restore --verbosity normal
- name: Publish artifacts to default path
run: dotnet publish src/my.Web.sln
- name: Upload build artifacts for deployment
uses: actions/upload-artifact#v2
with:
name: Application
path: /home/runner/work/my-website/my-website/src/my.Web/bin/Debug/netcoreapp3.1/publish/
I can download the artifacts after each merge fine, but all the .dll files are uploaded even though I only want the ones that were updated in the most recent push.
Stack Overflow answers on other questions suggested adding fetch-depth: 0 under the actions/checkout#v2 step to get only the latest push, but all the files of the application are still uploaded.

Dotnet Semantic Versioning and Release with Github Actions

I have a dotnet project and am trying to build a CI/CD pipeline that does the following using Github Actions:
Builds the project on a PR or master change.
Tests the project on a PR or master change.
On a master change calculates a semver (ideally a changelog too but that's less important).
On a master change uses this semver, builds a nuget package, and publishes it to GitHub and Nuget.
So far, I have this workflow that builds and tests my project. This seems to work nicely. However, it also has a publish step, which never seems to be run (I guess the if is wrong(?)) and I'm really not sure where to start with the SemVer part of what I want.
name: .NET Build, Test and Publish
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
env:
DISCOS_API_KEY: ${{ secrets.DISCOS_API_KEY }}
DISCOS_API_URL: http://localhost:3000/api/
steps:
- uses: actions/checkout#v2
with:
submodules: recursive
- name: Build docker stack
run: docker-compose -f src/DISCOSweb-Sdk/DISCOSweb-Sdk.Tests/docker-compose.yml up -d --force-recreate --build
- name: Setup .NET
uses: actions/setup-dotnet#v1
with:
dotnet-version: 6.0.x
- name: Restore dependencies
run: dotnet restore src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln
- name: Build
run: dotnet build --no-restore src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln
- name: Test
run: dotnet test --no-build --verbosity normal src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln
publish: # This stage is never run
if: github.event.pull_request.merged == 'true'
needs: build
runs-on: ubuntu-latest
steps:
- name: Publish
id: publish_nuget
uses: brandedoutcast/publish-nuget#v2
with:
PACKAGE_NAME: DISCOSweb-Sdk
PROJECT_FILE_PATH: "**/DISCOSweb-Sdk.csproj"
BUILD_CONFIGURATION: Release
NUGET_KEY: ${{secrets.NUGET_KEY}}
VERSION_STATIC: 1.0.0 # Replace with something better
I feel like this should be a relatively common and straightforward thing to do so any assistance would be really appreciated.
I managed to accomplish this by splitting my CI and CD workflows, and making use of some very helpful packages.
CI Workflow
This first workflow runs on PRs and pushes to master. It's worth noting that when branch protection is on, a push to master is synonymous with a merged PR.
name: .NET Continuous Integration
on:
pull_request:
branches: [ master ]
push:
branches: [ master ]
jobs:
test:
name: Test Project (Mock API)
runs-on: ubuntu-latest
env:
DISCOS_API_KEY: ${{ secrets.DISCOS_API_KEY }}
DISCOS_API_URL: http://localhost:3000/api/
steps:
- uses: actions/checkout#v3
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Build docker stack
run: docker-compose -f ./src/DiscosWebSdk/DiscosWebSdk.Tests/docker-compose.yml up -d --force-recreate --build
- name: Run tests against mock API
run: dotnet test --logger GitHubActions ./src/DiscosWebSdk/DiscosWebSdk.sln
CD Workflow
There's a bit more to the CD workflow. It runs on pushes to master but only when there are changes made to the folder containing the actual source code for the SDK (that's what the paths block does).
I then used the mathieudutour/github-tag-action#v6.0 action to tag the commit with a calculated semantic version (calculated using conventional commits).
The package build is then tagged with this version using the -p:PackageVersion=${{ steps.tag_version.outputs.new_version }} option on dotnet nuget pack.
The ncipollo/release-action#v1 also creates a release on Github.
Finally, building and pushing the release to Github and Nuget is done using dotnet nuget push as usual.
name: .NET Continuous Deployment
on:
push:
branches: [ master ]
paths:
- src/DiscosWebSdk/DiscosWebSdk/**
workflow_dispatch:
jobs:
test:
name: Test Project (Real API)
runs-on: ubuntu-latest
env:
DISCOS_API_KEY: ${{ secrets.DISCOS_API_KEY }}
DISCOS_API_URL: https://discosweb.esoc.esa.int/api/
steps:
- uses: actions/checkout#v3
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Test against real API
run: dotnet test --logger GitHubActions ./src/DiscosWebSdk/DiscosWebSdk.sln
semantic-release:
needs: test
name: Create a Package Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3 # Need the full commit history for conventional commit
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Bump version and push tag
id: tag_version
uses: mathieudutour/github-tag-action#v6.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Create a GitHub release
uses: ncipollo/release-action#v1
with:
tag: ${{ steps.tag_version.outputs.new_tag }}
name: Release ${{ steps.tag_version.outputs.new_tag }}
body: ${{ steps.tag_version.outputs.changelog }}
- name: Create Nuget Package
run: dotnet build -c Release ./src/DiscosWebSdk/DiscosWebSdk/DiscosWebSdk.csproj && dotnet pack -c Release -p:PackageVersion=${{ steps.tag_version.outputs.new_version }} -o . ./src/DiscosWebSdk/DiscosWebSdk/DiscosWebSdk.csproj
- name: Upload Package for Publishing
uses: actions/upload-artifact#v3
with:
name: PackedLib
path: ./*.nupkg
github-publish:
needs: semantic-release
name: Publish to Github
runs-on: ubuntu-latest
steps:
- name: Download built project
uses: actions/download-artifact#v3
with:
name: PackedLib
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Push Package to GitHub
run: dotnet nuget push --api-key ${{secrets.GITHUB_TOKEN}} --source "https://nuget.pkg.github.com/hughesjs/index.json" *.nupkg
nuget-publish:
needs: semantic-release
name: Publish to Nuget
runs-on: ubuntu-latest
steps:
- name: Download built project
uses: actions/download-artifact#v3
with:
name: PackedLib
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Push Package to Nuget
run: dotnet nuget push --api-key ${{secrets.NUGET_KEY}} --source "https://api.nuget.org/v3/index.json" *.nupkg

GitHub Actions only outputting DLL file

I recently tried automatically building and uploading my C# project. The build works fine, but the artifact sadly only contains a DLL file, and not a .exe file. When I build it locally, it outputs an .exe and a DLL file. Is that normal? This is my github actions file:
name: .NET
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
name: Build the app
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- name: Setup .NET
uses: actions/setup-dotnet#v2
with:
dotnet-version: 6.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build
- name: Upload a Build Artifact
uses: actions/upload-artifact#v2.2.2
with:
# Artifact name
name: buildresult #.zip will be added automatically
path: /home/runner/work/ParadoxicalLauncher/ParadoxicalLauncher/ParadoxicalLauncher/bin/Debug/net6.0/*.*

How to upload xUnit coverage reports to Codecov?

I have a .Net 5 solution with multiple xUnit test projects which is a public repository hosted on Github. I would like to generate code coverage reports and display them on Codecov.
First I run
dotnet add package coverlet.msbuild
for each test project. I know that I can navigate to the .sln directory and generate a new report via
dotnet test /p:CollectCoverage=true
I authorized Codecov, so it knows about this project. I think only the main and dev branches are relevant so I started with this workflow
name: Generate coverage report on push
on:
push:
branches:
- 'main'
- 'dev'
jobs:
generate-coverage-report-on-push:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./DirectoryWithSlnFile
steps:
- uses: actions/checkout#v2
- name: Setup .NET
uses: actions/setup-dotnet#v1
with:
dotnet-version: 5.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build project
run: dotnet build --no-restore
- name: Generate coverage report
run: dotnet test --no-build --verbosity normal /p:CollectCoverage=true
What needs to be done now to upload the report from all test projects to Codecov? E.g.
- name: Upload coverage report
run: upload to Codecov with CODECOV_TOKEN if pushed on main or dev
I just stumbled upon this when having the same question. This is how I made it work.
First, the step you already had but just for completeness. Add coverlet to the test project(s):
dotnet add package coverlet.msbuild
Then, in the GitHub Actions workflow file, add the following steps:
- name: Test
run: dotnet test --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
- name: Codecov
uses: codecov/codecov-action#v2
with:
file: coverage.opencover.xml
directory: FUI.Tests

Categories

Resources