openssl::rsa_sign rather than PKI signing. (#1333)Added support for deploying Node.js applications to Posit Connect.
deployApp() and writeManifest() now automatically detect Node.js content
from package.json and generate the appropriate manifest. Added
envManagementNodejs parameter for controlling Node.js environment
management. Node.js support is
in Early Access as of Connect version 2026.04.0. (#1322)
Added a new function, connectCloudClientCredentials, for adding Posit Connect
Cloud credentials (managed at https://login.posit.cloud/identity/credentials)
non-interactively.
Fixed an issue where Bioconductor packages could be incorrectly associated with a CRAN repository URL when the same package appeared in CRAN's Transit directory. (#1314)
The global deployment history file used by the Workbench dashboard no longer uses a fixed temporary file name during updates, eliminating a race condition that could cause the file to rapidly grow during concurrent deployments. The history is also capped at 100 records and resets if the file grows excessively large. (#1320)
deployApp() with logLevel = "verbose" no longer errors using the httr2 backend. (#1312)
deployApp(), writeManifest(), and appDependencies() gain a
dependencyResolution parameter. Set dependencyResolution = "library" to ignore
the renv.lock file and resolve package dependencies by scanning the code.
The version that is recorded is what is installed in the libraries active in the
R session (i.e. what is displayed with .libPaths()). This is useful when
deploying from environments where there is a mismatch between the
renv lock file and the user's environment. (#1046, #1315, #1317)
Improved error messages when renv::snapshot() fails during dependency
discovery. (#1078)
addServer() now reports the underlying reason a URL was rejected (e.g.
connection error, TLS/certificate problem, or unexpected HTTP status). (#1197)rsconnect now uses httr2 as its HTTP client.
There should be no user-visible changes as a result, but if something does
not work as expected, please file an issue, and you can set
options(rsconnect.httr2 = FALSE) as a temporary workaround. (#1284)
Added support for renv profiles and renv lockfiles that are located outside of the project root. (#1122)
Resolved a bug where renv.lock files that had multiple repositories were not
being translated faithfully when creating the manifest file. (#1268)
Packages installed locally via pak are resolved against configured repositories. (#1305)
Added support for overriding R package repository resolution behavior. (#1272)
Push-button publishing from desktop RStudio is now compatible with Connect servers hosted on Snowflake. This includes support for browser-based authentication during deployment. (#1289)
The snowflakeConnectionName parameter now respects the default Snowflake
connection name in the connections.toml file (when it exists), making it
optional in many cases. This is only applicable to Connect servers hosted on
Snowflake. (#1283)
Added support for using identity federation to authenticate against Connect when running in Posit Workbench, when available. This allows deploying to Connect servers without the need to store long-lived credentials. (#1287)
Upgraded to use v1 APIs for deploying to Connect servers, which enables
new features for specifying settings in the manifest file. (#1280)
Removed support for log streaming from shinyapps.io due to loss of support
for this feature on the shinyapps.io platform (showLogs(streaming = TRUE)).
If this feature is important to your workflow, please file an issue and we
will consider reintroduction of log streaming via rsconnect in Connect Cloud.
(#1292)
Removed several functions, including addConnectServer() and
discoverServer(), as well as HTTP backends other than libcurl,
which were deprecated in rsconnect 1.0.0. (#1282)
Added support for deploying from manifest.json files created by
writeManifest(): use the manifestPath argument of deployApp() and related
functions to specify the path to an existing manifest file. (#1259)
urlEncode() now uses curl::curl_escape() instead of RCurl::curlEscape(),
as RCurl is a Suggests dependency. (#1265)
The User-Agent header in requests made from rsconnect will now be of the
format RSConnect/x.y.z instead of rsconnect/x.y.z in order to satisfy web
application firewalls that enforce Pascal case.
Fix an opaque error when creating a manifest using Python <= 3.10 with a
version requirement in a pyproject.toml file. A warning is shown rather
than an error when the tomllib package is not present. (#1226)
Address CRAN test failures caused by some openssl configurations. (#1255)
Fix account registration from RStudio. (#1250)
SPCS/Snowflake authentication supports Connect API keys for user
identification. The connectSPCSUser() function now requires an apiKey
parameter, and the API key is included in the X-RSC-Authorization header
alongside Snowflake token authentication. This aligns with updated Connect
server requirements where Snowflake tokens provide proxied authentication
while API keys identify users to the Connect server itself.
Support deploying to Posit Connect Cloud. Use connectCloudUser() to add
Connect Cloud credentials.
rsconnect now sets the rsconnect.max.bundle.size and
rsconnect.max.bundle.files options to their default values on startup
if they have not yet been set. (#1204)
The default rsconnect.max.bundle.size limit has increased to 5 GiB. (#1200)
getLogs() returns log lines for a shinyapps.io hosted application. (#1209)
Python environment inspection errors include the path to the target Python binary. (#1207)
Improve cookie expiration date handling. (#1212)
Improve documentation and advice for deployApp(envVars...).
Removed support for publishing to Posit Cloud. (#1215)
Existing Posit Cloud account records may be removed by using
removeAccount("yourname", "posit.cloud").
Existing Posit Cloud deployment records may be removed by using
forgetDeployment(name="deployment", account="yourname", server="posit.cloud").
Removed the Posit Cloud-exclusive space argument from deployApp(). (#1215)
Address user registration for Posit Connect deployments hosted in Snowpark Container Services when there is more than one configured Snowflake connection. (#1189)
Process cookie expiration dates in addition to the cookie max-age. Some servers return already-expired cookies. (1187)
Removed unused internal methods from Connect client. (#1182)
Fixed processing error during server validation, which prevented registration of new Connect accounts. (#1166)
When waiting for initial Connect account authorization, allow HTTP 401 responses. (#1167)
Content directories with a period in their name are no longer treated as a document path when computing the location for deployment records. (#1138)
Quarto documents which specify a server must include executable code or an engine declaration. (#1145)
Fixed errors when analyzing Quarto documents containing long chunks. (#1114)
A _server.yml file indicates that the content is an API. (#1144)
Expand tilde when resolving the rsconnect.ca.bundle option. (#1152)
Added support for interaction with Posit Connect deployments hosted in Snowpark Container Services.
Introduced detection of required R interpreter version based on
DESCRIPTION file and renv.lock file. This setting is inserted
into the manifest as environment.r.requires.
Introduced detection of required Python interpreter version based on
project files .python-version, pyproject.toml and setup.cfg.
This setting is inserted into the manifest as environment.python.requires.
Primary Quarto document detection only considers .R, .Rmd, and .qmd as
end-of-file extensions. Previously, a file with .R elsewhere in its name,
such as .Rprofile, was incorrectly considered. (#1106)
Use the repository name identified by renv when available.packages() does
not enumerate the package, which occurs for archived packages. (#1110)
Remove remaining directory layout validation check. (#1102)
Use the public Connect server API endpoint /v1/tasks/{id} to poll task
progress. (#1088)
deployApp(logLevel = "quiet") suppresses Posit Connect deployment task
output. (#1051)
deployApp(logLevel = "quiet") and writeManifest(quiet=TRUE) suppress
output when using renv to analyze dependencies. (#1051)
deployApp() and writeManifest() receive the default value for the
image argument from the RSCONNECT_IMAGE environment variable. (#1063)
deployTF() can deploy a TensorFlow model to Posit Connect. Requires Posit
Connect 2024.05.0 or higher.
Skip tests when suggested packages are not available. Skip Quarto tests when run by CRAN. (#1074)
Use internally computed SHA1 sums and PKI signing when SHA1 is disabled in FIPS mode. (#768, #1054)
Allow Quarto content with a rendered script as its primary target. (#1055)
LC_TIME locale after computing an RFC-2616 date. (#1035)Addressed a number of republishing and collaboration issues where the content was incorrectly published to a new location rather than reusing an existing deployment. (#981, #1007, #1013, #1019)
showLogs(), configureApp(), setProperty(), and unsetProperty()
search for the application by name when there are no matching deployment
records. (#985, #989)
rpubsUpload() correctly records the initial RPubs destination, allowing
republishing. (#976)
deployApp() and friends record multi-value metadata entries as
comma-separated values. (#1017)
accountInfo() includes name and username fields. Older versions of
rsconnect store account records with a username field. Recent rsconnect
versions record name. Both name and username should contain the same
value. (#1024)
Added space parameter to deploy directly to a space in Posit Cloud.
Improve reporting of errors returned by shinyapps.io. (#997)
Remove most directory layout validation checks. (#998)
Do not use getOption("available_packages_filters") option when calling
available.packages(). (#1002)
Packages installed from source within an renv project are not associated with repositories. (#1004)
Fixed analysis of directories that were smaller than the
rsconnect.max.bundle.files=10000 limit but larger than the
renv.config.dependencies.limit=1000 limit. (#968)
Ignore .env, .venv, and venv files only when they reference Python
virtual environments. (#972)
deployApp() and writeManifest() accept optional envManagement,
envManagementR, and envManagementPy arguments. These args specify whether
Posit Connect should install packages in the package cache.
If envManagement is FALSE then Connect will not perform any package
installation and it is the administrator's responsibility to ensure the
required R/Python packages are available in the runtime environment. This is
especially useful if off-host execution is enabled, when the execution
environment (specified by the image argument) already contains the required
packages. These values are ignored when
Applications.ManifestEnvironmentManagementSelection = false.
Requires Posit Connect >=2023.07.0. (#977)
Fix account discovery by showProperties(). (#980)
Fixed redeployments to shinyapps.io where appName is provided, but no local
record of the deployment exists. (#932)
deployApp() and writeManifest() now error if your library and renv.lock
are out-of-sync. Previously it always used what was defined in the renv.lock
but that was (a) slow and (b) could lead to different results than what you
see when running locally (#930).
Deploying from an renv project includes the renv.lock in the bundle. A
manifest created for an renv project references the renv.lock in the
manifest.json. (#926)
Use the environment variable RSCONNECT_PACKRAT to analyze dependencies
using packrat, as was done prior to rsconnect-1.0.0. Use of the
rsconnect.packrat option is discouraged, as it is not effective when using
push-button deployment in the RStudio IDE. (#935)
The renv.lock is ignored when the RSCONNECT_PACKRAT environment variable
or the rsconnect.packrat option is set. (#936)
The content type is inferred by analyzing the set of top-level files. (#942)
deployApp() and writeManifest() accept an optional appMode argument.
Provide this argument if your project includes auxiliary files which mislead
the existing appMode inference. For example, if an HTML project includes
a downloadable Shiny app.R, that content will be assumed to be a Shiny
application even if that application is not meant to be run. (#948)
appDependencies() accepts an appFileManifest argument as an alternate
way of providing the target set of files.
deployDoc() includes .Rprofile, requirements.txt and renv.lock when
deploying .Rmd or .qmd. These additional files are not included with
rendered HTML documents. (#919)
Explicit renv dependencies are preserved. (#916)
deployApp() and deployDoc() now support deploying static content to Posit
Cloud. Static RMarkdown and Quarto content can be rendered server-side.
rsconnect requires renv 1.0.0.
deployApp() and writeManifest() now respect renv lock files, if present.
If you don't want to use these lockfiles, and instead return the previous
behaviour of snapshotting on every deploy, add your renv.lock to
.rscignore (#671). Learn more ?appDependencies().
Additionally, deployApp() and writeManifest() now use renv to capture app
dependencies, rather than packrat. If this causes a previously working deploy
to fail, please file an issue then set options(rsconnect.packrat = TRUE) to
revert to the previous behaviour.
deployApp()'s quarto argument now takes values TRUE, FALSE or
NA. The previous value (a path to a quarto binary) is now ignored,
and instead we automatically figure out the package from QUARTO_PATH and
PATH env vars (#658). deploySite() now supports quarto websites (#813).
deployApp() gains a new envVars argument which takes a vector of the
names of environment variables that should be securely copied to the server.
The names (not values) of these environment variables are also saved in the
deployment record and will be updated each time you re-deploy the app (#667).
This currently only works with Connect, but we hope to add support to
Posit cloud and shinyapps.io in the future.
rsconnect gains two new functions for understanding and updating the
environment variables that your apps currently use. listServerEnvVars()
will return a data frame of applications, with a envVars list-column
giving the names of the environment variables used by each application.
updateServerEnvVars() will update all applications that use a specific
environment variable with the current value of that environment variable
(#667).
Non-libcurl rsconnect.http options have been deprecated. This allows us to
focus our efforts on a single backend, rather than spreading development
efforts across five. The old backends will remain available for at least 2
years, but if you are using them because libcurl doesn't work for you, please
report the problem ASAP so we can fix it.
addConnectServer() has been deprecated because it does the same
thing as addServer() now that addServer() also validates URLs.
deployTFModel() is defunct. Posit Connect no longer supports hosting of
TensorFlow Model APIs. A TensorFlow model can be deployed as a Plumber
API, Shiny
application, or other
supported content type.
discoverServer() has been deprecated; it never worked.
deployApp("foo.Rmd") has been deprecated. It was never documented, and
it does the same job as deployDoc() (#698).
New rsconnect.http.headers and rsconnect.http.cookies allow you to
set extra arbitrary additional headers/cookies on each request (#405).
Their use is documented in the new vignette("custom-http").
Uploading large files to RPubs works once more (#450).
When recording details about deployments to Posit Cloud, appId now represents
the content id (as seen in URLs of the format
https://posit.cloud/content/{id}) instead of the application id.
Deployment records no longer contain the time the app was deployed (when)
or when it's metadata was last synced (lastSyncTime) as these variables
are not very useful, and they lead to uninteresting diffs if you have
committed the deployment records to git (#770). A version field has been
added to deployment DCF files to facilitate future file format changes, if
needed. Its value for this release is 1.,
accounts() returns a zero-row data frame if no accounts are registered.
accountInfo() and removeAccount() no longer require account be
supplied (#666).
accountInfo() and servers() redact sensitive information (secrets,
private keys, and certificates) to make it hard to accidentally reveal
such information in logs (#675).
addServer() includes the port in the default server name, if present.
appDependencies() includes implicit dependencies, and returns an additional
column giving the Repository (#670). Its documentation contains more
information about how dependency discovery works, and how you can control
it, if needed.
applications() now returns the application title, if available (#484),
and processes multiple pages of results from a Connect server (#860).
connectApiUser() now clearly requires an apiKey (#741).
deployApp() output has been thoroughly reviewed and tweaked. As well as
general polish it now gives you more information about what it has discovered
about the deployment, like the app name, account & server, and which files
are included in the bundle (#669).
deployApp() is more aggressive about saving deployment data, which should
make it less likely that you need to repeat yourself after a failed
deployment. In particular, it now saves both before and after uploading the
contents (#677) and it saves when you're updating content originally created
by someone else (#270).
deployApp() now gives an actionable error if you attempt to set
visibility of an app deployed to posit.cloud (#838).
deployApp() now uses a stricter policy for determining whether or not
a locally installed package can be successfully installed on the deployment
server. This means that you're more likely to get a clean failure prior to
deployment (#659).
deployApp() will now detect if you're attempting to publish to an app
that has been deleted and will prompt you to create a new app (#226).
deployApp() includes some new conveniences for large uploads including
reporting the size of the bundle you're uploading and showing a progress bar
in interactive sessions (#754).
deployApp() now follows redirects, which should make it more robust to your
server moving to a new url (#674).
deployApp() uses simpler logic for determining whether it should create a
new app or update an existing app. Now appName, account, and server are
used to find existing deployments. If none are found, it will create a new
deployment; if one is found, it'll be updated; if more than one are found, it
will prompt you to disambiguate (#666).
deployApp() improves account resolution from account and server
arguments by giving specific recommendations on the values that you might use
in the case of ambiguity or lack of matches (#666). Additionally, you'll now
receive a clear error if you accidentally provide something other than a
string or NULL to these arguments.
deployApp() now generates an interactive prompt to select account/server
(if no previous deployments) or appName/account/server (if multiple
previous deployments) (#691).
deployApp() now advertises which startup scripts are run at the normal
logLevel, and it evaluates each script in its own environment (#542).
deployApp() now derives appName from appDir and appPrimaryDoc,
never using the title (#538). It now only simplifies the path if you are
publishing to shinyapps.io, since its restrictions on application names are
much tighter than those of Posit Connect.
deployApp() will now warn if appFiles or appManifestFiles contain
files that don't exist, rather than silently ignoring them (#706).
deployApp() excludes temporary backup files (names starting or ending
with ~) when automatically determining files to bundle (#111) as well as
directories that are likely to be Python virtual environments (#632).
Additionally, ignore rules are always now applied to all directories;
previously some (like .Rproj.user and "manifest.json") were only
applied to the root directory. It correctly handles .rscignore files
(i.e. as documented) (#568).
deployApp(appSourceDoc) has been deprecated; it did the same job as
recordDir.
deployDoc() includes a .Rprofile in the bundle, if one is found in the
same directory as the document.
lint() should have fewer false positives for path problems:
the relative path linter has been removed (#244) and the case-sensitive
linter now only checks strings containing a / (#611).
New listDeploymentFiles(), which supsersedes listBundleFiles().
It now errors when if the bundle is either too large or contains too many
files, rather than silently truncating as before (#684).
serverInfo() and removeServer() no longer require a server when
called interactively.
showMetrics() once again returns a correctly named data frame (#528).
Removed Rmd generation code (writeRmdIndex()) which had not worked, or
been necessary, for quite some time (#106, #109).
Locale detection has been improved on windows (#233).
The rsconnect.pre.deploy and rsconnect.post.deploy hooks are now always
called with the content directory, not sometimes the path to a specific file
(#696).
Functions that should only interact with shinyapps.io enforce the server
type. Updated addAuthorizedUser(), removeAuthorizedUser(),
showUsers(), showInvited(), resendInvitation(), configureApp(),
setProperty(), unsetProperty(), purgeApp(), restartApp(),
terminateApp(), showUsage(), and showMetrics() (#863, #864).
When needed packages are not installed, and you're in an interactive environment, rsconnect will now prompt you to install them (#665).
The confirmation prompt presented upon lint failures indicates "no" as its default. (#652)
Introduced support for publishing to Posit Cloud. This feature is currently in closed beta and requires access to an enabled account on Posit Cloud. See Posit Cloud's Announcement for more information and to request access.
Update company and product names for rebranding to Posit.
Shiny applications and Shiny documents no longer include an implicit
dependency on ragg when that package is present
in the local environment. This reverts a change introduced in 0.8.27.
Shiny applications should add an explicit dependency on ragg (usually with
a library("ragg") statement) to see it used by shiny::renderPlot (via
shiny::plotPNG).
The documentation for shiny::plotPNG explains the use of ragg. (#598)
Fix bug that prevented publishing or writing manifests for non-Quarto content
when a Quarto path was provided to the quarto argument of writeManifest(),
deployApp(), and related functions.
Escape account names when performing a directory search to determine an appropriate server. (#620)
quarto argument. (#594).rscignore. (#599)appDir and quarto binary but not an
appPrimaryDoc work more consistently. A directory containing a .qmd file
will deploy as Quarto content instead of failing, and a directory containing
an .Rmd file will successfully deploy as Quarto content instead of falling
back to R Markdown. (#601)ragg package is installed locally, it is now added as an implicit
dependency to shiny apps since shiny::renderPlot() now uses it by default
(when available). This way, shiny apps won't have to add library(ragg) to
get consistent (higher-quality) PNG images when deployed. (#598)openssl version to 2.0.0 to enable publishing for users
on FIPS-compliant systems without the need for API keys. (#452)writeManifest, which requires passing the absolute
path to a Quarto executable to its new quarto parameterquarto parameter to deployApp to enable deploying Quarto documents
and websites by supplying the path to a Quarto executablejupyter runtimeimage in the bundle manifestshowLogs function takes a server parameter. (#57)rsconnect.tar option, which can be used to specify the path to a
tar implementation instead of R's internal implementation. The previous
method, using the RSCONNECT_TAR environment variable, still works, but the
new option will take precedence if both are set.curl option -T when uploading files to avoid out of memory
errors with large files. (#544)rsconnect.max.bundle.size and rsconnect.max.bundle.files options are
enforced when processing an enumerated set of files. Previously, these
limits were enforced only when bundling an entire content directory. (#542)tools::R_user_dir. Configuration created by earlier versions of this
package is automatically migrated to the new location. (#550).rscignore file to exclude files or directories from publishing (#368)R CMD CHECKR_USER_CONFIG_DIRshiny.R instead of server.R (#509)verbose option to writeManifest utility (#468)options(rsconnect.http.trace.json = TRUE) could cause deployment errors with some HTTP transports (#490)RSCONNECT_TAR environment variable can be used to select the tar implementation used to create bundles (#446)showUsers() (#398)connectApiUser() did not set a user id (#407)deployApp to force the generation of a Python environment file or a requirements.txt file (#409)server.R is present (#461)packrat 0.5 or later (#434)writeManifest() no longer reference packrat files in the generated manifest.json. The packrat entries were transient and only existed while computing dependencies. (#472)applications when ShinyApps does not return size details (#496)browser() debugging calls when deploying (#196)appId and other global deployment parameters to deploySite (#231)deployments() without any registered accounts (#261)renv files from deployment bundle (#367)RETICULATE_PYTHON when writing manifests (#374)on.failure user hook to run a function when deployApp() fails (#375)requirements.txt for Python, if it exists (#386)