2

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.

1
  • Does if: github.event.pull_request.merged == true trigger your publishing? Commented Jun 20, 2022 at 9:35

1 Answer 1

4

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/[email protected] 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/[email protected]
      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
Sign up to request clarification or add additional context in comments.

1 Comment

I have achieved something similar using the semantic-release NPM package. You can find a working example here: github.com/droidsolutions/semantic-version

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.