feat: verify deployment on a draft, activate on success#805
Conversation
|
☂️ Python Coverage
Overall Coverage
New FilesNo new covered files... Modified Files
|
marcosnav
left a comment
There was a problem hiding this comment.
This looks good, with one caveat for Server.HideVersion. Not sure how often customers configure Connect with it, but it'll block the drafts feature in those cases even for recent versions of Connect. Something to keep in mind for docs maybe.
| def supports_verify_before_activate(self) -> bool: | ||
| """Whether the target server supports deploying a bundle as a draft and | ||
| activating it separately. shinyapps.io / Posit Cloud and pre-2025.06.0 Connect | ||
| do not, so for those we deploy and activate in one step and verify the active | ||
| content instead.""" |
There was a problem hiding this comment.
One caveat, Connect configured with Server.HideVersion will hide the version even for authenticated users
There was a problem hiding this comment.
I'm not sure there is a good way around this because if you try to deploy a draft and the version of Connect doesn't support it, it errors badly, and that means you have to upload the bundle again, which could be expensive.
I had an idea for how to work around this though, WDYT? #807
There was a problem hiding this comment.
Yeah, I think setting an env var is a good workaround, it is an easy thing to do to unblock folks
Deploy commands now deploy the new bundle as a draft (activate=false), verify it by accessing its preview URL, and only activate it once the verification succeeds. If verification fails, the bundle is left as a draft and the previously-active bundle keeps serving, so a broken build never becomes the active version. This also fixes #768: --draft now verifies the draft bundle rather than the currently-active content. --no-verify retains the old behavior of activating immediately without verification. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dirname("/__api__") returns "/", so joining it with "/content/..."
produced a "//content/..." path. Connect normalizes it, but it is sloppy
and made the verification request URL awkward to register in tests. Strip
the trailing slash from the base so root-hosted and path-prefixed servers
both produce a clean single-slash path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add two live-Connect integration tests (run via posit-dev/with-connect) that exercise the verify-before-activate guarantees and are expected to fail without the changes on this branch: - test_default_deploy_does_not_activate_broken_bundle (#769): a broken redeploy fails and leaves the previously-active working bundle serving; without the change the broken bundle is activated before verification. - test_draft_deploy_verifies_the_draft_not_the_active_bundle (#768): deploying a broken draft fails verification; without the change --draft verified the still-good active content and reported success. Both reuse the existing flask / flask-bad fixtures (flask-bad builds fine but raises at startup). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Connect added the `activate` field on the deploy endpoint in 2025.06.0; older servers reject the unknown field, which broke every deploy against them once verify-before-activate became the default. Gate the draft-first flow on server version: on Connect >= 2025.06.0 we deploy a draft, verify it, and activate on success; on older servers (and shinyapps.io) we deploy and activate in one step and verify the active content, as before. Add a unit test for the fallback path on an unsupported server, and bump the two live integration tests to require Connect 2025.06.0 since they assert the verify-before-activate behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
should_deploy_as_draft() returned True for --draft regardless of server support, so --draft against Connect < 2025.06.0 still sent activate:false and failed with a cryptic "unknown field" error. Raise a clear RSConnectException instead; silently downgrading to a non-draft deploy would activate the bundle, the opposite of --draft's intent. Add a unit test for --draft on an unsupported server. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d3f57db to
4cfb709
Compare
Closes #769. Also fixes #768.
What
Makes verify-before-activate the default for
rsconnect deploy, on Connect servers that support it:activate: false.access_contenthits the draft bundle's preview URL (/content/<guid>/_bundle<id>/), which cold-starts the process, so a non-5xx response confirms the content actually runs.POST .../deploywithactivate: true(the "Activate Draft" button's behavior). If verification fails, the bundle is left as a draft and the previously-active bundle keeps serving, so a broken build never becomes the active version.This also fixes #768:
--draftnow verifies the draft bundle rather than the currently-active content.Flag behavior (Connect >= 2025.06.0)
--draft--no-verifyVersion gating
Connect added the
activatefield on the deploy endpoint in 2025.06.0; older servers reject the unknown field. So the draft-first flow is gated on server version:activatefield sent) and verify the active content — i.e. the pre-PR behavior.--draftagainst these servers is unsupported (it cannot be expressed without theactivatefield).Changes
api.py:access_contenttakes an optionalbundle_idand accesses the draft preview URL when given one.verify_deploymenttargets the draft bundle when one was deployed (not yet active), otherwise the active content.activate_deploymentmethod (re-issues the deploy withactivate: true).bundle_idthreaded into the deploy result.server_supports_draft_deploy(version)helper +RSConnectExecutor.supports_verify_before_activate(cached) andshould_deploy_as_draft(...)to centralize the gating decision.//contentdouble-slash in the access path.main.py: deploy call sites useshould_deploy_as_draft/supports_verify_before_activate;--draft/--no-verifyhelp text updated.tests/test_main.py:activatefield, single deploy, verify active).posit-dev/with-connect, gated to Connect >= 2025.06.0) that fail without these changes:test_default_deploy_does_not_activate_broken_bundle(feat: verify deployment on a draft, activate on success #769) — a broken redeploy fails and leaves the previously-active working bundle serving.test_draft_deploy_verifies_the_draft_not_the_active_bundle(bug: verify_deployment doesn't verify a draft #768) — deploying a broken draft fails verification; previously--draftverified the still-good active content and reported success.🤖 Generated with Claude Code