This guide will demonstrate how to use {fledge}, using a mock R package as an example. We are going to call our package “{SuperFrob}”. We will develop it from scratch and also maintain a changelog as the development progresses. Finally, we will demonstrate how this changelog can eventually be converted to release notes when the package is submitted to CRAN.
Before we start development for {SuperFrob}, we set up the basic development environment required for any typical R package.
We will start by creating a new package. For this demo, the package is created in a temporary directory. A real project will live somewhere in your home directory.
tempdir <- tempfile("fledge")
dir.create(tempdir)
The usethis::create_package()
function sets up a package project ready for development. The output shows the details of the package created.
pkg <- usethis::create_package(file.path(tempdir, "SuperFrob"))
## Package: SuperFrob
## Title: What the Package Does (One Line, Title Case)
## Version: 0.0.0.9000
## Authors@R (parsed):
## * First Last <first.last@example.com> [aut, cre] (YOUR-ORCID-ID)
## Description: What the package does (one paragraph).
## License: `use_mit_license()`, `use_gpl3_license()` or friends to
## pick a license
## Encoding: UTF-8
## LazyData: true
## Roxygen: list(markdown = TRUE)
## RoxygenNote: 7.0.0
In an interactive RStudio session, a new window opens. Users of other environments would change the working directory manually. For this demo, we manually set the active project.
usethis::proj_set()
The infrastructure files and directories that comprise a minimal R package are created:
fs::dir_tree()
## .
## ├── DESCRIPTION
## ├── NAMESPACE
## └── R
Next we set up this package for development and create a Git repository for the package.
usethis::use_git()
In interactive mode, the usethis::use_git()
function creates an initial commit, and the repository is in a clean state. In the demo this needs to be carried out manually.
## [89b5632] 2021-03-08: Initial commit.
git2r::commits()
## [[1]]
## [89b5632] 2021-03-08: Initial commit.
git2r::status()
## working directory clean
For working in branches, it is recommended to turn off fast-forward merging:
git2r::config(merge.ff = "false")
An alternative is to use squash commits.
An initial NEWS file can be created with usethis::use_news_md()
.
usethis::use_news_md()
Let’s take a look at the contents:
## # SuperFrob 0.0.0.9000
##
## * Added a `NEWS.md` file to track changes to the package.
This file needs to be tracked by Git:
## Staged changes:
## New: NEWS.md
git2r::commit(message = "Initial NEWS.md .")
## [9745a6d] 2021-03-08: Initial NEWS.md .
Now we start coding in the functionality for the package. We start by creating the new R file called super.R
and adding frobnication code.
usethis::use_r("super")
writeLines("# frobnicate", "R/super.R")
We commit this file to Git with a relevant message. Note the use of the bullet (-) before the commit message. This indicates that the message should be included in NEWS.md
when it is updated.
## [9a3360e] 2021-03-08: - Add support for frobmication.
The code in super.R
warrants a test:
usethis::use_test("super")
## test_that("multiplication works", {
## expect_equal(2 * 2, 4)
## })
In a real project we would substitute the testing code from the template by real tests. In this demo we commit straight away, again with a bulleted message.
## Staged changes:
## Modified: DESCRIPTION
## New: tests/testthat.R
## New: tests/testthat/test-super.R
git2r::commit(message = "- Add tests for frobnication.")
## [7d402a5] 2021-03-08: - Add tests for frobnication.
We use fledge::bump_version()
to assign a new dev version number to the package and also update NEWS.md
.
fledge::bump_version()
##
##
##
##
## → Committing changes.
##
##
## NULL
Let us see what NEWS.md
looks like after that bump.
## <!-- NEWS.md is maintained by https://cynkra.github.io/fledge, do not edit -->
##
## # SuperFrob 0.0.0.9001
##
## - Add tests for frobnication.
## - Add support for frobmication.
##
##
## # SuperFrob 0.0.0.9000
##
## * Added a `NEWS.md` file to track changes to the package.
While reviewing we notice that there was a typo in one of the comments. Let’s fix the typo:
## <!-- NEWS.md is maintained by https://cynkra.github.io/fledge, do not edit -->
##
## # SuperFrob 0.0.0.9001
##
## - Add tests for frobnication.
## - Add support for frobnication.
##
##
## # SuperFrob 0.0.0.9000
##
## * Added a `NEWS.md` file to track changes to the package.
writeLines(news, "NEWS.md")
This does not affect the original commit message, only NEWS.md
.
After tweaking NEWS.md
, it is important to use fledge::finalize_version()
and not to commit manually. This ensures that the tag is set to the correct version in spite of the NEWS.md
update. It should be called every time NEWS.md
is manually updated.
fledge::finalize_version()
## → Resetting to previous commit.
## → Committing changes.
##
##
When done, we push to the remote (GitHub or another Git service) with tags using fledge::finalize_version(push = TRUE)
, as advised. In this demo, no remote repository is set up, and the push process is not shown.
{SuperFrob} with frobnication is tested, now we want to enhance with super-frob. This requires changes to the code, and perhaps a new test. We create a branch and switch to this branch to implement this.
git2r::branch_create(git2r::last_commit(), name = "f-super-frob")
git2r::checkout(branch = "f-super-frob")
On the branch, separate commits are used for the tests and the implementation. These commit messages do not need to be formatted specially, because {fledge} will ignore them anyway.
usethis::use_test("frob")
## Staged changes:
## New: tests/testthat/test-frob.R
git2r::commit(message = "Add super-frob tests.")
## [4526096] 2021-03-08: Add super-frob tests.
usethis::use_r("frob")
writeLines("# super-frob", "R/frob.R")
git2r::add(path = ".")
git2r::status()
## Staged changes:
## New: R/frob.R
git2r::commit(message = "Add super-frob implementation.")
## [9258b13] 2021-03-08: Add super-frob implementation.
This branch can be pushed to the remote as usual. Only when merging we specify the message to be included in the changelog, again with a bullet.1
## Merge
git2r::status()
## Staged changes:
## New: R/frob.R
## New: tests/testthat/test-frob.R
git2r::commit(message = "- Super-frobnication enabled.")
## [9ff4840] 2021-03-08: - Super-frobnication enabled.
The same strategy can be used when merging a pull/merge/… request on GitHub, GitLab, …: use bullet points in the merge commit message to indicate the items to include in NEWS.md
.
Now that we have added super-frobnication support to our package, it is time to bump the version again.
fledge::bump_version()
##
##
##
##
## → Committing changes.
##
##
## NULL
## <!-- NEWS.md is maintained by https://cynkra.github.io/fledge, do not edit -->
##
## # SuperFrob 0.0.0.9002
##
## - Super-frobnication enabled.
##
##
## # SuperFrob 0.0.0.9001
##
## - Add tests for frobnication.
## - Add support for frobnication.
##
##
## # SuperFrob 0.0.0.9000
##
## * Added a `NEWS.md` file to track changes to the package.
After multiple cycles of development, review and testing, we decide that our package is ready for release to CRAN. This is where {fledge} simplifies the release process by making use of the all the commit messages that we provided earlier.
We wish to release this package as a patch and so we use fledge::bump_version()
with the “patch” argument.
fledge::bump_version("patch")
##
##
##
##
## → Committing changes.
This updates the version of our package to 0.0.4.
We review the NEWS.md
that were generated by {fledge}:
## <!-- NEWS.md is maintained by https://cynkra.github.io/fledge, do not edit -->
##
## # SuperFrob 0.0.1
##
## - Same as previous version.
##
##
## # SuperFrob 0.0.0.9002
##
## - Super-frobnication enabled.
##
##
## # SuperFrob 0.0.0.9001
##
## - Add tests for frobnication.
## - Add support for frobnication.
##
##
## # SuperFrob 0.0.0.9000
##
## * Added a `NEWS.md` file to track changes to the package.
Some of the intermediate commit messages are not relevant in the release notes for this release. We need to edit NEWS.md
to convert the changelog to meaningful release notes.
length(news) <- 5
news[3:5] <- c(
"Initial CRAN release.",
"",
"Basic functionality: Super-frobnication."
)
cat(news, sep = "\n")
## <!-- NEWS.md is maintained by https://cynkra.github.io/fledge, do not edit -->
##
## Initial CRAN release.
##
## Basic functionality: Super-frobnication.
writeLines(news, "NEWS.md")
Unlike with development versions, we commit the changes to NEWS.md
manually:
## Staged changes:
## Modified: NEWS.md
git2r::commit(message = "Update NEWS.")
## [efb4962] 2021-03-08: Update NEWS.
The package is now ready to be released to CRAN. I prefer devtools::use_release_issue()
to create a checklist of things to do before release, and devtools::submit_cran()
to submit. The devtools::release()
function is a more verbose alternative.
Some time passed and our {SuperFrob} package was accepted on CRAN. At this stage, {fledge} can help to tag the released version and create a new version for development.
It is now the time to tag the released version using the fledge::tag_version()
function.
fledge::tag_version()
##
##
It is advised to push to remote, with git push --tags
from the command line, or your favorite Git client.
If your package is hosted on GitHub, usethis::use_github_release()
creates a draft GitHub release from the contents already in NEWS.md
. You need to submit the draft release from the GitHub release page.
We will now make the package ready for future development. The fledge::bump_version()
takes care of it.
fledge::bump_version()
##
##
##
##
## → Committing changes.
##
##
## NULL
## <!-- NEWS.md is maintained by https://cynkra.github.io/fledge, do not edit -->
##
## # SuperFrob 0.0.1.9000 (2021-03-08)
##
## - Same as previous version.
##
##
## Initial CRAN release.
##
## Basic functionality: Super-frobnication.
Push to remote.
Note that we really need a merge commit here; the default is to fast-forward which doesn’t give us the opportunity to insert the message intended for the changelog. Earlier, we set the merge.ff
config option to "false"
to achieve this.↩︎