Skip to content
Open
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
11 changes: 11 additions & 0 deletions .yamato/_run-all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -444,3 +444,14 @@ run_all_project_tests_cmb_service_default:
{% endfor -%}
{% endfor -%}
{% endfor -%}


# Runs the NGO 2.x -> 3.x editor script upgrade validation (see api-updater-test.yml)
run_all_api_updater_tests:
name: Run All API Updater Tests
dependencies:
{% for platform in test_platforms.default -%}
{% for editor in validation_editors.default -%}
- .yamato/api-updater-test.yml#api_updater_test_{{ platform.name }}_{{ editor }}
{% endfor -%}
{% endfor -%}
17 changes: 12 additions & 5 deletions .yamato/_triggers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,6 @@ pr_code_changes_checks:
cancel_old_ci: true







# Unified (NGO + N4E) validation, on demand.
# This job allows the Unified tests to be kicked off by commenting "/ci unified".
# This is useful for PRs where pr_code_changes_checks doesn't trigger.
Expand All @@ -134,6 +129,18 @@ unified_pr_checks:
cancel_old_ci: true


# NGO 2.x -> 3.x on demand editor script upgrade validation.
# This job allows the API updater test to be kicked off by commenting "/ci apiupdater".
api_updater_pr_checks:
name: API Updater checks [on demand]
dependencies:
- .yamato/_run-all.yml#run_all_api_updater_tests
triggers:
expression: |-
pull_request.comment eq "apiupdater"
cancel_old_ci: true


# Run all tests on nightly basis.
# Same subset as pull_request_trigger with addition of mobile/desktop/console tests and webgl builds
# Those tests are all running on trunk and the default editor (since it's daily and running all of them would add a lot of overhead)
Expand Down
41 changes: 41 additions & 0 deletions .yamato/api-updater-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{% metadata_file .yamato/project.metafile %}
---

# DESCRIPTION--------------------------------------------------------------------------
# This job validates the NGO 2.x -> 3.x upgrade path for editor scripts.
# NGO 3.0 renamed the editor assembly and its namespaces (Unity.Netcode.Editor ->
# Unity.Netcode.GameObjects.Editor), and every relocated public type carries a [MovedFrom] so that
# Unity's API updater rewrites a 2.x project's editor scripts automatically on upgrade.
# apiupdaterproject holds editor code written against the 2.x API; the job imports it with
# -accept-apiupdate and asserts that every 2.x type reference was rewritten and none survived.
# See apiupdaterproject/README.md.


# TECHNICAL CONSIDERATIONS---------------------------------------------------------------
# apiupdaterproject/Packages/manifest.json references the package by relative path
# (file:../../com.unity.netcode.gameobjects), so the job tests the package as it sits in the repo
# and needs no package-pack dependency.
# The script restores the 2.x sources when it finishes, so the checkout is left unmodified and the
# job is safe to re-run on the same agent.
# --clean purges Library first: the assertion is meaningless against a warm Library that already
# holds rewritten sources from a previous run.

{% for platform in test_platforms.default -%}
{% for editor in validation_editors.default -%}
api_updater_test_{{ platform.name }}_{{ editor }}:
name : API Updater Test - NGO 2.x editor scripts upgrade [{{ platform.name }}, {{ editor }}]
agent:
type: {{ platform.type }}
image: {{ platform.image }}
flavor: {{ platform.flavor }}
commands:
- unity-downloader-cli --fast --wait -u {{ editor }} -c Editor # Installing basic editor for the import
- python apiupdaterproject/run_upgrade_test.py --unity .Editor --clean
artifacts:
logs:
paths:
- "apiupdaterproject/upgrade-test.log"
dependencies:
- .yamato/_run-all.yml#run_quick_checks # initial checks to perform fast validation of common errors
{% endfor -%}
{% endfor -%}
78 changes: 78 additions & 0 deletions apiupdaterproject/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# This .gitignore file should be placed at the root of your Unity project directory
Comment thread
NoelStephensUnity marked this conversation as resolved.
#
# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
#
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/

# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/

# Asset meta data should only be ignored when the corresponding asset is also ignored
!/[Aa]ssets/**/*.meta

# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*

# Autogenerated Jetbrains Rider plugin
/[Aa]ssets/Plugins/Editor/JetBrains*

# Visual Studio cache directory
.vs/

# Gradle cache directory
.gradle/

# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db

# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta

# Unity3D generated file on crash reports
sysinfo.txt

# Builds
*.apk
*.aab
*.unitypackage

# Crashlytics generated file
crashlytics-build.properties

# Packed Addressables
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*

# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*
/[Aa]ssets/[Ss]treamingAssets/BuildInfo.json
/[Aa]ssets/[Ss]treamingAssets/BuildInfo.json.meta

InitTestScene*

# API updater test run log
upgrade-test.log
81 changes: 81 additions & 0 deletions apiupdaterproject/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# apiupdaterproject — agent notes

Background for anyone changing this project or the relocation metadata it tests. `README.md` covers
what it is and how to run it; this file covers why it is built this way and what will bite you.

