Commit fbc48da
authored
feat: add
* feat: add support for deploying to Posit Connect Cloud
Adds Posit Connect Cloud as a deployment target alongside Posit Connect
and shinyapps.io, mirroring the R rsconnect package's support:
- Select the target with --connect-cloud or -s connect.posit.cloud.
- Authenticate with an interactive OAuth device-code login or a service
account client ID/secret (client credentials grant), with automatic
token refresh and write-back to the credential store.
- Register credentials with `rsconnect add`, verifying the account
exists and grants the content:create permission before storing.
- Deploy through the Connect Cloud revision model: create or update
content, upload the bundle to a presigned URL, publish, poll the
revision, and print the publish log from the logs service on failure.
- Record deployments locally before publishing, since Connect Cloud
cannot look content up by name.
- Support the production, staging, and development environments via
CONNECT_CLOUD_ENVIRONMENT, pinned to the saved server's URL.
Fixes #817
* fix: repair Connect Cloud log authorization on Python 3.8
`cast(dict[str, Any], ...)` evaluates its first argument at runtime, so
`from __future__ import annotations` does not cover it and `dict[...]`
raises TypeError on Python 3.8. Describe the response with a TypedDict
instead, matching the other ConnectCloudClient methods.
* feat: add `content migrate-to-connect-cloud`
Point a directory's local deployment record at an existing Posit Connect
Cloud content item, so the next deploy from that directory updates that
item instead of creating a second one. Connect Cloud cannot look content
up by name, so the local record is the only way back to a content item;
without one, deploying content that already exists there duplicates it.
Nothing is copied and no bundle is uploaded. The record that was
migrated from is removed, leaving the directory with one deployment
target rather than two; `--from-server` chooses which record to migrate
when the store covers several servers, and `-o/--overwrite` replaces an
existing Connect Cloud record.
Records are keyed by account, and a deploy refuses content owned by
another account, so a record written under the wrong account would be
silently useless. Migration therefore requires the content's owning
account to be the one being targeted and names it when it is not. With
no local record at all the record is reconstructed from the content,
with app mode `unknown`, which `validate_app_mode` already tolerates.
Fixes #826
* feat: add `content migrate-to-connect-cloud`
Point a directory's local deployment record at an existing Posit Connect
Cloud content item, so the next deploy from that directory updates that
item instead of creating a second one. Connect Cloud cannot look content
up by name, so the local record is the only way back to a content item;
without one, deploying content that already exists there duplicates it.
Nothing is copied and no bundle is uploaded. The record that was
migrated from is removed, leaving the directory with one deployment
target rather than two; `--from-server` chooses which record to migrate
when the store covers several servers, and `-o/--overwrite` replaces an
existing Connect Cloud record.
Records are keyed by account, and a deploy refuses content owned by
another account, so a record written under the wrong account would be
silently useless. Migration therefore requires the content's owning
account to be the one being targeted and names it when it is not. With
no local record at all the record is reconstructed from the content,
with app mode `unknown`, which `validate_app_mode` already tolerates.
Widening `AppMetadata.app_guid` to `Optional[str]` also types the None
that the Connect Cloud deploy in #840 already passes.
Fixes #826
* fix: refuse unusable Connect Cloud migration targets
Two ways `content migrate-to-connect-cloud` could remove the source
deployment record and leave behind one that cannot be deployed.
A viewer role on the owning account passed the ownership check.
`validate_connect_cloud_server` resolves publish permission through
`get_account_by_name` only when the account id is not already known, so
an id saved with a nickname skipped it and the refusal came from the
deploy instead, after the source record was gone. The account is now
checked before anything is written, reusing `_can_publish` so a viewer
role is judged the same way in both places.
The id-keyed and name-keyed record locations collide when an account's
name equals its id, and removing the name-keyed record then deleted the
record just written, emptying the store and reporting "The deployment
record could not be saved." The fallback is now removed only when it
differs from the target.
Also drop the claim that migration leaves one deployment target: with
`--from-server`, records for other servers are deliberately kept.
* fix: keep a Posit Connect record when migrating to Connect Cloud
A lone deployment record for a Posit Connect server was silently taken as
the migration source and removed, so the next deploy to that server
created new content instead of updating the existing item — the
duplication this command exists to prevent, on the Connect side.
Removing the source is only justified for shinyapps.io: that content has
been migrated away, so its record is dead. Connect content still exists
and is still deployable, and deploying one directory to both Connect and
Connect Cloud is a supported setup. The source record still supplies the
title and app mode either way; only a shinyapps.io record is removed.
`--from-server` chooses which record supplies the metadata; it does not
make a live Connect record removable.
Reported by vrsarah in review of #838.
* fix: match --from-server against a record URL with a trailing slash
Deployment record keys are the server URL as typed at deploy time --
AbstractRemoteServer stores it verbatim -- so a record can be keyed
"https://connect.example.com/" while --from-server names it without the
slash, or the reverse. Either way migration_source_record's exact == found
no match and the migration was refused.
The rest of the function was already slash-insensitive: is_connect_cloud_url
tolerates a trailing slash, and _is_shinyapps_record strips one. A shinyapps
record stored with a slash was therefore classified correctly, and would
have been removed by the migration, but could not be selected.
Route all three comparisons through one _record_server_url helper instead of
spelling the expression out per site. --from-server is stripped before
resolve_server_alias, since the shinyapps.io short name resolves by exact
comparison.
* feat: accept a saved nickname for --from-server
--from-server resolved only the two hard-coded pseudo server names
(shinyapps.io, connect.posit.cloud) and never consulted the server store, so
a Posit Connect instance had to be named by URL while shinyapps.io could be
named by name. Look the value up as a nickname first, and fall back to the
URL and alias handling.
A nickname for a saved shinyapps.io server resolves to the same API URL as
"shinyapps.io", so its record is removed like any other shinyapps.io source.
A Connect record is still kept, as bd7cd7b established. Tested both ways.
The option help called the value a URL while giving `shinyapps.io` as the
example; it now names both forms.
TestConnectCloudMigrate gets a temp-dir ServerStore, since resolving a
nickname would otherwise read the developer's own saved servers.content migrate-to-connect-cloud (#838)1 parent 055d9fd commit fbc48da
5 files changed
Lines changed: 870 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
12 | 23 | | |
13 | 24 | | |
14 | 25 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | | - | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
74 | 82 | | |
75 | 83 | | |
76 | 84 | | |
| |||
1273 | 1281 | | |
1274 | 1282 | | |
1275 | 1283 | | |
| 1284 | + | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
| 1288 | + | |
| 1289 | + | |
| 1290 | + | |
| 1291 | + | |
| 1292 | + | |
| 1293 | + | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
| 1297 | + | |
| 1298 | + | |
| 1299 | + | |
| 1300 | + | |
| 1301 | + | |
| 1302 | + | |
| 1303 | + | |
| 1304 | + | |
| 1305 | + | |
| 1306 | + | |
| 1307 | + | |
| 1308 | + | |
| 1309 | + | |
| 1310 | + | |
| 1311 | + | |
| 1312 | + | |
| 1313 | + | |
| 1314 | + | |
| 1315 | + | |
| 1316 | + | |
| 1317 | + | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
| 1324 | + | |
| 1325 | + | |
| 1326 | + | |
1276 | 1327 | | |
1277 | 1328 | | |
1278 | 1329 | | |
| |||
2236 | 2287 | | |
2237 | 2288 | | |
2238 | 2289 | | |
| 2290 | + | |
| 2291 | + | |
| 2292 | + | |
| 2293 | + | |
| 2294 | + | |
| 2295 | + | |
| 2296 | + | |
| 2297 | + | |
| 2298 | + | |
| 2299 | + | |
| 2300 | + | |
| 2301 | + | |
| 2302 | + | |
| 2303 | + | |
| 2304 | + | |
| 2305 | + | |
| 2306 | + | |
| 2307 | + | |
| 2308 | + | |
| 2309 | + | |
| 2310 | + | |
| 2311 | + | |
| 2312 | + | |
| 2313 | + | |
| 2314 | + | |
| 2315 | + | |
| 2316 | + | |
| 2317 | + | |
| 2318 | + | |
| 2319 | + | |
| 2320 | + | |
| 2321 | + | |
| 2322 | + | |
| 2323 | + | |
| 2324 | + | |
| 2325 | + | |
| 2326 | + | |
| 2327 | + | |
| 2328 | + | |
| 2329 | + | |
| 2330 | + | |
| 2331 | + | |
| 2332 | + | |
| 2333 | + | |
| 2334 | + | |
| 2335 | + | |
| 2336 | + | |
| 2337 | + | |
| 2338 | + | |
| 2339 | + | |
| 2340 | + | |
| 2341 | + | |
| 2342 | + | |
| 2343 | + | |
| 2344 | + | |
| 2345 | + | |
| 2346 | + | |
| 2347 | + | |
| 2348 | + | |
| 2349 | + | |
| 2350 | + | |
| 2351 | + | |
| 2352 | + | |
| 2353 | + | |
| 2354 | + | |
| 2355 | + | |
| 2356 | + | |
| 2357 | + | |
| 2358 | + | |
| 2359 | + | |
| 2360 | + | |
| 2361 | + | |
| 2362 | + | |
| 2363 | + | |
| 2364 | + | |
| 2365 | + | |
| 2366 | + | |
| 2367 | + | |
| 2368 | + | |
| 2369 | + | |
| 2370 | + | |
| 2371 | + | |
| 2372 | + | |
| 2373 | + | |
| 2374 | + | |
| 2375 | + | |
| 2376 | + | |
| 2377 | + | |
| 2378 | + | |
| 2379 | + | |
| 2380 | + | |
| 2381 | + | |
| 2382 | + | |
| 2383 | + | |
| 2384 | + | |
| 2385 | + | |
| 2386 | + | |
| 2387 | + | |
| 2388 | + | |
| 2389 | + | |
| 2390 | + | |
| 2391 | + | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
| 2395 | + | |
| 2396 | + | |
| 2397 | + | |
| 2398 | + | |
| 2399 | + | |
| 2400 | + | |
| 2401 | + | |
| 2402 | + | |
| 2403 | + | |
| 2404 | + | |
| 2405 | + | |
| 2406 | + | |
| 2407 | + | |
| 2408 | + | |
| 2409 | + | |
| 2410 | + | |
| 2411 | + | |
| 2412 | + | |
| 2413 | + | |
| 2414 | + | |
| 2415 | + | |
| 2416 | + | |
| 2417 | + | |
| 2418 | + | |
| 2419 | + | |
| 2420 | + | |
| 2421 | + | |
| 2422 | + | |
| 2423 | + | |
| 2424 | + | |
| 2425 | + | |
| 2426 | + | |
| 2427 | + | |
| 2428 | + | |
| 2429 | + | |
| 2430 | + | |
| 2431 | + | |
| 2432 | + | |
| 2433 | + | |
| 2434 | + | |
| 2435 | + | |
| 2436 | + | |
| 2437 | + | |
| 2438 | + | |
| 2439 | + | |
| 2440 | + | |
| 2441 | + | |
| 2442 | + | |
| 2443 | + | |
| 2444 | + | |
| 2445 | + | |
| 2446 | + | |
| 2447 | + | |
| 2448 | + | |
| 2449 | + | |
| 2450 | + | |
2239 | 2451 | | |
2240 | 2452 | | |
2241 | 2453 | | |
| |||
3529 | 3741 | | |
3530 | 3742 | | |
3531 | 3743 | | |
| 3744 | + | |
| 3745 | + | |
| 3746 | + | |
| 3747 | + | |
| 3748 | + | |
| 3749 | + | |
| 3750 | + | |
| 3751 | + | |
| 3752 | + | |
| 3753 | + | |
| 3754 | + | |
| 3755 | + | |
| 3756 | + | |
| 3757 | + | |
| 3758 | + | |
| 3759 | + | |
| 3760 | + | |
| 3761 | + | |
| 3762 | + | |
| 3763 | + | |
| 3764 | + | |
| 3765 | + | |
| 3766 | + | |
| 3767 | + | |
| 3768 | + | |
| 3769 | + | |
3532 | 3770 | | |
3533 | 3771 | | |
3534 | 3772 | | |
| |||
3541 | 3779 | | |
3542 | 3780 | | |
3543 | 3781 | | |
3544 | | - | |
3545 | | - | |
3546 | | - | |
3547 | | - | |
| 3782 | + | |
3548 | 3783 | | |
3549 | 3784 | | |
3550 | 3785 | | |
| |||
0 commit comments