Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 200 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,210 @@ on:
workflow_dispatch:
inputs:
version:
description: 'Version to bump to (e.g. 2.6.0). Only used by manual trigger.'
description: 'Version to bump to (e.g. 3.0.0). Only used by manual trigger.'
required: true
default: '2.6.0'
default: '3.0.0'

permissions:
contents: write
pull-requests: write
id-token: write

jobs:
# ---------------------------------------------------------------------------
# Quality gates. These MUST pass before any package is published or any
# GitHub Release is created. Every downstream publish job depends on the
# `quality-gate` aggregation job via `needs:`, so a failure in any gate
# short-circuits the whole release: no NuGet/MyGet push, no GitHub Release.
#
# The gates mirror the PR CI pipeline (.github/workflows/build-pr-ci.yml) and
# reuse the exact same coverage script (.github/scripts/check-coverage.sh)
# so thresholds stay identical and cannot drift:
# Unit 95% / E2E 80% / NativeAOT Unit 100% / NativeAOT E2E 95%.
# ---------------------------------------------------------------------------
lint:
name: Lint (Release gate)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
10.0.x
- name: Lint (dotnet format)
shell: bash
run: |
dotnet format AspectCore-Framework.sln --verify-no-changes --verbosity diagnostic

unit-coverage:
name: Unit Coverage (Release gate)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
10.0.x
- name: Collect unit test coverage
shell: bash
run: |
chmod +x ./.github/scripts/check-coverage.sh
./.github/scripts/check-coverage.sh collect unit --output coverage-results/unit.env
- name: Assert unit coverage (min 95%)
shell: bash
run: |
./.github/scripts/check-coverage.sh assert unit --input coverage-results/unit.env

e2e-coverage:
name: E2E Coverage (Release gate)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
10.0.x
- name: Collect E2E test coverage
shell: bash
run: |
chmod +x ./.github/scripts/check-coverage.sh
./.github/scripts/check-coverage.sh collect e2e --output coverage-results/e2e.env
- name: Assert E2E coverage (min 80%)
shell: bash
run: |
./.github/scripts/check-coverage.sh assert e2e --input coverage-results/e2e.env

nativeaot-coverage:
name: NativeAOT Coverage (Release gate)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
10.0.x
- name: Collect NativeAOT unit coverage
shell: bash
run: |
chmod +x ./.github/scripts/check-coverage.sh
./.github/scripts/check-coverage.sh collect nativeaot-unit --output coverage-results/nativeaot-unit.env
- name: Collect NativeAOT E2E coverage
shell: bash
run: |
./.github/scripts/check-coverage.sh collect nativeaot-e2e --output coverage-results/nativeaot-e2e.env
- name: Assert NativeAOT unit coverage (min 100%)
shell: bash
run: |
./.github/scripts/check-coverage.sh assert nativeaot-unit --input coverage-results/nativeaot-unit.env
- name: Assert NativeAOT E2E coverage (min 95%)
shell: bash
run: |
./.github/scripts/check-coverage.sh assert nativeaot-e2e --input coverage-results/nativeaot-e2e.env

nativeaot-verify:
name: NativeAOT Publish + Run (Release gate)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
10.0.x
- name: Restore dependencies
run: dotnet restore AspectCore-Framework.sln
- name: Build solution
run: dotnet build AspectCore-Framework.sln -c Release --no-restore
- name: Publish NativeAOT E2E (self-contained AOT binary)
run: dotnet publish tests/AspectCore.NativeAot.E2E/AspectCore.NativeAot.E2E.csproj -c Release -r linux-x64 -o ./publish-aot --no-restore
- name: Run NativeAOT E2E binary
run: ./publish-aot/AspectCore.NativeAot.E2E

codeql:
name: CodeQL (Release gate)
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
10.0.x
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: csharp
- name: Build for CodeQL
shell: bash
run: |
for project in $(find ./src -name "*.csproj"); do
dotnet build --configuration Release $project
done
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:csharp"

quality-gate:
name: Quality Gate (all checks passed)
runs-on: ubuntu-latest
needs:
- lint
- unit-coverage
- e2e-coverage
- nativeaot-coverage
- nativeaot-verify
- codeql
steps:
- name: All quality gates passed
run: echo "All release quality gates passed. Proceeding to package and publish."

