Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
13 changes: 12 additions & 1 deletion .github/workflows/pr-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ jobs:
src:
- 'UnityProject/Packages/com.jasonxudeveloper.jengine.core/**'
- 'UnityProject/Packages/com.jasonxudeveloper.jengine.util/**'
- 'UnityProject/Packages/com.jasonxudeveloper.jengine.ui/**'
- 'UnityProject/Assets/Tests/**'
- '.github/workflows/unity-tests.yml'
- '.github/workflows/pr-tests.yml'
Expand Down Expand Up @@ -105,7 +106,17 @@ jobs:
files: coverage/**/TestCoverageResults*.xml
flags: util
name: jengine-util
fail_ci_if_error: false
fail_ci_if_error: true
verbose: true
Comment thread
JasonXuDeveloper marked this conversation as resolved.

- name: Upload coverage to Codecov (ui package)
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage/**/TestCoverageResults*.xml
flags: ui
name: jengine-ui
fail_ci_if_error: true
verbose: true
Comment thread
JasonXuDeveloper marked this conversation as resolved.

comment-results:
Expand Down
86 changes: 78 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ on:
description: 'New Util version (e.g., 1.0.1)'
required: false
type: string
release_ui:
description: 'Release JEngine.UI?'
required: true
type: boolean
default: false
ui_version:
description: 'New UI version (e.g., 1.0.0)'
required: false
type: string
manual_changelog:
description: 'Manual changelog entries (optional)'
required: false
Expand All @@ -37,6 +46,7 @@ jobs:
outputs:
core_version: ${{ steps.validate.outputs.core_version }}
util_version: ${{ steps.validate.outputs.util_version }}
ui_version: ${{ steps.validate.outputs.ui_version }}
release_tag: ${{ steps.validate.outputs.release_tag }}
create_github_release: ${{ steps.validate.outputs.create_github_release }}

Expand All @@ -48,7 +58,7 @@ jobs:
id: validate
run: |
# Check at least one package is selected
if [ "${{ inputs.release_core }}" != "true" ] && [ "${{ inputs.release_util }}" != "true" ]; then
if [ "${{ inputs.release_core }}" != "true" ] && [ "${{ inputs.release_util }}" != "true" ] && [ "${{ inputs.release_ui }}" != "true" ]; then
echo "Error: At least one package must be selected for release"
exit 1
fi
Expand All @@ -65,9 +75,11 @@ jobs:
# Get current versions from package.json
CURRENT_CORE_VERSION=$(jq -r '.version' UnityProject/Packages/com.jasonxudeveloper.jengine.core/package.json)
CURRENT_UTIL_VERSION=$(jq -r '.version' UnityProject/Packages/com.jasonxudeveloper.jengine.util/package.json)
CURRENT_UI_VERSION=$(jq -r '.version' UnityProject/Packages/com.jasonxudeveloper.jengine.ui/package.json)

echo "Current Core version: $CURRENT_CORE_VERSION"
echo "Current Util version: $CURRENT_UTIL_VERSION"
echo "Current UI version: $CURRENT_UI_VERSION"

# Validate Core version if releasing
if [ "${{ inputs.release_core }}" == "true" ]; then
Expand Down Expand Up @@ -106,6 +118,24 @@ jobs:
echo "util_version=$CURRENT_UTIL_VERSION" >> $GITHUB_OUTPUT
fi

# Validate UI version if releasing
if [ "${{ inputs.release_ui }}" == "true" ]; then
if [ -z "${{ inputs.ui_version }}" ]; then
echo "Error: UI version is required when releasing UI package"
exit 1
fi
validate_version "${{ inputs.ui_version }}"

if [ "${{ inputs.ui_version }}" == "$CURRENT_UI_VERSION" ]; then
echo "Error: New UI version must be different from current version"
exit 1
fi

echo "ui_version=${{ inputs.ui_version }}" >> $GITHUB_OUTPUT
else
echo "ui_version=$CURRENT_UI_VERSION" >> $GITHUB_OUTPUT
fi

