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
179 changes: 176 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@ on:
branches:
- master
tags:
- '*'
- 'v*'
pull_request:
workflow_dispatch:
inputs:
version:
description: 'UPM version to build (without leading v), e.g. 3.0.0. Only used by the upm job; the main build runs on the current ref.'
required: false

permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write # upload nupkgs to the draft release
id-token: write # mint GitHub OIDC token for NuGet trusted publishing
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down Expand Up @@ -52,8 +60,173 @@ jobs:
- name: Build NuGet Packages
run: dotnet pack ./src/Enjin.Platform.Sdk/Enjin.Platform.Sdk/Enjin.Platform.Sdk.csproj --configuration Release --no-build --output ./src/Enjin.Platform.Sdk/nuget-packages/

- name: Upload Artifacts
- name: Upload nupkgs to draft release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
if: startsWith(github.ref, 'refs/tags/v')
with:
# Keep the release in draft mode until the publish-release job flips
# it. softprops/action-gh-release upserts the release, so uploads from
# multiple jobs/workflows on the same tag all attach to the same
# draft. This avoids the "immutable release" upload error that
# happens when assets are pushed after publication.
draft: true
files: ./src/Enjin.Platform.Sdk/nuget-packages/*.nupkg

- name: NuGet login (OIDC -> temp API key)
id: nuget-login
if: startsWith(github.ref, 'refs/tags/v')
uses: NuGet/login@v1
with:
user: ${{ secrets.NUGET_USER }}

- name: Publish to NuGet.org
if: startsWith(github.ref, 'refs/tags/v')
run: |
dotnet nuget push ./src/Enjin.Platform.Sdk/nuget-packages/*.nupkg \
--api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" \
--source https://api.nuget.org/v3/index.json \
--skip-duplicate

upm:
# Assembles the Unity Package Manager distribution from unity-template/ +
# the freshly-built DLL and publishes it to the dedicated
# `enjin/platform-unity-sdk` repo: the package tree is committed to that
# repo's `master` branch (latest, always browsable) and pinned with a
# `v<version>` git tag. Users reference either in their Unity Package
# Manager git URL:
# https://github.com/enjin/platform-unity-sdk.git (latest)
# https://github.com/enjin/platform-unity-sdk.git#v3.0.0 (pinned)
# The tarball is still attached to this repo's draft GitHub Release.
needs: build
# Run on v* tag pushes, or on manual dispatches that supply a version. A
# workflow_dispatch with an empty version input is treated as "main build
# only" and skips the UPM job rather than hard-failing.
if: |
startsWith(github.ref, 'refs/tags/v')
|| (github.event_name == 'workflow_dispatch' && github.event.inputs.version != '')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Determine version
id: version
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
VERSION="${{ github.event.inputs.version }}"
if [[ -z "${VERSION}" ]]; then
echo "::error::workflow_dispatch requires the 'version' input"
exit 1
fi
TAG="v${VERSION}"
elif [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
# strip leading 'v' from refs/tags/v3.0.0
VERSION="${GITHUB_REF_NAME#v}"
TAG="v${VERSION}"
else
echo "::error::upm job triggered on an unsupported ref ${GITHUB_REF}"
exit 1
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "Building UPM package for version ${VERSION} (tag ${TAG})"

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x

- name: Cache NuGet Packages
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
restore-keys: |
${{ runner.os }}-nuget-

- name: Build SDK (Release)
run: dotnet build ./src/Enjin.Platform.Sdk/Enjin.Platform.Sdk/Enjin.Platform.Sdk.csproj --configuration Release

- name: Assemble UPM package
run: ./scripts/assemble-upm.sh ${{ steps.version.outputs.version }}

- name: Setup SSH
# Loads the deploy-key for enjin/platform-unity-sdk so the publish step
# below can push over SSH. webfactory/ssh-agent also adds github.com to
# known_hosts. The matching public key must be registered as a
# write-enabled deploy key on enjin/platform-unity-sdk.
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.UNITY_SDK_DEPLOY_KEY }}

- name: Publish package to platform-unity-sdk
# Commits the assembled upm-staging/ tree to the dedicated repo's master
# branch (latest) and pins it with a v<version> tag. End users reference
# either in their Unity Package Manager git URL:
# https://github.com/enjin/platform-unity-sdk.git (latest)
# https://github.com/enjin/platform-unity-sdk.git#v3.0.0 (pinned)
# The package lives at the repo root, so no ?path= suffix is needed.
run: |
set -euo pipefail
VERSION="${{ steps.version.outputs.version }}"
TAG="${{ steps.version.outputs.tag }}"
BRANCH="master"

WORK="$(mktemp -d)"
git clone --depth 1 git@github.com:enjin/platform-unity-sdk.git "${WORK}"
(
cd "${WORK}"
git checkout -B "${BRANCH}"
# Replace tracked contents with the freshly assembled package.
git rm -rqf . >/dev/null 2>&1 || true
cp -R "${GITHUB_WORKSPACE}/upm-staging/." .
git add -A
# Skip the commit when the assembled package is identical to the
# current branch contents (e.g. re-running a release tag), so the
# job stays idempotent instead of failing on "nothing to commit".
if git diff --cached --quiet; then
echo "UPM package contents unchanged; skipping commit"
else
git -c user.name="github-actions[bot]" \
-c user.email="41898282+github-actions[bot]@users.noreply.github.com" \
commit -m "UPM package v${VERSION}"
fi
git tag -f "${TAG}"
git push origin "HEAD:${BRANCH}"
git push -f origin "refs/tags/${TAG}"
)
rm -rf "${WORK}"
echo "Published v${VERSION} to platform-unity-sdk (${BRANCH} + tag ${TAG})"

- name: Attach UPM tarball to draft release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/v')
with:
draft: true
files: EnjinPlatformSdk-v${{ steps.version.outputs.version }}-upm.tar.gz

- name: Upload tarball as workflow artifact
# Always upload (including workflow_dispatch runs) so manual builds are
# downloadable for inspection without needing a release.
uses: actions/upload-artifact@v4
with:
name: EnjinPlatformSdk-v${{ steps.version.outputs.version }}-upm
path: EnjinPlatformSdk-v${{ steps.version.outputs.version }}-upm.tar.gz

publish-release:
# Flip the draft release to published once both the nupkgs and UPM tarball
# have been attached. This step is what makes the release "go live" on the
# repo's Releases page and on the GitHub Releases API.
needs: [build, upm]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- name: Publish GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
set -euo pipefail
TAG="${GITHUB_REF_NAME}"
echo "Publishing release ${TAG}"
gh release edit "${TAG}" --draft=false
104 changes: 0 additions & 104 deletions .github/workflows/unity.yml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,32 @@ public void DefaultUserAgentIsDerivedFromAssemblyVersion()
version = version[1..];
}

var expected = $"Enjin.Platform.Sdk/{version}";
var expected = $"Enjin-Platform-CSharp-SDK/{version}";

// Act
using var client = new PlatformClient(new Uri(_server.Urls[0] + "/graphql"));

// Assert
Assert.That(client.UserAgent, Is.EqualTo(expected));
}

[Test]
public void ParameterlessConstructorUsesDefaultBaseAddress()
{
// Act
using var client = new PlatformClient();

// Assert
Assert.That(client.BaseAddress, Is.EqualTo(PlatformClient.DefaultBaseAddress));
}

[Test]
public void NullBaseAddressUsesDefaultBaseAddress()
{
// Act
using var client = new PlatformClient(null);

// Assert
Assert.That(client.BaseAddress, Is.EqualTo(PlatformClient.DefaultBaseAddress));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ namespace Enjin.Platform.Sdk;
[PublicAPI]
public sealed class PlatformClient : IPlatformClient
{
/// <summary>
/// The default base address of the Enjin Platform GraphQL endpoint.
/// </summary>
public static readonly Uri DefaultBaseAddress = new("https://platform.enjin.io/graphql");

private static readonly string DefaultUserAgent = BuildDefaultUserAgent();

private static string BuildDefaultUserAgent()
Expand All @@ -38,7 +43,7 @@ private static string BuildDefaultUserAgent()
version = version[1..];
}

return $"Enjin.Platform.Sdk/{version}";
return $"Enjin-Platform-CSharp-SDK/{version}";
}

private readonly HttpClient _httpClient;
Expand All @@ -58,21 +63,18 @@ private static string BuildDefaultUserAgent()
/// <summary>
/// Initializes a new <see cref="PlatformClient"/>.
/// </summary>
/// <param name="baseAddress">The base address of the platform's GraphQL endpoint (e.g. <c>https://platform.enjin.io/graphql</c>).</param>
/// <param name="userAgent">Optional User-Agent header value. Defaults to <c>Enjin.Platform.Sdk/{assembly-version}</c>.</param>
/// <param name="baseAddress">The base address of the platform's GraphQL endpoint (e.g. <c>https://platform.enjin.io/graphql</c>). Defaults to <see cref="DefaultBaseAddress"/>.</param>
/// <param name="userAgent">Optional User-Agent header value. Defaults to <c>Enjin-Platform-CSharp-SDK/{assembly-version}</c>.</param>
/// <param name="logger">Optional logger; when provided HTTP traffic is logged at the given <paramref name="httpLogLevel"/>.</param>
/// <param name="httpLogLevel">HTTP log level. Ignored when <paramref name="logger"/> is <c>null</c>.</param>
public PlatformClient(
Uri baseAddress,
Uri? baseAddress = null,
string? userAgent = null,
ILogger? logger = null,
HttpLogLevel httpLogLevel = HttpLogLevel.None
)
{
if (baseAddress == null)
{
throw new ArgumentNullException(nameof(baseAddress));
}
baseAddress ??= DefaultBaseAddress;

Comment thread
JayPavlina marked this conversation as resolved.
UserAgent = userAgent ?? DefaultUserAgent;

Expand Down
Loading