Skip to content

Commit 837335e

Browse files
ci: Setup CI/CD pipeline with GitHub Actions
- Add CI workflow (ci.yml): - Build & test on push/PR to main/develop - Code coverage reporting with Cobertura - Security vulnerability scanning - Test result artifacts - Add Docker workflow (docker.yml): - Build and push to GitHub Container Registry - Multi-platform support (linux/amd64) - SBOM generation for security - Semantic versioning tags - Add Release workflow (release.yml): - Automated GitHub releases on version tags - Changelog generation from PRs - Release artifact (ZIP) creation - Add Dependabot configuration: - Weekly NuGet package updates - Weekly GitHub Actions updates - Weekly Docker base image updates - Add PR template for consistent reviews - Add CI/CD documentation (docs/CI-CD.md) JIRA: BD-691 Epic: BD-689 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent c6691f2 commit 837335e

File tree

6 files changed

+476
-0
lines changed

6 files changed

+476
-0
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Summary
2+
3+
Brief description of changes.
4+
5+
## JIRA Ticket
6+
7+
[BD-XXX](https://printerpix.atlassian.net/browse/BD-XXX)
8+
9+
## Changes
10+
11+
- Change 1
12+
- Change 2
13+
- Change 3
14+
15+
## Type of Change
16+
17+
- [ ] Bug fix (non-breaking change which fixes an issue)
18+
- [ ] New feature (non-breaking change which adds functionality)
19+
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
20+
- [ ] Documentation update
21+
- [ ] Refactoring (no functional changes)
22+
23+
## Testing
24+
25+
- [ ] Unit tests added/updated
26+
- [ ] Integration tests added/updated
27+
- [ ] Manual testing completed
28+
29+
## Checklist
30+
31+
- [ ] Code follows project style guidelines
32+
- [ ] Self-review completed
33+
- [ ] Tests pass locally
34+
- [ ] No new warnings introduced
35+
- [ ] Documentation updated (if needed)

.github/dependabot.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
version: 2
2+
updates:
3+
# NuGet packages
4+
- package-ecosystem: "nuget"
5+
directory: "/"
6+
schedule:
7+
interval: "weekly"
8+
day: "monday"
9+
open-pull-requests-limit: 5
10+
labels:
11+
- "dependencies"
12+
- "nuget"
13+
commit-message:
14+
prefix: "chore(deps)"
15+
16+
# GitHub Actions
17+
- package-ecosystem: "github-actions"
18+
directory: "/"
19+
schedule:
20+
interval: "weekly"
21+
day: "monday"
22+
open-pull-requests-limit: 3
23+
labels:
24+
- "dependencies"
25+
- "github-actions"
26+
commit-message:
27+
prefix: "chore(ci)"
28+
29+
# Docker
30+
- package-ecosystem: "docker"
31+
directory: "/"
32+
schedule:
33+
interval: "weekly"
34+
day: "monday"
35+
open-pull-requests-limit: 2
36+
labels:
37+
- "dependencies"
38+
- "docker"
39+
commit-message:
40+
prefix: "chore(docker)"

.github/workflows/ci.yml

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
env:
10+
DOTNET_VERSION: '8.0.x'
11+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
12+
DOTNET_CLI_TELEMETRY_OPTOUT: true
13+
14+
jobs:
15+
build:
16+
name: Build & Test
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Setup .NET
24+
uses: actions/setup-dotnet@v4
25+
with:
26+
dotnet-version: ${{ env.DOTNET_VERSION }}
27+
28+
- name: Restore dependencies
29+
run: dotnet restore
30+
31+
- name: Build
32+
run: dotnet build --no-restore --configuration Release
33+
34+
- name: Run Unit Tests
35+
run: |
36+
dotnet test tests/OrderMonitor.UnitTests/OrderMonitor.UnitTests.csproj \
37+
--no-build \
38+
--configuration Release \
39+
--logger "trx;LogFileName=unit-test-results.trx" \
40+
--collect:"XPlat Code Coverage" \
41+
--results-directory ./TestResults
42+
43+
- name: Run Integration Tests
44+
run: |
45+
dotnet test tests/OrderMonitor.IntegrationTests/OrderMonitor.IntegrationTests.csproj \
46+
--no-build \
47+
--configuration Release \
48+
--logger "trx;LogFileName=integration-test-results.trx" \
49+
--results-directory ./TestResults
50+
51+
- name: Upload Test Results
52+
uses: actions/upload-artifact@v4
53+
if: always()
54+
with:
55+
name: test-results
56+
path: ./TestResults
57+
retention-days: 7
58+
59+
- name: Upload Coverage Report
60+
uses: actions/upload-artifact@v4
61+
if: always()
62+
with:
63+
name: coverage-report
64+
path: ./TestResults/**/coverage.cobertura.xml
65+
retention-days: 7
66+
67+
- name: Code Coverage Summary
68+
uses: irongut/CodeCoverageSummary@v1.3.0
69+
if: always()
70+
with:
71+
filename: ./TestResults/**/coverage.cobertura.xml
72+
badge: true
73+
format: markdown
74+
output: both
75+
thresholds: '60 80'
76+
77+
lint:
78+
name: Code Analysis
79+
runs-on: ubuntu-latest
80+
81+
steps:
82+
- name: Checkout code
83+
uses: actions/checkout@v4
84+
85+
- name: Setup .NET
86+
uses: actions/setup-dotnet@v4
87+
with:
88+
dotnet-version: ${{ env.DOTNET_VERSION }}
89+
90+
- name: Restore dependencies
91+
run: dotnet restore
92+
93+
- name: Run Code Analysis
94+
run: dotnet build --no-restore --configuration Release /p:TreatWarningsAsErrors=false
95+
96+
security:
97+
name: Security Scan
98+
runs-on: ubuntu-latest
99+
100+
steps:
101+
- name: Checkout code
102+
uses: actions/checkout@v4
103+
104+
- name: Setup .NET
105+
uses: actions/setup-dotnet@v4
106+
with:
107+
dotnet-version: ${{ env.DOTNET_VERSION }}
108+
109+
- name: Restore dependencies
110+
run: dotnet restore
111+
112+
- name: Run Security Audit
113+
run: dotnet list package --vulnerable --include-transitive 2>&1 | tee security-report.txt
114+
115+
- name: Upload Security Report
116+
uses: actions/upload-artifact@v4
117+
if: always()
118+
with:
119+
name: security-report
120+
path: security-report.txt
121+
retention-days: 7

.github/workflows/docker.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Docker Build & Push
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ['v*']
7+
workflow_dispatch:
8+
9+
env:
10+
REGISTRY: ghcr.io
11+
IMAGE_NAME: ${{ github.repository }}
12+
13+
jobs:
14+
build-and-push:
15+
name: Build & Push Docker Image
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
packages: write
20+
21+
steps:
22+
- name: Checkout code
23+
uses: actions/checkout@v4
24+
25+
- name: Set up Docker Buildx
26+
uses: docker/setup-buildx-action@v3
27+
28+
- name: Log in to Container Registry
29+
uses: docker/login-action@v3
30+
with:
31+
registry: ${{ env.REGISTRY }}
32+
username: ${{ github.actor }}
33+
password: ${{ secrets.GITHUB_TOKEN }}
34+
35+
- name: Extract metadata
36+
id: meta
37+
uses: docker/metadata-action@v5
38+
with:
39+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
40+
tags: |
41+
type=ref,event=branch
42+
type=ref,event=pr
43+
type=semver,pattern={{version}}
44+
type=semver,pattern={{major}}.{{minor}}
45+
type=sha,prefix=sha-
46+
47+
- name: Build and push Docker image
48+
uses: docker/build-push-action@v5
49+
with:
50+
context: .
51+
push: ${{ github.event_name != 'pull_request' }}
52+
tags: ${{ steps.meta.outputs.tags }}
53+
labels: ${{ steps.meta.outputs.labels }}
54+
cache-from: type=gha
55+
cache-to: type=gha,mode=max
56+
platforms: linux/amd64
57+
58+
- name: Generate SBOM
59+
uses: anchore/sbom-action@v0
60+
if: github.event_name != 'pull_request'
61+
with:
62+
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ github.sha }}
63+
format: spdx-json
64+
output-file: sbom.spdx.json
65+
66+
- name: Upload SBOM
67+
uses: actions/upload-artifact@v4
68+
if: github.event_name != 'pull_request'
69+
with:
70+
name: sbom
71+
path: sbom.spdx.json
72+
retention-days: 30

