Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- `login` and `add --connect-cloud` can start device-code authentication and return
approval details as JSON. Finish a pending login by nickname with `--finish`.
Use `--timeout` to bound the entire finish invocation, including account lookup.
Resumable login requires POSIX (Linux or macOS). Pending state is validated
before saving and uses owner-only permissions. Resumable authentication omits
sensitive provider diagnostics. Connect Cloud finish retains the original OAuth client.
- Added `rsconnect preflight` to check Python and Node.js runtime availability on
self-hosted Posit Connect and Snowpark Container Services (SPCS), from POSIX systems. For first
publishes, it considers server installations marked publishable. Python
preflight can add a missing `.python-version` for new content with no
constraint; Node.js preflight checks `package.json`'s `engines.node` range and
server runtime availability.
Preflight accepts Python file targets as well as directories. Its JSON reports
distinguish unresolved checks from operational errors. Runtime incompatibility
exits with status 3; operational errors exit with status 1.
Unsafe or oversized deployment records return actionable uncertainty.
- `write-manifest` now writes `requirements.txt` with the same bytes that it uses for
the manifest checksum. On Windows, the file had CRLF line endings and the checksum did
not match. An existing requirements file with CRLF line endings also has the correct
Expand Down
61 changes: 61 additions & 0 deletions docs/commands/add.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,64 @@
# `rsconnect add`

Use `add --connect-cloud` to authenticate with Posit Connect Cloud. The command normally waits for browser approval. If the shell must return before approval, start device authentication and finish it separately.

Both `rsconnect add` and its `rsconnect server add` alias support these options.

## Start Connect Cloud authentication

Pass the account and nickname, then add `--no-wait`:

```{.bash filename="Terminal"}
rsconnect add --connect-cloud --account team --name cloud --no-wait
```

The command exits with JSON that includes the approval URL, the user code, and the duration until expiration. Show the user `verification_uri` and `user_code` so they can approve the request. The JSON does not include the secret device code or any token.

If a valid pending login already exists for the same account and nickname, the command reuses it.
Starting a login for a different target with that nickname fails.
The command stores pending logins under its configuration directory. Files use owner-only permissions on POSIX.
Resumable device login requires a POSIX system such as Linux or macOS. Use a private configuration directory.
Existing blocking login remains available on Windows.

Pending state contains device codes and token checkpoints in plaintext, even when final credentials use a keyring.
Owner-only permissions restrict ordinary access to your operating-system account; processes running as that account and backups can still read it.
Finish pending logins promptly. Abandoned state has no background cleanup, and deleting local state does not revoke an issued token.
Use HTTPS with certificate verification and keep the configuration directory private and outside your application directory.

Finish the login after the user approves:

```{.bash filename="Terminal"}
rsconnect add --connect-cloud --name cloud --finish --timeout 120
```

The timeout bounds the entire finish invocation, including account lookup.
Slowly streamed response headers and bodies use the remaining timeout budget. An operating-system DNS lookup can still outlast it.
Finish reuses the OAuth client selected when the login started.
The command prints JSON with `status` set to `pending` or `done`. Finish requires `--connect-cloud` and `--name`.
It accepts `--connect-cloud`, `--name`, `--finish`, optional `--timeout`, and optional verbosity flags.

Do not pass account, server, TLS, identity, client, or default options. `--timeout` accepts any positive integer and defaults to 120 seconds. Use it only with `--finish`.

A pending result exits successfully so callers can parse the JSON. A transient pending result remains available for another finish attempt.
Denied, expired, or rejected authorization requests exit with status 1 and remove the pending request.
A completed lookup that cannot find the requested account also removes the request, so you can start again with a corrected account name.
Concurrent login operations for the same nickname serialize their state updates.
If finish exhausts its timeout waiting for another operation, it reports `pending` with `server: null`.

Start reports contain `status`, `name`, `server`, `verification_uri`, `user_code`, and `expires_in`.
Pending finish reports contain `status`, `name`, and `server`. Completed finish reports also contain `account`.
Errors exit with status 1 and print diagnostics to stderr. Invalid command syntax exits with status 2.
Use `-v` or `-vv` for diagnostics on stderr; stdout remains reserved for the JSON result.

The `rsconnect server add` alias accepts the same commands:

