diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a1e5db..300de99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this package will be documented in this file. +## [2.4.4] - 2024-07-19 + +### Fixed + +- Fixed the Unity Editor stuck on "Creating workspace" when "Use Unity Version Control" was selected from the Hub + ## [2.4.3] - 2024-06-20 ### Added diff --git a/Editor/PlasticSCM/CollabMigration/MigrationDialog.cs b/Editor/PlasticSCM/CollabMigration/MigrationDialog.cs index 1a027a1..193c7c6 100644 --- a/Editor/PlasticSCM/CollabMigration/MigrationDialog.cs +++ b/Editor/PlasticSCM/CollabMigration/MigrationDialog.cs @@ -277,8 +277,7 @@ void LaunchMigration( { tokenExchangeResponse = AutoConfig.PlasticCredentials( unityAccessToken, - serverName, - projectPath); + serverName); if (tokenExchangeResponse.Error != null) { diff --git a/Editor/PlasticSCM/Configuration/AutoConfig.cs b/Editor/PlasticSCM/Configuration/AutoConfig.cs index ec79830..491c6a7 100644 --- a/Editor/PlasticSCM/Configuration/AutoConfig.cs +++ b/Editor/PlasticSCM/Configuration/AutoConfig.cs @@ -1,8 +1,11 @@ -using Codice.Client.Common; +using System; +using Codice.Client.Common; using Codice.CM.Common; -using PlasticGui; +using Codice.LogWrapper; +using PlasticGui.WorkspaceWindow.Home; using Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome; using Unity.PlasticSCM.Editor.WebApi; +using UnityEngine; namespace Unity.PlasticSCM.Editor.Configuration { @@ -10,127 +13,59 @@ internal static class AutoConfig { internal static TokenExchangeResponse PlasticCredentials( string unityAccessToken, - string serverName, - string wkPath) + string serverName) { - SetupUnityEditionToken.CreateCloudEditionTokenIfNeeded(); + SetupUnityEditionToken.CreateCloudEditionToken(); - bool isClientConfigConfigured = ClientConfig.IsConfigured(); - if (!isClientConfigConfigured) - { - ConfigureClientConf.FromUnityAccessToken( - unityAccessToken, serverName, wkPath); - } - - TokenExchangeResponse tokenExchangeResponse = WebRestApiClient. - PlasticScm.TokenExchange(unityAccessToken); - - if (tokenExchangeResponse.Error != null) - return tokenExchangeResponse; + var startTick = Environment.TickCount; - CloudEditionWelcomeWindow.JoinCloudServer( - serverName, - tokenExchangeResponse.User); - - if (!isClientConfigConfigured) - return tokenExchangeResponse; - - ConfigureProfile.ForServerIfNeeded( - serverName, - tokenExchangeResponse.User); + var tokenExchangeResponse = WebRestApiClient.PlasticScm.TokenExchange(unityAccessToken); - return tokenExchangeResponse; - } + mLog.DebugFormat("TokenExchange time {0} ms", Environment.TickCount - startTick); - static class ConfigureClientConf - { - internal static void FromUnityAccessToken( - string unityAccessToken, - string serverName, - string wkPath) + if (tokenExchangeResponse == null) { - CredentialsResponse response = WebRestApiClient. - PlasticScm.GetCredentials(unityAccessToken); - - if (response.Error != null) - { - UnityEngine.Debug.LogErrorFormat( - PlasticLocalization.GetString( - PlasticLocalization.Name.ErrorGettingCredentialsCloudProject), - response.Error.Message, - response.Error.ErrorCode); - - return; - } - - ClientConfigData configData = BuildClientConfigData( - serverName, wkPath, response); - - ClientConfig.Get().Save(configData); + mLog.Warn("Token exchange response null"); + Debug.LogWarning("Token exchange response null"); + return null; } - static ClientConfigData BuildClientConfigData( - string serverName, - string wkPath, - CredentialsResponse response) - { - SEIDWorkingMode workingMode = GetWorkingMode(response.Type); - - ClientConfigData configData = new ClientConfigData(); - - configData.WorkspaceServer = serverName; - configData.CurrentWorkspace = wkPath; - configData.WorkingMode = workingMode.ToString(); - configData.SecurityConfig = UserInfo.GetSecurityConfigStr( - workingMode, - response.Email, - GetPassword(response.Token, response.Type)); - configData.LastRunningEdition = InstalledEdition.Get(); - return configData; - } - - static string GetPassword( - string token, - CredentialsResponse.TokenType tokenType) + if (tokenExchangeResponse.Error != null) { - if (tokenType == CredentialsResponse.TokenType.Bearer) - return BEARER_PREFIX + token; - - return token; + var warning = string.Format("Unable to exchange token: {0} [code {1}]", + tokenExchangeResponse.Error.Message, tokenExchangeResponse.Error.ErrorCode); + mLog.ErrorFormat(warning); + Debug.LogWarning(warning); + return tokenExchangeResponse; } - static SEIDWorkingMode GetWorkingMode(CredentialsResponse.TokenType tokenType) + if (string.IsNullOrEmpty(tokenExchangeResponse.AccessToken)) { - if (tokenType == CredentialsResponse.TokenType.Bearer) - return SEIDWorkingMode.SSOWorkingMode; - - return SEIDWorkingMode.LDAPWorkingMode; + var warning = string.Format("Access token is empty for user: {0}", + tokenExchangeResponse.User); + mLog.InfoFormat(warning); + Debug.LogWarning(warning); } + + // This creates the client.conf if needed but doesn't overwrite it if it exists already, + // and it also updates the profiles.conf and tokens.conf with the new AccessToken + UserAccounts.SaveAccount( + serverName, + SEIDWorkingMode.SSOWorkingMode, // Hub sign-in working mode + tokenExchangeResponse.User, + tokenExchangeResponse.AccessToken, + null, + null, + null); - const string BEARER_PREFIX = "Bearer "; - } - - static class ConfigureProfile - { - internal static void ForServerIfNeeded(string serverName, string user) - { - ProfileManager profileManager = CmConnection.Get().GetProfileManager(); - - ServerProfile serverProfile = profileManager.GetProfileForServer(serverName); - - if (serverProfile != null) - return; - - serverProfile = ProfileManager.CreateProfile( - serverName, - SEIDWorkingMode.SSOWorkingMode, - user); + CloudEditionWelcomeWindow.JoinCloudServer( + serverName, + tokenExchangeResponse.User); - profileManager.SaveProfile(serverProfile); - } + return tokenExchangeResponse; } + static readonly ILog mLog = PlasticApp.GetLogger("AutoConfig"); } - } diff --git a/Editor/PlasticSCM/Configuration/CloudEdition/Welcome/CloudEditionWelcomeWindow.cs b/Editor/PlasticSCM/Configuration/CloudEdition/Welcome/CloudEditionWelcomeWindow.cs index 05534b3..c34ec49 100644 --- a/Editor/PlasticSCM/Configuration/CloudEdition/Welcome/CloudEditionWelcomeWindow.cs +++ b/Editor/PlasticSCM/Configuration/CloudEdition/Welcome/CloudEditionWelcomeWindow.cs @@ -52,6 +52,8 @@ internal static CloudEditionWelcomeWindow GetWelcomeWindow() return GetWindow(); } + // Set the Default Server in the config files of all our clients so they are already all configured at once + // this avoids having the Desktop application asking the user again later internal static void JoinCloudServer( string cloudServer, string username) @@ -65,7 +67,7 @@ internal static void JoinCloudServer( KnownServers.ServersFromCloud.InitializeForWindows( PlasticGuiConfig.Get().Configuration.DefaultCloudServer); - SetupUnityEditionToken.CreateCloudEditionTokenIfNeeded(); + SetupUnityEditionToken.CreateCloudEditionToken(); ClientConfigData clientConfigData = ConfigurationChecker.GetClientConfigData(); diff --git a/Editor/PlasticSCM/Hub/Operations/CreateWorkspace.cs b/Editor/PlasticSCM/Hub/Operations/CreateWorkspace.cs index bb9b49b..b961ea7 100644 --- a/Editor/PlasticSCM/Hub/Operations/CreateWorkspace.cs +++ b/Editor/PlasticSCM/Hub/Operations/CreateWorkspace.cs @@ -114,8 +114,7 @@ void CreateWorkspaceIfNeeded(object state) TokenExchangeResponse tokenExchangeResponse = AutoConfig.PlasticCredentials( parameters.AccessToken, - parameters.RepositorySpec.Server, - parameters.WorkspaceFullPath); + parameters.RepositorySpec.Server); if (tokenExchangeResponse.Error != null) { diff --git a/Editor/PlasticSCM/Hub/Operations/DownloadRepository.cs b/Editor/PlasticSCM/Hub/Operations/DownloadRepository.cs index 6a9dfd2..527710a 100644 --- a/Editor/PlasticSCM/Hub/Operations/DownloadRepository.cs +++ b/Editor/PlasticSCM/Hub/Operations/DownloadRepository.cs @@ -92,8 +92,7 @@ void DownloadRepositoryToPathIfNeeded(object state) TokenExchangeResponse tokenExchangeResponse = AutoConfig.PlasticCredentials( parameters.AccessToken, - parameters.RepositorySpec.Server, - parameters.WorkspaceFullPath); + parameters.RepositorySpec.Server); if (tokenExchangeResponse.Error != null) { diff --git a/Editor/PlasticSCM/UnityConfigurationChecker.cs b/Editor/PlasticSCM/UnityConfigurationChecker.cs index 24821f6..6fcdd88 100644 --- a/Editor/PlasticSCM/UnityConfigurationChecker.cs +++ b/Editor/PlasticSCM/UnityConfigurationChecker.cs @@ -41,21 +41,21 @@ static bool IsPlasticInstalling() return window.IsPlasticInstalling; } } + + // The plugin rely on the "cloudedition.token" to be created in the "plastic4e config folder, instead of checking + // the one in the UVCS installation directory, since it can run without an existing installation. internal static class SetupUnityEditionToken { - internal static void CreateCloudEditionTokenIfNeeded() + // Always create the "cloudedition.token" when called from the Hub or the Cloud Edition Welcome window + internal static void CreateCloudEditionToken() { - string toolPath = PlasticInstallPath.GetPlasticExePath(); + var tokenFilePath = UserConfigFolder.GetConfigFile(EditionToken.CLOUD_EDITION_FILE_NAME); - if (!string.IsNullOrEmpty(toolPath)) - return; - - string tokenFilePath = UserConfigFolder.GetConfigFile( - EditionToken.CLOUD_EDITION_FILE_NAME); - - File.Create(tokenFilePath).Dispose(); + if (!File.Exists(tokenFilePath)) + File.Create(tokenFilePath).Dispose(); } - + + // Synchronize the "cloudedition.token" file between the installation directory and the "plastic4" config folder internal static void FromPlasticInstallation(string plasticClientBinDir) { bool isCloudPlasticInstall = IsPlasticInstallOfEdition( diff --git a/package.json b/package.json index 7dd651e..f98c66c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.unity.collab-proxy", "displayName": "Version Control", - "version": "2.4.3", + "version": "2.4.4", "unity": "2020.3", "unityRelease": "48f1", "description": "The package gives you the ability to use Unity Version Control in the Unity editor. To use Unity Version Control, a subscription is required. Learn more about how you can get started for free by visiting https://unity.com/solutions/version-control", @@ -23,18 +23,18 @@ ], "category": "Editor", "relatedPackages": { - "com.unity.collab-proxy.tests": "2.4.3" + "com.unity.collab-proxy.tests": "2.4.4" }, "_upm": { - "changelog": "### Added\n\n- Changed the default ignore.conf to not ignore itself\n- Added \"Undo unchanged\" and \"Undo checkouts keeping changes\" options to pending changes view\n- Removed focus redirection after Check-in\n\n### Fixed\n\n- Moving folders in the Editor now correctly use the UVCS \"Move\" operation\n- Fixed hang on domain reload \n- Fixed \"item with the same key has already been added\" error\n- Fixed failure to delete a .meta file when deleting a private folder from the pending changes\n- Supported workspace name with non-latin characters in Pending Changes\n- Fixed text cut-off in filter rules dialog\n- Fixed unexpected error while switching between branches\n- Fixed error after renaming a parent branch of the working branch\n- Fixed variables's value becoming clear after resolving conflict in inspector\n- Removed misleading indication about shelves\n- Fixed column sorting in pending changes view\n- Fixed missing incoming changes after removing a branch\n- Fixed \"Collection was modified\" error when doing multiple renames in a row\n- Fixed undo & check-in operations not working when the current scene was never saved\n- Fixed check in error if nothing is selected in the pending changes tree" + "changelog": "### Fixed\n\n- Fixed the Unity Editor stuck on \"Creating workspace\" when \"Use Unity Version Control\" was selected from the Hub" }, "upmCi": { - "footprint": "37d231fcc2d5df5d9a23dabe85e2454320fa3a37" + "footprint": "a7e26997432f77ab1e4a2cbf5ba58e4f2f4982ad" }, "documentationUrl": "https://docs.unity3d.com/Packages/com.unity.collab-proxy@2.4/manual/index.html", "repository": { "url": "https://github.cds.internal.unity3d.com/unity/com.unity.cloud.collaborate.git", "type": "git", - "revision": "d4c8fa70dd9679b33019945dc0a483c8c7e8038f" + "revision": "03b1de8d838eb1e427cb1b1d8bf9157f33377542" } }