chore: initialize standalone UPM package
Publish UPM package / publish (push) Failing after 1s

This commit is contained in:
2026-08-26 02:55:30 +08:00
commit c3b57fd023
14 changed files with 544 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
name: Publish UPM package
on:
push:
tags:
- 'v*'
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
env:
NODE_AUTH_TOKEN: ${{ secrets.SHRINKSDK_PACKAGE_TOKEN }}
steps:
- name: Fetch tagged revision
shell: bash
run: |
set -eu
ref="${{ gitea.sha }}"
test -n "$ref"
git init .
git remote add origin "https://git.crash.work/ShrinkSDK/Installer.git"
git fetch --depth=1 origin "$ref"
git checkout --detach FETCH_HEAD
- name: Validate immutable release version
shell: bash
run: |
set -eu
tag="$(git describe --exact-match --tags HEAD)"
version="$(node -p "require('./package.json').version")"
test "$tag" = "v$version"
npm pack --dry-run
- name: Publish to ShrinkSDK registry
shell: bash
run: |
set -eu
: "${NODE_AUTH_TOKEN:?SHRINKSDK_PACKAGE_TOKEN is required}"
npmrc="$HOME/.npmrc"
cleanup() { rm -f "$npmrc"; }
trap cleanup EXIT
printf '%s\n' \
'registry=https://git.crash.work/api/packages/ShrinkSDK/npm/' \
'//git.crash.work/api/packages/ShrinkSDK/npm/:_authToken=${NODE_AUTH_TOKEN}' > "$npmrc"
npm publish --registry=https://git.crash.work/api/packages/ShrinkSDK/npm/
+39
View File
@@ -0,0 +1,39 @@
name: Verify standalone Unity package
on:
workflow_dispatch:
jobs:
editmode:
runs-on: unity-2022.3.62f3
container:
image: docker.1panel.live/unityci/editor:ubuntu-2022.3.62f3-windows-mono-3
volumes:
- /www/dk_project/bt-recovery/gitea/runner/seedskey-unity-license:/root/.local/share/unity3d/Unity
- /www/dk_project/bt-recovery/gitea/runner/seedskey-unity-entitlements:/root/.config/unity3d/Unity/licenses
steps:
- name: Fetch selected revision
shell: bash
run: |
set -eu
ref="${{ gitea.sha }}"
git init .
git remote add origin "https://git.crash.work/ShrinkSDK/Installer.git"
git fetch --depth=1 origin "$ref"
git checkout --detach FETCH_HEAD
- name: Run package EditMode tests
shell: bash
run: |
set -eu
unity_bin="$(command -v unity-editor || command -v unity || command -v Unity || true)"
test -n "$unity_bin"
"$unity_bin" \
-batchmode \
-nographics \
-quit \
-projectPath "$PWD/Development~/UnityProject" \
-runTests \
-testPlatform EditMode \
-testResults "$PWD/TestResults/editmode.xml" \
-logFile "$PWD/TestResults/unity.log"
+10
View File
@@ -0,0 +1,10 @@
/Development~/UnityProject/[Ll]ibrary/
/Development~/UnityProject/[Tt]emp/
/Development~/UnityProject/[Oo]bj/
/Development~/UnityProject/[Ll]ogs/
/Development~/UnityProject/[Uu]ser[Ss]ettings/
/Development~/UnityProject/TestResults/
/Tools~/**/[Bb]in/
/Tools~/**/[Oo]bj/
*.user
*.DotSettings.user
+8
View File
@@ -0,0 +1,8 @@
.git/
.gitea/
Development~/
Tools~/
*.csproj
*.sln
*.user
*.DotSettings.user
+6
View File
@@ -0,0 +1,6 @@
[Ll]ibrary/
[Tt]emp/
[Oo]bj/
[Ll]ogs/
[Uu]ser[Ss]ettings/
TestResults/
@@ -0,0 +1,15 @@
{
"scopedRegistries": [
{
"name": "ShrinkSDK",
"url": "https://git.crash.work/api/packages/ShrinkSDK/npm/",
"scopes": [
"com.cneicy"
]
}
],
"dependencies": {
"com.unity.test-framework": "1.1.33",
"com.cneicy.shrink-installer": "file:../../.."
}
}
@@ -0,0 +1,2 @@
m_EditorVersion: 2022.3.62f3
m_EditorVersionWithRevision: 2022.3.62f3 (96770f904ca7)
+17
View File
@@ -0,0 +1,17 @@
{
"name": "ShrinkInstaller.Editor",
"rootNamespace": "ShrinkSDK.Installer",
"references": [
"Unity.Newtonsoft.Json"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
+175
View File
@@ -0,0 +1,175 @@
#if UNITY_EDITOR
#nullable enable
using System;
using System.Linq;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEngine;
namespace ShrinkSDK.Installer
{
internal sealed class ShrinkSdkInstallerWindow : EditorWindow
{
private AddRequest? _addRequest;
private ListRequest? _listRequest;
private ResolveRequest? _resolveRequest;
private ShrinkSdkPackageEntry? _pendingInstall;
private int _selectedPackageIndex;
private string _status = "Ready";
private MessageType _statusType = MessageType.Info;
[MenuItem("ShrinkSDK/Packages")]
private static void Open()
{
GetWindow<ShrinkSdkInstallerWindow>("ShrinkSDK Packages");
}
private void OnEnable()
{
RefreshDiagnostics();
}
private void OnGUI()
{
EditorGUILayout.LabelField("ShrinkSDK", EditorStyles.boldLabel);
EditorGUILayout.Space(4f);
EditorGUILayout.LabelField("Registry", ShrinkSdkManifestStore.HasShrinkSdkRegistry()
? ShrinkSdkPackageCatalog.RegistryUrl
: "Not configured");
using (new EditorGUI.DisabledScope(IsBusy))
{
if (GUILayout.Button("Configure Registry"))
{
ConfigureRegistry();
}
EditorGUILayout.Space(8f);
if (GUILayout.Button("Install Starter Basic"))
{
BeginInstall(ShrinkSdkPackageCatalog.StarterBasic);
}
var labels = ShrinkSdkPackageCatalog.Packages.Select(entry =>
entry.DisplayName + " " + entry.Version).ToArray();
_selectedPackageIndex = EditorGUILayout.Popup("Package", _selectedPackageIndex, labels);
if (GUILayout.Button("Install Selected Package"))
{
BeginInstall(ShrinkSdkPackageCatalog.Packages[_selectedPackageIndex]);
}
if (GUILayout.Button("Refresh Diagnostics"))
{
RefreshDiagnostics();
}
}
EditorGUILayout.Space(8f);
EditorGUILayout.HelpBox(_status, _statusType);
}
private bool IsBusy => _resolveRequest != null || _addRequest != null || _listRequest != null;
private void Update()
{
if (_resolveRequest != null && _resolveRequest.IsCompleted)
{
var request = _resolveRequest;
_resolveRequest = null;
if (request.Status != StatusCode.Success)
{
SetStatus("Registry resolve failed: " + request.Error.message, MessageType.Error);
return;
}
if (_pendingInstall != null)
{
_addRequest = Client.Add(_pendingInstall.PackageSpecifier);
SetStatus("Installing " + _pendingInstall.PackageSpecifier, MessageType.Info);
}
}
if (_addRequest != null && _addRequest.IsCompleted)
{
var request = _addRequest;
_addRequest = null;
if (request.Status == StatusCode.Success)
{
SetStatus("Installed " + request.Result.name + " " + request.Result.version, MessageType.Info);
}
else
{
SetStatus("Package install failed: " + request.Error.message, MessageType.Error);
}
_pendingInstall = null;
}
if (_listRequest != null && _listRequest.IsCompleted)
{
var request = _listRequest;
_listRequest = null;
if (request.Status == StatusCode.Success)
{
var installed = request.Result.Count(package => package.name.StartsWith("com.cneicy.", StringComparison.Ordinal));
SetStatus("Registry is configured. Installed ShrinkSDK packages: " + installed, MessageType.Info);
}
else
{
SetStatus("Package diagnostics failed: " + request.Error.message, MessageType.Warning);
}
}
}
private void ConfigureRegistry()
{
try
{
ShrinkSdkManifestStore.EnsureShrinkSdkRegistry();
_pendingInstall = null;
_resolveRequest = Client.Resolve();
SetStatus("Registry configuration written. Resolving packages.", MessageType.Info);
}
catch (Exception exception)
{
SetStatus(exception.Message, MessageType.Error);
}
}
private void BeginInstall(ShrinkSdkPackageEntry entry)
{
try
{
ShrinkSdkManifestStore.EnsureShrinkSdkRegistry();
_pendingInstall = entry;
_resolveRequest = Client.Resolve();
SetStatus("Resolving registry for " + entry.PackageSpecifier, MessageType.Info);
}
catch (Exception exception)
{
SetStatus(exception.Message, MessageType.Error);
}
}
private void RefreshDiagnostics()
{
if (IsBusy)
{
return;
}
_listRequest = Client.List(true);
SetStatus("Refreshing installed package diagnostics.", MessageType.Info);
}
private void SetStatus(string message, MessageType messageType)
{
_status = message;
_statusType = messageType;
Repaint();
}
}
}
#endif
+131
View File
@@ -0,0 +1,131 @@
#if UNITY_EDITOR
#nullable enable
using System;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
namespace ShrinkSDK.Installer
{
internal static class ShrinkSdkManifestStore
{
internal static string ManifestPath => Path.Combine(
Path.GetFullPath(Path.Combine(Application.dataPath, "..")),
"Packages",
"manifest.json");
internal static bool HasShrinkSdkRegistry()
{
var manifest = ReadManifest();
return GetShrinkSdkRegistry(manifest) != null;
}
internal static void EnsureShrinkSdkRegistry()
{
var manifest = ReadManifest();
var registries = manifest["scopedRegistries"] as JArray;
if (registries == null)
{
registries = new JArray();
manifest["scopedRegistries"] = registries;
}
var conflictingRegistry = registries
.OfType<JObject>()
.FirstOrDefault(registry =>
!UrlEquals((string?)registry["url"], ShrinkSdkPackageCatalog.RegistryUrl) &&
(registry["scopes"] as JArray)?.Values<string>().Any(scope =>
string.Equals(scope, ShrinkSdkPackageCatalog.RegistryScope, StringComparison.Ordinal)) == true);
if (conflictingRegistry != null)
{
throw new InvalidOperationException(
"Packages/manifest.json already maps com.cneicy to another scoped registry. Resolve that registry explicitly before installing ShrinkSDK.");
}
var registry = GetShrinkSdkRegistry(manifest);
if (registry == null)
{
registry = new JObject
{
["name"] = ShrinkSdkPackageCatalog.RegistryName,
["url"] = ShrinkSdkPackageCatalog.RegistryUrl,
["scopes"] = new JArray(ShrinkSdkPackageCatalog.RegistryScope)
};
registries.Add(registry);
}
else
{
registry["name"] = ShrinkSdkPackageCatalog.RegistryName;
registry["url"] = ShrinkSdkPackageCatalog.RegistryUrl;
var scopes = registry["scopes"] as JArray ?? new JArray();
if (!scopes.Values<string>().Any(scope =>
string.Equals(scope, ShrinkSdkPackageCatalog.RegistryScope, StringComparison.Ordinal)))
{
scopes.Add(ShrinkSdkPackageCatalog.RegistryScope);
}
registry["scopes"] = scopes;
}
AtomicWrite(manifest.ToString(Formatting.Indented) + Environment.NewLine);
}
private static JObject ReadManifest()
{
if (!File.Exists(ManifestPath))
{
throw new FileNotFoundException("Unity package manifest was not found.", ManifestPath);
}
return JObject.Parse(File.ReadAllText(ManifestPath, Encoding.UTF8));
}
private static JObject? GetShrinkSdkRegistry(JObject manifest)
{
return (manifest["scopedRegistries"] as JArray)?
.OfType<JObject>()
.FirstOrDefault(registry => UrlEquals((string?)registry["url"], ShrinkSdkPackageCatalog.RegistryUrl));
}
private static bool UrlEquals(string? left, string right)
{
return string.Equals(NormalizeUrl(left), NormalizeUrl(right), StringComparison.OrdinalIgnoreCase);
}
private static string NormalizeUrl(string? url)
{
return (url ?? string.Empty).Trim().TrimEnd('/') + "/";
}
private static void AtomicWrite(string content)
{
var directory = Path.GetDirectoryName(ManifestPath);
if (string.IsNullOrWhiteSpace(directory))
{
throw new InvalidOperationException("Unity package manifest directory could not be resolved.");
}
var temporaryPath = Path.Combine(directory, ".manifest.shrinksdk.tmp");
File.WriteAllText(temporaryPath, content, new UTF8Encoding(false));
try
{
File.Replace(temporaryPath, ManifestPath, null);
}
catch
{
if (File.Exists(temporaryPath))
{
File.Delete(temporaryPath);
}
throw;
}
}
}
}
#endif
+59
View File
@@ -0,0 +1,59 @@
#if UNITY_EDITOR
#nullable enable
using System.Collections.Generic;
namespace ShrinkSDK.Installer
{
internal sealed class ShrinkSdkPackageEntry
{
public ShrinkSdkPackageEntry(string displayName, string packageName, string version)
{
DisplayName = displayName;
PackageName = packageName;
Version = version;
}
public string DisplayName { get; }
public string PackageName { get; }
public string Version { get; }
public string PackageSpecifier => PackageName + "@" + Version;
}
internal static class ShrinkSdkPackageCatalog
{
internal const string RegistryName = "ShrinkSDK";
internal const string RegistryUrl = "https://git.crash.work/api/packages/ShrinkSDK/npm/";
internal const string RegistryScope = "com.cneicy";
internal static readonly ShrinkSdkPackageEntry StarterBasic = new(
"ShrinkApp Starter Basic",
"com.cneicy.shrink-app-starter-basic",
"0.1.0");
internal static readonly IReadOnlyList<ShrinkSdkPackageEntry> Packages = new[]
{
new ShrinkSdkPackageEntry("ShrinkApp Core", "com.cneicy.shrink-app-core", "0.1.1"),
StarterBasic,
new ShrinkSdkPackageEntry("ShrinkCommand", "com.cneicy.shrink-command", "0.2.0"),
new ShrinkSdkPackageEntry("ShrinkCommand Integration App", "com.cneicy.shrink-command-integration-app", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkCommand Integration EventBus", "com.cneicy.shrink-command-integration-eventbus", "0.1.1"),
new ShrinkSdkPackageEntry("ShrinkCommand Integration Network", "com.cneicy.shrink-command-integration-network", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkContext App Adapter", "com.cneicy.shrink-context-app-adapter", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkContext Core", "com.cneicy.shrink-context-core", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkContext EventBus Adapter", "com.cneicy.shrink-context-eventbus-adapter", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkDataSaver", "com.cneicy.shrink-datasaver", "2.2.0"),
new ShrinkSdkPackageEntry("ShrinkDataSaver Integration App", "com.cneicy.shrink-datasaver-integration-app", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkDataSaver Integration EventBus", "com.cneicy.shrink-datasaver-integration-eventbus", "2.1.0"),
new ShrinkSdkPackageEntry("ShrinkEventBus", "com.cneicy.shrink-eventbus", "2.0.0"),
new ShrinkSdkPackageEntry("ShrinkEventBus Entities", "com.cneicy.shrink-eventbus-entities", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkModFramework", "com.cneicy.shrink-mod-framework", "0.2.0"),
new ShrinkSdkPackageEntry("ShrinkNetwork", "com.cneicy.shrink-network", "0.2.0"),
new ShrinkSdkPackageEntry("ShrinkNetwork Integration App", "com.cneicy.shrink-network-integration-app", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkNetwork Integration EventBus", "com.cneicy.shrink-network-integration-eventbus", "0.1.1"),
new ShrinkSdkPackageEntry("ShrinkShared CodeGen", "com.cneicy.shrink-shared-codegen", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkTutorial", "com.cneicy.shrink-tutorial", "0.1.0")
};
}
}
#endif
+13
View File
@@ -0,0 +1,13 @@
# ShrinkSDK Installer
`com.cneicy.shrink-installer` is the Git URL bootstrap package for ShrinkSDK.
Install the package from an immutable tag, then open `ShrinkSDK/Packages` in the Unity editor. The window merges the public ShrinkSDK scoped registry without replacing other registries and installs only catalogued package versions.
The installer does not copy templates into `Assets`, does not store credentials, and does not add an unpinned package version.
## Bootstrap URL
```text
https://git.crash.work/ShrinkSDK/Installer.git#v0.1.0
```
+20
View File
@@ -0,0 +1,20 @@
{
"name": "com.cneicy.shrink-installer",
"version": "0.1.0",
"displayName": "ShrinkSDK Installer",
"description": "ShrinkSDK registry bootstrapper and fixed-version package installer.",
"unity": "2022.3",
"documentationUrl": "https://git.crash.work/ShrinkSDK/Installer",
"dependencies": {
"com.unity.nuget.newtonsoft-json": "3.2.2"
},
"keywords": [
"shrink",
"installer",
"upm"
],
"author": {
"name": "cneicy",
"url": "https://git.crash.work/ShrinkSDK"
}
}