Skip to content

Commit acdfc89

Browse files
author
Gideon de Swardt
committed
Automate build, publish and releases
This change set automates the build, test, package, and publish process for our .NET project using GitVersion to obtain the semantic version. The CD pipeline is triggered when a new release branch is created in the format of release/v{MAJOR.MINOR.PATCH}. It will publish a pre-release package to NuGet first, and only on approval will it publish the final version, create a tag that matches the version number, and generate the GitHub release with release notes. To ensure the version is calculated correctly, a tag was added to the previous commit that was released. The CD pipeline uses this tag to calculate the version number. The implementation details include: - Using GitVersion plugin to obtain the semantic version - Automating the build, test, package, and publish process - Creating a tag on the previous commit that was released to ensure correct version calculation - Publishing a pre-release package to NuGet first and only on approval publishing the final version, creating a tag that matches the version number, and generating the GitHub release with release notes - Create a pull request to ensure that any changes that were committed to the `release` branch is also merged back into `master` This change set simplifies the release process and ensures that all our artifacts are versioned correctly, making it easier for other developers to understand and track our what has changed in each release.
1 parent 3ece65b commit acdfc89

11 files changed

Lines changed: 337 additions & 27 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: build
2+
description: 'Restore and build the dotnet solution'
3+
4+
inputs:
5+
dotnet-build-configuration:
6+
default: Release
7+
description: 'Defines the build configuration. The default for most projects is Release.'
8+
required: true
9+
10+
runs:
11+
using: "composite"
12+
steps:
13+
- name: Restore dependencies
14+
shell: bash
15+
run: dotnet restore
16+
17+
- name: Build solutions
18+
shell: bash
19+
run: dotnet build --no-restore --configuration ${{ inputs.dotnet-build-configuration }}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: nuget
2+
description: 'Publish NuGet packages'
3+
4+
inputs:
5+
dotnet-version:
6+
description: 'The dotnet framework and SDK version.'
7+
default: 7.0.x
8+
required: true
9+
nuget-api-key:
10+
description: 'The NuGet API key to publish artifacts'
11+
default: 'nuget-api-key'
12+
required: true
13+
packages-directory:
14+
description: 'The root directory of the NuGet packages that should be published'
15+
server-url:
16+
description: 'Specifies the NuGet server URL'
17+
required: true
18+
default: 'https://api.nuget.org/v3/index.json'
19+
20+
runs:
21+
using: "composite"
22+
steps:
23+
- name: Setup dotnet environment
24+
uses: actions/setup-dotnet@v3
25+
id: setup
26+
with:
27+
dotnet-version: ${{ inputs.dotnet-version }}
28+
29+
- name: Publish to NuGet
30+
working-directory: ${{ inputs.packages-directory }}
31+
shell: bash
32+
run: 'dotnet nuget push "*.nupkg" --skip-duplicate --api-key ${{ inputs.nuget-api-key }} --source ${{ inputs.server-url }}'
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: pack
2+
description: 'Packs and sign the code into a NuGet package'
3+
4+
inputs:
5+
dotnet-build-configuration:
6+
default: Release
7+
description: 'Defines the build configuration. The default for most projects is Release.'
8+
required: true
9+
pre-release-version:
10+
description: 'The semantic version to be used for pre-release artifacts'
11+
required: true
12+
release-version:
13+
description: 'The semantic version to be used for release artifacts'
14+
required: true
15+
16+
runs:
17+
using: "composite"
18+
steps:
19+
- name: Pack pre-release version ${{steps.version.outputs.nuGetVersionV2}}
20+
shell: bash
21+
run: dotnet pack --configuration ${{ inputs.dotnet-build-configuration }} --verbosity normal --no-restore -p:PackageVersion=${{ inputs.pre-release-version }} --output ./packages/preview
22+
23+
- name: Pack release version ${{steps.version.outputs.majorMinorPatch}}
24+
shell: bash
25+
run: dotnet pack --configuration ${{ inputs.dotnet-build-configuration }} --verbosity normal --no-restore -p:PackageVersion=${{ inputs.release-version }} --output ./packages/release
26+
27+
- name: Upload artifacts
28+
uses: actions/upload-artifact@v3
29+
with:
30+
name: packages
31+
path: |
32+
./packages/preview
33+
./packages/release
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: test
2+
description: 'Execute the unit tests and parse results report'
3+
4+
inputs:
5+
dotnet-build-configuration:
6+
default: Release
7+
description: 'Defines the build configuration. The default for most projects is Release.'
8+
required: true
9+
results-directory:
10+
description: 'The test results output directory'
11+
default: './test-results'
12+
github-token:
13+
description: 'GitHub personal access token'
14+
required: true
15+
16+
runs:
17+
using: "composite"
18+
steps:
19+
20+
- name: Execute unit tests
21+
shell: bash
22+
run: dotnet test --logger trx --results-directory ${{ inputs.results-directory }} --no-build --configuration ${{ inputs.dotnet-build-configuration }} --verbosity normal
23+
24+
- name: Parse the unit test files
25+
uses: nasamin/trx-parser@v0.2.0
26+
with:
27+
TRX_PATH: ${{ github.workspace }}/test-results
28+
REPO_TOKEN: ${{ inputs.github-token }}
29+
30+
- name: Upload artifacts
31+
uses: actions/upload-artifact@v3
32+
if: always()
33+
with:
34+
name: unit-test-logs
35+
path: |
36+
./test-logs
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: version
2+
description: 'Use the git tools to calculate the semantic version and update the dotnet project files'
3+
inputs:
4+
dotnet-version:
5+
description: 'The dotnet framework and SDK version.'
6+
default: 7.0.x
7+
required: true
8+
git-tools-version:
9+
description: 'The version specification to be used of the git tools '
10+
default: 5.x
11+
required: true
12+
config-file-path:
13+
description: 'Tha path of the git version configuration file'
14+
default: GitVersion.yml
15+
required: true
16+
17+
runs:
18+
using: "composite"
19+
steps:
20+
- name: Setup dotnet environment
21+
uses: actions/setup-dotnet@v3
22+
id: setup
23+
with:
24+
dotnet-version: ${{ inputs.dotnet-version }}
25+
26+
- name: Setup the git version tools
27+
uses: gittools/actions/gitversion/setup@v0.9.15
28+
with:
29+
versionSpec: ${{ inputs.git-tools-version }}
30+
31+
- name: Update the semantic version of the projects
32+
uses: gittools/actions/gitversion/execute@v0.9.15
33+
id: version
34+
with:
35+
useConfigFile: true
36+
configFilePath: ${{ inputs.config-file-path }}
37+
additionalArguments: '/updateprojectfiles'
38+
39+
outputs:
40+
dotnet-version:
41+
description: 'The dotnet framework and sdk version'
42+
value: ${{ steps.setup.outputs.dotnet-version }}
43+
pre-release-version:
44+
description: 'The semantic version to be used for pre-release artifacts'
45+
value: ${{steps.version.outputs.nuGetVersionV2}}
46+
release-version:
47+
description: 'The semantic version to be used for release artifacts'
48+
value: ${{steps.version.outputs.majorMinorPatch}}
49+
50+
51+