```{.bash filename="Terminal"}
rsconnect server add --connect-cloud --account team --name cloud --no-wait
rsconnect server add --connect-cloud --name cloud --finish --timeout 120
```

Without `--no-wait` or `--finish`, `add` keeps its existing blocking behavior and options.

::: mkdocs-click
:module: rsconnect.main
:command: add
Expand Down
66 changes: 66 additions & 0 deletions docs/commands/login.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,69 @@
# `rsconnect login`

Use `login` to authenticate with Posit Connect through OAuth. The command normally opens a browser and waits for approval. If the shell must return before approval, start device authentication and finish it in separate commands.

The `--identity-token` and `--identity-token-file` options accept OpenID Connect (OIDC) identity tokens for token exchange.

## Start device authentication

Pass the server base URL, a nickname, and `--no-wait`. This option selects device authentication without requiring `--use-device-code`:

```{.bash filename="Terminal"}
rsconnect login https://connect.example.com --name myserver --no-wait
```

The command exits with JSON that includes the approval URL, the user code, and the duration until expiration:

```json
{
"status": "pending",
"name": "myserver",
"server": "https://connect.example.com",
"verification_uri": "https://connect.example.com/activate",
"user_code": "ABCD-EFGH",
"expires_in": 900
}
```

Show the user `verification_uri` and `user_code` so they can approve the request. The JSON does not include the secret device code or any token.

If a valid pending login already exists for the same server and nickname, `login --no-wait` reuses it.
Starting a login for a different target with that nickname fails.
The command stores pending logins under its configuration directory. Files use owner-only permissions on POSIX.
Resumable device login requires a POSIX system such as Linux or macOS. Use a private configuration directory.
Existing blocking login remains available on Windows.

Pending state contains device codes and token checkpoints in plaintext, even when final credentials use a keyring.
Owner-only permissions restrict ordinary access to your operating-system account; processes running as that account and backups can still read it.
Finish pending logins promptly. Abandoned state has no background cleanup, and deleting local state does not revoke an issued token.
Use HTTPS with certificate verification and keep the configuration directory private and outside your application directory.

## Finish device authentication

After the user approves the request, finish the login by naming the saved nickname:

```{.bash filename="Terminal"}
rsconnect login --name myserver --finish --timeout 120
```

The timeout bounds the entire finish invocation. The command prints JSON with `status` set to `pending` or `done`.
Slowly streamed response headers and bodies use the remaining timeout budget. An operating-system DNS lookup can still outlast it.
`--timeout` accepts any positive integer and defaults to 120 seconds. Use it only with `--finish`.

Finish selects the pending login by `--name`, so omit the `SERVER` argument. It accepts `--name`, `--finish`, optional `--timeout`, and optional verbosity flags.
Do not pass the server URL or any other start option.

A pending result exits successfully so callers can parse the JSON. A transient pending result remains available for another finish attempt.
Denied, expired, or rejected authorization requests exit with status 1 and remove the pending request.
Concurrent login operations for the same nickname serialize their state updates.
If finish exhausts its timeout waiting for another operation, it reports `pending` with `server: null`.

Start reports contain `status`, `name`, `server`, `verification_uri`, `user_code`, and `expires_in`.
Finish reports contain `status`, `name`, and `server`. Errors exit with status 1 and print diagnostics to stderr.
Invalid command syntax exits with status 2. Use `-v` or `-vv` for diagnostics on stderr; stdout remains reserved for the JSON result.

Without `--no-wait` or `--finish`, `login` keeps its existing blocking behavior and options.

::: mkdocs-click
:module: rsconnect.main
:command: login
96 changes: 96 additions & 0 deletions docs/commands/preflight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# `rsconnect preflight`

Use `preflight` to compare a project's runtime constraint with versions reported by a
self-hosted Posit Connect or Snowpark Container Services (SPCS) server. It supports
OAuth credentials and does not support Posit Connect Cloud. Preflight checks runtime
availability only. It does not assess application or dependency compatibility.
Preflight requires a POSIX system such as Linux or macOS; existing deployment commands remain available on Windows.

```{.bash filename="Terminal"}
rsconnect preflight --name myserver ./project
```

The `--runtime` option accepts `python` or `nodejs` and defaults to `python`. Select
Node.js with `--runtime nodejs`:

```{.bash filename="Terminal"}
rsconnect preflight -n myserver ./node-app --runtime nodejs
```

