Skip to content
Merged
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
193 changes: 193 additions & 0 deletions .github/workflows/release-csharp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: Publish C#
run-name: "C# Release: ${{ github.ref_name }}"

on:
push:
tags: ['v*']

permissions:
contents: read
id-token: write

concurrency:
group: release-csharp-${{ github.ref }}
cancel-in-progress: false

jobs:
publish-csharp:
runs-on: ubuntu-latest
if: github.repository == 'apache/fory'
env:
NUGET_SOURCE: https://api.nuget.org/v3/index.json
steps:
- uses: actions/checkout@v5

- uses: actions/setup-python@v6
with:
python-version: '3.11'
cache: 'pip'

- name: Bump C# version
shell: bash
run: |
set -euo pipefail
VERSION="${{ github.ref_name }}"
VERSION="${VERSION#v}"
python ci/release.py bump_version -l csharp -version "$VERSION"

- name: Set up .NET 8
uses: actions/setup-dotnet@v5
with:
dotnet-version: "8.0.x"
cache: true
cache-dependency-path: |
csharp/**/*.csproj
csharp/Fory.sln

- name: Restore C# dependencies
shell: bash
working-directory: csharp
run: |
set -euo pipefail
dotnet restore Fory.sln

- name: Build C# solution
shell: bash
working-directory: csharp
run: |
set -euo pipefail
dotnet build Fory.sln -c Release --no-restore

- name: Run C# tests
shell: bash
working-directory: csharp
run: |
set -euo pipefail
dotnet test Fory.sln -c Release --no-build

- name: Pack Apache.Fory
shell: bash
working-directory: csharp
run: |
set -euo pipefail
rm -rf artifacts/nuget
mkdir -p artifacts/nuget
dotnet pack src/Fory/Fory.csproj \
-c Release \
--no-restore \
-o artifacts/nuget \
-p:ContinuousIntegrationBuild=true

- name: Verify packed artifacts
shell: bash
working-directory: csharp
run: |
set -euo pipefail
VERSION="${{ github.ref_name }}"
VERSION="${VERSION#v}"
test -f "artifacts/nuget/Apache.Fory.$VERSION.nupkg"
test -f "artifacts/nuget/Apache.Fory.$VERSION.snupkg"
ls -l artifacts/nuget

- name: Exchange GitHub OIDC token for NuGet API key
id: nuget-login
shell: bash
env:
NUGET_AUDIENCE: https://www.nuget.org
NUGET_TOKEN_SERVICE_URL: https://www.nuget.org/api/v2/token
run: |
set -euo pipefail
if [[ -z "${ACTIONS_ID_TOKEN_REQUEST_TOKEN:-}" || -z "${ACTIONS_ID_TOKEN_REQUEST_URL:-}" ]]; then
echo "GitHub OIDC token exchange is unavailable. Ensure the job has id-token: write permission." >&2
exit 1
fi
python <<'PY'
import json
import os
import urllib.error
import urllib.parse
import urllib.request

def fetch_json(url: str, headers: dict[str, str], data: bytes | None = None) -> dict:
request = urllib.request.Request(url, data=data, headers=headers)
try:
with urllib.request.urlopen(request) as response:
return json.load(response)
except urllib.error.HTTPError as error:
body = error.read().decode("utf-8", errors="replace")
raise SystemExit(f"HTTP {error.code} from {url}: {body}") from error

request_token = os.environ["ACTIONS_ID_TOKEN_REQUEST_TOKEN"]
request_url = os.environ["ACTIONS_ID_TOKEN_REQUEST_URL"]
audience = os.environ["NUGET_AUDIENCE"]
token_service_url = os.environ["NUGET_TOKEN_SERVICE_URL"]

print(f"::add-mask::{request_token}")

oidc_response = fetch_json(
f"{request_url}&audience={urllib.parse.quote(audience, safe='')}",
{"Authorization": f"Bearer {request_token}"},
)
oidc_token = oidc_response.get("value")
if not oidc_token:
raise SystemExit("GitHub OIDC response did not contain a token value.")
print(f"::add-mask::{oidc_token}")