# Release tag always follows Core version
# GitHub releases are only created when Core is released
if [ "${{ inputs.release_core }}" == "true" ]; then
Expand Down Expand Up @@ -276,13 +306,36 @@ jobs:
# Build changelog
CHANGELOG=""

# Add package release info (always show both versions for clarity)
if [ "${{ inputs.release_core }}" == "true" ] && [ "${{ inputs.release_util }}" == "true" ]; then
CHANGELOG="${CHANGELOG}**Released**: JEngine.Core v${{ needs.validate.outputs.core_version }}, JEngine.Util v${{ needs.validate.outputs.util_version }}\n\n"
elif [ "${{ inputs.release_core }}" == "true" ]; then
CHANGELOG="${CHANGELOG}**Released**: JEngine.Core v${{ needs.validate.outputs.core_version }} (Util remains v${{ needs.validate.outputs.util_version }})\n\n"
# Add package release info
RELEASED_PACKAGES=""
UNCHANGED_PACKAGES=""

if [ "${{ inputs.release_core }}" == "true" ]; then
RELEASED_PACKAGES="${RELEASED_PACKAGES}JEngine.Core v${{ needs.validate.outputs.core_version }}, "
else
CHANGELOG="${CHANGELOG}**Released**: JEngine.Util v${{ needs.validate.outputs.util_version }} (Core remains v${{ needs.validate.outputs.core_version }})\n\n"
UNCHANGED_PACKAGES="${UNCHANGED_PACKAGES}Core v${{ needs.validate.outputs.core_version }}, "
fi

if [ "${{ inputs.release_util }}" == "true" ]; then
RELEASED_PACKAGES="${RELEASED_PACKAGES}JEngine.Util v${{ needs.validate.outputs.util_version }}, "
else
UNCHANGED_PACKAGES="${UNCHANGED_PACKAGES}Util v${{ needs.validate.outputs.util_version }}, "
fi

if [ "${{ inputs.release_ui }}" == "true" ]; then
RELEASED_PACKAGES="${RELEASED_PACKAGES}JEngine.UI v${{ needs.validate.outputs.ui_version }}, "
else
UNCHANGED_PACKAGES="${UNCHANGED_PACKAGES}UI v${{ needs.validate.outputs.ui_version }}, "
fi

# Remove trailing comma and space
RELEASED_PACKAGES=$(echo "$RELEASED_PACKAGES" | sed 's/, $//')
UNCHANGED_PACKAGES=$(echo "$UNCHANGED_PACKAGES" | sed 's/, $//')

if [ -n "$UNCHANGED_PACKAGES" ]; then
CHANGELOG="${CHANGELOG}**Released**: ${RELEASED_PACKAGES} (${UNCHANGED_PACKAGES} unchanged)\n\n"
else
CHANGELOG="${CHANGELOG}**Released**: ${RELEASED_PACKAGES}\n\n"
fi

if [ -n "$BREAKING" ]; then
Expand Down Expand Up @@ -341,6 +394,14 @@ jobs:
mv /tmp/package.json UnityProject/Packages/com.jasonxudeveloper.jengine.util/package.json
echo "✅ Updated Util package.json to v${{ needs.validate.outputs.util_version }}"

- name: Update UI package.json
if: inputs.release_ui == true
run: |
jq '.version = "${{ needs.validate.outputs.ui_version }}"' \
UnityProject/Packages/com.jasonxudeveloper.jengine.ui/package.json > /tmp/package.json
mv /tmp/package.json UnityProject/Packages/com.jasonxudeveloper.jengine.ui/package.json
echo "✅ Updated UI package.json to v${{ needs.validate.outputs.ui_version }}"

# Update README files (only when releasing Core)
- name: Update README.md
if: inputs.release_core == true
Expand Down Expand Up @@ -554,13 +615,17 @@ jobs:
echo "✅ **JEngine.Util**: v${{ needs.validate.outputs.util_version }}" >> $GITHUB_STEP_SUMMARY
fi

if [ "${{ inputs.release_ui }}" == "true" ]; then
echo "✅ **JEngine.UI**: v${{ needs.validate.outputs.ui_version }}" >> $GITHUB_STEP_SUMMARY
fi

