Goodbye R-Forge, hello Codeberg
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
After 20 years of service the R-Forge package hosting platform will be retiring soon. Codeberg is a modern alternative that shares many of the ideas and values that R-Forge was built on. A tutorial for transitioning to Codeberg (or other Git-based platforms) is provided.
You say goodbye
R-Forge was created 20 years ago after the 2nd useR! conference in 2006. Kurt Hornik had the idea that “R should have its own SourceForge!” (note that GitHub did not yet exist at the time). However, the goal was that this code sharing platform should be created by the R community for the R community. The implementation was led by Stefan Theussl in the following months using GForge/FusionForge, a fork of the software behind SourceForge. Hosting and funding was provided by WU Wirtschaftsuniversität Wien and The R Project.
R-Forge offers a Subversion (SVN) repository for collaborative development of R packages along with various other services that were state of the art at the time: daily package builds and checks, forums, mailing lists, bug trackers, web pages. A short introduction was published in the inaugural issue of The R Journal: Theußl & Zeileis (2009). “Collaborative Software Development Using R-Forge.” The R Journal, 1(1):9-14. doi:10.32614/RJ-2009-007
As the FusionForge system is no longer maintained, R-Forge will be retired in the next months, switching to a read-only site. The system was somewhat dated anyways: The website has a certain “00s” vibe (see the screenshot of my profile page below) and it lacks services that became standard over the last two decades like issues, pull requests, and continuous integration.

I say hello
Codeberg is a non-profit, community-led effort that provides services to free and open-source projects, such as Git hosting (using Forgejo), pages, continuous integration, etc. It is run by the non-profit organization Codeberg e.V. based in Berlin, Germany, which contributors can (but do not have to) become a member of. (I joined this summer.)
Thus, Codeberg shares many of the ideas and values, that R-Forge was built on, but provides state-of-the-art open-source tools for collaborative development of R packages (and beyond). For a first impression of the look and feel, see the screenshot of my profile page below.

