flowchart TD A[Create GitHub Pre-release] --> B[Trigger GitHub Action] B --> C[Run R CMD check] C --> D{Checks Pass?} D -->|No| E[Fail Workflow] D -->|Yes| F[Extract Package Metadata] F --> G[Submit to CRAN] G --> H[Create GitHub<br/>Issue with Status] H --> I[Developer Responds<br/>to CRAN Email]
This post describes an experimental workflow that automates CRAN submissions using GitHub Actions. While not yet a proper GitHub Action, it demonstrates the potential for future development.
As R package developers, we’ve all been there - you’ve spent weeks polishing a new version of your package, running tests, updating documentation, and making sure everything is perfect. Then comes the slightly tedious process of submitting to CRAN.
Usually, this involves:
- Building your package tarball (which can take forever for packages with compiled code like
mlpack
) - Going to the CRAN submission web form
- Filling out your information
- Uploading your package
- Confirming the submission
- Waiting for the confirmation email
- Clicking the link in the email to complete the submission
While devtools::submit_cran()
helps streamline some of this process, it still requires manual intervention and local building. Even more problematic are packages with extensive C++ code that can take 30+ minutes to build on a personal machine, making the process painfully slow. Though, under current CI/CD approaches, we’re able to download the built package tarball from GitHub artifacts with some additional scripting to retain it and submit it to CRAN at the cost of additional manual steps.
Enter the What if… What if we could automate this process and trigger it directly from our GitHub repository when we create a pre-release? This would align the R package ecosystem more closely with Python’s PyPI publishing workflow, which can be entirely automated through GitHub Actions.
GitHub-Powered CRAN Submissions: An Experimental Workflow
Today, I’m excited to share an experimental workflow that automates the CRAN submission process when you publish a pre-release of your package. This is not yet a proper GitHub Action, but rather an experiment that will hopefully lead to a full-fledged action in the future. This approach allows you to:
- Tag your repository with a pre-release version
- Have GitHub Actions automatically run R CMD check
- Submit your package to CRAN if checks pass
- Create a GitHub issue notifying you of the submission status
The idea is that once your package is accepted by CRAN, you can convert the pre-release to a full release, maintaining a clean workflow that ties your GitHub releases to CRAN releases. This also will remove the need for a CRAN-RELEASE
file or similar to track CRAN submission status inside the repository in favor of an issue-based approach.
Prerequisites
Before implementing this workflow, ensure you have:
- A GitHub repository for your R package
- A properly configured R package with:
- Valid
DESCRIPTION
file - Proper maintainer information
- Tests that pass
R CMD check
without warnings or errors
- Valid
- GitHub Actions enabled on your repository
- Permission to create releases and issues in your repository
Under the Hood: How the Workflow Functions
The workflow combines several components to automate the CRAN submission. Essentially, it runs R CMD check using r-lib/actions/check-r-package
and, then, submits the package to CRAN using a custom R script based on the core functionality of what devtools::submit_cran()
does behind the scenes, but wraps it in a GitHub Actions workflow that can be triggered automatically. Here’s a quick overview of the process:
The action performs several important steps:
- Safety checks: It runs a full
R CMD check
with--as-cran
to ensure your package meets CRAN’s requirements - Metadata extraction: It parses your
DESCRIPTION
file to get package name, version, and maintainer information - Submission handling: It use a script that mimics the HTTP requests made by
devtools::submit_cran()
- Notification: It creates a GitHub issue with the status and next steps, so you know whether the submission was successful
Preventing Problematic Submissions
I’ve taken great care to ensure that this action doesn’t lead to problematic submissions:
- The workflow will only run on pre-releases, not on every commit
- It performs a full R CMD check and fails if there are any warnings or errors
- It verifies package metadata before submission
- It creates a GitHub issue with detailed next steps, including a reminder to check your email
- The maintainer’s email is partially obfuscated in the GitHub issue for privacy
Even with these safety measures, you should always ensure your package meets CRAN standards before creating a pre-release that triggers submission.
Monitoring the Submission
After a successful or unsuccessful submission, the workflow will create a GitHub issue in your repository with the submission status and next steps.
Here’s an example of what the issue might look like if it completes successfully:
## CRAN Submission Status: Submitted
A CRAN submission for **testpkg** version **0.1.0** has been submitted.
### Next Steps:
1. **Check your email**: You MUST reply to the confirmation email from CRAN to complete the submission.
2. **Verify submission**: Check if your package appears at https://CRAN.R-project.org/incoming/
3. **If issues occur**: Contact CRAN administrators at cran-sysadmin@R-project.org
### Submission details:
- Package: testpkg
- Version: 0.1.0
- Maintainer: James Joseph Balamuta
- Email: ja****@gmail.com
- Submission Date: 2025-03-04T04:06:10Z
- Trigger: Pre-release tagged as "0.0.1"
Note: You will need to manually handle any feedback from CRAN reviewers.
You can see an example on the GitHub repository.
Implementing the Workflow
To use this experimental workflow in your own package, you’ll need to:
- Copy the
.github/workflows/submit-cran.yaml
and.github/scripts/submit-to-cran.R
files to your repository - Create a GitHub pre-release when you’re ready to submit to CRAN
- Monitor the GitHub Action logs and the created issue
- Check your email for the CRAN confirmation link (you still need to click this!)
- Convert the pre-release to a full release once CRAN accepts your package
Triggering the Workflow
After copying the workflow files to your repository, you can trigger the workflow by creating a pre-release in your GitHub repository. Specifically:
- Create a pre-release:
- Go to your GitHub repository
- Click on “Releases” in the sidebar
- Click “Draft a new release”
- Enter your tag version (e.g.,
v1.0.0-rc1
) - Check “This is a pre-release”
- Click “Publish release”
- Monitor the workflow:
- Go to the “Actions” tab in your repository
- Watch the “CRAN Submission” workflow run
- Check the logs for any issues
- Read the GitHub issue:
- Once the workflow completes, check the “Issues” tab in your repository
- Look for the issue created by the workflow
- Check out the submission status and next steps
- Respond to the confirmation email:
- If the issue indicates the workflow completes successfully, check your email for the CRAN confirmation
- Click the link in the email to confirm the submission
The Road Ahead: Limitations and Future Plans
This experimental workflow is just the beginning. Currently, it:
- Cannot completely automate the process (you still need to respond to the CRAN confirmation email)
- Doesn’t handle any back-and-forth with CRAN reviewers
- Still needs more real-world testing with different packages
In future, I hope to:
- Transform this experiment into a proper, reusable GitHub Action with configurable inputs
- Add more customization options for different submission workflows
- Improve error handling and recovery mechanisms
Conclusion
While not a complete solution, this experimental workflow takes a significant step toward automating the CRAN submission process. By bridging the gap between GitHub releases and CRAN submissions, we can make the R package publication process more streamlined and git-driven. The workflow is especially beneficial for packages with compiled code, where build times can be significant and offloading this work to GitHub Actions can save valuable development time.
Try it out in your next package update, and let me know what you think! Pull requests and suggestions are welcome to improve this workflow for the entire R community.
The complete code is available on GitHub.
Acknowledgements
This project was inspired by the automated publishing workflows available for Python packages and the desire to bring similar capabilities to the R ecosystem. Thanks to the R package development community for their continued work on streamlining the package development process.
Questions and Answers
Is this a complete replacement for devtools::submit_cran()
?
Not entirely. This workflow automates the submission process but still requires manual intervention for the confirmation email and any subsequent communication with CRAN reviewers.
Will this work for packages with compiled code?
Yes! In fact, packages with compiled code (C++, Fortran, etc.) benefit the most from this workflow, as it offloads the time-consuming build process to GitHub Actions.
What happens if my package doesn’t pass R CMD check?
The workflow will fail before submitting to CRAN, preventing problematic submissions. You’ll see the errors in the GitHub Actions logs.
How will I know if the submission was successful?
The workflow creates a GitHub issue in your repository with the submission status and next steps.