Skip to content

Commit 5b76014

Browse files
committed
update Github Actions & Workflows
- add ASP.NET.OTUS\.github\* - add Dockerfile.ci & global.json - add monorepo support - add .github\workflows\clean-ghcr.yml - add run Test in Docker fix .dockerignore tune Dockerfile tune docker-compose.Development.yml add coverage.runsettings + add package - add docker-compose.test.yml для тестирования опубликованного GHCR image
1 parent 6c0c5a6 commit 5b76014

12 files changed

Lines changed: 317 additions & 17 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: build-dotnet
2+
description: ".NET restore + build"
3+
4+
inputs:
5+
project-dir:
6+
description: "Project working directory"
7+
required: true
8+
9+
runs:
10+
using: composite
11+
steps:
12+
- name: Setup .NET SDK (from global.json)
13+
uses: actions/setup-dotnet@v4
14+
with:
15+
global-json-file: '${{ inputs.project-dir }}/global.json'
16+
17+
- name: Cache NuGet packages
18+
uses: actions/cache@v4
19+
with:
20+
path: ~/.nuget/packages
21+
key: ${{ runner.os }}-nuget-${{ hashFiles(format('{0}/**/*.csproj', inputs.project-dir), format('{0}/global.json', inputs.project-dir)) }}
22+
restore-keys: ${{ runner.os }}-nuget-
23+
24+
- name: Clean Release
25+
run: dotnet clean --configuration Release
26+
shell: bash
27+
working-directory: ${{ inputs.project-dir }}
28+
29+
- name: Restore
30+
run: dotnet restore
31+
shell: bash
32+
working-directory: ${{ inputs.project-dir }}
33+
34+
- name: Build Release (warnings as errors)
35+
run: dotnet build --configuration Release --no-restore -warnaserror
36+
shell: bash
37+
working-directory: ${{ inputs.project-dir }}

.github/workflows/cd.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Manual Deployment
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
image_tag:
7+
description: 'Tag to deploy'
8+
required: true
9+
default: 'latest'
10+
11+
env:
12+
REGISTRY: ghcr.io
13+
IMAGE_NAME: goodman74/asp.net.otus
14+
15+
jobs:
16+
cd-main-deploy:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Pull image
20+
run: docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ inputs.image_tag }}
21+
22+
- name: Run container
23+
run: docker run -d -p 8080:8080 ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.image_tag }}
24+
25+
- name: Health check
26+
run: |
27+
for i in {1..20}; do
28+
curl -f http://localhost:8080/api/v1/roles && exit 0
29+
sleep 1
30+
done
31+
exit 1

.github/workflows/ci.yml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Build, Test, Publish Image
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'Homeworks/06 Настройка CI/**'
8+
9+
concurrency:
10+
group: ci-main
11+
cancel-in-progress: false
12+
13+
env:
14+
REGISTRY: ghcr.io
15+
IMAGE_NAME: ${{ github.repository }}
16+
PROJECT_DIR: 'Homeworks/06 Настройка CI/src'
17+
18+
permissions:
19+
contents: read
20+
packages: write
21+
22+
jobs:
23+
build-test-push:
24+
runs-on: ubuntu-latest
25+
defaults:
26+
run:
27+
working-directory: ${{ env.PROJECT_DIR }}
28+
29+
steps:
30+
- name: Checkout
31+
uses: actions/checkout@v4
32+
33+
- name: Check working directory
34+
run: pwd
35+
36+
- name: Build-dotnet
37+
uses: ./.github/actions/build-dotnet
38+
with:
39+
project-dir: ${{ env.PROJECT_DIR }}
40+
41+
- name: Run tests
42+
run: |
43+
dotnet test --configuration Release --no-build --no-restore --collect:"XPlat Code Coverage" \
44+
--settings "PromoCodeFactory.UnitTests/coverage.runsettings" --logger "trx"
45+
46+
- name: Generate HTML Coverage Report
47+
uses: danielpalme/ReportGenerator-GitHub-Action@5
48+
with:
49+
reports: '${{ env.PROJECT_DIR }}/*/TestResults/*/coverage.cobertura.xml'
50+
targetdir: '${{ env.PROJECT_DIR }}/coveragereport'
51+
reporttypes: 'Html'
52+
53+
- name: Upload coverage report
54+
uses: actions/upload-artifact@v4
55+
with:
56+
name: coverage-html
57+
path: '${{ env.PROJECT_DIR }}/coveragereport/'
58+
59+
- name: Publish test results
60+
if: always()
61+
uses: actions/upload-artifact@v4
62+
with:
63+
name: test-results
64+
path: '${{ env.PROJECT_DIR }}/*/TestResults/*.trx'
65+
66+
- name: Log in to container registry
67+
uses: docker/login-action@v3
68+
with:
69+
registry: ${{ env.REGISTRY }}
70+
username: ${{ github.actor }}
71+
password: ${{ secrets.GITHUB_TOKEN }}
72+
73+
- name: Extract metadata (tags, labels)
74+
id: meta
75+
uses: docker/metadata-action@v5
76+
with:
77+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
78+
tags: |
79+
type=sha
80+
type=ref,event=branch
81+
type=ref,event=tag
82+
type=raw,value=latest,enable={{is_default_branch}}
83+
84+
- name: Build and push Docker image
85+
uses: docker/build-push-action@v6
86+
with:
87+
context: '${{ env.PROJECT_DIR }}'
88+
file: '${{ env.PROJECT_DIR }}/Dockerfile.ci'
89+
push: true
90+
tags: ${{ steps.meta.outputs.tags }}
91+
labels: ${{ steps.meta.outputs.labels }}

