@@ -148,17 +148,28 @@ release_type <- function(version) {
148148
149149# ' Draft a GitHub release
150150# '
151- # ' Creates a __draft__ GitHub release for the current package using the current
152- # ' version and `NEWS.md`. If you are comfortable that it is correct, you will
153- # ' need to publish the release from GitHub. It also deletes `CRAN-RELEASE` and
154- # ' checks that you've pushed all commits to GitHub.
151+ # ' @description
152+ # ' Creates a __draft__ GitHub release for the current package. Once you are
153+ # ' satisfied that it is correct, you will need to publish the release from
154+ # ' GitHub. The key pieces of info are which commit / SHA to tag, the associated
155+ # ' package version, and the relevant NEWS entries.
156+ # '
157+ # ' If you use `devtools::release()` or `devtools::submit_cran()` to submit to
158+ # ' CRAN, information about the submitted state is captured in a CRAN-SUBMISSION
159+ # ' or CRAN-RELEASE file. `use_github_release()` uses this info to populate the
160+ # ' draft GitHub release and, after success, deletes the CRAN-SUBMISSION or
161+ # ' CRAN-RELEASE file.
162+ # '
163+ # ' In the absence of such a file, we must fall back to assuming the current
164+ # ' state (SHA of `HEAD`, package version, NEWS) is the submitted state.
155165# '
156- # ' @param host,auth_token `r lifecycle::badge("deprecated")`: No longer consulted
157- # ' now that usethis allows the gh package to lookup a token based on a URL
158- # ' determined from the current project's GitHub remotes.
166+ # ' @param host,auth_token `r lifecycle::badge("deprecated")`: No longer
167+ # ' consulted now that usethis allows the gh package to lookup a token based on
168+ # ' a URL determined from the current project's GitHub remotes.
159169# ' @export
160170use_github_release <- function (host = deprecated(),
161171 auth_token = deprecated()) {
172+ check_is_package(" use_github_release()" )
162173 if (lifecycle :: is_present(host )) {
163174 deprecate_warn_host(" use_github_release" )
164175 }
@@ -173,37 +184,129 @@ use_github_release <- function(host = deprecated(),
173184 is required to draft a release." )
174185 }
175186
176- challenge_non_default_branch(
177- " Are you sure you want to create a release on a non-default branch?"
178- )
179- check_branch_pushed()
180-
181- cran_release <- proj_path(" CRAN-RELEASE" )
182- if (file_exists(cran_release )) {
183- file_delete(cran_release )
184- }
185-
186- path <- proj_path(" NEWS.md" )
187- if (file_exists(path )) {
188- news <- news_latest(read_utf8(path ))
189- } else {
190- news <- " Initial release"
191- }
187+ dat <- get_release_data(tr )
188+ news <- get_release_news(SHA = dat $ SHA , tr = tr )
192189
193- package <- package_data()
190+ release_name <- glue(" {dat$Package} {dat$Version}" )
191+ tag_name <- glue(" v{dat$Version}" )
192+ kv_line(" Release name" , release_name )
193+ kv_line(" Tag name" , tag_name )
194+ kv_line(" SHA" , dat $ SHA )
194195
195196 gh <- gh_tr(tr )
196197 release <- gh(
197198 " POST /repos/{owner}/{repo}/releases" ,
198- tag_name = paste0(" v" , package $ Version ),
199- target_commitish = gert :: git_info(repo = git_repo())$ commit ,
200- name = paste0(package $ Package , " " , package $ Version ),
201- body = news , draft = TRUE
199+ name = release_name , tag_name = tag_name ,
200+ target_commitish = dat $ SHA , body = news , draft = TRUE
202201 )
203202
203+ if (! is.null(dat $ file )) {
204+ ui_done(" {ui_path(dat$file)} deleted" )
205+ file_delete(dat $ file )
206+ }
207+
204208 view_url(release $ html_url )
209+ ui_todo(" Publish the release via \" Edit draft\" > \" Publish release\" " )
205210}
206211
212+ get_release_data <- function (tr = target_repo(github_get = TRUE )) {
213+ package <- package_data()
214+ cran_submission <-
215+ path_first_existing(proj_path(c(" CRAN-SUBMISSION" , " CRAN-RELEASE" )))
216+
217+ if (is.null(cran_submission )) {
218+ ui_done(" Using current HEAD commit for the release" )
219+ challenge_non_default_branch()
220+ check_branch_pushed()
221+ return (list (
222+ Package = package $ Package ,
223+ Version = package $ Version ,
224+ SHA = gert :: git_info(repo = git_repo())$ commit
225+ ))
226+ }
227+
228+ if (path_file(cran_submission ) == " CRAN-SUBMISSION" ) {
229+ # new style ----
230+ # Version: 2.4.2
231+ # Date: 2021-10-13 20:40:36 UTC
232+ # SHA: fbe18b5a22be8ebbb61fa7436e826ba8d7f485a9
233+ out <- as.list(read.dcf(cran_submission )[1 , ])
234+ }
235+
236+ if (path_file(cran_submission ) == " CRAN-RELEASE" ) {
237+ gh <- gh_tr(tr )
238+ # old style ----
239+ # This package was submitted to CRAN on 2021-10-13.
240+ # Once it is accepted, delete this file and tag the release (commit e10658f5).
241+ lines <- read_utf8(cran_submission )
242+ str_extract <- function (marker , pattern ) {
243+ re_match(grep(marker , lines , value = TRUE ), pattern )$ .match
244+ }
245+ date <- str_extract(" submitted.*on" , " [0-9]{4}-[0-9]{2}-[0-9]{2}" )
246+ sha <- str_extract(" commit" , " [[:xdigit:]]{7,40}" )
247+ if (nchar(sha ) != 40 ) {
248+ # the release endpoint requires the full sha
249+ sha <-
250+ gh(" /repos/{owner}/{repo}/commits/{commit_sha}" , commit_sha = sha )$ sha
251+ }
252+
253+ HEAD <- gert :: git_info(repo = git_repo())$ commit
254+ if (HEAD == sha ) {
255+ version <- package $ Version
256+ } else {
257+ tf <- glue(" {package_data()$Package}-DESCRIPTION-{substr(sha, 1, 7)}-" )
258+ tf <- withr :: local_tempfile(pattern = tf )
259+ gh(
260+ " /repos/{owner}/{repo}/contents/{path}" ,
261+ path = " DESCRIPTION" , ref = sha ,
262+ .destfile = tf ,
263+ .accept = " application/vnd.github.v3.raw"
264+ )
265+ version <- desc :: desc(file = tf )$ get_version()
266+ }
267+
268+ out <- list (
269+ Version = version ,
270+ Date = Sys.Date(),
271+ SHA = sha
272+ )
273+ }
274+
275+ out $ Package <- package $ Package
276+ out $ file <- cran_submission
277+ ui_done("
278+ {ui_path(out$file)} file found, from a submission on {as.Date(out$Date)}" )
279+
280+ out
281+ }
282+
283+ get_release_news <- function (SHA = gert :: git_info(repo = git_repo())$ commit ,
284+ tr = target_repo(github_get = TRUE )) {
285+ package <- package_data()
286+ HEAD <- gert :: git_info(repo = git_repo())$ commit
287+
288+ if (HEAD == SHA ) {
289+ news_path <- proj_path(" NEWS.md" )
290+ } else {
291+ news_path <- glue(" {package_data()$Package}-NEWS-{substr(SHA, 1, 7)}-" )
292+ news_path <- withr :: local_tempfile(pattern = news_path )
293+ gh <- purrr :: possibly(gh_tr(tr ), otherwise = NULL )
294+ gh(
295+ " /repos/{owner}/{repo}/contents/{path}" ,
296+ path = " NEWS.md" , ref = SHA ,
297+ .destfile = news_path ,
298+ .accept = " application/vnd.github.v3.raw"
299+ )
300+ }
301+
302+ if (file_exists(news_path )) {
303+ news <- news_latest(read_utf8(news_path ))
304+ } else {
305+ news <- " Initial release"
306+ }
307+
308+ news
309+ }
207310
208311cran_version <- function (package = project_name(),
209312 available = utils :: available.packages()) {
0 commit comments