Skip to content

Commit 0458d5e

Browse files
committed
feat(ci): add CI workflows for build, test, and release
1 parent 82cf4be commit 0458d5e

File tree

6 files changed

+400
-24
lines changed

6 files changed

+400
-24
lines changed

.github/release-drafter.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Release Drafter Configuration
2+
# Documentation: https://github.com/release-drafter/release-drafter
3+
4+
name-template: 'Version $RESOLVED_VERSION'
5+
tag-template: 'v$RESOLVED_VERSION'
6+
7+
# Categories for organizing release notes
8+
categories:
9+
- title: '🚀 Features'
10+
labels:
11+
- 'feature'
12+
- 'enhancement'
13+
- title: '🐛 Bug Fixes'
14+
labels:
15+
- 'bug'
16+
- 'fix'
17+
- title: '🔧 Maintenance'
18+
labels:
19+
- 'maintenance'
20+
- 'chore'
21+
- 'refactor'
22+
- 'dependencies'
23+
- title: '📚 Documentation'
24+
labels:
25+
- 'documentation'
26+
- 'docs'
27+
- title: '⚡ Performance'
28+
labels:
29+
- 'performance'
30+
- title: '🔒 Security'
31+
labels:
32+
- 'security'
33+
34+
# Exclude certain labels from release notes
35+
exclude-labels:
36+
- 'skip-changelog'
37+
- 'wip'
38+
39+
# Change template (how each PR is listed)
40+
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
41+
change-title-escapes: '\<*_&' # Escape special markdown characters
42+
43+
# Template for the release body
44+
template: |
45+
## What's Changed
46+
47+
$CHANGES
48+
49+
## 📦 NuGet Packages
50+
51+
The following packages are included in this release:
52+
53+
- `MyCSharp.HttpClientHints`
54+
- `MyCSharp.HttpClientHints.AspNetCore`
55+
56+
### Installation
57+
58+
```bash
59+
dotnet add package MyCSharp.HttpClientHints
60+
dotnet add package MyCSharp.HttpClientHints.AspNetCore
61+
```
62+
63+
## Contributors
64+
65+
$CONTRIBUTORS
66+
67+
---
68+
69+
**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION
70+
71+
# Automatically label PRs based on modified files
72+
autolabeler:
73+
- label: 'documentation'
74+
files:
75+
- '*.md'
76+
- 'docs/**/*'
77+
- label: 'bug'
78+
branch:
79+
- '/fix\/.+/'
80+
title:
81+
- '/fix/i'
82+
- label: 'feature'
83+
branch:
84+
- '/feature\/.+/'
85+
title:
86+
- '/feature/i'
87+
- label: 'dependencies'
88+
files:
89+
- '**/packages.lock.json'
90+
- '**/*.csproj'
91+
- 'Directory.Packages.props'
92+
- 'Directory.Build.props'
93+
- label: 'github-actions'
94+
files:
95+
- '.github/workflows/**/*'
96+
- label: 'tests'
97+
files:
98+
- 'tests/**/*'
99+
- '**/*Tests.cs'
100+
- '**/*Test.cs'
101+
- label: 'performance'
102+
files:
103+
- 'perf/**/*'
104+
- '**/*Benchmark*.cs'
105+
106+
# Version resolver (uses version from workflow input)
107+
version-resolver:
108+
default: patch
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
name: Build and Test (Reusable)
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
dotnet-version:
7+
description: '.NET version to use (can be multi-line for multiple versions)'
8+
required: false
9+
type: string
10+
default: |
11+
8.0.x
12+
9.0.x
13+
10.0.x
14+
configuration:
15+
description: 'Build configuration'
16+
required: false
17+
type: string
18+
default: 'Release'
19+
upload-test-results:
20+
description: 'Whether to upload test results as artifacts'
21+
required: false
22+
type: boolean
23+
default: false
24+
create-pack:
25+
description: 'Whether to pack NuGet packages'
26+
required: false
27+
type: boolean
28+
default: false
29+
outputs:
30+
version:
31+
description: 'The calculated version from NBGV'
32+
value: ${{ jobs.build.outputs.version }}
33+
34+
jobs:
35+
build:
36+
name: Build and Test
37+
runs-on: ubuntu-latest
38+
outputs:
39+
version: ${{ steps.nbgv.outputs.SemVer2 }}
40+
41+
steps:
42+
- name: Checkout code
43+
uses: actions/checkout@v6
44+
with:
45+
fetch-depth: 0 # Required for GitVersion
46+
47+
- name: Setup .NET
48+
uses: actions/setup-dotnet@v5
49+
with:
50+
dotnet-version: ${{ inputs.dotnet-version }}
51+
global-json-file: ./global.json
52+
53+
- name: Calculate Version with NBGV
54+
uses: dotnet/nbgv@master
55+
id: nbgv
56+
with:
57+
setAllVars: true
58+
59+
- name: Version Info
60+
run: |
61+
echo "Calculated version: ${{ steps.nbgv.outputs.SemVer2 }}"
62+
63+
- name: Restore dependencies
64+
run: dotnet restore
65+
66+
- name: Build
67+
run: dotnet build --configuration ${{ inputs.configuration }} --no-restore /p:Version=${{ steps.nbgv.outputs.SemVer2 }}
68+
69+
- name: Test
70+
run: dotnet test --configuration ${{ inputs.configuration }} --no-build --verbosity normal --logger "trx;LogFileName=test-results.trx"
71+
72+
- name: Upload test results
73+
if: always() && inputs.upload-test-results
74+
uses: actions/upload-artifact@v6
75+
with:
76+
name: test-results-${{ inputs.dotnet-version }}
77+
path: '**/TestResults/**/*.trx'
78+
79+
- name: Pack NuGet packages
80+
if: inputs.create-pack
81+
run: dotnet pack --configuration ${{ inputs.configuration }} --no-build --output ./artifacts /p:PackageVersion=${{ steps.nbgv.outputs.SemVer2 }}
82+
83+
- name: Upload NuGet packages
84+
if: inputs.create-pack
85+
uses: actions/upload-artifact@v6
86+
with:
87+
name: nuget-packages
88+
path: ./artifacts/*.nupkg
89+
retention-days: 30

.github/workflows/ci.yml

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

.github/workflows/main-build.yml

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Main Build
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
packages: write
11+
12+
jobs:
13+
build-and-test:
14+
name: Build, Test and Pack
15+
uses: ./.github/workflows/build-and-test.yml
16+
with:
17+
create-pack: true
18+
19+
create-draft-release:
20+
name: Create Draft Release
21+
needs: build-and-test
22+
runs-on: ubuntu-latest
23+
permissions:
24+
contents: write
25+
26+
steps:
27+
- name: Checkout code
28+
uses: actions/checkout@v6
29+
30+
- name: Download NuGet packages
31+
uses: actions/download-artifact@v4
32+
with:
33+
name: nuget-packages
34+
path: ./artifacts
35+
36+
- name: Check if tag exists
37+
id: check-tag
38+
run: |
39+
TAG="v${{ needs.build-and-test.outputs.version }}"
40+
if git rev-parse "$TAG" >/dev/null 2>&1; then
41+
echo "exists=true" >> $GITHUB_OUTPUT
42+
echo "⚠️ Tag $TAG already exists"
43+
else
44+
echo "exists=false" >> $GITHUB_OUTPUT
45+
echo "✅ Tag $TAG does not exist yet"
46+
fi
47+
48+
- name: Delete existing draft releases
49+
if: steps.check-tag.outputs.exists == 'false'
50+
env:
51+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52+
run: |
53+
echo "Checking for existing draft releases..."
54+
gh release list --json isDraft,tagName --jq '.[] | select(.isDraft) | .tagName' | while read -r tag_name; do
55+
echo "Deleting existing draft release: $tag_name"
56+
gh release delete "$tag_name" --yes --cleanup-tag || echo "Failed to delete release $tag_name"
57+
done
58+
59+
- name: Create Draft Release
60+
if: steps.check-tag.outputs.exists == 'false'
61+
uses: release-drafter/release-drafter@v6
62+
env:
63+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
64+
with:
65+
config-name: release-drafter.yml
66+
version: v${{ needs.build-and-test.outputs.version }}
67+
tag: v${{ needs.build-and-test.outputs.version }}
68+
name: Version ${{ needs.build-and-test.outputs.version }}
69+
publish: false
70+
prerelease: false
71+
72+
- name: Upload packages to draft release
73+
if: steps.check-tag.outputs.exists == 'false'
74+
env:
75+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76+
run: |
77+
TAG="v${{ needs.build-and-test.outputs.version }}"
78+
# Wait a moment for the release to be created
79+
sleep 2
80+
81+
# Upload new artifacts to the draft release
82+
echo "📦 Uploading new NuGet packages..."
83+
for file in ./artifacts/*.nupkg; do
84+
gh release upload "$TAG" "$file" --clobber
85+
done
86+
echo "✅ Uploaded NuGet packages to draft release"
87+
88+
- name: Summary
89+
if: steps.check-tag.outputs.exists == 'false'
90+
run: |
91+
echo "✅ Draft release created/updated" >> $GITHUB_STEP_SUMMARY
92+
echo "Version: v${{ needs.build-and-test.outputs.version }}" >> $GITHUB_STEP_SUMMARY
93+
echo "" >> $GITHUB_STEP_SUMMARY
94+
echo "### Next steps:" >> $GITHUB_STEP_SUMMARY
95+
echo "1. Go to [Releases](../../releases)" >> $GITHUB_STEP_SUMMARY
96+
echo "2. Review the draft release" >> $GITHUB_STEP_SUMMARY
97+
echo "3. Edit release notes if needed" >> $GITHUB_STEP_SUMMARY
98+
echo "4. Publish release to trigger production deployment" >> $GITHUB_STEP_SUMMARY
99+
100+
- name: Release already exists
101+
if: steps.check-tag.outputs.exists == 'true'
102+
run: |
103+
echo "ℹ️ Release v${{ needs.build-and-test.outputs.version }} already exists" >> $GITHUB_STEP_SUMMARY
104+
echo "No action taken" >> $GITHUB_STEP_SUMMARY
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: PR Validation
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: read
10+
pull-requests: read
11+
12+
jobs:
13+
validate-dotnet-8:
14+
name: Test on .NET 8.0
15+
uses: ./.github/workflows/build-and-test.yml
16+
with:
17+
dotnet-version: '8.0.x'
18+
upload-test-results: true
19+
20+
validate-dotnet-9:
21+
name: Test on .NET 9.0
22+
uses: ./.github/workflows/build-and-test.yml
23+
with:
24+
dotnet-version: '9.0.x'
25+
upload-test-results: true
26+
27+
validate-dotnet-10:
28+
name: Test on .NET 10.0
29+
uses: ./.github/workflows/build-and-test.yml
30+
with:
31+
dotnet-version: '10.0.x'
32+
upload-test-results: true

0 commit comments

Comments
 (0)