I say go go go
For transitioning from R-Forge to Codeberg – or some other Git-based code hosting platform – Reto Stauffer has written up a step-by-step guide. The most important steps are also listed below.
1. SVN checkout from R-Forge
The starting point for the transition is the SVN repository from
R-Forge that you probably have already checked out. For illustration we are using the c403 R package
that is one of the packages contained in the exams project on R-Forge.
svn checkout svn://R-Forge.R-project.org/svnroot/exams/
2. List of R-Forge contributors
To find all SVN usernames who ever contributed to the SVN on R-Forge repository
(in this example, to the folder exams/pkg/c403) the command svn log -q can be used. Using the following shell command
a text file with the unique names can be created. Note that exams/pkg/c403 needs to be replaced for other projects
and the output file name can be adjusted too:
(cd exams/pkg/c403 && svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq) > \
authors_c403.txt
This creates the text file authors_c403.txt which will look something like:
azeileis retos
This file needs to be modified by adding the full names and e-mail addresses of the contributors. Important: The leading spaces need to be removed in each line for the subsequent commands to work.
azeileis = Achim Zeileis <[email protected]> retos = Reto Stauffer <[email protected]>
Provided the profile pages on R-Forge are up to date for the users, it is also possible to scrape this information, see the optional step 2*. below.
3. Clone a Git version of the SVN
Using git-svn a Git version of the SVN can be easily created.
For this step it is crucial that all users are listed in the authors file created in the previous
step, otherwise git-svn will fail.
git svn clone svn://R-Forge.R-project.org/svnroot/exams/pkg/c403 \
--authors-file=authors_c403.txt --no-metadata \
git-c403
Again, adjust the URL of the SVN, the authors file name, and the name of the git repository (git-c403)
as needed.
4. Optional: Filter files in the Git repository
This step is not needed for the c403 example but is particularly useful when migrating a full
R-Forge repository (rather than just a pkg sub-folder). In that case
it might be useful to filter out certain files or directories such as the initial README file
auto-created by R-Forge or the www sub-directory (typically just containing original PHP file or
a auto-generated web page from pkgdown or altdoc).
Such files can be filtered, i.e., erased completely from the repository history, using git-filter-repo:
git-filter-repo --force --path 'README' --invert-paths git-filter-repo --force --path 'www' --invert-paths
5. Import Git repository on Codeberg
First, create a new project on Codeberg, e.g., https://codeberg.org/zeileis/c403. The project should be completely empty without any initial commit.
Then, all left to do then is to tell the Git repository where its new home is (again adjust all names correspondingly):
cd git-c403 git remote add origin ssh://[email protected]/zeileis/c403.git git push --set-upstream origin main
Analogous commands can be used for setting the origin to a project on GitHub, GitLab, etc.
All history will be immediately available in the new repository. If the authors have accounts on Codeberg, their profiles will be linked based on the e-mail address(es) associated with their Codeberg account.
6. Package builds and checks via R-universe
To automatically build and check the development versions of the R package on Codeberg, the most convenient solution is to use the R-universe service developed by Jeroen Ooms and provided by rOpenSci.
In short, to make use of it, you need a GitHub account and create a repository
like zeileis.r-universe.dev.
This should contain a packages.json file with the names and repository URLs
of one or more R packages, e.g.,
[
{
"package": "c403",
"url": "https://codeberg.org/zeileis/c403"
}
]
As a final step, the R-universe app has to be installed on the same GitHub account. See the R-universe set up documentation for more details.
7. Codeberg pages
If you want to add a project page for your package, e.g., generated via altdoc or pkgdown, then https://codeberg.page/ can be used.
The c403 package does not have a page, yet, but for an example see
https://zeileis.codeberg.page/topmodels/ which is generated from
the topmodels R package
using altdoc in combination with quarto.
All that needs to be done to create the page manually, is to create an
empty branch pages via git switch --orphan pages, adding the static
site files, and pushing them to the repository.
Alternatively, it is also possible to use Forgejo actions to do this automatically.
8. Update descriptions and links
Finally, inform users where the sources of the package can be found, i.e., update
the DESCRIPTION (especially the URL and BugReports fields) and in the NEWS.
Additionally, a README.md file would be expected in a project while on R-Forge
this was often not used (because R-Forge would be aware of the DESCRIPTION instead).
Finally, it is recommended to add a link from the old R-Forge project to the new
Codeberg project (possibly also in the www folder). To assure that none of the
contributors can make modifications in the old R-Forge SVN, the permissions
on R-Forge can be switched to read-only (typically for the Senior Developer role).
Optional addition: 2.* Scrape author names and e-mail addresses
In step 2, after the file with the author names (authors_c403.txt in the example above) has been created,
one can try to automate the addition of proper names and e-mail addresses. This is particularly useful
if there are more than just a handful of users. It works when the R-Forge user pages list the proper names
and the (current) e-mail addresses.
The function below can be called in R as
rforge_authors("c403")
It first reads the authors_c403.txt file, looks up all users on R-Forge
(using the rvest package),
and then updates the authors_c403.txt file accordingly.
rforge_authors <- function(x) {
txt <- sprintf("authors_%s.txt", x)
if (file.exists(txt)) {
a <- readLines(txt)
a <- gsub(" ", "", a)
} else {
stop(sprintf("Please use 'svn log' to set up an '%s' file with all user names", txt))
}
for (i in seq_along(a)) {
doc <- a[i] |>
sprintf(fmt = "https://r-forge.r-project.org/users/%s/") |>
rvest::read_html()
n <- doc |>
rvest::html_table() |>
lapply(as.data.frame) |>
lapply(subset, subset = X1 == "Real Name:", select = "X2", drop = TRUE) |>
unlist() |>
unique()
if (length(n) < 1L) n <- "FIXME"
e <- doc |>
rvest::html_table() |>
lapply(as.data.frame) |>
lapply(subset, subset = X1 == "Email Address:", select = "X2", drop = TRUE) |>
unlist() |>
unique() |>
gsub(pattern = " @nospam@ ", replacement = "@", fixed = TRUE)
if (length(e) < 1L) e <- "FIXME"
a[i] <- sprintf("%s = %s <%s>", a[i], n, e)
}
writeLines(a, txt)
invisible(a)
}
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.