## Orientation

* This is a standalone Unity project at the repo root. It is not part of `testproject` or
`minimalproject`, and the package does not reference it.
* It validates one thing end to end: that a project written against the **NGO 2.x** editor API is
migrated automatically by Unity's API updater when the package is upgraded to **3.x**.
* **The mechanism it tests does not live here.** The `[MovedFrom]` attributes are on the real types in
`com.unity.netcode.gameobjects/Editor/**`. This project only consumes them.
* **Do not "fix" the sources under `Assets/Editor`.** They are deliberately written against the 2.x
API and are the input to the test. A helpful cleanup there silently guts it.
* The expected-type list in `run_upgrade_test.py` is frozen: it enumerates the public editor API of
`develop-2.0.0`, which is released and cannot change. It only needs extending if a public editor
type is relocated again within 3.x.
* CI runs it on demand only — comment `/ci apiupdater` on a PR. See `.yamato/api-updater-test.yml`.
* **Opening this project locally mutates it.** Unity rewrites `ProjectVersion.txt` to whatever editor
opened it, and the package manager can add builtin modules to `Packages/manifest.json` that only
exist in that editor — `com.unity.modules.smartstrings` from a 6000.7 alpha broke the 6000.6 CI job
exactly this way. Check `git diff` on those two files before committing, and keep the manifest to
modules that exist in the editor the job downloads (`validation_editors.default`).
* Verified beyond this project: a real sample project upgraded 7 of its own scripts automatically,
including a `NetcodeEditorBase<T>` subclass.

## Why not `[Obsolete(... (UnityUpgradable))]` skeletons

That is the other mechanism for this, and it was measured first: a second assembly declaring an empty
skeleton of each 2.x type under the old namespace, each carrying
`[Obsolete("... (UnityUpgradable) -> [asm] ns.Type", true)]`. It works for every non-generic type, but

* it **cannot** relocate a generic type — a target carrying a type argument list is treated as a
same-namespace *rename*, so the namespace and assembly are dropped (see the table below), which
left `NetcodeEditorBase<TT>` needing `MovedFrom` anyway;
* it costs a second assembly and a hand-maintained parallel API surface that has to track the real
one's `#if` guards and eventually be deleted;
* it leaves the stale `using` directives and expands namespace aliases at the reference site, where
`MovedFrom` removes the dead usings and rewrites aliases in place.

What it buys, and `MovedFrom` does not, is a better error when the user *declines* the update:
`'NetworkManagerEditor' is obsolete: ... Use Unity.Netcode.GameObjects.Editor.NetworkManagerEditor
instead` rather than a bare CS0246. It is also the only route for member-level redirects (a renamed
method, a changed signature) and for type *renames*, which `MovedFrom` explicitly does not support.
Neither applies to this change — it is a pure relocation.

## Measured behaviour

Probed against 6000.7.0a5 with throwaway types, for a namespace + assembly move:

