Introducing multideploy: Streamline file deployments across multiple repositories

Challenging the Challenge of Managing Many Repositories

r
github
devops
Author

James Balamuta

Published

March 21, 2025

If you’re managing multiple GitHub repositories, you’ve probably encountered the frustration of maintaining consistent files across them all. Whether it’s standardizing CI workflows, license files, code style configurations, or security policies - keeping everything in sync can be tedious and error-prone.

How do you update a GitHub Actions workflow across 50 repositories? What about implementing a new organizational guide across dozens of repos?

Introducing multideploy

Today I’m excited to announce {multideploy} (GitHub), an R package designed to streamline the process of deploying file changes across multiple GitHub repositories.

multideploy

What Can {multideploy} Do?

With just a few lines of R code, you can:

  • Deploy any file to multiple repositories in a single operation
  • Create pull requests with multiple file changes
  • Precisely target subsets of repositories using regex patterns
  • Preview changes with dry-run mode before applying them
  • Deploy entire directory structures while preserving their organization

The package handles all the GitHub API interactions through the gh package, providing a clean interface that abstracts away the complexities of batch operations.

Getting Started

You can install multideploy from GitHub:

# install.packages("remotes")
remotes::install_github("coatless-rpkg/multideploy")

Before using multideploy, you need to authenticate with GitHub. The package leverages the gh package for authentication, which looks for a GitHub Personal Access Token (PAT) in the GITHUB_PAT or GITHUB_TOKEN environment variables.

For security, it’s best to store your PAT in your git credential system rather than in your scripts. You can set it up with the gitcreds package shown below.

If you need to set up authentication in your script:

# Set GitHub PAT (or better, use .Renviron)
Sys.setenv(GITHUB_PAT = askpass::askpass("What is your GitHub Personal Access Token (PAT)?"))

For regular use, add your PAT to the git credential system with:

gitcreds::gitcreds_set()

Then check out the documentation for more examples and advanced features or read on for a quick example.

Quick Example

Here’s how simple it is to update a workflow file across all repositories that match a pattern:

library(multideploy)

# Find all API repositories
repos <- repos("my-organization", filter_regex = "^api-")

# Deploy an updated CI workflow to all of them
results <- file_deploy(
  source_file = "templates/ci.yml",
  target_path = ".github/workflows/ci.yml",
  repos = repos,
  commit_message = "Update CI workflow for security compliance"
)

# See what happened
print(results)

Need a pull request instead? Just use pr_create() with a mapping of files:

mapping <- file_mapping(
  "templates/ci.yml" = ".github/workflows/ci.yml",
  "templates/.lintr" = ".lintr",
  "templates/CODEOWNERS" = ".github/CODEOWNERS"
)

pr_create(
  repos = repos,
  branch_name = "update/standard-files",
  title = "Update standard repository files",
  body = "Updates CI workflow, linting config, and CODEOWNERS",
  file_mapping = mapping
)

The possibilities are endless with being able to map files without having to have a copy of the repository locally.

Fin

If you manage multiple GitHub repositories, multideploy can save you countless hours and help maintain consistency across your organization’s code. Give it a try and let me know what you think!

Would you like to see any specific features added to multideploy? Open a feature issue request on the project’s GitHub repository.