Skip to content

Commit

Permalink
feat: Determining the most recent tag now uses the new `get_last_vers…
Browse files Browse the repository at this point in the history
…ion_tag()` and works when the version tag is on a diverged branch (e.g., after squash-merging) (#844)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: krlmlr <[email protected]>
  • Loading branch information
3 people authored Dec 1, 2024
1 parent 0b0e706 commit 28b8f09
Show file tree
Hide file tree
Showing 23 changed files with 288 additions and 35 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export(commit_version)
export(create_demo_project)
export(finalize_version)
export(get_last_tag)
export(get_last_version_tag)
export(get_top_level_commits)
export(local_demo_project)
export(plan_release)
Expand Down
5 changes: 4 additions & 1 deletion R/api-get-last-tag.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#' The most recent tag
#'
#' Returns the most recent Git tag.
#' Returns the most recent Git tag that is reachable from the current branch.
#' This will not be accurate if the version bump and tag has occurred on a branch
#' which has been squashed into the main branch.
#' See [get_last_version_tag()] for a version that works in this scenario.
#'
#' @return A one-row tibble with columns `name`, `ref` and `commit`.
#' For annotated tags (as created by fledge), `commit` may be different
Expand Down
14 changes: 14 additions & 0 deletions R/api-get-last-version-tag.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#' The most recent versioned tag
#'
#' Returns the Git tag of the form vx.y, vx.y.z or vx.y.z.w with the latest version.
#' An older version of this logic is used in [get_last_tag()],
#' which traverses the Git history but does not work with squash-merging of version bumps.
#'
#' @inherit get_last_tag return
#'
#' @example man/examples/get-last-version-tag.R
#'
#' @export
get_last_version_tag <- function() {
with_repo(get_last_version_tag_impl())
}
3 changes: 2 additions & 1 deletion R/api-get-top-level-commits.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
#' - `commit`: the commit SHA
#' - `message`: the commit message
#'
#' @param since A commit SHA, e.g. as returned from [get_last_tag()].
#' @param since A commit SHA, e.g. as returned in the `commit` component of
#' [get_last_version_tag()].
#' If `NULL`, the entire log is retrieved.
#'
#' @example man/examples/get-last-tag.R
Expand Down
11 changes: 7 additions & 4 deletions R/api-update-news.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#' Update NEWS.md with messages from top-level commits
#'
#' Lists all commits from a range (default: top-level commits since the most
#' recent tag) and adds bullets from their body to `NEWS.md`.
#' recent tag as determined by [get_last_version_tag()])
#' and adds bullets from their body to `NEWS.md`.
#' Creates `NEWS.md` if necessary.
#'
#' @param messages A character vector of commit messages,
#' e.g. as in the `message` column in the return value of [get_top_level_commits()].
#' The default uses the top level commits since the last tag as retrieved by [get_last_tag()].
#' The default uses the top level commits since the last tag as retrieved by [get_last_version_tag()].
#' @param which Component of the version number to update. Supported
#' values are
#' * `"auto"` (default: `"samedev"` or `"dev"`, depending on contents of `NEWS.md`),
Expand Down Expand Up @@ -46,6 +48,7 @@ update_news <- function(
invisible(NULL)
}

default_commit_range <- function(ref = "HEAD") {
get_top_level_commits_impl(since = get_last_tag_impl(ref)$commit, ref)
default_commit_range <- function(current_version = NULL, ref = "HEAD") {
since <- get_last_version_tag_impl(current_version)$commit
get_top_level_commits_impl(since = since, ref)
}
10 changes: 5 additions & 5 deletions R/auto.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ plan_release_impl <- function(which, force) {
orig_fledgeling <- read_fledgling()

fledgeling <- update_news_impl(
default_commit_range(),
default_commit_range(current_version = orig_fledgeling$version),
which = "dev",
fledgeling = orig_fledgeling,
no_change_message = NA_character_
Expand Down Expand Up @@ -661,7 +661,7 @@ check_post_release <- function() {
# Need PAT for creating GitHub release
check_gh_pat("repo")

if (!no_change(main_branch)) {
if (!no_change()) {
cli_abort(c(
"The main branch contains newsworthy commits.",
i = "Run {.run fledge::bump_version()} on the main branch."
Expand Down Expand Up @@ -807,7 +807,7 @@ release_after_cran_built_binaries <- function() {
}

get_last_release_version <- function() {
tag_df <- get_last_tag_impl(
tag_df <- get_last_version_tag_impl(
pattern = "^v[0-9]+[.][0-9]+[.][0-9]+(?:[.-][0-9]{1,3})?$"
)
as.package_version(gsub("^v", "", tag_df$name))
Expand All @@ -826,8 +826,8 @@ extract_version_pr <- function(title) {
regmatches(title, matches)
}

no_change <- function(ref = "HEAD") {
no_change <- function(ref) {
# Only review meaningful comments
news <- collect_news(default_commit_range(ref), no_change_message = NA_character_)
news <- collect_news(default_commit_range(ref = ref), no_change_message = NA_character_)
NROW(news) == 0
}
2 changes: 1 addition & 1 deletion R/bump-version.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ bump_version_impl <- function(fledgeling,
}
#' 1. [update_news()], using the `which` argument.
out <- update_news_impl(
default_commit_range(),
default_commit_range(current_version = fledgeling$version),
which = which,
fledgeling = fledgeling,
no_change_message = if (no_change_behavior == "bump") no_change_message else NA_character_
Expand Down
37 changes: 30 additions & 7 deletions R/commits.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ local_repo <- function(.local_envir = caller_env()) {
get_top_level_commits_impl <- function(since, ref = "HEAD") {
commit <- gert::git_log(ref, max = 1)$commit

if (!is.null(since)) {
ab <- gert::git_ahead_behind(since, commit)
if (ab$behind > 0) {
cli::cli_abort("{.val {since}} not reachable from current HEAD.")
}
}

commit <- get_first_parent(commit, since)
message <- map_chr(commit, ~ gert::git_commit_info(.x)$message)
merge <- map_lgl(commit, ~ (length(gert::git_commit_info(.x)$parents) > 1))
Expand Down Expand Up @@ -81,3 +74,33 @@ get_last_tag_impl <- function(ref = "HEAD", pattern = NULL) {
min_tag <- which.min(tags_b)
gert::git_tag_list(match = names(min_tag))
}

get_last_version_tag_impl <- function(current_version = NULL, pattern = NULL) {
all_tags <- gert::git_tag_list()

if (nrow(all_tags) == 0) {
return(NULL)
}

if (is.null(current_version)) {
current_version <- read_fledgling()$version
}

current_version <- base::as.package_version(current_version)

version_tags <- all_tags[grep("^v[0-9]+(?:[.][0-9]+)+$", all_tags$name), ]

if (!is.null(pattern)) {
version_tags <- version_tags[grep(pattern, version_tags$name, perl = TRUE), ]
}

versions <- base::as.package_version(sub("^v", "", version_tags$name))

version_tags <- version_tags[versions <= current_version, ]
versions <- versions[versions <= current_version]

if (length(versions) == 0) {
return(NULL)
}
version_tags[order(versions, decreasing = TRUE) == 1, ]
}
1 change: 1 addition & 0 deletions R/unbump-version.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#' @rdname unbump_version
#' @usage NULL
unbump_version_impl <- function() {
# We are not assuming diverged branches here, get_last_tag() is fine
tag <- get_last_tag()
tag_last_commit <- gert::git_log(tag$commit, max = 1)
last_commit <- gert::git_log(max = 1)
Expand Down
3 changes: 2 additions & 1 deletion _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ reference:
- release
- title: Lower-level functions
contents:
- get_last_tag
- get_last_version_tag
- get_top_level_commits
- tag_version
- update_news
- get_last_tag
- title: Helper for fledge demonstration
contents:
- create_demo_project
Expand Down
29 changes: 29 additions & 0 deletions man/examples/get-last-version-tag.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Create mock package in a temporary directory.
# Set open to TRUE if you want to play in the mock package.
with_demo_project({
# Use functions as if inside the newly created package project.
# (Or go and actually run code inside the newly created package project!)
# Add a new R file.
usethis::use_r("cool-function", open = FALSE)
# Pretend we added useful code inside it.
# Track the new R file with Git.
gert::git_add("R/cool-function.R")
gert::git_commit("- Add cool function.")
# Switch to branch for bumping version.
gert::git_branch_create("fledge")
# Bump version with fledge.
fledge::bump_version(check_default_branch = FALSE)
fledge::finalize_version()

# Merge the version bump branch into main.
gert::git_branch_checkout("main")
gert::git_merge("fledge", squash = TRUE)

print(get_top_level_commits(since = NULL))

# get_last_tag() doesn't work in this scenario
print(fledge::get_last_tag())

# get_last_version_tag() is better
print(fledge::get_last_version_tag())
})
2 changes: 1 addition & 1 deletion man/examples/tag-version.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ with_demo_project({
gert::git_add("NEWS.md")
gert::git_commit(message = "release notes tweaking")
fledge::tag_version()
print(fledge::get_last_tag())
print(fledge::get_last_version_tag())
})
5 changes: 4 additions & 1 deletion man/get_last_tag.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions man/get_last_version_tag.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/get_top_level_commits.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/tag_version.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions man/update_news.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/update_version.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 28b8f09

Please sign in to comment.