Skip to content

Commit

Permalink
add CI/CD for nuget
Browse files Browse the repository at this point in the history
  • Loading branch information
trudyhood committed Jun 9, 2024
1 parent 4838772 commit 0137ee3
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 104 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/nuget-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Publish Nugets

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:

env:
BUILD_CONFIG: 'Release'

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Bump versions
uses: SiqiLu/[email protected]
with:
version_files: "**/VpnHood.Client.App.Android.Ads.UnityAds.csproj"
version_mask: 0.0.1.0
version_overwrite: "*.*.*.*"
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup .NET
uses: actions/setup-dotnet@v2
with:
dotnet-version: 8.0.x

- name: Restore dependencies
run: dotnet restore

- name: Build Solution
run: dotnet build --no-restore --configuration $BUILD_CONFIG

- name: Pack All Projects
run: dotnet pack --configuration $BUILD_CONFIG -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg

- name: Publish
run: nuget push **\*.nupkg -Source 'https://api.nuget.org/v3/index.json' -ApiKey ${{secrets.NUGET_API_KEY}}
2 changes: 1 addition & 1 deletion Sample/Sample.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework>
<SupportedOSPlatformVersion>24</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion>23</SupportedOSPlatformVersion>
<OutputType>Exe</OutputType>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
7 changes: 6 additions & 1 deletion VpnHood.Client.App.Android.Ads.UnityAds.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ VisualStudioVersion = 17.10.34928.147
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VpnHood.Client.App.Android.Ads.UnityAds", "VpnHood.Client.App.Android.Ads.UnityAds\VpnHood.Client.App.Android.Ads.UnityAds.csproj", "{63761376-9057-4A2C-B45B-E25049D0FAC6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample", "Sample\Sample.csproj", "{A9B2B42A-B01B-47C1-AE52-3591349139AF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample", "Sample\Sample.csproj", "{A9B2B42A-B01B-47C1-AE52-3591349139AF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B7A98153-A1DD-4080-AC02-A4C63CBEDC5C}"
ProjectSection(SolutionItems) = preProject
.github\workflows\nuget-main.yml = .github\workflows\nuget-main.yml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
13 changes: 0 additions & 13 deletions VpnHood.Client.App.Android.Ads.UnityAds/AdException.cs

This file was deleted.

13 changes: 0 additions & 13 deletions VpnHood.Client.App.Android.Ads.UnityAds/AdLoadException.cs

This file was deleted.

138 changes: 63 additions & 75 deletions VpnHood.Client.App.Android.Ads.UnityAds/UnityAdService.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
using Com.Unity3d.Ads;
using Android.Content;
using Com.Unity3d.Ads;
using VpnHood.Client.App.Abstractions;
using VpnHood.Client.Device;
using VpnHood.Client.Device.Droid;
using VpnHood.Common.Exceptions;
using VpnHood.Common.Utils;

namespace VpnHood.Client.App.Droid.Ads.VhUnityAds;

public class UnityAdService(string adGameId, string adPlacementId, bool testMode = false) : IAppAdService
{
private MyAdInitializationListener? _adInitializationListener;
private MyAdLoadListener? _adLoadListener;
private MyAdShowListener? _adShowListener;
private DateTime _lastLoadAdTime = DateTime.MinValue;
private static bool _isUnityAdInitialized;
private static bool _isUnityAdLoaded;
public string NetworkName => "UnityAds";
public AppAdType AdType => AppAdType.InterstitialAd;
public DateTime? AdLoadedTime { get; private set; }

public static UnityAdService Create(string adGameId, string adPlacementId, bool testMode = false)
{
Expand All @@ -23,12 +23,25 @@ public static UnityAdService Create(string adGameId, string adPlacementId, bool

public bool IsCountrySupported(string countryCode)
{
throw new NotImplementedException();
return countryCode != "IR";
}

public string NetworkName => "UnityAds";
public AppAdType AdType => AppAdType.InterstitialAd;
public DateTime? AdLoadedTime { get; }
private async Task EnsureUnityAdInitialized(Context context, CancellationToken cancellationToken)
{
if (_isUnityAdInitialized)
return;

var adInitializationListener = new MyAdInitializationListener();
UnityAds.Initialize(context, adGameId, testMode, adInitializationListener);

var cancellationTask = new TaskCompletionSource();
cancellationToken.Register(cancellationTask.SetResult);
await Task.WhenAny(adInitializationListener.Task, cancellationTask.Task).VhConfigureAwait();
cancellationToken.ThrowIfCancellationRequested();

await adInitializationListener.Task.VhConfigureAwait();
_isUnityAdInitialized = true;
}

public async Task LoadAd(IUiContext uiContext, CancellationToken cancellationToken)
{
Expand All @@ -37,57 +50,23 @@ public async Task LoadAd(IUiContext uiContext, CancellationToken cancellationTok
if (activity.IsDestroyed)
throw new AdException("MainActivity has been destroyed before loading the ad.");

// Initialize ad
if (!_isUnityAdInitialized)
{
try
{
_adInitializationListener = new MyAdInitializationListener();
activity.RunOnUiThread(() => UnityAds.Initialize(
activity, adGameId, testMode, _adInitializationListener));

var cancellationTask = new TaskCompletionSource();
cancellationToken.Register(cancellationTask.SetResult);
await Task.WhenAny(_adInitializationListener.Task, cancellationTask.Task).VhConfigureAwait();
cancellationToken.ThrowIfCancellationRequested();

_isUnityAdInitialized = await _adInitializationListener.Task.VhConfigureAwait();

}
catch (Exception ex) when (ex is not OperationCanceledException)
{
_isUnityAdInitialized = false;
if (ex is AdLoadException) throw;
throw new AdLoadException($"Failed to load {AdType}.", ex);
}
}

// Ad already loaded
if (_adLoadListener != null && _lastLoadAdTime.AddHours(1) < DateTime.Now)
_isUnityAdLoaded = await _adLoadListener.Task.VhConfigureAwait();
// Initialize unity
await EnsureUnityAdInitialized(activity, cancellationToken);

// reset the last loaded ad
AdLoadedTime = null;

// Load a new Ad
try
{
_adLoadListener = new MyAdLoadListener();
activity.RunOnUiThread(() => UnityAds.Load(adPlacementId, _adLoadListener));
var adLoadListener = new MyAdLoadListener();
activity.RunOnUiThread(() => UnityAds.Load(adPlacementId, adLoadListener));

var cancellationTask = new TaskCompletionSource();
cancellationToken.Register(cancellationTask.SetResult);
await Task.WhenAny(_adLoadListener.Task, cancellationTask.Task).VhConfigureAwait();
cancellationToken.ThrowIfCancellationRequested();
var cancellationTask = new TaskCompletionSource();
cancellationToken.Register(cancellationTask.SetResult);
await Task.WhenAny(adLoadListener.Task, cancellationTask.Task).VhConfigureAwait();
cancellationToken.ThrowIfCancellationRequested();

_isUnityAdLoaded = await _adLoadListener.Task.VhConfigureAwait();
_lastLoadAdTime = DateTime.Now;
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
_isUnityAdLoaded = false;
_lastLoadAdTime = DateTime.MinValue;
if (ex is AdLoadException) throw;
throw new AdLoadException($"Failed to load {AdType}.", ex);
}
await adLoadListener.Task.VhConfigureAwait();
AdLoadedTime = DateTime.Now;
}

public async Task ShowAd(IUiContext uiContext, string? customData, CancellationToken cancellationToken)
Expand All @@ -97,30 +76,37 @@ public async Task ShowAd(IUiContext uiContext, string? customData, CancellationT
if (activity.IsDestroyed)
throw new AdException("MainActivity has been destroyed before showing the ad.");

if (!_isUnityAdLoaded)
if (AdLoadedTime == null)
throw new AdException($"The {AdType} has not been loaded.");

_adShowListener = new MyAdShowListener();
activity.RunOnUiThread(() => UnityAds.Show(activity, adPlacementId, _adShowListener));
try
{

// wait for show or dismiss
var cancellationTask = new TaskCompletionSource();
cancellationToken.Register(cancellationTask.SetResult);
await Task.WhenAny(_adShowListener.Task, cancellationTask.Task).VhConfigureAwait();
cancellationToken.ThrowIfCancellationRequested();
var adShowListener = new MyAdShowListener();
activity.RunOnUiThread(() => UnityAds.Show(activity, adPlacementId, adShowListener));

// wait for show or dismiss
var cancellationTask = new TaskCompletionSource();
cancellationToken.Register(cancellationTask.SetResult);
await Task.WhenAny(adShowListener.Task, cancellationTask.Task).VhConfigureAwait();
cancellationToken.ThrowIfCancellationRequested();

await _adShowListener.Task.VhConfigureAwait();
_isUnityAdLoaded = false;
await adShowListener.Task.VhConfigureAwait();
}
finally
{
AdLoadedTime = null;
}
}

private class MyAdInitializationListener : Java.Lang.Object, IUnityAdsInitializationListener
{
private readonly TaskCompletionSource<bool> _loadedCompletionSource = new();
public Task<bool> Task => _loadedCompletionSource.Task;
private readonly TaskCompletionSource _loadedCompletionSource = new();
public Task Task => _loadedCompletionSource.Task;

public void OnInitializationComplete()
{
_loadedCompletionSource.TrySetResult(true);
_loadedCompletionSource.TrySetResult();
}

public void OnInitializationFailed(UnityAds.UnityAdsInitializationError? error, string? message)
Expand All @@ -132,12 +118,12 @@ public void OnInitializationFailed(UnityAds.UnityAdsInitializationError? error,

private class MyAdLoadListener : Java.Lang.Object, IUnityAdsLoadListener
{
private readonly TaskCompletionSource<bool> _loadedCompletionSource = new();
public Task<bool> Task => _loadedCompletionSource.Task;
private readonly TaskCompletionSource _loadedCompletionSource = new();
public Task Task => _loadedCompletionSource.Task;

public void OnUnityAdsAdLoaded(string? adPlacementId)
{
_loadedCompletionSource.TrySetResult(true);
_loadedCompletionSource.TrySetResult();
}

public void OnUnityAdsFailedToLoad(string? adUnitId, UnityAds.UnityAdsLoadError? error, string? message)
Expand All @@ -149,12 +135,12 @@ public void OnUnityAdsFailedToLoad(string? adUnitId, UnityAds.UnityAdsLoadError?

private class MyAdShowListener : Java.Lang.Object, IUnityAdsShowListener
{
private readonly TaskCompletionSource<bool> _loadedCompletionSource = new();
public Task<bool> Task => _loadedCompletionSource.Task;
private readonly TaskCompletionSource _loadedCompletionSource = new();
public Task Task => _loadedCompletionSource.Task;

public void OnUnityAdsShowStart(string? adPlacementId)
{
_loadedCompletionSource.TrySetResult(true);
_loadedCompletionSource.TrySetResult();
}
public void OnUnityAdsShowFailure(string? adPlacementId, UnityAds.UnityAdsShowError? error, string? message)
{
Expand All @@ -169,7 +155,9 @@ public void OnUnityAdsShowComplete(string? adPlacementId, UnityAds.UnityAdsShowC
{
}
}

public void Dispose()
{
GC.SuppressFinalize(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Description>VpnHood Android Ad Library for UnityAds</Description>
<TargetFramework>net8.0-android</TargetFramework>
<SupportedOSPlatformVersion>24</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion>23</SupportedOSPlatformVersion>
<RootNamespace>VpnHood.Client.App.Droid.Ads.VhUnityAds</RootNamespace>
</PropertyGroup>

Expand Down

0 comments on commit 0137ee3

Please sign in to comment.