From f8b7ad0cc323a891a243ab2c2fd50b785b9b5a98 Mon Sep 17 00:00:00 2001
From: Willy <63505597+willysoft@users.noreply.github.com>
Date: Fri, 18 Apr 2025 13:36:41 +0800
Subject: [PATCH] ci: add GitHub Actions workflow for automated releases
- Add build-release.yml for CI/CD pipeline with semantic versioning
- Configure semantic-release with .releaserc.json
- Mark sample projects as non-packable
- Include README and LICENSE in NuGet packages
- Fix documentation comments and null annotations
---
.github/workflows/build-release.yml | 105 ++++++++++++++++++
.releaserc.json | 12 ++
.../AutoQueryApiDemo/AutoQueryApiDemo.csproj | 1 +
sample/AutoQueryDemo/AutoQueryDemo.csproj | 1 +
.../AutoQuery.AspNetCore.csproj | 7 +-
.../AutoQueryServiceExtensions.cs | 1 +
.../EnableFieldProjectionAttribute.cs | 1 +
test/AutoQuery.Tests/QueryProcessorTests.cs | 4 +-
8 files changed, 129 insertions(+), 3 deletions(-)
create mode 100644 .github/workflows/build-release.yml
create mode 100644 .releaserc.json
diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
new file mode 100644
index 0000000..9a148fe
--- /dev/null
+++ b/.github/workflows/build-release.yml
@@ -0,0 +1,105 @@
+name: build-release
+
+on:
+ workflow_dispatch:
+ inputs:
+ # nuget
+ nuget-push:
+ description: "nuget-push: true = upload nuget package. false = not upload"
+ required: false
+ type: boolean
+ default: true
+
+jobs:
+ test-dotnet:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-dotnet@v4
+ # test
+ - run: dotnet test -c Release
+
+ create-release:
+ needs: [test-dotnet]
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ outputs:
+ new_release_published: ${{ steps.semantic.outputs.new_release_published }}
+ new_release_version: ${{ steps.semantic.outputs.new_release_version }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Semantic Release
+ uses: cycjimmy/semantic-release-action@v4
+ id: semantic
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ create-nuget-package:
+ needs: [create-release]
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ if: needs.create-release.outputs.new_release_published == 'true'
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-dotnet@v4
+ # build and pack
+ - run: dotnet build -c Release -p:Version=${{ needs.create-release.outputs.new_release_version }}
+ - run: dotnet pack -c Release --no-build -p:Version=${{ needs.create-release.outputs.new_release_version }} -o ./publish
+ # Store artifacts.
+ - uses: actions/upload-artifact@v4
+ with:
+ name: nuget
+ path: ./publish/
+ retention-days: 1
+
+ push-nuget-package:
+ needs: [create-nuget-package]
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ if: needs.create-release.outputs.new_release_published == 'true'
+ env:
+ NUGET_PATH: |
+ ./*.nupkg
+ ./*.snupkg
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-dotnet@v4
+
+ # Download(All) Artifacts to current directory
+ - uses: actions/download-artifact@v4
+ with:
+ name: nuget
+ - name: Show download aritifacts
+ run: ls -lR
+ - name: Validate package exists in artifact - NuGet
+ run: |
+ while read -r nuget_path; do
+ if [[ "${nuget_path}" == "" ]]; then continue; fi
+ # shellcheck disable=SC2086
+ if ! ls -l ${nuget_path}; then
+ echo "Specified nuget package not found. path: $nuget_path"
+ if [[ "${nuget_path}" == *.nupkg ]]; then
+ echo ".nupkg must be included in the artifact."
+ exit 1
+ fi
+ fi
+ done <<< "${NUGET_PATH}"
+
+ # Upload to NuGet
+ - name: Upload to NuGet
+ if: ${{ inputs.nuget-push }}
+ run: |
+ while read -r nuget_path; do
+ if [[ "$nuget_path" == "" ]]; then continue; fi
+ # shellcheck disable=SC2086
+ if ! ls -l ${nuget_path} >/dev/null 2>&1;then
+ echo "skipping nuget push, $nuget_path not found."
+ continue
+ fi
+
+ dotnet nuget push "${nuget_path}" --skip-duplicate -s https://api.nuget.org/v3/index.json -k "${NUGET_KEY}"
+ done <<< "${NUGET_PATH}"
+ env:
+ NUGET_KEY: ${{ secrets.PS_NUGET_KEY }}
diff --git a/.releaserc.json b/.releaserc.json
new file mode 100644
index 0000000..c1cd335
--- /dev/null
+++ b/.releaserc.json
@@ -0,0 +1,12 @@
+{
+ "plugins": [
+ "@semantic-release/commit-analyzer",
+ "@semantic-release/release-notes-generator",
+ [
+ "@semantic-release/github"
+ ]
+ ],
+ "branches": [
+ "main"
+ ]
+}
\ No newline at end of file
diff --git a/sample/AutoQueryApiDemo/AutoQueryApiDemo.csproj b/sample/AutoQueryApiDemo/AutoQueryApiDemo.csproj
index 6c4b467..53bcb94 100644
--- a/sample/AutoQueryApiDemo/AutoQueryApiDemo.csproj
+++ b/sample/AutoQueryApiDemo/AutoQueryApiDemo.csproj
@@ -4,6 +4,7 @@
net8.0
enable
enable
+ false
diff --git a/sample/AutoQueryDemo/AutoQueryDemo.csproj b/sample/AutoQueryDemo/AutoQueryDemo.csproj
index c8bd435..a5fe224 100644
--- a/sample/AutoQueryDemo/AutoQueryDemo.csproj
+++ b/sample/AutoQueryDemo/AutoQueryDemo.csproj
@@ -5,6 +5,7 @@
net8.0
enable
enable
+ false
diff --git a/src/AutoQuery.AspNetCore/AutoQuery.AspNetCore.csproj b/src/AutoQuery.AspNetCore/AutoQuery.AspNetCore.csproj
index db432a5..18b6102 100644
--- a/src/AutoQuery.AspNetCore/AutoQuery.AspNetCore.csproj
+++ b/src/AutoQuery.AspNetCore/AutoQuery.AspNetCore.csproj
@@ -36,5 +36,10 @@
-
+
+
+
+
+
+
diff --git a/src/AutoQuery.AspNetCore/AutoQueryServiceExtensions.cs b/src/AutoQuery.AspNetCore/AutoQueryServiceExtensions.cs
index 56f19bc..b38658a 100644
--- a/src/AutoQuery.AspNetCore/AutoQueryServiceExtensions.cs
+++ b/src/AutoQuery.AspNetCore/AutoQueryServiceExtensions.cs
@@ -16,6 +16,7 @@ public static class AutoQueryServiceExtensions
/// 向服務集合中添加查詢建構器服務。
///
/// 服務集合。
+ /// 要應用配置的程序集。
/// 更新後的服務集合。
public static IServiceCollection AddAutoQuery(this IServiceCollection services, Assembly assembly)
{
diff --git a/src/AutoQuery.AspNetCore/EnableFieldProjectionAttribute.cs b/src/AutoQuery.AspNetCore/EnableFieldProjectionAttribute.cs
index 3157ae9..8921855 100644
--- a/src/AutoQuery.AspNetCore/EnableFieldProjectionAttribute.cs
+++ b/src/AutoQuery.AspNetCore/EnableFieldProjectionAttribute.cs
@@ -99,6 +99,7 @@ private static object FilterResult(object value, HashSet selectedFields,
/// 要過濾的物件。
/// 選擇的字段集合。
/// JSON 序列化選項。
+ /// 是否僅過濾第一層屬性。
/// 過濾後的字典。
private static Dictionary FilterObject(object value, HashSet selectedFields, JsonSerializerOptions serializerOptions, bool firstLevelOnly = false)
{
diff --git a/test/AutoQuery.Tests/QueryProcessorTests.cs b/test/AutoQuery.Tests/QueryProcessorTests.cs
index a945519..13c48f9 100644
--- a/test/AutoQuery.Tests/QueryProcessorTests.cs
+++ b/test/AutoQuery.Tests/QueryProcessorTests.cs
@@ -121,9 +121,9 @@ public class TestQueryOptions : IQueryOptions
public class TestData
{
- public string Name { get; set; }
+ public string Name { get; set; } = null!;
public int Age { get; set; }
- public string Address { get; set; }
+ public string Address { get; set; } = null!;
}
public class UserQueryConfiguration : IFilterQueryConfiguration