Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
7a357da
Add Python IPC library (uipath-ipc) with server and client
eduard-dumitru Mar 31, 2026
cb91b01
python taking shape
eduard-dumitru Mar 31, 2026
9bab3ae
Add .NET interop test and fix named pipe concurrent I/O
eduard-dumitru Mar 31, 2026
6447210
Move existing Python attempt to _attempt0/
eduard-dumitru May 27, 2026
81f2c10
Scaffold uipath-ipc Python client package
eduard-dumitru May 27, 2026
87eb6a7
Add Visual Studio project file for uipath-ipc
eduard-dumitru May 27, 2026
51fe9b1
Wire up pytest test scaffolding
eduard-dumitru May 27, 2026
e2dd701
Switch uipath-ipc pyproj to glob-based file enumeration
eduard-dumitru May 28, 2026
f96ca15
Add wire DTOs and round-trip tests
eduard-dumitru May 28, 2026
0b36250
Add wire framing layer
eduard-dumitru May 28, 2026
b30455b
Add NamedPipeClientTransport
eduard-dumitru May 28, 2026
5c391b1
Add IpcConnection — request/response dispatcher
eduard-dumitru May 28, 2026
fca5df3
Add IpcClient + dynamic proxy
eduard-dumitru May 28, 2026
2c7abe6
Refine RemoteException — message/type/stack/chain mapping
eduard-dumitru May 28, 2026
ac0fd75
Forward caller cancellation to the server
eduard-dumitru May 28, 2026
c328cb0
Add per-client request timeout
eduard-dumitru May 28, 2026
1a2412f
Auto-reconnect on transport disconnect
eduard-dumitru May 28, 2026
2feb512
Add TcpClientTransport
eduard-dumitru May 28, 2026
2392e23
Polish: README, py.typed, explicit wheel packaging, smoke checks
eduard-dumitru May 28, 2026
3fd4eb7
Add gated .NET interop tests
eduard-dumitru May 28, 2026
3dfbf3a
Flip integration tests to opt-out
eduard-dumitru May 28, 2026
4a50117
Retry briefly on FileNotFoundError when connecting a named pipe
eduard-dumitru May 28, 2026
2d9689f
Add dedicated .NET test server and fix wire serialization
eduard-dumitru May 28, 2026
b48e3cc
Add debugpy to dev extras
eduard-dumitru May 28, 2026
b3cdd0e
Wire CI for project-scoped npm feed and bypass Safe Chain Guard
eduard-dumitru May 28, 2026
ad36ce6
Parameterize CI: opt-in publish stages, reuseArtifactsFromBuildId
eduard-dumitru May 28, 2026
5260b42
Publish NPM to uipath-ipc-deps as primary; GitHub Packages best-effort
eduard-dumitru May 28, 2026
2b93f16
Fix Npm@1 publish param name: publishFeed (not publishFeedCombined)
eduard-dumitru May 28, 2026
26ef0fd
Add Python build, test, and publish to the pipeline (Pass 2)
eduard-dumitru May 28, 2026
fb7d06a
Apply Windows-style FileNotFoundError retry to POSIX connect too
eduard-dumitru May 28, 2026
05009da
Default reuseArtifactsFromBuildId to '0' (no-reuse sentinel)
eduard-dumitru May 28, 2026
41bf13f
Bind Python package version to the same source as NuGet/NPM
eduard-dumitru May 28, 2026
7e441e2
Split Build into per-technology stages (NuGet / NPM / Python)
eduard-dumitru May 28, 2026
402e9ec
Add opt-out build parameters (buildNuGet / buildNpm / buildPython)
eduard-dumitru May 28, 2026
1411701
Add server-to-client callback support (uipath-ipc 0.2.0)
eduard-dumitru May 29, 2026
c6578fa
Treat empty Data string as a void response (not just null)
eduard-dumitru May 29, 2026
34810a5
feat(python): add IPC server (listen/accept/host-services)
eduard-dumitru Jun 9, 2026
b9d6a0e
feat(python): port Message.Client / GetCallback reach-back
eduard-dumitru Jun 9, 2026
68c17fc
test(python): reverse .NET-client <-> Python-IpcServer interop + disp…
eduard-dumitru Jun 9, 2026
a98387f
chore(python): delete _attempt0 reference port
eduard-dumitru Jun 9, 2026
7e1a012
fix(python): address code-review findings (server + reach-back)
eduard-dumitru Jun 10, 2026
079c8f6
ci: split the pipeline into separate CI and Publish pipelines
eduard-dumitru Jun 10, 2026
257566a
ci: make azp-start.yaml the param-free CI entry (drop azp-ci.yaml)
eduard-dumitru Jun 10, 2026
d3ba542
feat(python): per-call request timeout via a Message argument
eduard-dumitru Jun 10, 2026
f2118c8
ci: drop the ci pipeline resource from Publish; take ciPipelineId as …
eduard-dumitru Jun 11, 2026
4cdf2e6
feat(python): BeforeConnect + BeforeCall hooks (client & server)
eduard-dumitru Jun 11, 2026
73267c9
ci: re-add the ci pipeline resource, hardcoded to the "CI" pipeline
eduard-dumitru Jun 11, 2026
d7322bc
test(python): e2e coverage for per-call timeouts + hooks (incl. self-…
eduard-dumitru Jun 11, 2026
a1181fe
feat(python): infinite per-call timeout + Message wire_body (subclass…
eduard-dumitru Jun 11, 2026
c8be1c4
fix(python): address review feedback (framing, TMPDIR, fail-closed, l…
eduard-dumitru Jun 12, 2026
721a2ef
feat: MethodNotFoundException + close EndpointNotFoundException test …
eduard-dumitru Jun 12, 2026
ea14087
ci: hang-blame + timeouts for the .NET unit-test step
eduard-dumitru Jun 12, 2026
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
13 changes: 5 additions & 8 deletions src/CI/azp-dotnet-dist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@ steps:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactType: 'Container'

- task: DotNetCoreCLI@2
displayName: 'dotnet push to UiPath-Internal'
condition: succeeded()
inputs:
command: push
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg'
publishVstsFeed: 'Public.Feeds/UiPath-Internal'
# The `dotnet nuget push` step previously lived here and fired on every
# build (condition: succeeded). It now lives in
# `azp-nuget.publish.steps.yaml` under the Publish_NuGet stage, gated on
# the `publishNuGet` pipeline parameter so publishing is opt-in.

- task: PublishSymbols@2
displayName: 'Publish Symbols to UiPath Azure Artifacts Symbol Server'
Expand All @@ -29,4 +26,4 @@ steps:
symbolsFolder: $(Build.SourcesDirectory)
searchPattern: '**/UiPath.CoreIpc/bin/**/UiPath.CoreIpc.pdb'
symbolServerType: teamServices
indexSources: false
indexSources: false
9 changes: 8 additions & 1 deletion src/CI/azp-dotnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@ steps:
projects: '$(DotNet_SessionSolution)'
arguments: '--configuration $(DotNet_BuildConfiguration) -p:Version="$(FullVersion)" -p:DefineConstantsEx="CI"'

# The test step occasionally wedged forever on hosted agents with no output
# (e.g. build 12340525 — 50+ min on a step that normally takes ~1 min, zero
# log lines, nothing to diagnose). --blame-hang turns the next occurrence
# into a fast, diagnosable failure: vstest aborts after the timeout, NAMES
# the in-flight test(s), and attaches mini dumps to the run. The step-level
# timeout is a backstop for a wedge outside vstest itself.
- task: DotNetCoreCLI@2
displayName: '$(Label_DotNet) Run unit tests'
timeoutInMinutes: 20
inputs:
command: 'test'
projects: '$(DotNet_SessionSolution)'
publishTestResults: true
testRunTitle: '.NET tests'
arguments: '--no-build --configuration $(DotNet_BuildConfiguration) --logger "console;verbosity=detailed" -p:Version="$(FullVersion)" -p:DefineConstantsEx="CI"'
arguments: '--no-build --configuration $(DotNet_BuildConfiguration) --logger "console;verbosity=detailed" --blame-hang --blame-hang-timeout 10m --blame-hang-dump-type mini -p:Version="$(FullVersion)" -p:DefineConstantsEx="CI"'
84 changes: 78 additions & 6 deletions src/CI/azp-js.publish-npm.steps.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,37 @@
parameters:
- name: reuseArtifactsFromBuildId
type: string
default: ''
# Pipeline DEFINITION id that produced the artifact. Defaults to the current
# pipeline (single-pipeline reuse). The separate Publish pipeline passes the
# CI pipeline's id (e.g. $(resources.pipeline.ci.pipelineID)) so it can pull a
# CI build's artifact by id.
- name: sourcePipelineId
type: string
default: '$(System.DefinitionId)'

steps:
- checkout: none

- download: current
artifact: 'NPM package'
# The destination path is $(Pipeline.Workspace)
# Pull the NPM artifact: from the current run by default, or from a
# previously-completed build if `reuseArtifactsFromBuildId` is a real id.
# '0' (default) and '' both mean "no reuse — pull from current run".
- ${{ if in(parameters.reuseArtifactsFromBuildId, '0', '') }}:
- download: current
artifact: 'NPM package'
- ${{ if not(in(parameters.reuseArtifactsFromBuildId, '0', '')) }}:
- task: DownloadPipelineArtifact@2
displayName: 'Download NPM package from build ${{ parameters.reuseArtifactsFromBuildId }}'
inputs:
buildType: specific
project: $(System.TeamProject)
pipeline: ${{ parameters.sourcePipelineId }}
buildVersionToDownload: specific
buildId: ${{ parameters.reuseArtifactsFromBuildId }}
artifactName: 'NPM package'
targetPath: '$(Pipeline.Workspace)/NPM package'

- task: NodeTool@0
- task: NodeTool@0
displayName: 'Use Node.js 20.11.0'
inputs:
versionSpec: '20.11.0'
Expand All @@ -17,15 +43,61 @@ steps:
destinationFolder: '$(System.DefaultWorkingDirectory)/unzipped'
cleanDestinationFolder: true

# ---------------------------------------------------------------------
# Primary target: project-scoped Azure Artifacts feed `uipath-ipc-deps`.
# ---------------------------------------------------------------------
# Authenticated via the pipeline's built-in identity (already an
# administrator on the feed — see CoreIpc/_artifacts/feed/uipath-ipc-deps).
# No PAT, no service connection, no rotation policy to fight with.
# ---------------------------------------------------------------------
- task: Npm@1
displayName: 'Publish to Azure Artifacts (uipath-ipc-deps) — NodeJS'
inputs:
command: 'publish'
workingDir: '$(System.DefaultWorkingDirectory)/unzipped/dist/prepack/node'
publishRegistry: 'useFeed'
publishFeed: 'CoreIpc/9a5bdfb1-0ab4-40b9-b9d2-de4cf6c011eb'

- task: Npm@1
displayName: 'Publish to Azure Artifacts (uipath-ipc-deps) — Web'
inputs:
command: 'publish'
workingDir: '$(System.DefaultWorkingDirectory)/unzipped/dist/prepack/web'
publishRegistry: 'useFeed'
publishFeed: 'CoreIpc/9a5bdfb1-0ab4-40b9-b9d2-de4cf6c011eb'

# ---------------------------------------------------------------------
# Secondary target: GitHub Packages (best-effort, currently expected to fail)
# ---------------------------------------------------------------------
# Following the May 11–12, 2026 npm supply-chain incident (Mini Shai-Hulud
# / TanStack), UiPath revoked classic GitHub PATs org-wide and is migrating
# everyone to fine-grained PATs. Fine-grained PATs don't have the Packages
# permission available at org level for UiPath — so the existing
# `PublishNPM` service connection can no longer authenticate.
#
# Per Liviu Bud's #dev announcement on 2026-05-25, a sanctioned pipeline-
# auth replacement is being worked on but not yet available:
# https://uipath.enterprise.slack.com/archives/CMDRA3VFH/p1779699547818419
#
# We leave the GitHub Packages publish wired up with continueOnError so
# (a) the run doesn't fail when the publish fails on policy, and
# (b) the publish resumes automatically the moment the service connection
# is updated with whatever the platform team ships.
#
# Each Publish_NPM run will be marked "Succeeded with issues" until then.
# Revert continueOnError when the publish path is healthy again.
# ---------------------------------------------------------------------
- task: Npm@1
displayName: 'Publish NPM (NodeJS)'
displayName: 'Publish to GitHub Packages — NodeJS (best-effort)'
continueOnError: true
inputs:
command: 'publish'
workingDir: '$(System.DefaultWorkingDirectory)/unzipped/dist/prepack/node'
publishEndpoint: PublishNPM

- task: Npm@1
displayName: 'Publish NPM (Web)'
displayName: 'Publish to GitHub Packages — Web (best-effort)'
continueOnError: true
inputs:
command: 'publish'
workingDir: '$(System.DefaultWorkingDirectory)/unzipped/dist/prepack/web'
Expand Down
54 changes: 53 additions & 1 deletion src/CI/azp-nodejs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,63 @@

- task: Npm@1
displayName: 'Npm Install'
# ---------------------------------------------------------------------
# Safe Chain Guard (SCG) bypass — see azp-start.yaml SCG_KILL_SWITCH
# ---------------------------------------------------------------------
# The UiPath DevOps team rolled out an organization-wide pipeline
# decorator that injects pre/post steps installing the Aikido Safe
# Chain shims (https://www.aikido.dev/blog/introducing-safe-chain).
# The decorator replaces /usr/bin/npm (and npx, python, etc.) with
# /home/vsts/.safe-chain/shims/* so every install goes through a
# malware-scanning proxy that also blocks packages younger than 2 days.
#
# In practice the shim has had recurring interop issues with both
# Azure Artifacts feeds and GitHub Packages downloads — it surfaces
# them as opaque 400/403 errors whose text mentions Azure Storage SAS
# signatures, which sends you on a long wild-goose chase before you
# realize the shim is what's failing, not the registry. The DevOps
# team ships SCG_KILL_SWITCH as the designed escape hatch (lives in
# the pipeline-level `variables:` block in azp-start.yaml — it MUST
# be at pipeline scope; setting it as task `env:` is too late, the
# shim is installed in pre-job before any task env is read).
#
# Short story for whoever's debugging this next:
# - CI for the CoreIpc Python-client PR (#125) started failing on
# `npm install` with `npm ERR! code E403 ... Server failed to
# authenticate the request. Make sure the value of Authorization
# header is formed correctly including the signature.` while
# pulling yocto-queue-0.1.0.tgz.
# - The error appeared to be Azure-Storage-side (the URL in the
# log was a *.blob.core.windows.net SAS URL).
# - Switching from the org-level `npm-packages` feed to a project-
# scoped `uipath-ipc-deps` feed didn't help — same blob, same
# symptom.
# - Eventually traced via #devops Slack threads to the SCG shim
# being the real culprit. SCG_KILL_SWITCH=true (pipeline scope!)
# unblocks it.
#
# References:
# - SCG rollout announcement by Russell Boley (2026-04-24, #devops):
# https://uipath.enterprise.slack.com/archives/CMCKWF5TR/p1777039233780949
# - Stefan Botan reporting an analogous SCG-induced npm failure on
# a SemanticProxy build, with SCG_KILL_SWITCH workaround
# confirmed by the DevOps team (2026-05-13, #devops):
# https://uipath.enterprise.slack.com/archives/CMCKWF5TR/p1778680523566469
#
# Trade-off: the kill switch opts this pipeline out of SCG-side
# malware scanning across npm, npx, pip, poetry, python — every
# shim SCG installs. Acceptable here — the CoreIpc deps are a
# narrow, stable set, and SCG keeps malfunctioning. Revisit when
# the DevOps fix lands.
inputs:
command: 'install'
workingDir: $(NodeJS_ProjectPath)
customRegistry: 'useFeed'
customFeed: '424ca518-1f12-456b-a4f6-888197fc15ee'
# Project-scoped feed `uipath-ipc-deps` (CoreIpc) mirroring
# npmjs.org. Project-owned so the CoreIpc team controls retention,
# permissions, and which upstreams are allowed. (See the rename
# from `EddiesExperimentalFeed` in the same conversation.)
customFeed: 'CoreIpc/9a5bdfb1-0ab4-40b9-b9d2-de4cf6c011eb'

- task: CmdLine@2
displayName: 'Npm Run Build'
Expand Down
39 changes: 39 additions & 0 deletions src/CI/azp-nuget.publish.steps.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
parameters:
- name: reuseArtifactsFromBuildId
type: string
default: ''
# Pipeline DEFINITION id that produced the artifact. Defaults to the current
# pipeline (single-pipeline reuse). The separate Publish pipeline passes the
# CI pipeline's id (e.g. $(resources.pipeline.ci.pipelineID)) so it can pull a
# CI build's artifact by id.
- name: sourcePipelineId
type: string
default: '$(System.DefinitionId)'

steps:
- checkout: none

# Pull the NuGet artifact: from the current run by default, or from a
# previously-completed build if `reuseArtifactsFromBuildId` is a real id.
# '0' (default) and '' both mean "no reuse — pull from current run".
- ${{ if in(parameters.reuseArtifactsFromBuildId, '0', '') }}:
- download: current
artifact: 'NuGet package'
- ${{ if not(in(parameters.reuseArtifactsFromBuildId, '0', '')) }}:
- task: DownloadPipelineArtifact@2
displayName: 'Download NuGet package from build ${{ parameters.reuseArtifactsFromBuildId }}'
inputs:
buildType: specific
project: $(System.TeamProject)
pipeline: ${{ parameters.sourcePipelineId }}
buildVersionToDownload: specific
buildId: ${{ parameters.reuseArtifactsFromBuildId }}
artifactName: 'NuGet package'
targetPath: '$(Pipeline.Workspace)/NuGet package'

- task: DotNetCoreCLI@2
displayName: 'dotnet push to UiPath-Internal'
inputs:
command: push
packagesToPush: '$(Pipeline.Workspace)/NuGet package/**/*.nupkg'
publishVstsFeed: 'Public.Feeds/UiPath-Internal'
Loading
Loading