For Node.js, preflight compares `package.json`'s `engines.node` constraint with server
Node.js installations using npm semver. Node.js must be enabled and allowed by the
server license. For first publishes, an installation must also be marked publishable.
If a legacy server omits required runtime or publishability flags, the result can be
`unknown`.

Use `--node` with a path to select the local Node.js executable. It is valid only with
`--runtime nodejs`; passing it with Python is an error. Node.js preflight does not
support `--fix` and does not modify `package.json`, `package-lock.json`, or other
project files.

The command prints a JSON report with `status` set to `ok`, `incompatible`, or
`unknown`, along with runtime diagnostics, `warnings`, and `actions`. Operational errors return an `error` report.
For Python, the
report includes:

- `status`, `runtime`, `server`, `warnings`, and `actions`: check results, runtime name, and suggested next steps
- `publishable_python_versions`: Python versions from installations the server marks publishable for first publishes
- `local_python`: the local Python version
- `local_python_publishable`: whether the server marks the local Python minor version publishable, or `null` if unknown
- `recommended_python`: a suggested Python minor version for unconstrained first publication, or `null`
- `python_requires`: the project’s declared Python requirement, if present
- `existing_content`: an object with `exists`, `app_id`, `installed_python_version`, `server_python_versions`, and `python_compatibility`
- `quarto_available`: whether the local Quarto command is available
- `changed_files`: files changed by `--fix`

For Node.js, the report includes:

- `status`, `runtime`, `server`, `warnings`, and `actions`: check results, runtime name, and suggested next steps
- `local_node`: the selected local Node.js version
- `node_requires`: the `package.json` `engines.node` range
- `server_node_versions`: the server-reported installed Node.js versions
- `publishable_node_versions`: versions marked publishable for first publishes
- `nodejs_enabled` and `nodejs_status`: server Node.js availability and status
- `existing_content`: an object with `exists`, `app_id`, `node_version`, and `compatibility`
- `changed_files`: empty because Node.js preflight does not change project files

The server's enabled, license, and publishable flags inform the status. Treat `unknown`
as unresolved and inspect `warnings` and `actions`; do not treat it as compatible. An
`incompatible` result exits with status 3. An `ok` or `unknown` result exits with status 0.
Operational errors exit with status 1. Their JSON contains `status: error`, `runtime`, `error`, `changed_files`, `warnings`, and `actions`.
Invalid command syntax exits with status 2 and prints diagnostics to stderr.
Use `-v` or `-vv` for diagnostics on stderr; stdout remains reserved for the JSON result.

Use `--new` to check a new content item when the project has a deployment record. Use `--app-id` to check a content item by its identifier (ID) or globally unique identifier (GUID). Do not combine these options.

```{.bash filename="Terminal"}
rsconnect preflight --name myserver ./project --new
rsconnect preflight --name myserver ./project --app-id 00000000-0000-0000-0000-000000000000
```

For content deployed from a notebook, manifest, bundle, or Quarto file, pass that file to select its deployment record:

```{.bash filename="Terminal"}
rsconnect preflight --name myserver ./project/report.ipynb
```

Preflight reads project metadata and local prerequisites from the file's parent directory.
An unreadable content item or ambiguous deployment record returns `unknown`; inspect its actions before deploying.
If a directory contains file deployment history, pass the exact deployed file or `--app-id` to resolve the target.
An unresolved target prevents `--fix` from creating a Python pin.
Symlinked, non-regular, or oversized deployment records also return `unknown`.
Inspect the suggested actions and repair the record, or pass `--app-id` to select the existing content directly.

## Add a Python version pin

For new content with no Python constraint, add `--fix` to create a missing `.python-version` file:

```{.bash filename="Terminal"}
rsconnect preflight --name myserver ./project --fix
```

The command chooses an installation the server marks publishable for first publishes. If its Python minor version differs from the local Python version, the report includes a compatibility warning. `--fix` never overwrites an existing `.python-version` file or adds a pin when the project declares a Python constraint. The report lists any file it creates in `changed_files`.

::: mkdocs-click
:module: rsconnect.main
:command: preflight
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ nav:
- integration: commands/integration.md
- login: commands/login.md
- logout: commands/logout.md
- preflight: commands/preflight.md
- quickstart: commands/quickstart.md
- server:
- add: commands/add.md
Expand Down
Loading
Loading