echo "" >> $GITHUB_STEP_SUMMARY
echo "🏷️ **Git Tag**: ${{ needs.validate.outputs.release_tag }}" >> $GITHUB_STEP_SUMMARY

if [ "${{ needs.validate.outputs.create_github_release }}" == "true" ]; then
echo "📋 **GitHub Release**: Will be created" >> $GITHUB_STEP_SUMMARY
else
echo "ℹ️ **GitHub Release**: Not created (Util-only update)" >> $GITHUB_STEP_SUMMARY
echo "ℹ️ **GitHub Release**: Not created (non-Core update)" >> $GITHUB_STEP_SUMMARY
fi

echo "" >> $GITHUB_STEP_SUMMARY
Expand Down Expand Up @@ -605,6 +670,7 @@ jobs:
```bash
openupm add com.jasonxudeveloper.jengine.core
openupm add com.jasonxudeveloper.jengine.util
openupm add com.jasonxudeveloper.jengine.ui # Optional: UI utilities
```

## 📖 Documentation
Expand Down Expand Up @@ -637,6 +703,10 @@ jobs:
echo "✅ **JEngine.Util**: v${{ needs.validate.outputs.util_version }}" >> $GITHUB_STEP_SUMMARY
fi

if [ "${{ inputs.release_ui }}" == "true" ]; then
echo "✅ **JEngine.UI**: v${{ needs.validate.outputs.ui_version }}" >> $GITHUB_STEP_SUMMARY
fi

echo "" >> $GITHUB_STEP_SUMMARY
echo "**OpenUPM will automatically detect and build the packages within 10-15 minutes.**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
Expand Down
2 changes: 1 addition & 1 deletion UnityProject/Assets/HotUpdate/Code/EntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
using Cysharp.Threading.Tasks;
using JEngine.Core;
using JEngine.Core.Encrypt;
using JEngine.Core.Misc;
using JEngine.Core.Update;
using JEngine.UI;
Comment thread
JasonXuDeveloper marked this conversation as resolved.
Outdated
using Obfuz;
using UnityEngine;
using UnityEngine.Scripting;
Expand Down
4 changes: 3 additions & 1 deletion UnityProject/Assets/HotUpdate/Code/HotUpdate.Code.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:3fe1a3e70da50184f9897101cad7e4f2",
"GUID:6055be8ebefd69e48b49212b09b47b2f",
"GUID:ba02d1bbd77cf4a0c8606d3e5cbbbe79"
"GUID:ba02d1bbd77cf4a0c8606d3e5cbbbe79",
"GUID:5c8e1f4d7a3b9e2c6f0d8a4b7e3c1f9d",
"GUID:5655bcbaa4dec434b86ecd07e2c6f24d"
Comment thread
JasonXuDeveloper marked this conversation as resolved.
Outdated
],
"includePlatforms": [],
"excludePlatforms": [],
Expand Down
8 changes: 8 additions & 0 deletions UnityProject/Assets/Scripts.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions UnityProject/Assets/Scripts/PromptInitializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// PromptInitializer.cs
//
// Author:
// JasonXuDeveloper <jason@xgamedev.net>
//
// Copyright (c) 2025 JEngine
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// ============================================================================
// IMPORTANT: This script requires the JEngine.UI package to be installed.
//
// To use this script:
// 1. Add the JEngine.UI package via OpenUPM:
// openupm add com.jasonxudeveloper.jengine.ui
//
// 2. Or add to your manifest.json:
// "com.jasonxudeveloper.jengine.ui": "1.0.0"
//
// If you don't need MessageBox dialogs, you can:
// - Delete this script entirely (Bootstrap will log warnings and continue)
// - Implement your own custom dialog provider by assigning to Prompt.ShowDialogAsync
// ============================================================================

using JEngine.Core;
using JEngine.UI;
using UnityEngine;

