Skip to content

Commit 77d879e

Browse files
committed
auto release csharp
1 parent 9c82aaa commit 77d879e

1 file changed

Lines changed: 193 additions & 0 deletions

File tree

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
name: Publish C#
19+
run-name: "C# Release: ${{ github.ref_name }}"
20+
21+
on:
22+
push:
23+
tags: ['v*']
24+
25+
permissions:
26+
contents: read
27+
id-token: write
28+
29+
concurrency:
30+
group: release-csharp-${{ github.ref }}
31+
cancel-in-progress: false
32+
33+
jobs:
34+
publish-csharp:
35+
runs-on: ubuntu-latest
36+
if: github.repository == 'apache/fory'
37+
env:
38+
NUGET_SOURCE: https://api.nuget.org/v3/index.json
39+
steps:
40+
- uses: actions/checkout@v5
41+
42+
- uses: actions/setup-python@v6
43+
with:
44+
python-version: '3.11'
45+
cache: 'pip'
46+
47+
- name: Bump C# version
48+
shell: bash
49+
run: |
50+
set -euo pipefail
51+
VERSION="${{ github.ref_name }}"
52+
VERSION="${VERSION#v}"
53+
python ci/release.py bump_version -l csharp -version "$VERSION"
54+
55+
- name: Set up .NET 8
56+
uses: actions/setup-dotnet@v5
57+
with:
58+
dotnet-version: "8.0.x"
59+
cache: true
60+
cache-dependency-path: |
61+
csharp/**/*.csproj
62+
csharp/Fory.sln
63+
64+
- name: Restore C# dependencies
65+
shell: bash
66+
working-directory: csharp
67+
run: |
68+
set -euo pipefail
69+
dotnet restore Fory.sln
70+
71+
- name: Build C# solution
72+
shell: bash
73+
working-directory: csharp
74+
run: |
75+
set -euo pipefail
76+
dotnet build Fory.sln -c Release --no-restore
77+
78+
- name: Run C# tests
79+
shell: bash
80+
working-directory: csharp
81+
run: |
82+
set -euo pipefail
83+
dotnet test Fory.sln -c Release --no-build
84+
85+
- name: Pack Apache.Fory
86+
shell: bash
87+
working-directory: csharp
88+
run: |
89+
set -euo pipefail
90+
rm -rf artifacts/nuget
91+
mkdir -p artifacts/nuget
92+
dotnet pack src/Fory/Fory.csproj \
93+
-c Release \
94+
--no-restore \
95+
-o artifacts/nuget \
96+
-p:ContinuousIntegrationBuild=true
97+
98+
- name: Verify packed artifacts
99+
shell: bash
100+
working-directory: csharp
101+
run: |
102+
set -euo pipefail
103+
VERSION="${{ github.ref_name }}"
104+
VERSION="${VERSION#v}"
105+
test -f "artifacts/nuget/Apache.Fory.$VERSION.nupkg"
106+
test -f "artifacts/nuget/Apache.Fory.$VERSION.snupkg"
107+
ls -l artifacts/nuget
108+
109+
- name: Exchange GitHub OIDC token for NuGet API key
110+
id: nuget-login
111+
shell: bash
112+
env:
113+
NUGET_AUDIENCE: https://www.nuget.org
114+
NUGET_TOKEN_SERVICE_URL: https://www.nuget.org/api/v2/token
115+
run: |
116+
set -euo pipefail
117+
if [[ -z "${ACTIONS_ID_TOKEN_REQUEST_TOKEN:-}" || -z "${ACTIONS_ID_TOKEN_REQUEST_URL:-}" ]]; then
118+
echo "GitHub OIDC token exchange is unavailable. Ensure the job has id-token: write permission." >&2
119+
exit 1
120+
fi
121+
python <<'PY'
122+
import json
123+
import os
124+
import urllib.error
125+
import urllib.parse
126+
import urllib.request
127+
128+
def fetch_json(url: str, headers: dict[str, str], data: bytes | None = None) -> dict:
129+
request = urllib.request.Request(url, data=data, headers=headers)
130+
try:
131+
with urllib.request.urlopen(request) as response:
132+
return json.load(response)
133+
except urllib.error.HTTPError as error:
134+
body = error.read().decode("utf-8", errors="replace")
135+
raise SystemExit(f"HTTP {error.code} from {url}: {body}") from error
136+
137+
request_token = os.environ["ACTIONS_ID_TOKEN_REQUEST_TOKEN"]
138+
request_url = os.environ["ACTIONS_ID_TOKEN_REQUEST_URL"]
139+
audience = os.environ["NUGET_AUDIENCE"]
140+
token_service_url = os.environ["NUGET_TOKEN_SERVICE_URL"]
141+
142+
print(f"::add-mask::{request_token}")
143+
144+
oidc_response = fetch_json(
145+
f"{request_url}&audience={urllib.parse.quote(audience, safe='')}",
146+
{"Authorization": f"Bearer {request_token}"},
147+
)
148+
oidc_token = oidc_response.get("value")
149+
if not oidc_token:
150+
raise SystemExit("GitHub OIDC response did not contain a token value.")
151+
print(f"::add-mask::{oidc_token}")
152+
153+
api_key_response = fetch_json(
154+
token_service_url,
155+
{
156+
"Authorization": f"Bearer {oidc_token}",
157+
"Content-Type": "application/json",
158+
"User-Agent": "apache-fory-release-csharp-workflow",
159+
},
160+
json.dumps({"username": "chaokunyang", "tokenType": "ApiKey"}).encode("utf-8"),
161+
)
162+
api_key = api_key_response.get("apiKey")
163+
if not api_key:
164+
raise SystemExit('NuGet token exchange response did not contain "apiKey".')
165+
print(f"::add-mask::{api_key}")
166+
167+
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
168+
output.write(f"NUGET_API_KEY={api_key}\n")
169+
PY
170+
171+
- name: Publish Apache.Fory package
172+
shell: bash
173+
working-directory: csharp
174+
run: |
175+
set -euo pipefail
176+
VERSION="${{ github.ref_name }}"
177+
VERSION="${VERSION#v}"
178+
dotnet nuget push "artifacts/nuget/Apache.Fory.$VERSION.nupkg" \
179+
--api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" \
180+
--source "$NUGET_SOURCE" \
181+
--skip-duplicate
182+
183+
- name: Publish Apache.Fory symbols
184+
shell: bash
185+
working-directory: csharp
186+
run: |
187+
set -euo pipefail
188+
VERSION="${{ github.ref_name }}"
189+
VERSION="${VERSION#v}"
190+
dotnet nuget push "artifacts/nuget/Apache.Fory.$VERSION.snupkg" \
191+
--api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" \
192+
--source "$NUGET_SOURCE" \
193+
--skip-duplicate

0 commit comments

Comments
 (0)