| Mechanism / `(UnityUpgradable)` target form | Non-generic type | Generic type |
| --- | --- | --- |
| `[Asm] Ns.Type` | rewritten, fully qualified | name replaced, namespace dropped |
| `[Asm] Ns.Type<TT>` | n/a | name replaced, namespace dropped (a no-op when the name is unchanged) |
| ``[Asm] Ns.Type`1`` | n/a | backtick emitted into the source verbatim |
| `* [Asm] Ns.Type<TT>` | n/a | not rewritten |
| `[MovedFrom(true, oldNs, oldAsm, null)]` | rewritten, fully qualified | rewritten, fully qualified |

Reference forms `MovedFrom` was confirmed to handle, via `Assets/Editor/DeprecatedApiUsage.cs` and
`Assets/Editor/DeprecatedApiUsageQualified.cs`: `using` + simple name, fully qualified name, namespace
alias, type alias, base type, `typeof`, and generic type argument. The dead
`using Unity.Netcode.Editor;` directives are removed and namespace aliases are rewritten in place
rather than expanded at each use.

## Known gap: assembly definition references

The updater rewrites C# source only; it does not touch `.asmdef` files.

References made **by GUID** — the Unity default — keep working untouched. A GUID reference resolves
to whichever `.asmdef` *asset* carries that GUID, independent of the `name` field inside it, and
`Editor/Unity.Netcode.Editor.asmdef` kept both its path and its GUID through the rename. So a 2.x
project referencing it by GUID silently ends up referencing `Unity.Netcode.GameObjects.Editor`.

References made **by name** (`"Unity.Netcode.Editor"`) no longer resolve and have to be repointed at
`Unity.Netcode.GameObjects.Editor` by hand. The same applies to the other renamed assemblies:
`Unity.Netcode.Editor.CodeGen` and `Unity.Netcode.PackageChecker.Editor`. Nothing can be done about
this from the package side — reviving the old assembly name is not an option, because
`Unity.Netcode.Editor` differs from N4E's `Unity.NetCode.Editor` only by the case of one letter and
the two `Library/ScriptAssemblies/*.dll` filenames collide when both packages are installed. Removing
that collision is what the 3.0 rename is for.
16 changes: 16 additions & 0 deletions apiupdaterproject/Assets/DefaultNetworkPrefabs.asset
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e651dbb3fbac04af2b8f5abf007ddc23, type: 3}
m_Name: DefaultNetworkPrefabs
m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkPrefabsList
IsDefault: 1
List: []
8 changes: 8 additions & 0 deletions apiupdaterproject/Assets/DefaultNetworkPrefabs.asset.meta

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

8 changes: 8 additions & 0 deletions apiupdaterproject/Assets/Editor.meta

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

32 changes: 32 additions & 0 deletions apiupdaterproject/Assets/Editor/DeprecatedApiUsage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Update only if new public editor API is added to NGO v2.x.x.
// It is used to validate the upgrade test. See ../../README.md.
#pragma warning disable 169 // Ignore field is never used warnings

using ApiUpdaterProject;
using Unity.Netcode.Editor;
using Unity.Netcode.Editor.Configuration;

namespace ApiUpdaterProject.Editor
{
internal class DeprecatedApiUsage
{
// Unity.Netcode.Editor -> Unity.Netcode.GameObjects.Editor
private NetworkPrefabsEditor m_NetworkPrefabsEditor;
private HiddenScriptEditor m_HiddenScriptEditor;
private UnityTransportEditor m_UnityTransportEditor;
private NetworkAnimatorEditor m_NetworkAnimatorEditor;
private NetworkRigidbodyEditor m_NetworkRigidbodyEditor;
private NetworkRigidbody2DEditor m_NetworkRigidbody2DEditor;
private NetcodeEditorBase<UpgradeProbeBehaviour> m_NetcodeEditorBase;
private NetworkBehaviourEditor m_NetworkBehaviourEditor;
private NetworkManagerEditor m_NetworkManagerEditor;
private NetworkManagerHelper m_NetworkManagerHelper;
private NetworkObjectEditor m_NetworkObjectEditor;
private NetworkRigidbodyBaseEditor m_NetworkRigidbodyBaseEditor;
private NetworkTransformEditor m_NetworkTransformEditor;

// Unity.Netcode.Editor.Configuration -> Unity.Netcode.GameObjects.Editor.Configuration
private NetcodeForGameObjectsProjectSettings m_ProjectSettings;
private NetworkPrefabProcessor m_NetworkPrefabProcessor;
}
}
11 changes: 11 additions & 0 deletions apiupdaterproject/Assets/Editor/DeprecatedApiUsage.cs.meta

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

24 changes: 24 additions & 0 deletions apiupdaterproject/Assets/Editor/DeprecatedApiUsageQualified.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Update only if new public editor API is added to NGO v2.x.x.
// It is used to validate the upgrade test. See ../../README.md.
#pragma warning disable 169 // Ignore field is never used warnings

using System;
using Cfg = Unity.Netcode.Editor.Configuration;
using ManagerEditor = Unity.Netcode.Editor.NetworkManagerEditor;

namespace ApiUpdaterProject.Editor
{
internal class DeprecatedApiUsageQualified
{
private Unity.Netcode.Editor.NetworkObjectEditor m_FullyQualified;
private Unity.Netcode.Editor.NetcodeEditorBase<ApiUpdaterProject.UpgradeProbeBehaviour> m_FullyQualifiedGeneric;
private Cfg.NetworkPrefabProcessor m_ThroughNamespaceAlias;
private ManagerEditor m_ThroughTypeAlias;

private Type TransformEditorType => typeof(Unity.Netcode.Editor.NetworkTransformEditor);
}

internal class DerivesFromDeprecatedBase : Unity.Netcode.Editor.HiddenScriptEditor
{
}
}

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

20 changes: 20 additions & 0 deletions apiupdaterproject/Assets/UpgradeProbeBehaviour.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using UnityEngine;

namespace ApiUpdaterProject
{
/// <summary>
/// Type argument for the <c>NetcodeEditorBase&lt;TT&gt;</c> references in Assets/Editor.
/// </summary>
/// <remarks>
/// Deliberately a local MonoBehaviour rather than NGO's NetworkManager. com.unity.transport 6.6.0
/// (the builtin on some 6000.6 editors) ships a `Unity.Netcode.NetworkManager` of its own in
/// Unity.Networking.Transport.NetcodeInterop, so any NetworkManager reference from an
/// auto-referencing assembly like Assembly-CSharp-Editor is CS0433-ambiguous. The type argument is
/// incidental to what the upgrade test measures - only the generic type reference itself has to be
/// rewritten - so this keeps the test independent of the resolved transport version.
/// </remarks>
// public, not internal: the references to it live in Assembly-CSharp-Editor, a different assembly.
public class UpgradeProbeBehaviour : MonoBehaviour
{
}
}
11 changes: 11 additions & 0 deletions apiupdaterproject/Assets/UpgradeProbeBehaviour.cs.meta

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

Loading