.github/workflows/build.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: build
2+
on:
3+
workflow_call:
4+
inputs:
5+
pack:
6+
default: false
7+
required: true
8+
type: boolean
9+
10+
jobs:
11+
build-and-sign:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v3
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Semantic version
20+
uses: './.github/actions/dotnet/version'
21+
id: version
22+
23+
- name: Restore and build
24+
uses: './.github/actions/dotnet/build'
25+
26+
- name: Execute unit test and publish reports
27+
uses: './.github/actions/dotnet/test'
28+
with:
29+
github-token: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Pack and sign NuGet packages
32+
uses: './.github/actions/dotnet/pack'
33+
if: ${{ inputs.pack }}
34+
with:
35+
pre-release-version: ${{steps.version.outputs.pre-release-version}}
36+
release-version: ${{steps.version.outputs.release-version}}

.github/workflows/cd.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: continuous-delivery
2+
run-name: Publish pipeline after ${{github.event_name}} by @${{ github.actor }}
3+
4+
on:
5+
push:
6+
branches:
7+
- release/**
8+
9+
jobs:
10+
continuous-integration:
11+
uses: ./.github/workflows/build.yml
12+
with:
13+
pack: true
14+
secrets: inherit
15+
16+
publish-preview-packages:
17+
uses: ./.github/workflows/publish.yml
18+
needs: [ continuous-integration ]
19+
with:
20+
environment: preview
21+
secrets: inherit
22+
23+
publish-release-packages:
24+
uses: ./.github/workflows/publish.yml
25+
needs: [ publish-preview-packages ]
26+
with:
27+
environment: release
28+
secrets: inherit
29+
30+
tag-and-release:
31+
runs-on: ubuntu-latest
32+
needs: [ publish-release-packages ]
33+
steps:
34+
- name: Checkout
35+
uses: actions/checkout@v3
36+
with:
37+
fetch-depth: 0
38+
39+
- name: Semantic version
40+
uses: './.github/actions/dotnet/version'
41+
id: version
42+
43+
- name: Create tag
44+
uses: rickstaa/action-create-tag@v1
45+
id: tag
46+
with:
47+
tag: 'v${{steps.version.outputs.release-version}}'
48+
tag_exists_error: true
49+
github_token: ${{ secrets.GITHUB_TOKEN }}
50+
51+
- name: Create pull request
52+
uses: devops-infra/action-pull-request@v0.5.5
53+
with:
54+
github_token: ${{ secrets.GITHUB_TOKEN }}
55+
target_branch: master
56+
title: Release v${{steps.version.outputs.release-version}}
57+
draft: false
58+
get_diff: true
59+
ignore_users: "dependabot"
60+
allow_no_diff: true
61+
62+
- name: Create the release
63+
uses: ncipollo/release-action@v1
64+
with:
65+
allowUpdates: true
66+
generateReleaseNotes: true
67+
name: 'v${{steps.version.outputs.release-version}}'
68+
tag: 'v${{steps.version.outputs.release-version}}'

.github/workflows/ci.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: continuous-integration
2+
run-name: Build pipeline after ${{github.event_name}} by @${{ github.actor }}
3+
4+
on:
5+
workflow_dispatch:
6+
7+
push:
8+
branches:
9+
- master
10+
- feature/**
11+
- bugfix/**
12+
13+
pull_request:
14+
branches:
15+
- feature/**
16+
- bugfix/**
17+
18+
jobs:
19+
continuous-integration:
20+
uses: ./.github/workflows/build.yml
21+
with:
22+
pack: false
23+
secrets: inherit

.github/workflows/dotnet-core.yml

Lines changed: 0 additions & 27 deletions
This file was deleted.

.github/workflows/publish.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: publish
2+
on:
3+
workflow_call:
4+
inputs:
5+
environment:
6+
type: string
7+
required: true
8+
9+
jobs:
10+
publish:
11+
environment: ${{ inputs.environment }}
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v3
16+
17+
- name: Download artifacts
18+
uses: actions/download-artifact@v3
19+
id: download
20+
with:
21+
name: 'packages'
22+
path: './packages'
23+
24+
- name: Publish packages
25+
uses: './.github/actions/dotnet/nuget'
26+
with:
27+
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
28+
packages-directory: '${{steps.download.outputs.download-path}}/${{ inputs.environment }}'

0 commit comments

Comments
 (0)