1 Apply label across repositories

Code
librarian::shelf(
  dplyr, fs, gitcreds, gh, glue, knitr, listviewer, tidyjson,
  quiet = T)

org <- "MarineSensitivity"

lbls_custom <- list(
  list(
    name = "spatial-units",
    description = "spatial units for analysis and comparison, e.g. regions, planning areas, aliquots, etc.",
    color       = "89E836"))

# get repositories
repos_lst <- gh(glue("GET /orgs/{org}/repos"))
listviewer::jsonedit(repos_lst)
Code
(repos <- vapply(repos_lst, "[[", "", "name"))
[1] "server"                      "workflows"                  
[3] "api"                         "msens"                      
[5] "apps"                        "docs"                       
[7] "MarineSensitivity.github.io" "objectives"                 
[9] "manuscripts"                
Code
# add label (if missing)
if (F){
  for (lbl in lbls_custom){ # lbl = lbls_custom[[1]]
    
    print(glue("adding label {lbl$name} to {length(repos)} repositories"))
    
    for (repo in repos){
      repo_lbls <- gh(glue("GET /repos/{org}/{repo}/labels")) |> 
        vapply("[[", "", "name")
      
      if (lbl$name %in% repo_lbls){
        print(glue("  {repo}: exists"))
      } else {
        print(glue("  {repo}: adding"))
        gh(
          glue("POST /repos/{org}/{repo}/labels"),
          name        = lbl$name,
          description = lbl$description,
          color       = lbl$color)
      }
    }
  }
}
# TODO: move to functions in new ecoquants/ghmgt R package

2 Clone all repos locally

Code
for (repo in repos){  # repo = repos[1]
  dir_repo <- glue("~/Github/{org}/{repo}")
  if (!dir_exists(dir_repo)){
    message("cloning {repo}")
    cmd <- glue("git clone https://github.com/{org}/{repo}.git {dir_repo}")
    print(cmd)
    system(cmd)
  }
}

3 Get repo descriptions

Code
gh(glue("GET /orgs/{org}/repos")) |> 
  spread_all() |> 
  as_tibble() |> 
  select(name, description) |>
  arrange(name) |> 
  kable()
name description
MarineSensitivity.github.io default website
api application programming interface (API) using R Plumber package
apps Shiny applications
docs documentation for BOEM’s offshore environmental sensitivity index products
manuscripts Manuscripts with review of sensitivities by industry and receptors (species, habitats, human uses)
msens R library of functions for mapping marine sensitivities, sponsored by BOEM
objectives repository for issues spanning multiple repositories and doing big picture roadmapping
server server setup for R Shiny apps, RStudio IDE, R Plumber API, PostGIS database, pg_tileserv
workflows scripts for testing data analytics and visualization as well as production workflows

4 Add issues to project

Need to use:

Code
librarian::shelf(
  dplyr, 
  ropensci/ghql, 
  jsonlite)

token <- Sys.getenv("GITHUB_TOKEN") # vi ~/.Renviron # /Users/bbest/My Drive/private/pat4rstudio.txt

gq <- get_gq(token)

prj_id <- get_prj_id(gq, "MarineSensitivity", 1)

devtools::load_all("~/Github/ecoquants/ghmgt")

get_prj_issues <- function(prj_id){
  # return IDs of issues in project
  
  qry <- Query$new()
  qry$query(
    'q', glueb( 
      '{ node(id: "[prj_id]") { 
      ... on ProjectV2 { 
        items(first: 20) { 
          nodes{ 
            id  
            content{ 
              ...on Issue { 
                id title } 
      }}}}}}') )
  con$exec(qry$queries$q) |> 
    fromJSON() |> 
    (\(x){ x$data$node$items$nodes$content$id })()
}

prj_issues <- get_prj_issues(prj_id)


get_owner_repos <- function(owner = "MarineSensitivity"){
  gh(glue("GET /orgs/{owner}/repos")) |> 
    vapply("[[", "", "name") |> 
    sort()
}

repos <- get_owner_repos(org)