build-and-test:
# Publishing is gated: this job (and therefore NuGet/MyGet push and the
# GitHub Release created within it) only runs after every quality gate
# succeeds. If quality-gate fails, this job is skipped and nothing ships.
needs: quality-gate
permissions:
id-token: write
contents: write
Expand Down Expand Up @@ -197,8 +390,12 @@ jobs:
generate_release_notes: true

update-version:
# Runs only after a successful publish (build-and-test). Combined with the
# quality-gate chain, the version bump PR is never opened when a release
# was blocked by a failing gate or a failed publish.
# For tag pushes: only bump version for stable releases (not pre-releases like beta/rc/alpha)
# For manual trigger: always run
# For manual trigger: always run (subject to build-and-test success)
needs: build-and-test
if: ${{ github.event_name == 'workflow_dispatch' || !contains(github.ref_name, '-') }}
runs-on: ubuntu-latest
steps:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ DocProject/Help/html
# Click-Once directory
publish/

# NativeAOT publish output
publish-aot/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
Expand Down
9 changes: 7 additions & 2 deletions build/common.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
<PropertyGroup>
<Authors>Lemon</Authors>
<Product>AspectCore Framework</Product>
<PackageIconUrl>https://avatars1.githubusercontent.com/u/19426425?v=3&amp;s=200</PackageIconUrl>
<PackageIcon>icon.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageProjectUrl>https://github.com/dotnetcore/AspectCore-Framework</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/dotnetcore/AspectCore-Framework/blob/dev/LICENSE</PackageLicenseUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/dotnetcore/AspectCore-Framework</RepositoryUrl>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
Expand All @@ -18,4 +19,8 @@
needed for NativeAOT AOP support while remaining compatible with net6.0 as the lowest TFM -->
<LangVersion>13.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)../icon.png" Pack="true" PackagePath="\" Visible="false" />
<None Include="$(MSBuildThisFileDirectory)../README.md" Pack="true" PackagePath="\" Visible="false" />
</ItemGroup>
</Project>
10 changes: 10 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- [安装](./getting-started/installation.md) — NuGet 包与目标框架
- [快速上手](./getting-started/quick-start.md) — 五分钟跑通第一个拦截器
- [核心概念](./getting-started/concepts.md) — 拦截器、代理、切面上下文等术语
- [NativeAOT 上手](./getting-started/nativeaot.md) — 把使用 AspectCore 的应用发布成 NativeAOT 原生二进制

### 📖 使用指南(guide)
面向日常开发的功能说明。
Expand All @@ -26,6 +27,8 @@
- [数据校验](./guide/data-validation.md) — DataAnnotations 校验拦截
- [反射扩展](./guide/reflection-extensions.md) — AspectCore.Extensions.Reflection 高性能反射
- [常见场景](./guide/common-scenarios.md) — 日志、缓存、重试、性能监控等
- [从 2.x 升级到 3.0](./guide/upgrade-to-3.0.md) — 升级前提、破坏性变更、升级步骤与常见问题
- [Source Generator 诊断目录](./guide/source-generator-diagnostics.md) — ACSGxxx 诊断的含义、触发条件与修复

### 🏛 架构设计(architecture)
面向贡献者与深度使用者的设计文档。
Expand All @@ -46,11 +49,18 @@
- [贡献指南](./development/contributing.md) — 分支、提交、PR 流程
- [开发规范](./development/development-guidelines.md) — 工程结构识别、命令粒度、测试、性能、设计原则
- [Code Review 规范](./development/code-review-guidelines.md) — Review 维度、BLOCKING 问题、自查清单
- [GA 发布流程](./development/release-process.md) — 正式版发布的步骤与门禁

### ✅ 测试(testing)
- [测试策略](./testing/testing-strategy.md) — 单元、双引擎一致性、E2E、覆盖率门槛
- [运行测试](./testing/running-tests.md) — 如何运行与筛选测试

### 📦 发布说明(release-notes)
每个大版本的发布记录。

- [v3.0.0 变更日志](./release-notes/v3.0.0-changelog.md) — 结构化变更清单(特性 / 性能 / 修复 / 破坏性变更 / 工程)
- [v3.0.0 发布叙事](./release-notes/v3.0.0.md) — 发布背景与研发过程的叙事版本

## 版本说明

本文档基于源码扫描生成,力求与代码一致。文中区分「已实现能力」与「设计/提案」,未实现的内容会显式标注。产品版本见 `build/version.props`。
Loading
Loading