Summary
aspire deploy / aspire publish can hang for a TypeScript AppHost when the AppHost is launched through Yarn Classic. The CLI logs show it intends to pass publish/deploy operation arguments to the AppHost, but Yarn 1.22 drops those arguments unless a -- separator is used. As a result, the TypeScript AppHost runs as if no --operation publish --step deploy arguments were provided, so builder.build().run() enters normal run mode and starts DCP.
DCP should not be involved in deploy/publish.
Environment
- Aspire CLI:
13.3.0+be8c19e483c7fca17f64510d1713ce5228a58843
- Build ID:
13.300.26.22906
- OS: macOS
- Node:
v22.20.0
- npm:
10.9.3
- Yarn:
1.22.22
- AppHost: TypeScript
apphost.ts
Repro
With a TypeScript AppHost that ends with:
await builder.build().run();
Run:
NO_COLOR=1 aspire deploy --apphost apphost.ts --debug --non-interactive
or:
NO_COLOR=1 aspire publish --apphost apphost.ts --debug --non-interactive
The command hangs after the pre-start deployment pipeline steps.
Observed behavior
The Aspire CLI debug log shows the TypeScript AppHost is launched like this:
Launching: yarn exec tsx --tsconfig tsconfig.apphost.json /path/to/apphost.ts --operation publish --step deploy
Executing: /path/to/yarn exec tsx --tsconfig tsconfig.apphost.json /path/to/apphost.ts --operation publish --step deploy
But with Yarn Classic, the AppHost does not receive the trailing args. A minimal argv probe shows:
yarn --silent exec tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts --operation publish --step deploy
prints:
["node","/path/to/argv-probe.ts"]
So .modules/aspire.ts uses:
args: options?.args ?? process.argv.slice(2)
and sends no --operation publish --step deploy args to Aspire.Hosting/createBuilder.
The AppHost then behaves like a normal run and starts DCP. During the hung deploy, the process tree included:
dcp start-apiserver ...
dcp run-controllers ...
aspire-managed dashboard ...
Expected behavior
aspire deploy and aspire publish should not start DCP. The TypeScript AppHost should receive the operation args and execute the publish/deploy pipeline path.
Additional evidence
Adding a -- separator before the AppHost args preserves them with Yarn Classic:
yarn --silent exec tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts -- --operation publish --step deploy
prints:
["node","/path/to/argv-probe.ts","--operation","publish","--step","deploy"]
This form also works:
yarn --silent exec -- tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts --operation publish --step deploy
Direct tsx also preserves the args:
node_modules/.bin/tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts --operation publish --step deploy
Suspected fix
When launching TypeScript AppHosts through Yarn Classic, Aspire should insert an argument separator so AppHost args are forwarded, for example:
yarn exec tsx --tsconfig tsconfig.apphost.json apphost.ts -- --operation publish --step deploy
or:
yarn exec -- tsx --tsconfig tsconfig.apphost.json apphost.ts --operation publish --step deploy
The current launch form appears to let Yarn consume/drop the AppHost operation args.
Summary
aspire deploy/aspire publishcan hang for a TypeScript AppHost when the AppHost is launched through Yarn Classic. The CLI logs show it intends to pass publish/deploy operation arguments to the AppHost, but Yarn 1.22 drops those arguments unless a--separator is used. As a result, the TypeScript AppHost runs as if no--operation publish --step deployarguments were provided, sobuilder.build().run()enters normal run mode and starts DCP.DCP should not be involved in deploy/publish.
Environment
13.3.0+be8c19e483c7fca17f64510d1713ce5228a5884313.300.26.22906v22.20.010.9.31.22.22apphost.tsRepro
With a TypeScript AppHost that ends with:
Run:
or:
The command hangs after the pre-start deployment pipeline steps.
Observed behavior
The Aspire CLI debug log shows the TypeScript AppHost is launched like this:
But with Yarn Classic, the AppHost does not receive the trailing args. A minimal argv probe shows:
yarn --silent exec tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts --operation publish --step deployprints:
So
.modules/aspire.tsuses:and sends no
--operation publish --step deployargs toAspire.Hosting/createBuilder.The AppHost then behaves like a normal run and starts DCP. During the hung deploy, the process tree included:
Expected behavior
aspire deployandaspire publishshould not start DCP. The TypeScript AppHost should receive the operation args and execute the publish/deploy pipeline path.Additional evidence
Adding a
--separator before the AppHost args preserves them with Yarn Classic:yarn --silent exec tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts -- --operation publish --step deployprints:
This form also works:
yarn --silent exec -- tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts --operation publish --step deployDirect
tsxalso preserves the args:Suspected fix
When launching TypeScript AppHosts through Yarn Classic, Aspire should insert an argument separator so AppHost args are forwarded, for example:
yarn exec tsx --tsconfig tsconfig.apphost.json apphost.ts -- --operation publish --step deployor:
yarn exec -- tsx --tsconfig tsconfig.apphost.json apphost.ts --operation publish --step deployThe current launch form appears to let Yarn consume/drop the AppHost operation args.