11 Commits
Author SHA1 Message Date
cneicy 9bdc57fd88 fix(installer): resolve updated manifests
Publish UPM package / publish (push) Successful in 3s
2026-08-26 12:02:48 +08:00
cneicy c346eef5b2 fix(installer): tolerate diagnostics during resolution
Publish UPM package / publish (push) Successful in 6s
2026-08-26 11:56:13 +08:00
cneicy a4eebd0393 fix(installer): pin module dependency releases
Publish UPM package / publish (push) Successful in 2s
2026-08-26 11:04:22 +08:00
cneicy 2ef9ad827b fix(installer): pin patched starter release
Publish UPM package / publish (push) Successful in 2s
2026-08-26 08:23:04 +08:00
cneicy ece3f072dd ci: mirror Git package dependencies 2026-08-26 07:07:03 +08:00
cneicy afc58da579 test: enable standalone host discovery 2026-08-26 06:56:05 +08:00
cneicy 6fa2ad2623 fix(installer): write pinned package dependencies
Publish UPM package / publish (push) Successful in 2s
2026-08-26 06:37:53 +08:00
ShrinkSDK Automation 7de7bbbcdc ci: fetch immutable release archive 2026-08-26 04:29:42 +08:00
ShrinkSDK Automation 182bacbb09 fix(installer): pin standalone ModFramework support
Publish UPM package / publish (push) Successful in 5m32s
2026-08-26 04:13:17 +08:00
ShrinkSDK Automation 098c4b098f fix(installer): support Unity 2022 package resolution
Publish UPM package / publish (push) Successful in 17s
2026-08-26 03:44:51 +08:00
ShrinkSDK Automation deea36068c ci: install Git in package publisher 2026-08-26 03:09:52 +08:00
15 changed files with 184 additions and 81 deletions
+27 -9
View File
@@ -15,22 +15,39 @@ jobs:
env: env:
NODE_AUTH_TOKEN: ${{ secrets.SHRINKSDK_PACKAGE_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.SHRINKSDK_PACKAGE_TOKEN }}
steps: steps:
- name: Fetch tagged revision - name: Fetch exact tagged release archive
env:
GITEA_REF: ${{ gitea.ref }}
shell: bash shell: bash
run: | run: |
set -eu set -eu
ref="${{ gitea.sha }}" tag="${GITEA_REF#refs/tags/}"
test -n "$ref" case "$tag" in
git init . v[0-9]*) ;;
git remote add origin "https://git.crash.work/ShrinkSDK/Installer.git" *) echo "Expected a version tag ref, got: $GITEA_REF" >&2; exit 1 ;;
git fetch --depth=1 origin "$ref" esac
git checkout --detach FETCH_HEAD export SHRINKSDK_ARCHIVE_URL="https://git.crash.work/ShrinkSDK/Installer/archive/${tag}.tar.gz"
node --input-type=module <<'NODE'
import { writeFile } from 'node:fs/promises';
const response = await fetch(process.env.SHRINKSDK_ARCHIVE_URL);
if (!response.ok) {
throw new Error(`Release archive download failed: ${response.status} ${response.statusText}`);
}
await writeFile('release.tar.gz', new Uint8Array(await response.arrayBuffer()));
NODE
mkdir release
tar -xzf release.tar.gz --strip-components=1 -C release
rm -f release.tar.gz
printf '%s' "$tag" > release/.shrink-sdk-release-tag
- name: Validate immutable release version - name: Validate immutable release version
shell: bash shell: bash
run: | run: |
set -eu set -eu
tag="$(git describe --exact-match --tags HEAD)" cd release
tag="$(cat .shrink-sdk-release-tag)"
version="$(node -p "require('./package.json').version")" version="$(node -p "require('./package.json').version")"
test "$tag" = "v$version" test "$tag" = "v$version"
npm pack --dry-run npm pack --dry-run
@@ -40,10 +57,11 @@ jobs:
run: | run: |
set -eu set -eu
: "${NODE_AUTH_TOKEN:?SHRINKSDK_PACKAGE_TOKEN is required}" : "${NODE_AUTH_TOKEN:?SHRINKSDK_PACKAGE_TOKEN is required}"
cd release
npmrc="$HOME/.npmrc" npmrc="$HOME/.npmrc"
cleanup() { rm -f "$npmrc"; } cleanup() { rm -f "$npmrc"; }
trap cleanup EXIT trap cleanup EXIT
printf '%s\n' \ printf '%s\n' \
'registry=https://git.crash.work/api/packages/ShrinkSDK/npm/' \ 'registry=https://git.crash.work/api/packages/ShrinkSDK/npm/' \
'//git.crash.work/api/packages/ShrinkSDK/npm/:_authToken=${NODE_AUTH_TOKEN}' > "$npmrc" '//git.crash.work/api/packages/ShrinkSDK/npm/:_authToken=${NODE_AUTH_TOKEN}' > "$npmrc"
npm publish --registry=https://git.crash.work/api/packages/ShrinkSDK/npm/ npm publish --registry=https://git.crash.work/api/packages/ShrinkSDK/npm/
+6 -1
View File
@@ -26,12 +26,17 @@ jobs:
shell: bash shell: bash
run: | run: |
set -eu set -eu
machine_id_file="/root/.local/share/unity3d/Unity/.machine-id"
if test -s "$machine_id_file"; then
cat "$machine_id_file" > /etc/machine-id
echo "Unity machine identity restored"
fi
git config --global url."https://ghfast.top/https://github.com/".insteadOf "https://github.com/"
unity_bin="$(command -v unity-editor || command -v unity || command -v Unity || true)" unity_bin="$(command -v unity-editor || command -v unity || command -v Unity || true)"
test -n "$unity_bin" test -n "$unity_bin"
"$unity_bin" \ "$unity_bin" \
-batchmode \ -batchmode \
-nographics \ -nographics \
-quit \
-projectPath "$PWD/Development~/UnityProject" \ -projectPath "$PWD/Development~/UnityProject" \
-runTests \ -runTests \
-testPlatform EditMode \ -testPlatform EditMode \
@@ -11,5 +11,8 @@
"dependencies": { "dependencies": {
"com.unity.test-framework": "1.1.33", "com.unity.test-framework": "1.1.33",
"com.cneicy.shrink-installer": "file:../../.." "com.cneicy.shrink-installer": "file:../../.."
} },
"testables": [
"com.cneicy.shrink-installer"
]
} }
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eac67073f2eb71043bb104ae8931248b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 87984663a86071f408003b68afa18e0c
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+16 -45
View File
@@ -12,10 +12,7 @@ namespace ShrinkSDK.Installer
{ {
internal sealed class ShrinkSdkInstallerWindow : EditorWindow internal sealed class ShrinkSdkInstallerWindow : EditorWindow
{ {
private AddRequest? _addRequest;
private ListRequest? _listRequest; private ListRequest? _listRequest;
private ResolveRequest? _resolveRequest;
private ShrinkSdkPackageEntry? _pendingInstall;
private int _selectedPackageIndex; private int _selectedPackageIndex;
private string _status = "Ready"; private string _status = "Ready";
private MessageType _statusType = MessageType.Info; private MessageType _statusType = MessageType.Info;
@@ -70,43 +67,10 @@ namespace ShrinkSDK.Installer
EditorGUILayout.HelpBox(_status, _statusType); EditorGUILayout.HelpBox(_status, _statusType);
} }
private bool IsBusy => _resolveRequest != null || _addRequest != null || _listRequest != null; private bool IsBusy => _listRequest != null;
private void Update() 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) if (_listRequest != null && _listRequest.IsCompleted)
{ {
var request = _listRequest; var request = _listRequest;
@@ -118,7 +82,12 @@ namespace ShrinkSDK.Installer
} }
else else
{ {
SetStatus("Package diagnostics failed: " + request.Error.message, MessageType.Warning); var errorMessage = request.Error?.message;
SetStatus(
string.IsNullOrWhiteSpace(errorMessage)
? "Package diagnostics did not complete while Unity was resolving packages. Refresh diagnostics after resolution completes."
: "Package diagnostics failed: " + errorMessage,
MessageType.Warning);
} }
} }
} }
@@ -128,9 +97,9 @@ namespace ShrinkSDK.Installer
try try
{ {
ShrinkSdkManifestStore.EnsureShrinkSdkRegistry(); ShrinkSdkManifestStore.EnsureShrinkSdkRegistry();
_pendingInstall = null; _listRequest = null;
_resolveRequest = Client.Resolve(); Client.Resolve();
SetStatus("Registry configuration written. Resolving packages.", MessageType.Info); SetStatus("Registry configuration written. Unity is resolving packages.", MessageType.Info);
} }
catch (Exception exception) catch (Exception exception)
{ {
@@ -142,10 +111,12 @@ namespace ShrinkSDK.Installer
{ {
try try
{ {
ShrinkSdkManifestStore.EnsureShrinkSdkRegistry(); ShrinkSdkManifestStore.EnsurePackageInstallation(entry);
_pendingInstall = entry; _listRequest = null;
_resolveRequest = Client.Resolve(); Client.Resolve();
SetStatus("Resolving registry for " + entry.PackageSpecifier, MessageType.Info); SetStatus(
"Pinned " + entry.PackageName + " " + entry.Version + " in Packages/manifest.json. Unity is resolving packages.",
MessageType.Info);
} }
catch (Exception exception) catch (Exception exception)
{ {
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 87b0b212685b2564eaa5586bb567bfab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+41 -1
View File
@@ -27,6 +27,28 @@ namespace ShrinkSDK.Installer
internal static void EnsureShrinkSdkRegistry() internal static void EnsureShrinkSdkRegistry()
{ {
var manifest = ReadManifest(); var manifest = ReadManifest();
EnsureShrinkSdkRegistry(manifest);
AtomicWrite(manifest.ToString(Formatting.Indented) + Environment.NewLine);
}
internal static void EnsurePackageInstallation(ShrinkSdkPackageEntry package)
{
var manifest = ReadManifest();
EnsureShrinkSdkRegistry(manifest);
EnsurePinnedDependency(manifest, package.PackageName, package.Version);
if (package.RequiresUniTask)
{
EnsurePinnedDependency(
manifest,
ShrinkSdkPackageCatalog.UniTaskPackageName,
ShrinkSdkPackageCatalog.UniTaskGitUrl);
}
AtomicWrite(manifest.ToString(Formatting.Indented) + Environment.NewLine);
}
private static void EnsureShrinkSdkRegistry(JObject manifest)
{
var registries = manifest["scopedRegistries"] as JArray; var registries = manifest["scopedRegistries"] as JArray;
if (registries == null) if (registries == null)
{ {
@@ -71,8 +93,26 @@ namespace ShrinkSDK.Installer
registry["scopes"] = scopes; registry["scopes"] = scopes;
} }
}
AtomicWrite(manifest.ToString(Formatting.Indented) + Environment.NewLine); private static void EnsurePinnedDependency(JObject manifest, string packageName, string version)
{
var dependencies = manifest["dependencies"] as JObject;
if (dependencies == null)
{
dependencies = new JObject();
manifest["dependencies"] = dependencies;
}
var existing = dependencies[packageName];
if (existing != null && !string.Equals(existing.Value<string>(), version, StringComparison.Ordinal))
{
throw new InvalidOperationException(
"Packages/manifest.json already pins " + packageName + " to " + existing.Value<string>() +
". ShrinkSDK requires the fixed version " + version + ".");
}
dependencies[packageName] = version;
} }
private static JObject ReadManifest() private static JObject ReadManifest()
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c7a718e89696b5d499781f9b04f63c27
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+25 -21
View File
@@ -7,17 +7,18 @@ namespace ShrinkSDK.Installer
{ {
internal sealed class ShrinkSdkPackageEntry internal sealed class ShrinkSdkPackageEntry
{ {
public ShrinkSdkPackageEntry(string displayName, string packageName, string version) public ShrinkSdkPackageEntry(string displayName, string packageName, string version, bool requiresUniTask = false)
{ {
DisplayName = displayName; DisplayName = displayName;
PackageName = packageName; PackageName = packageName;
Version = version; Version = version;
RequiresUniTask = requiresUniTask;
} }
public string DisplayName { get; } public string DisplayName { get; }
public string PackageName { get; } public string PackageName { get; }
public string Version { get; } public string Version { get; }
public string PackageSpecifier => PackageName + "@" + Version; public bool RequiresUniTask { get; }
} }
internal static class ShrinkSdkPackageCatalog internal static class ShrinkSdkPackageCatalog
@@ -25,34 +26,37 @@ namespace ShrinkSDK.Installer
internal const string RegistryName = "ShrinkSDK"; internal const string RegistryName = "ShrinkSDK";
internal const string RegistryUrl = "https://git.crash.work/api/packages/ShrinkSDK/npm/"; internal const string RegistryUrl = "https://git.crash.work/api/packages/ShrinkSDK/npm/";
internal const string RegistryScope = "com.cneicy"; internal const string RegistryScope = "com.cneicy";
internal const string UniTaskPackageName = "com.cysharp.unitask";
internal const string UniTaskGitUrl = "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask#7c0f199fe0d3fc528024488ccd671e6c7b27745b";
internal static readonly ShrinkSdkPackageEntry StarterBasic = new( internal static readonly ShrinkSdkPackageEntry StarterBasic = new(
"ShrinkApp Starter Basic", "ShrinkApp Starter Basic",
"com.cneicy.shrink-app-starter-basic", "com.cneicy.shrink-app-starter-basic",
"0.1.0"); "0.1.2",
requiresUniTask: true);
internal static readonly IReadOnlyList<ShrinkSdkPackageEntry> Packages = new[] internal static readonly IReadOnlyList<ShrinkSdkPackageEntry> Packages = new[]
{ {
new ShrinkSdkPackageEntry("ShrinkApp Core", "com.cneicy.shrink-app-core", "0.1.1"), new ShrinkSdkPackageEntry("ShrinkApp Core", "com.cneicy.shrink-app-core", "0.1.1", requiresUniTask: true),
StarterBasic, StarterBasic,
new ShrinkSdkPackageEntry("ShrinkCommand", "com.cneicy.shrink-command", "0.2.0"), new ShrinkSdkPackageEntry("ShrinkCommand", "com.cneicy.shrink-command", "0.2.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkCommand Integration App", "com.cneicy.shrink-command-integration-app", "0.1.0"), new ShrinkSdkPackageEntry("ShrinkCommand Integration App", "com.cneicy.shrink-command-integration-app", "0.1.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkCommand Integration EventBus", "com.cneicy.shrink-command-integration-eventbus", "0.1.1"), new ShrinkSdkPackageEntry("ShrinkCommand Integration EventBus", "com.cneicy.shrink-command-integration-eventbus", "0.1.1", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkCommand Integration Network", "com.cneicy.shrink-command-integration-network", "0.1.0"), new ShrinkSdkPackageEntry("ShrinkCommand Integration Network", "com.cneicy.shrink-command-integration-network", "0.1.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkContext App Adapter", "com.cneicy.shrink-context-app-adapter", "0.1.0"), new ShrinkSdkPackageEntry("ShrinkContext App Adapter", "com.cneicy.shrink-context-app-adapter", "0.1.2", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkContext Core", "com.cneicy.shrink-context-core", "0.1.0"), new ShrinkSdkPackageEntry("ShrinkContext Core", "com.cneicy.shrink-context-core", "0.1.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkContext EventBus Adapter", "com.cneicy.shrink-context-eventbus-adapter", "0.1.0"), new ShrinkSdkPackageEntry("ShrinkContext EventBus Adapter", "com.cneicy.shrink-context-eventbus-adapter", "0.1.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkDataSaver", "com.cneicy.shrink-datasaver", "2.2.0"), new ShrinkSdkPackageEntry("ShrinkDataSaver", "com.cneicy.shrink-datasaver", "2.2.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkDataSaver Integration App", "com.cneicy.shrink-datasaver-integration-app", "0.1.0"), new ShrinkSdkPackageEntry("ShrinkDataSaver Integration App", "com.cneicy.shrink-datasaver-integration-app", "0.1.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkDataSaver Integration EventBus", "com.cneicy.shrink-datasaver-integration-eventbus", "2.1.0"), new ShrinkSdkPackageEntry("ShrinkDataSaver Integration EventBus", "com.cneicy.shrink-datasaver-integration-eventbus", "2.1.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkEventBus", "com.cneicy.shrink-eventbus", "2.0.0"), new ShrinkSdkPackageEntry("ShrinkEventBus", "com.cneicy.shrink-eventbus", "2.0.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkEventBus Entities", "com.cneicy.shrink-eventbus-entities", "0.1.0"), new ShrinkSdkPackageEntry("ShrinkEventBus Entities", "com.cneicy.shrink-eventbus-entities", "0.1.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkModFramework", "com.cneicy.shrink-mod-framework", "0.2.0"), new ShrinkSdkPackageEntry("ShrinkModFramework", "com.cneicy.shrink-mod-framework", "0.2.1", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkNetwork", "com.cneicy.shrink-network", "0.2.0"), new ShrinkSdkPackageEntry("ShrinkNetwork", "com.cneicy.shrink-network", "0.2.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkNetwork Integration App", "com.cneicy.shrink-network-integration-app", "0.1.0"), new ShrinkSdkPackageEntry("ShrinkNetwork Integration App", "com.cneicy.shrink-network-integration-app", "0.1.0", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkNetwork Integration EventBus", "com.cneicy.shrink-network-integration-eventbus", "0.1.1"), new ShrinkSdkPackageEntry("ShrinkNetwork Integration EventBus", "com.cneicy.shrink-network-integration-eventbus", "0.1.1", requiresUniTask: true),
new ShrinkSdkPackageEntry("ShrinkShared CodeGen", "com.cneicy.shrink-shared-codegen", "0.1.0"), new ShrinkSdkPackageEntry("ShrinkShared CodeGen", "com.cneicy.shrink-shared-codegen", "0.1.0"),
new ShrinkSdkPackageEntry("ShrinkTutorial", "com.cneicy.shrink-tutorial", "0.1.0") new ShrinkSdkPackageEntry("ShrinkTutorial", "com.cneicy.shrink-tutorial", "0.1.1")
}; };
} }
} }
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7a785469a5003c64ba3c5a7663d703fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+2 -2
View File
@@ -2,12 +2,12 @@
`com.cneicy.shrink-installer` is the Git URL bootstrap package for ShrinkSDK. `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. 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 writes only catalogue-pinned dependencies to `Packages/manifest.json`. Packages which require UniTask also receive its fixed Git revision.
The installer does not copy templates into `Assets`, does not store credentials, and does not add an unpinned package version. The installer does not copy templates into `Assets`, does not store credentials, and does not add an unpinned package version.
## Bootstrap URL ## Bootstrap URL
```text ```text
https://git.crash.work/ShrinkSDK/Installer.git#v0.1.0 https://git.crash.work/ShrinkSDK/Installer.git#v0.1.7
``` ```
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cce500f16cff60c4a975bb202bc57b0c
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "com.cneicy.shrink-installer", "name": "com.cneicy.shrink-installer",
"version": "0.1.0", "version": "0.1.7",
"displayName": "ShrinkSDK Installer", "displayName": "ShrinkSDK Installer",
"description": "ShrinkSDK registry bootstrapper and fixed-version package installer.", "description": "ShrinkSDK registry bootstrapper and fixed-version package installer.",
"unity": "2022.3", "unity": "2022.3",
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c41475e2d6261484695ef0f146b55a01
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: