1

I have a C# solution containing a single project and multiple libraries using .Net 6. I'm using conventional commits (commitlint with husky) and want to use semantic-release to deploy the latest build as a ZIP file on Github based on the commit messages.


The setup I tried for C# projects:

  • Install packages

.

npm install semantic-release -D
npm install @semantic-release/changelog -D
npm install @semantic-release/npm -D
npm install @semantic-release/github -D
npm install @semantic-release/git -D
  • Create a .releaserc.json file inside the root directory

.

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/changelog",
    "@semantic-release/npm",
    [
      "@semantic-release/github",
      {
        "assets": [
          {
            "path": "my-project.zip",
            "label": "my-project-${nextRelease.gitTag}.zip",
            "name": "my-project-${nextRelease.gitTag}.zip"
          }
        ]
      }
    ],
    "@semantic-release/git"
  ]
}
  • Inside the package.json file set the key version to 0.0.0-development, set the key private to true and add a repository url
  • Create a release-on-push-on-main-branch.yml file inside the workflows directory

.

name: Release on push on main branch
 
on:
  push:
    branches:
      - main
 
jobs:
  release-on-push-on-main-branch:
    runs-on: ubuntu-latest
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: 16.x

      - name: Install Node dependencies
        run: npm install
 
      - name: Setup .Net
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '6.0.x'
 
      - name: Install .Net dependencies
        run: dotnet restore ./SolutionDir
 
      - name: Run build
        run: dotnet build ./SolutionDir
 
      - name: Run publish
        run: dotnet publish ./SolutionDir
 
      - name: Rename publish directory of MyProject to my-project and move it to root
        run: mv ./SolutionDir/MyProject/bin/Debug/net6.0 ./my-project
 
      - name: ZIP my-project directory
        run: zip -r my-project.zip my-project
 
      - name: Release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: npx semantic-release --branches main

It seems to work, whenever I push to the main branch it will deploy the distribution (containing the DLL) with the latest version to the Github releases.


But as you know semantic-release does not release the correct package version because it doesn't know about the assembly version yet. It takes the version from the package.json file.

What I want to achieve:

  • When making changes in libraries or apps inside the solution it should automatically increase their assembly versions based on the conventional commits. But obviously just if that project was modified.
  • When running the release process semantic-release should release the project with "name": "my-project-${assembly-version}.zip"

Is there something I can use?

Question3r
  • 2,166
  • 19
  • 100
  • 200

1 Answers1

4

You could dry-run semantic-release before dotnet publish to fetch the version number of the release (using the @semantic-release/exec plugin). Then pass this fetched version number to dotnet publish:

Add the @semantic-release/exec plugin to your npm install commands and adjust your .releaserc.json file to store the next release version (for example in an environment variable):

{
   "plugins": [
     ...,
     [
       '@semantic-release/exec',
       { verifyReleaseCmd: 'echo RELEASE_VERSION=\${nextRelease.version} >> $GITHUB_ENV' }
     ]
   ]
 }

Insert the dry run before the dotnet publish and adjust the dotnet publish step:

...
- name: Fetch release version
  env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: npx semantic-release --branches main --dry-run
- name: Run publish
  run: dotnet publish ./SolutionDir -p:Version=${{ env.RELEASE_VERSION }}
...

Note: instead of your Rename publish directory of MyProject to my-project and move it to root step, you could simply use the -o param of the dotnet publish command.

latonz
  • 1,601
  • 10
  • 21
  • thanks a lot for this guide! but there still is one problem: assuming I implemented a new feature in a library inside the solution this would still affect the published version of the project ... because that `feat: ...` commit counts for every project ... – Question3r Jan 01 '22 at 08:22
  • 2
    I think what you need for this is https://github.com/semantic-release/semantic-release/issues/193. However, as of this writing this is not yet implemented in semantic-release. There is a drop in replacement for `semantic-release` called `semantic-release-plus` (https://github.com/semantic-release-plus/semantic-release) which implements filtering commits by paths (see the `commitpaths` option). You could also try to use a plugin like https://github.com/folke/semantic-release-commit-filter or write a custom plugin. – latonz Jan 01 '22 at 09:49