Use rrepo

Publish packages

Publish R source packages from the dashboard or CI.

Publish source packages through the rrepo API from GitHub Actions or your preferred CI system. You can also upload sources manually in the dashboard.

Required secrets

Store these values as GitHub Actions secrets:

  • RREPO_REPOSITORY_URL, such as https://rrepo.dev/acme/internal
  • RREPO_API_KEY, with packages:write

Publish from GitHub Actions

rpx offers this same workflow template during package initialization. If you selected it there, configure the secrets above in your GitHub repository. Otherwise, save the workflow below as .github/workflows/release.yml.

Push a tag matching the version in DESCRIPTION, such as v1.2.0. This workflow builds the source package, uploads it to rrepo, and publishes the same archive as a GitHub Release asset. Add any package-specific build dependencies before the build step.

yaml
name: Release

on:
  push:
    tags:
      - 'v*'

permissions:
  contents: write

jobs:
  publish:
    name: Publish source package
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - uses: r-lib/actions/setup-r@v2
        with:
          r-version: release
      - name: Check release version
        shell: bash
        run: |
          version=$(awk '$1 == "Version:" {print $2}' DESCRIPTION)
          test "$GITHUB_REF_NAME" = "v$version"
      - name: Build source package
        run: R CMD build .
      - name: Upload source package to rrepo
        shell: bash
        env:
          RREPO_REPOSITORY_URL: ${{ secrets.RREPO_REPOSITORY_URL }}
          RREPO_API_KEY: ${{ secrets.RREPO_API_KEY }}
        run: |
          : "${RREPO_REPOSITORY_URL:?Set the RREPO_REPOSITORY_URL secret}"
          : "${RREPO_API_KEY:?Set the RREPO_API_KEY secret}"
          package=$(awk '$1 == "Package:" {print $2}' DESCRIPTION)
          version=$(awk '$1 == "Version:" {print $2}' DESCRIPTION)
          tarball="${package}_${version}.tar.gz"
          test -f "$tarball"
          curl --fail --show-error \
            --request POST \
            --header "Authorization: Bearer ${RREPO_API_KEY}" \
            --form "file=@${tarball}" \
            "${RREPO_REPOSITORY_URL%/}/upload"
      - name: Publish GitHub release
        shell: bash
        env:
          GH_TOKEN: ${{ github.token }}
          GH_REPO: ${{ github.repository }}
        run: |
          package=$(awk '$1 == "Package:" {print $2}' DESCRIPTION)
          version=$(awk '$1 == "Version:" {print $2}' DESCRIPTION)
          gh release create "$GITHUB_REF_NAME" "${package}_${version}.tar.gz" \
            --verify-tag --title "$GITHUB_REF_NAME" --generate-notes

Share your package

Share the package name and repository address with the people who will install it:

  • For rpx: https://rrepo.dev/acme/internal.
  • For R, rv, and renv: https://cran.rrepo.dev/acme/internal.

Install packages has commands for each tool. For private repositories, also provide a read key and the private access instructions.

Source uploads

Set RREPO_REPOSITORY_URL and RREPO_API_KEY in your terminal environment, then send the source archive as multipart field file to /upload.

macOS / Linux

Terminal
curl --fail-with-body --silent --show-error \
  --header "Authorization: Bearer ${RREPO_API_KEY}" \
  --form "file=@example_1.0.0.tar.gz" \
  "${RREPO_REPOSITORY_URL%/}/upload"

Windows

powershell
$repositoryUrl = $env:RREPO_REPOSITORY_URL.TrimEnd('/')
curl.exe --fail-with-body --silent --show-error `
  --header "Authorization: Bearer $env:RREPO_API_KEY" `
  --form "file=@example_1.0.0.tar.gz" `
  "$repositoryUrl/upload"

Replacing a source package

To replace an existing source package, add --form "replace=true" to the upload command, including the workflow's upload step. Without it, an existing source returns HTTP 409.