.github/workflows/release.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags: ['v*']
6+
7+
env:
8+
DOTNET_VERSION: '8.0.x'
9+
10+
jobs:
11+
release:
12+
name: Create Release
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: write
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Setup .NET
24+
uses: actions/setup-dotnet@v4
25+
with:
26+
dotnet-version: ${{ env.DOTNET_VERSION }}
27+
28+
- name: Restore dependencies
29+
run: dotnet restore
30+
31+
- name: Build Release
32+
run: dotnet build --configuration Release --no-restore
33+
34+
- name: Run Tests
35+
run: dotnet test --configuration Release --no-build
36+
37+
- name: Publish Application
38+
run: |
39+
dotnet publish src/OrderMonitor.Api/OrderMonitor.Api.csproj \
40+
--configuration Release \
41+
--output ./publish \
42+
--no-build
43+
44+
- name: Create Release Archive
45+
run: |
46+
cd publish
47+
zip -r ../OrderMonitor.Api-${{ github.ref_name }}.zip .
48+
49+
- name: Generate Changelog
50+
id: changelog
51+
uses: mikepenz/release-changelog-builder-action@v4
52+
with:
53+
configuration: |
54+
{
55+
"categories": [
56+
{
57+
"title": "## Features",
58+
"labels": ["feature", "enhancement"]
59+
},
60+
{
61+
"title": "## Bug Fixes",
62+
"labels": ["bug", "fix"]
63+
},
64+
{
65+
"title": "## Documentation",
66+
"labels": ["documentation"]
67+
},
68+
{
69+
"title": "## Other Changes",
70+
"labels": []
71+
}
72+
]
73+
}
74+
env:
75+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76+
77+
- name: Create GitHub Release
78+
uses: softprops/action-gh-release@v1
79+
with:
80+
body: ${{ steps.changelog.outputs.changelog }}
81+
files: |
82+
OrderMonitor.Api-${{ github.ref_name }}.zip
83+
draft: false
84+
prerelease: ${{ contains(github.ref_name, '-') }}
85+
env:
86+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)