FTP: unified-canvas UX, legacy designer removal, SFTP enumeration fixes [STUD-80716] - #590
Open
viogroza wants to merge 1 commit into
Open
FTP: unified-canvas UX, legacy designer removal, SFTP enumeration fixes [STUD-80716]#590viogroza wants to merge 1 commit into
viogroza wants to merge 1 commit into
Conversation
…es [STUD-80716] Unified canvas adoption across all 8 FTP activities: - Property configuration moved from ActivitiesMetadata.json into the ViewModels; the metadata JSON now declares activities only, matching the Cryptography pack. WithFtpSession's Body is declared as a DesignProperty and hidden there, the same way JavaScopeViewModel handles its scope body. - One section vocabulary across both layers: Input -> Options -> Security / Proxy (scope only) -> Output last, applied to the ViewModels and the runtime [LocalizedCategory] attributes. - Toggle widget for all booleans (including ContinueOnError), Number widget for Port / Timeout / ProxyPort, FtpsMode data source added. - Verb-first renames: Directory Exists -> Check If Folder Exists, File Exists -> Check If File Exists, Enumerate Objects -> List Files and Folders. Terminology, casing and placeholders normalised. - Three field-anchored design-time validations on WithFtpSession (missing username, no authentication method, negative timeout). Each fires only where ExecuteAsync already threw, so no workflow that ran before now fails validation. Legacy WPF designer removal: - UiPath.FTP.Activities.Design deleted (40 files); activities now render from their ViewModels, mirroring Cryptography's feb1052. - Activity search synonyms preserved via DisplayNameAliasKeys in the metadata JSON. - Packaging narrowed to $(PortableFramework); the Windows TFM existed only to carry the Design dll. InternalsVisibleTo grants and the stale XmlnsDefinition removed. SFTP enumeration fix (UiPath.FTP/SftpSession.cs) -- the reported "SftpPathNotFoundException: No such file" when enumerating ".": - An unreadable sub-directory (no-such-file, permission denied, bare SSH_FX_FAILURE) is now skipped and traced instead of discarding the whole enumeration; connection and timeout failures still propagate. The caller's own RemotePath is not covered by this leniency. This is the actual fix, applied to all four walks, sync and async. - Dropped the ChangeDirectory / restore dance; it was not in a finally, so a mid-walk failure left the shared session's working directory pointing into the tree. - No symbolic-link guard: measured against SSH.NET 2024.1.0, S_IFDIR and S_IFLNK are distinct values of the mode word's type field, so a link is never reported as a directory and never enters the recursion set. An earlier revision added an !IsSymbolicLink clause on the strength of a mock that set both flags; it could not fire and has been removed, with the reasoning recorded so it is not reinstated. - 16 listing tests (11 enumeration, 5 download). FakeItem now derives its type flags from one kind so a fake cannot describe an entry no server can send -- notably IsRegularFile is true for a link, which SSH.NET reports and the old fake denied. Package documentation (docs/ ships in the nupkg as content/docs): - List Files and Folders and Download Files now document the recursive walk: links are not descended into, an unreadable sub-folder is skipped and traced rather than fatal, connection failures still fail, and a bad RemotePath still fails. Download Files also states that it reports success on a partial transfer. - The same notes added to the coded-workflow API reference for EnumerateObjects and DownloadFiles. - The Link limitation below is now stated wherever the docs previously promised it: the Filter enum table, FtpObjectInfo.Type, the FtpObjectType reference in overview.md and coded-api.md, the filter-by-type example, and the Check If File/Folder Exists pair (a link answers True as a file and False as a folder). Known limitation, documented in the shipped docs, pinned by tests, and deliberately not fixed here: FtpObjectType.Link is unreachable on the SFTP path, because SSH.NET's IsRegularFile is a (mode & S_IFREG) == S_IFREG test and S_IFLNK contains S_IFREG. List Files and Folders therefore reports links as File and its Link filter matches nothing, where FTP/FTPS reports them correctly. Correcting it changes FtpObjectInfo.Type for shipped workflows, so it belongs in its own change with its own release note. Follow-ups: localization sync for the renamed strings and the three synonym keys; the UseSftp + FtpsMode protocol-selector consolidation needs a repo-owner decision (breaking contract change). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
There was a problem hiding this comment.
Pull request overview
This PR modernizes the FTP activity pack by moving to unified-canvas ViewModel-driven UX, removing the legacy WPF designer assembly/TFM, and hardening SFTP recursive enumeration to avoid failing the whole operation when a listed subdirectory cannot be opened.
Changes:
- Refactors FTP activity ViewModels to fully configure unified-canvas property UI (ordering, sections/categories, widgets, placeholders, and visibility).
- Removes the legacy
UiPath.FTP.Activities.Designproject and updates packaging/solutions to ship only the portable TFM output. - Updates SFTP listing walks to avoid
ChangeDirectoryside-effects and to skip unreadable subdirectories during recursion (with trace warnings), plus adjusts link classification behavior docs.
Reviewed changes
Copilot reviewed 70 out of 73 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| Activities/FTP/UiPath.FTP/SftpSession.cs | Refactors SFTP recursive listing/walk logic, adds async listing seam, and introduces “skip unreadable subdirectory” behavior with tracing. |
| Activities/FTP/UiPath.FTP/Extensions.cs | Documents and enforces SFTP symlink classification behavior (links reported as files), removes unreachable IsSymbolicLink branch. |
| Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs | Aligns runtime property categories with unified-canvas section vocabulary and adds design-time validations. |
| Activities/FTP/UiPath.FTP.Activities/UiPath.FTP.Activities.csproj | Removes InternalsVisibleTo for the deleted legacy designer assembly. |
| Activities/FTP/UiPath.FTP.Activities/Properties/AssemblyInfo.cs | Removes XmlnsDefinition mapping for the deleted legacy designer namespace. |
| Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/WithFtpSessionViewModel.cs | Moves scope UI/property configuration into ViewModel (sections, widgets, data sources, visibility, menu actions). |
| Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/UploadFilesViewModel.cs | ViewModel-driven unified-canvas property configuration (labels/tooltips/placeholders/widgets/sections). |
| Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/MoveItemViewModel.cs | ViewModel-driven unified-canvas property configuration and ContinueOnError wiring. |
| Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/FileExistsViewModel.cs | ViewModel-driven unified-canvas property configuration including Output section placement. |
| Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/EnumerateObjectsViewModel.cs | ViewModel-driven unified-canvas property configuration and Output section placement. |
| Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DownloadFilesViewModel.cs | ViewModel-driven unified-canvas property configuration and ContinueOnError wiring. |
| Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DirectoryExistsViewModel.cs | ViewModel-driven unified-canvas property configuration including Output section placement. |
| Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DeleteViewModel.cs | ViewModel-driven unified-canvas property configuration and ContinueOnError wiring. |
| Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/BaseFtpViewModel.cs | Centralizes ContinueOnError UI configuration for consistent unified-canvas behavior across activities. |
| Activities/FTP/UiPath.FTP.Activities/MoveItem.cs | Aligns runtime ContinueOnError category/strings with unified-canvas Options section vocabulary. |
| Activities/FTP/UiPath.FTP.Activities/DownloadFiles.cs | Fixes runtime category for LocalPath to be Input (not Output). |
| Activities/FTP/UiPath.FTP.Activities.Packaging/UiPath.FTP.Activities.Packaging.csproj | Drops Windows TFM and removes packaging references to the legacy Design assembly. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/overview.md | Updates activity names/descriptions and documents SFTP “Link never produced” behavior. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/coded-api.md | Documents recursive-walk behavior changes and SFTP symlink/type limitations for coded API consumers. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/activities/WithFtpSession.md | Updates property table text, placeholders, and wording to match unified-canvas UX. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/activities/UploadFiles.md | Updates naming/wording and adds placeholders consistent with unified-canvas UX. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/activities/MoveItem.md | Updates naming/wording and adds placeholders consistent with unified-canvas UX. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/activities/FileExists.md | Renames doc title/display name and adds SFTP symlink caveat. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/activities/EnumerateObjects.md | Renames doc title/display name and documents recursive-walk + SFTP symlink limitations. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/activities/DownloadFiles.md | Adds recursive-walk behavior notes and updates wording/placeholders. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/activities/DirectoryExists.md | Renames doc title/display name and adds SFTP symlink caveat. |
| Activities/FTP/UiPath.FTP.Activities.Packaging/docs/activities/Delete.md | Updates wording and adds placeholders consistent with unified-canvas UX. |
| Activities/FTP/UiPath.FTP.Activities.Design/WithFtpSessionDesigner.xaml.cs | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/WithFtpSessionDesigner.xaml | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/UploadFilesDesigner.xaml.cs | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/UploadFilesDesigner.xaml | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/UiPath.FTP.Activities.Design.csproj | Deleted (legacy WPF designer project removed). |
| Activities/FTP/UiPath.FTP.Activities.Design/ReleaseNotes.txt | Included in legacy designer removal set (no functional code impact). |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.zh-TW.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.zh-CN.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.tr.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.ru.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.ro.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.pt.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.pt-BR.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.ko.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.ja.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.fr.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.es.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.es-MX.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.de.resx | Deleted legacy designer localization resource. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.Designer.cs | Deleted legacy designer generated resource accessor. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/SharedResources.cs | Deleted legacy designer resource bridge type. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/Resources.cs | Deleted legacy designer resource wrapper. |
| Activities/FTP/UiPath.FTP.Activities.Design/Properties/AssemblyInfo.cs | Deleted legacy designer assembly metadata. |
| Activities/FTP/UiPath.FTP.Activities.Design/MoveItemsDesigner.xaml.cs | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/MoveItemsDesigner.xaml | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/FileExistsDesigner.xaml.cs | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/FileExistsDesigner.xaml | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/EnumerateObjectsDesigner.xaml.cs | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/EnumerateObjectsDesigner.xaml | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/DownloadFilesDesigner.xaml.cs | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/DownloadFilesDesigner.xaml | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/DirectoryExistsDesigner.xaml.cs | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/DirectoryExistsDesigner.xaml | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/DesignerMetadata.cs | Deleted legacy designer metadata/registration. |
| Activities/FTP/UiPath.FTP.Activities.Design/DeleteDesigner.xaml.cs | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/DeleteDesigner.xaml | Deleted as part of legacy designer project removal. |
| Activities/FTP/UiPath.FTP.Activities.Design/ApiRegistrationBase.cs | Deleted legacy synonym API registration base. |
| Activities/FTP/UiPath.FTP.Activities.Design/ActivitySynonymApiRegistration.cs | Deleted legacy activity synonym registration logic (now preserved via metadata). |
| Activities/Credentials/UiPath.Credentials.Activities/UiPath.Credentials.Activities.csproj | Removes an incorrect/obsolete InternalsVisibleTo to the deleted FTP designer assembly. |
| Activities/Community.Activities.sln | Removes the legacy FTP designer project from the top-level solution. |
| Activities/Activities.FTP.sln | Removes the legacy FTP designer project from the FTP pack solution. |
Files not reviewed (2)
- Activities/FTP/UiPath.FTP.Activities.Design/Properties/UiPath.FTP.Activities.Design.Designer.cs: Generated file
- Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.Designer.cs: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
185
to
189
| MenuActionsBuilder<PasswordInputMode>.WithValueProperty(ProxyPasswordInputModeSwitch) | ||
| .AddMenuProperty(ProxyPassword, PasswordInputMode.Password) | ||
| .AddMenuProperty(ProxySecurePassword, PasswordInputMode.SecurePassword) | ||
| .BuildAndInsertMenuActions(true); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Adopts the unified canvas across all 8 FTP activities, removes the legacy WPF designer project, and fixes the reported SFTP enumeration crash. Follows the Cryptography pack (
c21a272, STUD-80718) as the reference implementation.Unified canvas
ActivitiesMetadata.jsoninto the ViewModels. The JSON now declares activities only ("Properties": []), matching Cryptography.WithFtpSession'sBodyis declared as aDesignPropertyand hidden in the ViewModel, the same wayJavaScopeViewModelhandles its scope body.[LocalizedCategory]attributes so the two cannot drift.ContinueOnError), Number forPort/Timeout/ProxyPort, a data source forFtpsMode, placeholders on path fields.DisplayNameAliasKeys.WithFtpSession(missing username, no authentication method, negative timeout).Legacy designer removal
UiPath.FTP.Activities.Designdeleted (40 files) - activities render from their ViewModels now, mirroring Cryptography'sfeb1052. Packaging narrows to$(PortableFramework); the Windows TFM existed only to carry the Design dll. Activity search synonyms were preserved through the metadata JSON.SFTP enumeration fix
The reported failure -
SftpPathNotFoundException: No such filewhen enumerating".":readdirand then refuseopendiron it. That sub-directory is now skipped and its path traced, instead of failing the operation. Connection and timeout failures still propagate, and the caller's ownRemotePathis not covered by the leniency.ChangeDirectory/ restore dance. It was not in afinally, so a mid-walk failure left the shared session's working directory pointing into the tree - and since the scope shares one session, withContinueOnError = Trueevery later relative path resolved from the wrong place.Behaviour changes reviewers should look at
InvalidWorkflowExceptionat workflow load instead ofArgumentNullExceptionduring execution, which an in-workflow Try/Catch can no longer intercept. No previously-working workflow is affected: each validation fires only whereExecuteAsyncalready threw.Symbolic-link handling is unchanged across all 8 activities - the recursion and file-selection predicates are equivalent to the pre-branch ones. No public API change: no activity property added, removed, renamed or retyped; no
[RequiredArgument]/[Obsolete]/[DefaultValue]change; no design-timeIsRequiredchange;UiPath.FTP.Activities.APIuntouched.Known limitation - documented, pinned, deliberately not fixed here
FtpObjectType.Linkis unreachable on the SFTP path. SSH.NET'sIsRegularFileis a(mode & S_IFREG) == S_IFREGtest andS_IFLNKcontainsS_IFREG, so every symbolic link classifies asFile: List Files and Folders'Linkfilter matches nothing over SFTP, andCheck If File ExistsanswersTruefor a link whileCheck If Folder ExistsanswersFalsefor a linked folder. FTP/FTPS reportLinkcorrectly, so the two protocols disagree.The fix is understood - separate the dispatch classifier from the reporting one; a naive reorder regresses
DownloadandFileExists- but it changesFtpObjectInfo.Typefor shipped workflows, so it belongs in its own change with its own release note. The shipped docs now state it everywhere they previously promisedLink, andSFTP_GetFtpObjectType_ClassifiesSymbolicLinkAsFilepins it so it cannot be changed by accident.Verification
Activities.FTP.slnbuilds clean - 0 errors; the only warnings are 2 pre-existingCS0618(FtpSslProtocols.Default, x2 TFMs) and 2 NuGet pack deprecations.dotnet test Activities.FTP.sln: 59/59 inUiPath.FTP.Tests, 18/19 inUiPath.FTP.Activities.API.Tests(1 pre-existing skip).lib/net6.0withUiPath.FTP.dll,UiPath.FTP.Activities.dll,.API.dll/.xmland 13 satellite locales - no Design dll, nolib/net6.0-windows. Same layout Cryptography has shipped sincefeb1052..resx/ C# resource key resolves; all 8 icons present; runtime[LocalizedCategory]matches ViewModelCategoryon every visible property.Before merge
UiPath.FTP.Activities.Design.*.resxpath on the Localization side so the orphans do not come back.VersionPrefixis still3.2.0. The package now ships one fewer assembly and drops a TFM. Neither reference commit touched the version props, so precedent says leave it - flagging for a maintainer call.Follow-up, needs a repo-owner decision
UseSftp(bool) +FtpsMode(3-value enum) are two controls for one concept: the transport is really a four-way choice, so 6 states encode 4 meanings andFtpsModeis silently ignored whenUseSftpis on. Consolidating into oneProtocolselector touches public properties, so it needs owner sign-off. A cheap non-breaking slice exists in the meantime: there is no rule onUseSftp, so with SFTP selected the user still seesFtpsMode,SslProtocolsandAcceptAllCertificates, none of which SFTP reads.🤖 Generated with Claude Code