add_prj_issue <- function(prj_id, issue_id, verbose = T){
  # add issue to project, return id of new item in project
  
  # issue_id = repo_issue
  
  qry <- Query$new()
  q <- glueb(
      'mutation {
        addProjectV2ItemById(
          input: {
            projectId: "[prj_id]" 
            contentId: "[issue_id]" } )
        {item {id}} }')
  if (verbose) message(q)
  qry$query('q', q )
  con$exec(qry$queries$q) |> 
    fromJSON() |> 
    (\(x){ x$data$addProjectV2ItemById$item$id })() # PVTI_lADOCLQwZM4AW8mqzgKL5mU
}

for (repo in repos){ # repo = repos[1] # repo = "msens"
  
  repo_issues <- get_repo_issues(repo = repo)
  message(glue("{repo} issues -> project '{prj_id}'"))
          
  for (issue_id in repo_issues){ # repo_issue = repo_issues[1]
    if (issue_id %in% prj_issues){
      message(glue("  issue '{issue_id}' already in project"))
    } else {
      message(glue("  adding issue '{issue_id}' to project"))
      id_new <- add_prj_issue(prj_id, issue_id)
    }
  }
}
Code
qry$query(
  'flds', 
  '{ node(id: "PVT_kwDOCLQwZM4AW8mq") { ... on ProjectV2 { fields(first: 20) { nodes { ... on ProjectV2Field { id name } ... on ProjectV2IterationField { id name configuration { iterations { startDate id }}} ... on ProjectV2SingleSelectField { id name options { id name }}}}}}}')
(x <- con$exec(qry$queries$flds))
jsonlite::fromJSON(x)

qry <- Query$new()
qry$query(
  'flds_common', 
  '{ node(id: "PVT_kwDOCLQwZM4AW8mq") { ... on ProjectV2 { fields(first: 20) { nodes { ... on ProjectV2FieldCommon { id name __typename }}}}}}')
(x <- con$exec(qry$queries$flds_common))
jsonlite::fromJSON(x)

qry <- Query$new()
qry$query(
  'itms', 
  '{ node(id: "PVT_kwDOCLQwZM4AW8mq") { 
  ... on ProjectV2 { 
    items(first: 20) { 
      nodes{ 
        id fieldValues(first: 8) { 
          nodes{ 
            ... on ProjectV2ItemFieldTextValue { 
              text field {  ... on ProjectV2FieldCommon {  name }}} 
            ... on ProjectV2ItemFieldDateValue { 
              date field { ... on ProjectV2FieldCommon { name }}} 
          ... on ProjectV2ItemFieldSingleSelectValue { 
              name field { ... on ProjectV2FieldCommon { name }}} 
          }
        } 
        content{ 
          ... on DraftIssue { title body } 
          ...on Issue { 
            id title assignees(first: 10) { 
              nodes{ login }} } 
          ...on PullRequest { title assignees(first: 10) { nodes{ login }}}
  }}}}}}')
(x <- con$exec(qry$queries$itms))
jsonlite::fromJSON(x)



issueid <- "I_kwDOKemkec50y7V4"
prjid <- "PVT_kwDOCLQwZM4AW8mq"
qry <- Query$new()
qry$query(
  'addissue2prj', 
  glue(
    'mutation {
      addProjectV2ItemById(
        input: {
          projectId: "[prjid]" 
          contentId: "[issueid]" } )
      {item {id}} }',
    .open = "[",
    .close = "]"))
(x <- con$exec(qry$queries$addissue2prj))
id <- jsonlite::fromJSON(x) %>%
  .$data %>%
  .$addProjectV2ItemById %>%
  .$item %>%
  .$id
# PVTI_lADOCLQwZM4AW8mqzgKL5mU

# TODO:
# - loop through issues and add to Project
# - add to specific column (e.g. "To do")\
#   [Using the API to manage Projects - GitHub Enterprise Cloud Docs](https://docs.github.com/en/enterprise-cloud@latest/issues/planning-and-tracking-with-projects/automating-your-project/using-the-api-to-manage-projects#updating-a-custom-text-number-or-date-field)
# - add to specific iteration (e.g. "2021-01-01")
# - add to specific assignee (e.g. "bbest")
# - add to specific label (e.g. "type/status")
# - add to specific milestone (e.g. "v1.0.0")
# - add to specific project (e.g. "MarineSensitivity.github.io")
# - add to specific repository (e.g. "MarineSensitivity.github.io")
# - add to specific column (e.g. "To do")