How to deploy to RStudio Connect from a GtiHub Actions workflow

I am trying to build and deploy a pkgdown site to my organization's installation of RStudio Connect entirely from within a GitHub Actions workflow. I feel like I am almost there, but I am having trouble with authentication. I looked up my token and secret with rsconnect::accountInfo(), plugged them in as secrets in the GitHub settings page of the repo, and defined the following steps:

      - name: Build site
        run: pkgdown::build_site(preview = FALSE)
        shell: Rscript {0}

      - name: Deploy site
        run: |
          rsconnect::setAccountInfo(
            name = Sys.getenv("RSCONNECTNAME"),    # registered as a secret in GitHub settings
            token = Sys.getenv("RSCONNECTTOKEN"),  # registered as a secret in GitHub settings
            secret = Sys.getenv("RSCONNECTSECRET") # registered as a secret in GitHub settings
          )
          withr::with_dir(
            "docs",
            rsconnect::deployApp(
              appDir = ".",
              appFiles = list.files(".", recursive = TRUE, all.files = TRUE),
              appPrimaryDoc = "index.html",
              appId = REDACTED,
              appName = REDACTED,
              appTitle = REDACTED,
              account = Sys.getenv("RSCONNECTNAME"), # registered as a secret in GitHub settings
              server = "rstudio-connect.REDACTED.com"
            )
          )
        shell: Rscript {0}

Unfortunately, setAccountInfo() thinks it is going to shinyapps.io instead of rstudio-connect...com, and there is no way to tell it which server it should use. The workflow errors out with this:

Error: HTTP 401
GET https://api.shinyapps.io/v1/users/current/
Unauthorized

When I remove the setAccountInfo() call, I get a different error:

Error: You must register an account using setAccountInfo prior to proceeding.

Hi Will,

You can register the RStudio Connect server with the addConnectServer function from the rsconnect package. You can find more about the function's documentation here: Server Management Functions — servers • rsconnect

You can also use the rstudio/actions/connect-publish action in GitHub Actions and that allows you to publish things to RStudio Connect as well with the workflow you are following. You can also see an example of this in action :grin: in this repository: gha-deployment-connect-private-repo/deploy_to_connect.yml at main · ian-flores/gha-deployment-connect-private-repo · GitHub

Hope this is of help,
Ian Flores Siaca

2 Likes

Thanks for the clues! I am still getting still getting the same "You must register an account using setAccountInfo" error, but I changed my workflow step to something more promising. Do you know of a way I could troubleshoot the step below?

    env:
      CONNECT_API_KEY:  ${{ secrets.CONNECT_API_KEY }} # defined in GitHub settings
      RSCONNECTNAME: ${{ secrets.RSCONNECTNAME }} # defined in GitHub settings
      R_REMOTES_NO_ERRORS_FROM_WARNINGS: false

    steps:

...

      - name: Deploy site
        run: |
          rsconnect::addConnectServer(
            url = sprintf("https://%s@rstudio-connect.REDACTED.com", Sys.getenv("CONNECT_API_KEY")),
            name = "connect",
            quiet = TRUE
          )
          withr::with_dir(
            "docs",
            rsconnect::deployApp(
              appDir = ".",
              appFiles = list.files(".", recursive = TRUE, all.files = TRUE),
              appPrimaryDoc = "index.html",
              appId = REDACTED,
              appName = "REDACTED",
              appTitle = "REDACTED",
              account = Sys.getenv("RSCONNECTNAME"),
              server = "rstudio-connect. REDACTED.com"
            )
          )

Apologies if I misquoted, you need both setAccountInfo and addConnectServer. One registers the server in the environment and the other one "sets" the account info. I also made a small modification to your URL in the addConnectServer function. I include an example below. Hope you now have a successful deployment!

      - name: Register RStudio Connect Server
        run: |
           rsconnect::addConnectServer(
            url = "https://rstudio-connect.REDACTED.com",
            name = "connect",
            quiet = TRUE
          )
         shell: Rscript {0}
      - name: Register RStudio Connect Account
         run: |
          rsconnect::setAccountInfo(
            name = Sys.getenv("RSCONNECTNAME"),    # registered as a secret in GitHub settings
            token = Sys.getenv("RSCONNECTTOKEN"),  # registered as a secret in GitHub settings
            secret = Sys.getenv("RSCONNECTSECRET") # registered as a secret in GitHub settings
          )
        shell: Rscript {0}
      - name: Deploy site
        run: |
          withr::with_dir(
            "docs",
            rsconnect::deployApp(
              appDir = ".",
              appFiles = list.files(".", recursive = TRUE, all.files = TRUE),
              appPrimaryDoc = "index.html",
              appId = REDACTED,
              appName = REDACTED,
              appTitle = REDACTED,
              account = Sys.getenv("RSCONNECTNAME"), # registered as a secret in GitHub settings
              server = "connect"
            )
          )
        shell: Rscript {0}
1 Like

Thanks, makes perfect sense to call addConnectServer() before setAccountInfo(). The latter still seems to query shinyapps.io though, in spite the the preceding step.

Error: Error: HTTP 401
GET https://api.shinyapps.io/v1/users/current/
invalid token
Execution halted
Error: Process completed with exit code 1.

Actually, I can reproduce that error locally:

rsconnect::addConnectServer(
  url = "https://rstudio-connect.REDACTED.com",
  name = "connect",
  quiet = TRUE
)
rsconnect::setAccountInfo(
  name = Sys.getenv("RSCONNECTNAME"),    # set in ~/.Renviron
  token = Sys.getenv("RSCONNECTTOKEN"),  # set in ~/.Renviron
  secret = Sys.getenv("RSCONNECTSECRET") # set in ~/.Renviron
)
#> Error: HTTP 401
#> GET https://api.shinyapps.io/v1/users/current/
#>   invalid token

Also, I have been using the token from rsconnect::accountInfo(Sys.getenv("USER"))$token and the secret from rsconnect::accountInfo(Sys.getenv("USER"))$private_key. Is that right? Otherwise, I do not know how to get these credentials for my work's installation of Connect. Connect does give me an API key, but I am not sure how to use it for this purpose.

Calling setAccountInfo() locally seems to have somehow taken away my ability to publish to Connect from the rsconnect package. When I reconnected my account in the RStudio IDE global settings though, deployApp() started working locally again.

A colleague mentioned today that Connect can sync with a Git repo, and I tried it out with the usual pkgdown workflow and it worked like a dream! Git integration covers all my Connect cases beautifully.

1 Like

Actually, the manifest.json requirement turns out to be a bit of a snag. pkgdown::deploy_to_branch() does not generate a manifest automatically, and I thought I could hack one and stick in pkgdown/favicons/, but it's hard to keep it up to date. At the moment, it seems I need to write something else in the last step of this convenient GitHub Actions workflow file. Hoping pkgdown will eventually write its own manifest in deploy_to_branch().