api_key_response = fetch_json(
token_service_url,
{
"Authorization": f"Bearer {oidc_token}",
"Content-Type": "application/json",
"User-Agent": "apache-fory-release-csharp-workflow",
},
json.dumps({"username": "chaokunyang", "tokenType": "ApiKey"}).encode("utf-8"),
)
api_key = api_key_response.get("apiKey")
if not api_key:
raise SystemExit('NuGet token exchange response did not contain "apiKey".')
print(f"::add-mask::{api_key}")

with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
output.write(f"NUGET_API_KEY={api_key}\n")
PY

- name: Publish Apache.Fory package
shell: bash
working-directory: csharp
run: |
set -euo pipefail
VERSION="${{ github.ref_name }}"
VERSION="${VERSION#v}"
dotnet nuget push "artifacts/nuget/Apache.Fory.$VERSION.nupkg" \
--api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" \
--source "$NUGET_SOURCE" \
--skip-duplicate

- name: Publish Apache.Fory symbols
shell: bash
working-directory: csharp
run: |
set -euo pipefail
VERSION="${{ github.ref_name }}"
VERSION="${VERSION#v}"
dotnet nuget push "artifacts/nuget/Apache.Fory.$VERSION.snupkg" \
--api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" \
--source "$NUGET_SOURCE" \
--skip-duplicate
96 changes: 96 additions & 0 deletions .github/workflows/release-dart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: Publish Dart
run-name: "Dart Release: ${{ github.ref_name }}"

on:
push:
tags: ['v*']

permissions:
contents: read
id-token: write

concurrency:
group: release-dart-${{ github.ref }}
cancel-in-progress: false

jobs:
publish-dart:
runs-on: ubuntu-latest
if: github.repository == 'apache/fory'
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v5

- uses: actions/setup-python@v6
with:
python-version: '3.11'
cache: 'pip'

- name: Bump Dart package versions for the release tag
shell: bash
run: |
set -euo pipefail
VERSION="${{ github.ref_name }}"
VERSION="${VERSION#v}"
python ci/release.py bump_version -l dart -version "$VERSION"
VERSION="$VERSION" ruby <<'RUBY'
require "yaml"

expected = ENV.fetch("VERSION")
files = [
"dart/pubspec.yaml",
"dart/packages/fory/pubspec.yaml",
"dart/packages/fory-test/pubspec.yaml",
]

files.each do |path|
actual = YAML.load_file(path).fetch("version")
if actual != expected
abort("#{path} version mismatch after bump: expected #{expected}, got #{actual}")
end
end

puts "Verified bumped Dart package versions for #{expected}"
RUBY

- uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c # v1.7.1

- name: Install Dart package dependencies
shell: bash
working-directory: dart/packages/fory
run: |
set -euo pipefail
dart pub get

- name: Verify publish contents
shell: bash
working-directory: dart/packages/fory
run: |
set -euo pipefail
dart pub publish --dry-run

- name: Publish to pub.dev
shell: bash
working-directory: dart/packages/fory
run: |
set -euo pipefail
dart pub publish --force
14 changes: 14 additions & 0 deletions ci/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,12 @@ def bump_dart_version(new_version):
"dart/packages/fory-test",
]:
_bump_version(p, "pubspec.yaml", new_version, _update_pubspec_version)
_bump_version(
"dart/packages/fory",
"README.md",
new_version,
_update_dart_readme_dependency_version,
)


def bump_compiler_version(new_version):
Expand Down Expand Up @@ -497,6 +503,14 @@ def _update_pubspec_version(lines, v: str):
return lines


def _update_dart_readme_dependency_version(lines, v: str):
for index, line in enumerate(lines):
if re.match(r"^\s*fory:\s*\^[^\s]+\s*$", line):
lines[index] = f" fory: ^{v}\n"
return lines
raise ValueError("No Dart README dependency snippet for fory found")


def _update_csharp_props_version(lines, v: str):
for index, line in enumerate(lines):
if "<Version>" not in line:
Expand Down
Loading
Loading