diff --git a/.github/gha-triggers.yml b/.github/gha-triggers.yml new file mode 100644 index 00000000..b969e2a9 --- /dev/null +++ b/.github/gha-triggers.yml @@ -0,0 +1,153 @@ +check-quizzes.yml: + status: on + on-trigger: + workflow_dispatch: + pull_request: + branches: [ main, staging ] + paths: + - 'quizzes/*' + off-trigger: + workflow_dispatch: +delete-preview.yml: + status: on + on-trigger: + pull_request: + types: [closed] + off-trigger: + workflow_dispatch: + dependent_on: render-preview.yml +docker-build-test.yml: + status: on + on-trigger: + release: + types: + - created + pull_request: + branches: [ main, staging ] + paths: [ docker/Dockerfile, docker/github_package_list.tsv ] + workflow_dispatch: + inputs: + dockerhubpush: + description: 'Push to Dockerhub?' + required: true + default: 'false' + off-trigger: + workflow_dispatch: + inputs: + dockerhubpush: + description: 'Push to Dockerhub?' + required: true + default: 'false' +release-notes.yml: + status: on + on-trigger: + pull_request: + branches: [ main, staging ] + types: [ opened ] + off-trigger: +render-bookdown.yml: + status: on + on-trigger: + workflow_dispatch: + push: + branches: [ main, staging ] + paths: + - '**.Rmd' + - assets/* + off-trigger: + workflow_dispatch: +render-coursera.yml: + status: on + on-trigger: + workflow_dispatch: + workflow_run: + workflows: [ "Render Bookdown" ] + branches: [ main, staging ] + types: + - completed + off-trigger: + workflow_dispatch: + dependent_on: render-bookdown.yml +render-leanpub.yml: + status: on + on-trigger: + workflow_dispatch: + workflow_run: + workflows: [ "Render Coursera" ] + branches: [ main, staging ] + types: + - completed + off-trigger: + workflow_dispatch: + dependent_on: render-coursera.yml +render-preview.yml: + status: on + on-trigger: + pull_request: + branches: [ main, staging ] + off-trigger: + workflow_dispatch: +send-updates.yml: + status: on + on-trigger: + release: + types: + - published + workflow_dispatch: + inputs: + prtag: + description: 'Tag to use?' + required: true + default: 'null' + off-trigger: + workflow_dispatch: + inputs: + prtag: + description: 'Tag to use?' + required: true + default: 'null' +starting-course.yml: + status: on + on-trigger: + push: + branches: [ main, staging ] + workflow_dispatch: + off-trigger: + workflow_dispatch: +style-and-sp-check.yml: + status: on + on-trigger: + pull_request: + branches: [ main, staging ] + off-trigger: + workflow_dispatch: +test-send-updates.yml: + status: on + on-trigger: + off-trigger: + workflow_dispatch: + inputs: + repo: + description: 'What repo to test on e.g. jhudsl/OTTR_Template_Test' + required: true + default: 'jhudsl/OTTR_Template_Test' +transfer-rendered-files.yml: + status: on + on-trigger: + workflow_dispatch: + workflow_run: + workflows: [ "Render Bookdown" ] + branches: [ main, staging ] + types: + - completed + off-trigger: + workflow_dispatch: + dependent_on: render-bookdown.yml +url-checker.yml: + status: on + on-trigger: + workflow_dispatch: + pull_request: + branches: [ main, staging ] + off-trigger: + workflow_dispatch: diff --git a/.github/on-triggers.rds b/.github/on-triggers.rds new file mode 100644 index 00000000..6b7bf668 Binary files /dev/null and b/.github/on-triggers.rds differ diff --git a/.github/sync.yml b/.github/sync.yml index 1c00f763..e3c7c226 100755 --- a/.github/sync.yml +++ b/.github/sync.yml @@ -70,3 +70,25 @@ group: dest: scripts/spell-check.R repos: | jhudsl/OTTR_Template_Website + + repos: | + jhudsl/OTTR_Template_Website + - source: .github/workflows/style-and-sp-check.yml + dest: .github/workflows/style-and-sp-check.yml + - source: .github/workflows/url-checker.yml + dest: .github/workflows/url-checker.yml + - source: scripts/spell-check.R + dest: scripts/spell-check.R +###### TO ADD NEW REPOSITORY USE THIS FORMAT; Feel free to add/drop files that +# you specifically would like synced (or not). +# +# # Repositories to receive changes +# repos: | +# org/repo_name +# # Files which should be updated +# - source: .github/workflows/ + # dest: .github/workflows/ + # - source: scripts/ + # dest: scripts/ + # - source: docker/ + # dest: docker/ diff --git a/.github/workflows/manage-gha.yml b/.github/workflows/manage-gha.yml new file mode 100644 index 00000000..d36c6441 --- /dev/null +++ b/.github/workflows/manage-gha.yml @@ -0,0 +1,34 @@ +# Candace Savonen Feb 2022 + +name: Update Github Actions Switches + +on: + push: + paths: + - 'config_automation.yml' + +jobs: + update-triggers: + runs-on: ubuntu-latest + container: + image: jhudsl/course_template + + steps: + - name: checkout repo + uses: actions/checkout@v2 + + - name: Login as jhudsl-robot + run: | + git config --local user.email "itcrtrainingnetwork@gmail.com" + git config --local user.name "jhudsl-robot" + + - name: Run GHA switches script + run: Rscript --vanilla scripts/employ-gha-switches.R + + - name: Commit updated workflows to current branch + id: commit_it + run: | + branch_name=$(git rev-parse --abbrev-ref HEAD) + git add .github/workflows --force + git commit -m 'Update GHA switches' || echo "No changes to commit" + git push origin || echo "No changes to commit" diff --git a/.github/workflows/transfer-rendered-files.yml b/.github/workflows/transfer-rendered-files.yml index b70c47ce..61bca65c 100644 --- a/.github/workflows/transfer-rendered-files.yml +++ b/.github/workflows/transfer-rendered-files.yml @@ -11,9 +11,8 @@ name: Bookdown to Leanpub repo copy over #---TRIGGER-START---# on: workflow_dispatch: - # Only run after the render finishes running workflow_run: - workflows: [ "Render Bookdown and Coursera" ] + workflows: [ "Render Bookdown" ] branches: [ main, staging ] types: - completed diff --git a/config_automation.yml b/config_automation.yml new file mode 100644 index 00000000..1a01216a --- /dev/null +++ b/config_automation.yml @@ -0,0 +1,13 @@ +# PR Checks +check-quizzes: yes +url-checker: yes +render-preview: yes +style-and-sp-check: yes + +# Rendering +render-bookdown: yes +render-leanpub: yes +render-coursera: yes + +# Docker specific +docker-build-test: yes diff --git a/scripts/employ-gha-switches.R b/scripts/employ-gha-switches.R new file mode 100644 index 00000000..3b7169f8 --- /dev/null +++ b/scripts/employ-gha-switches.R @@ -0,0 +1,125 @@ +#!/usr/bin/env Rscript + +library(magrittr) + +option_list <- list( + optparse::make_option( + c("--overwrite"), + action = "store_true", + default = FALSE, + help = "TRUE or FALSE overwrite the trigger no matter what", + ) +) + +# Read the arguments passed +opt_parser <- optparse::OptionParser(option_list = option_list) +opt <- optparse::parse_args(opt_parser) + + +# Find .git root directory +root_dir <- rprojroot::find_root(rprojroot::has_dir(".github")) + +######## Load in triggers +# Each github action has its own on and off trigger versions which are stored +# in this file -- if triggers need to be altered, they must be altered in this file to take effect +trigger_config <- yaml::yaml.load_file(file.path(root_dir, ".github", "gha-triggers.yml")) + +######## Get the github actions file paths +# Get github actions directory +github_actions_dir <- file.path(root_dir, ".github", "workflows") + +# Get list of github actions files +github_actions_files <- list.files(github_actions_dir, + pattern = "\\.yml$", + full.names = TRUE +) + +######## Set up dataframe with information about the GHA +gha_df <- data.frame(gha_files = names(trigger_config)) + +# Read in the configuration file with the specs +config_df <- + yaml::read_yaml(file.path(root_dir, "config_automation.yml")) %>% + data.frame() %>% + t() %>% + data.frame() %>% + tibble::rownames_to_column("gha_files") %>% + dplyr::rename(new_status = '.') %>% + dplyr::mutate(gha_files = paste0(gsub("\\.", "-", gha_files), ".yml")) + +# Extract the "dependent on" information +dependent_on_df <- data.frame(dependent_on = unlist(trigger_config)[grep("dependent_on", names(unlist(trigger_config)))], + gha_files = gsub("\\.dependent_on$", "", grep("dependent_on", names(unlist(trigger_config)), value = TRUE))) + +# For GHA dependent on other ones, switch their status based on what the new status is +dependent_on_df$recoded_status <- config_df$new_status[match(dependent_on_df$dependent_on, config_df$gha_files)] + +# Put it all together +gha_df <- gha_df %>% + dplyr::left_join(config_df) %>% + dplyr::left_join(dependent_on_df) %>% + dplyr::mutate(new_status = dplyr::case_when( + !is.na(recoded_status) ~ recoded_status, + TRUE ~ new_status) + ) + +config_gha <- function(gha_file) { + + # Read in this GHA yaml + yaml_contents <- readLines(gha_file) + + # Get info about this particular GHA + trigger_info <- trigger_config[[basename(gha_file)]] + + # Extract what the status should be + new_status <- gha_df %>% + dplyr::filter(basename(gha_file) == gha_files) %>% + dplyr::pull("new_status") + + # If status specified in the config_automation.yml continue + if (!is.na(new_status) && length(new_status) == 1) { + + # If current status doesn't match specified status + # and it wasn't specified to overwrite anyway... + if ((new_status != trigger_info$status) || opt$overwrite) { + + # Output message + message(paste("Switching trigger for", basename(gha_file), "to", new_status)) + + # Get trigger for whether this should be on or off + trigger <- ifelse(new_status, trigger_info[["on-trigger"]], trigger_info[["off-trigger"]]) + + # Make sure it has `on:` at the beginning + trigger$on <- trigger + trigger <- trigger[-1] + + # Temporarily write to yaml so we can read in as plain text + yaml::write_yaml(trigger, "tmp-trigger.yml") + + # Find out where this trigger is supposed to go + trigger_indices <- (grep("TRIGGER-START", yaml_contents) + 1):(grep("TRIGGER-END", yaml_contents) - 1) + + # Remove current trigger + yaml_contents <- yaml_contents[-trigger_indices] + + # Set up new yaml trigger + trigger_text <- gsub("\\'on\\':", "on:", readLines("tmp-trigger.yml")) + + # Put new trigger in + yaml_contents <- append( + yaml_contents, + trigger_text, + after = trigger_indices[1] - 1 + ) + + # Remove temporary file + file.remove("tmp-trigger.yml") + + # Write lines to file + writeLines(yaml_contents, gha_file) + } + } +} + +# Read in all files +all_gha <- lapply(github_actions_files, config_gha)