.github/workflows/clean-ghcr.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Cleanup GHCR
2+
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: '0 3 * * 0'
7+
8+
permissions:
9+
packages: write
10+
contents: read
11+
12+
jobs:
13+
cleanup:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Keep last 5 images (prune others)
18+
uses: actions/delete-package-versions@v5
19+
with:
20+
package-name: asp.net.otus
21+
package-type: container
22+
min-versions-to-keep: 5

Homeworks/06 Настройка CI/src/.dockerignore

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
**/values.dev.yaml
2626
LICENSE
2727
README.md
28-
!**/.gitignore
29-
!.git/HEAD
30-
!.git/config
31-
!.git/packed-refs
32-
!.git/refs/heads/**
28+
# Исключаем локальные артефакты (если есть)
29+
**/publish/
30+
**/TestResults/
Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,42 @@
1-
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
1+
ARG DOTNET_VERSION=10.0
2+
# -------- base runtime --------
3+
FROM mcr.microsoft.com/dotnet/aspnet:${DOTNET_VERSION} AS base
4+
WORKDIR /app
5+
EXPOSE 8080
26

7+
# ---------- build ----------
8+
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} AS build
39
ARG BUILD_CONFIGURATION=Release
410
WORKDIR /src
5-
COPY . .
11+
# скопировать файлы, которые управляют restore (чтобы улучшить кеш restore)
12+
COPY ./global.json ./
13+
COPY ./*.sln* ./
14+
COPY ./PromoCodeFactory.Core/PromoCodeFactory.Core.csproj ./PromoCodeFactory.Core/
15+
COPY ./PromoCodeFactory.DataAccess/PromoCodeFactory.DataAccess.csproj ./PromoCodeFactory.DataAccess/
16+
COPY ./PromoCodeFactory.WebHost/PromoCodeFactory.WebHost.csproj ./PromoCodeFactory.WebHost/
17+
COPY ./PromoCodeFactory.UnitTests/PromoCodeFactory.UnitTests.csproj ./PromoCodeFactory.UnitTests/
18+
619
RUN dotnet restore
20+
21+
# теперь весь код
22+
COPY ./PromoCodeFactory.Core/ ./PromoCodeFactory.Core/
23+
COPY ./PromoCodeFactory.DataAccess/ ./PromoCodeFactory.DataAccess/
24+
COPY ./PromoCodeFactory.WebHost/ ./PromoCodeFactory.WebHost/
25+
COPY ./PromoCodeFactory.UnitTests/ ./PromoCodeFactory.UnitTests/
26+
727
RUN dotnet build -c $BUILD_CONFIGURATION --no-restore
828

9-
FROM build AS publish
29+
# ---------- test ----------
30+
FROM build AS test
31+
RUN dotnet test --no-build --no-restore -c Release --collect:"XPlat Code Coverage" --settings PromoCodeFactory.UnitTests/coverage.runsettings \
32+
--logger "trx" --results-directory /test-results
33+
34+
# ---------- publish ----------
35+
FROM test AS publish
1036
ARG BUILD_CONFIGURATION=Release
1137
RUN dotnet publish ./PromoCodeFactory.WebHost/PromoCodeFactory.WebHost.csproj \
12-
-c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false --no-build
38+
-c $BUILD_CONFIGURATION -o /app/publish --no-build --no-restore
1339

14-
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final
15-
WORKDIR /app
40+
FROM base AS final
1641
COPY --from=publish /app/publish .
17-
EXPOSE 8080
1842
ENTRYPOINT ["dotnet", "PromoCodeFactory.WebHost.dll"]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
ARG DOTNET_VERSION=10.0
2+
# -------- base runtime --------
3+
FROM mcr.microsoft.com/dotnet/aspnet:${DOTNET_VERSION} AS base
4+
WORKDIR /app
5+
EXPOSE 8080
6+
7+
# ---------- build ----------
8+
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} AS build
9+
ARG BUILD_CONFIGURATION=Release
10+
WORKDIR /src
11+
# скопировать файлы, которые управляют restore (чтобы улучшить кеш restore)
12+
COPY ./global.json ./
13+
COPY ./*.sln* ./
14+
COPY ./PromoCodeFactory.Core/PromoCodeFactory.Core.csproj ./PromoCodeFactory.Core/
15+
COPY ./PromoCodeFactory.DataAccess/PromoCodeFactory.DataAccess.csproj ./PromoCodeFactory.DataAccess/
16+
COPY ./PromoCodeFactory.WebHost/PromoCodeFactory.WebHost.csproj ./PromoCodeFactory.WebHost/
17+
COPY ./PromoCodeFactory.UnitTests/PromoCodeFactory.UnitTests.csproj ./PromoCodeFactory.UnitTests/
18+
19+
RUN dotnet restore
20+
21+
# теперь весь код
22+
COPY ./PromoCodeFactory.Core/ ./PromoCodeFactory.Core/
23+
COPY ./PromoCodeFactory.DataAccess/ ./PromoCodeFactory.DataAccess/
24+
COPY ./PromoCodeFactory.WebHost/ ./PromoCodeFactory.WebHost/
25+
COPY ./PromoCodeFactory.UnitTests/ ./PromoCodeFactory.UnitTests/
26+
27+
RUN dotnet build -c $BUILD_CONFIGURATION --no-restore
28+
29+
# ---------- publish ----------
30+
FROM build AS publish
31+
RUN dotnet publish ./PromoCodeFactory.WebHost/PromoCodeFactory.WebHost.csproj \
32+
-c $BUILD_CONFIGURATION -o /app/publish --no-build --no-restore
33+
34+
FROM base AS final
35+
COPY --from=publish /app/publish .
36+
ENTRYPOINT ["dotnet", "PromoCodeFactory.WebHost.dll"]

Homeworks/06 Настройка CI/src/PromoCodeFactory.UnitTests/PromoCodeFactory.UnitTests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>net10.0</TargetFramework>
@@ -10,7 +10,7 @@
1010
<ItemGroup>
1111
<PackageReference Include="AwesomeAssertions" Version="9.4.0" />
1212
<PackageReference Include="Bogus" Version="35.6.5" />
13-
<PackageReference Include="coverlet.collector" Version="8.0.0">
13+
<PackageReference Include="coverlet.collector" Version="10.0.0">
1414
<PrivateAssets>all</PrivateAssets>
1515
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1616
</PackageReference>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<RunSettings>
3+
<DataCollectionRunSettings>
4+
<DataCollectors>
5+
<DataCollector friendlyName="XPlat Code Coverage">
6+
<Configuration>
7+
8+
<!-- Формат -->
9+
<Format>cobertura</Format>
10+
11+
<!-- Исключаем мусор -->
12+
<ExcludeByFile>**/obj/**,**/bin/**,**/*.g.cs,**/*.generated.cs</ExcludeByFile>
13+
14+
<!-- (опционально) исключение по namespace/типам -->
15+
<Exclude>
16+
[*]Program
17+
</Exclude>
18+
19+
</Configuration>
20+
</DataCollector>
21+
</DataCollectors>
22+
</DataCollectionRunSettings>
23+
</RunSettings>

Homeworks/06 Настройка CI/docker-compose.Development.yaml renamed to Homeworks/06 Настройка CI/src/docker-compose.Development.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
name: HW06_promocode
12
services:
23
promocode-factory-api:
3-
build: src/
4+
build:
5+
context: .
46
container_name: 'promocode-factory-api'
57
restart: always
68
ports:
@@ -10,6 +12,6 @@ services:
1012
environment:
1113
- "ConnectionStrings:PromocodeFactoryDb=Filename=/app/db/PromoCodeFactoryDb.sqlite"
1214
- "ASPNETCORE_ENVIRONMENT=Development"
13-
15+
1416
volumes:
15-
db:
17+
db:

0 commit comments

Comments
 (0)