/// <summary>
/// Initializes the Prompt system to use MessageBox for dialogs.
/// This runs automatically before any scene loads.
/// </summary>
public static class PromptInitializer
Comment thread
JasonXuDeveloper marked this conversation as resolved.
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Initialize()
{
// Register MessageBox as the dialog provider for JEngine.Core
Prompt.ShowDialogAsync = MessageBox.Show;
Debug.Log("[JEngine] Prompt system initialized with MessageBox provider.");
}
}
Comment thread
JasonXuDeveloper marked this conversation as resolved.
11 changes: 11 additions & 0 deletions UnityProject/Assets/Scripts/PromptInitializer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using JEngine.Core.Encrypt;
using JEngine.Core.Misc;
using JEngine.Core.Update;
using Nino.Core;
using Obfuz;
Expand Down Expand Up @@ -203,7 +202,7 @@ private async void Initialize()
}
catch (Exception e)
{
await MessageBox.Show("Error", $"Initialization failed: {e.Message}", no: null);
await Prompt.ShowDialogAsync("Error", $"Initialization failed: {e.Message}", "OK", null);
Application.Quit();
}
}
Expand Down Expand Up @@ -235,9 +234,9 @@ private async UniTask InitializeGame()
OnStatusUpdate = status => updateStatusText.text = GetStatusText(status),
OnVersionUpdate = version => versionText.text = $"v{Application.version}.{version}",
OnDownloadPrompt = async (count, size) =>
await MessageBox.Show("Notice",
await Prompt.ShowDialogAsync("Notice",
$"Need to download {count} files, total size {size / 1024f / 1024f:F2}MB. Start download?",
"Download"),
"Download", "Cancel"),
OnDownloadProgress = data =>
{
if (updateStatusText != null)
Expand Down Expand Up @@ -272,7 +271,7 @@ await MessageBox.Show("Notice",
if (downloadProgressBar != null)
downloadProgressBar.value = 1f;
},
OnError = async error => await MessageBox.Show("Warning", error.Message, no: null)
OnError = async error => await Prompt.ShowDialogAsync("Warning", error.Message, "OK", null)
};

bool success = await UpdatePackage(package, packageInitCallbacks, encryptionOption);
Expand Down Expand Up @@ -328,8 +327,8 @@ await MessageBox.Show("Notice",
},
OnError = async exception =>
{
await MessageBox.Show("Error", $"Scene loading failed: {exception.Message}",
ok: "Retry");
await Prompt.ShowDialogAsync("Error", $"Scene loading failed: {exception.Message}",
"Retry", null);
}
};
downloadProgressBar.gameObject.SetActive(true);
Expand All @@ -342,7 +341,7 @@ await MessageBox.Show("Error", $"Scene loading failed: {exception.Message}",
catch (Exception ex)
{
Debug.LogError($"Initialization failed with exception: {ex}");
await MessageBox.Show("Error", $"Exception occurred during initialization: {ex.Message}");
await Prompt.ShowDialogAsync("Error", $"Exception occurred during initialization: {ex.Message}", "OK", "Cancel");
// Continue the loop to retry
}
}
Expand All @@ -353,15 +352,15 @@ private async UniTask LoadHotCode(Assembly hotUpdateAss)
Type type = hotUpdateAss.GetType(hotUpdateClassName);
if (type == null)
{
await MessageBox.Show("Error", "Code exception, please contact customer service", ok: null);
await Prompt.ShowDialogAsync("Error", "Code exception, please contact customer service", null, "OK");
Application.Quit();
return;
}

var method = type.GetMethod(hotUpdateMethodName, BindingFlags.Public | BindingFlags.Static);
if (method == null)
{
await MessageBox.Show("Error", "Code exception, please contact customer service", ok: null);
await Prompt.ShowDialogAsync("Error", "Code exception, please contact customer service", null, "OK");
Application.Quit();
return;
}
Expand Down Expand Up @@ -393,7 +392,7 @@ private async UniTask LoadHotCode(Assembly hotUpdateAss)
catch (Exception e)
{
Debug.LogError($"Failed to invoke hot update method {hotUpdateMethodName}: {e}");
await MessageBox.Show("Error", $"Function call failed: {e.Message}", ok: "Exit", no: null);
await Prompt.ShowDialogAsync("Error", $"Function call failed: {e.Message}", "Exit", null);
Application.Quit();
}
}
Expand Down

This file was deleted.

This file was deleted.

Loading
Loading