From bcb686d8a83a3659783bcbdbf9a0e559246eeb61 Mon Sep 17 00:00:00 2001 From: Maxim Belkin Date: Fri, 14 Aug 2020 11:34:28 -0500 Subject: [PATCH] GitHub Actions: check lesson template (#489) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Co-authored-by: Maxim Belkin Co-authored-by: François Michonneau --- .github/workflows/template.yml | 124 +++++++++++++++++++++++++++++++++ Makefile | 9 ++- bin/dependencies.R | 68 ++++++++++++++++++ bin/generate_md_episodes.R | 29 -------- 4 files changed, 199 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/template.yml create mode 100644 bin/dependencies.R diff --git a/.github/workflows/template.yml b/.github/workflows/template.yml new file mode 100644 index 0000000..80a68aa --- /dev/null +++ b/.github/workflows/template.yml @@ -0,0 +1,124 @@ +name: Template +on: + push: + branches: gh-pages + pull_request: +jobs: + check-template: + name: Test lesson template + if: github.repository == 'carpentries/styles' + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + lesson: [swcarpentry/shell-novice, datacarpentry/r-intro-geospatial, librarycarpentry/lc-git] + os: [ubuntu-latest, macos-latest, windows-latest] + defaults: + run: + shell: bash # forces 'Git for Windows' on Windows + steps: + - name: Set up Ruby + uses: actions/setup-ruby@main + with: + ruby-version: '2.7.1' + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install GitHub Pages, Bundler, and kramdown gems + run: | + gem install github-pages bundler kramdown + + - name: Install Python modules + run: | + if [[ $RUNNER_OS == macOS || $RUNNER_OS == Linux ]]; then + python3 -m pip install --upgrade pip setuptools wheel pyyaml==5.3.1 requests + elif [[ $RUNNER_OS == Windows ]]; then + python -m pip install --upgrade pip setuptools wheel pyyaml==5.3.1 requests + fi + + - name: Checkout the ${{ matrix.lesson }} lesson + uses: actions/checkout@master + with: + repository: ${{ matrix.lesson }} + path: lesson + fetch-depth: 0 + + - name: Look for R-markdown files + id: check-rmd + working-directory: lesson + run: | + echo "::set-output name=count::$(shopt -s nullglob; files=($(find . -iname '*.Rmd')); echo ${#files[@]})" + + - name: Set up R + if: steps.check-rmd.outputs.count != 0 + uses: r-lib/actions/setup-r@master + with: + r-version: 'release' + + - name: Install needed packages + if: steps.check-rmd.outputs.count != 0 + run: | + install.packages(c('remotes', 'rprojroot', 'renv', 'desc')) + shell: Rscript {0} + + - name: Query dependencies + if: steps.check-rmd.outputs.count != 0 + working-directory: lesson + run: | + source('bin/dependencies.R') + deps <- identify_dependencies() + create_description(deps) + saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) + writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") + shell: Rscript {0} + + - name: Cache R packages + if: runner.os != 'Windows' && steps.check-rmd.outputs.count != 0 + uses: actions/cache@v1 + with: + path: ${{ env.R_LIBS_USER }} + key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- + + - name: Install system dependencies for R packages + if: runner.os == 'Linux' && steps.check-rmd.outputs.count != 0 + working-directory: lesson + run: | + while read -r cmd + do + eval $cmd + done < <(Rscript -e 'cat(remotes::system_requirements("ubuntu", "18.04"), sep = "\n")') + + - name: Install R lessons package dependencies + if: steps.check-rmd.outputs.count != 0 + working-directory: lesson + run: | + remotes::install_deps(dependencies = TRUE) + file.remove("DESCRIPTION") + shell: Rscript {0} + + - name: Determine the proper reference to use + id: styles-ref + run: | + if [[ -n "${{ github.event.pull_request.number }}" ]]; then + echo "::set-output name=ref::refs/pull/${{ github.event.pull_request.number }}/head" + else + echo "::set-output name=ref::gh-pages" + fi + + - name: Sync lesson with carpentries/styles + working-directory: lesson + run: | + git config --global user.email "team@carpentries.org" + git config --global user.name "The Carpentries Bot" + git remote add styles https://github.com/carpentries/styles.git + git config --local remote.styles.tagOpt --no-tags + git fetch styles ${{ steps.styles-ref.outputs.ref }}:styles-ref + git merge -s recursive -Xtheirs --no-commit styles-ref + git commit -m "Sync lesson with carpentries/styles" + + - run: make site + working-directory: lesson diff --git a/Makefile b/Makefile index b585662..1407962 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ endif # Controls -.PHONY : commands clean files +.PHONY : commands clean files install-rmd-deps # Default target .DEFAULT_GOAL := commands @@ -119,10 +119,15 @@ HTML_DST = \ $(patsubst _extras/%.md,${DST}/%/index.html,$(sort $(wildcard _extras/*.md))) \ ${DST}/license/index.html +## * install-rmd-deps : Install R packages dependencies to build the RMarkdown lesson +install-rmd-deps: + Rscript -e 'source("bin/dependencies.R"); install_dependencies(identify_dependencies())' + ## * lesson-md : convert Rmarkdown files to markdown lesson-md : ${RMD_DST} -_episodes/%.md: _episodes_rmd/%.Rmd +_episodes/%.md: _episodes_rmd/%.Rmd install-rmd-dependencies + @mkdir -p _episodes @bin/knit_lessons.sh $< $@ ## * lesson-check : validate lesson Markdown diff --git a/bin/dependencies.R b/bin/dependencies.R new file mode 100644 index 0000000..b710558 --- /dev/null +++ b/bin/dependencies.R @@ -0,0 +1,68 @@ +find_root <- function() { + if (!requireNamespace("rprojroot", quietly = TRUE)) { + install.packages("rprojroot", lib = lib, repos = repos) + } + + cfg <- rprojroot::has_file_pattern("^_config.y*ml$") + root <- rprojroot::find_root(cfg) + + root +} + +identify_dependencies <- function(lib = NULL, repos = getOption("repos")) { + + if (is.null(lib)) { + lib <- .libPaths() + } + + if (!requireNamespace("renv", quietly = TRUE)) { + install.packages("renv", lib = lib, repos = repos) + } + + root <- find_root() + + required_pkgs <- unique(c( + ## Packages for episodes + renv::dependencies(file.path(root, "_episodes_rmd"), progress = FALSE, error = "ignore")$Package, + ## Packages for tools + renv::dependencies(file.path(root, "bin"), progress = FALSE, error = "ignore")$Package + )) + + required_pkgs +} + +install_dependencies <- function(required_pkgs, + lib = NULL, repos = getOption("repos"), + update = FALSE, ...) { + + if (missing(lib)) { + lib <- .libPaths() + } + + missing_pkgs <- setdiff(required_pkgs, rownames(installed.packages())) + + if (length(missing_pkgs)) { + message("Installing missing required packages: ", + paste(missing_pkgs, collapse=", ")) + install.packages(missing_pkgs, lib = lib, repos = repos) + } + + if (update) { + update.packages( + lib.loc = lib, repos = repos, + ask = FALSE, checkBuilt = TRUE, ... + ) + } + + if (require("knitr") && packageVersion("knitr") < '1.9.19') { + stop("knitr must be version 1.9.20 or higher") + } + +} + +create_description <- function(required_pkgs) { + require("desc") + d <- description$new("!new") + lapply(required_pkgs, function(x) d$set_dep(x)) + d$write("DESCRIPTION") +} diff --git a/bin/generate_md_episodes.R b/bin/generate_md_episodes.R index 7c137d7..ce9e8aa 100644 --- a/bin/generate_md_episodes.R +++ b/bin/generate_md_episodes.R @@ -1,34 +1,5 @@ generate_md_episodes <- function() { - if (!requireNamespace("renv", quietly = TRUE)) { - install.packages("renv", repos = c(CRAN = "https://cloud.r-project.org/")) - } - - if (!requireNamespace("rprojroot", quietly = TRUE)) { - install.packages("rprojroot", repos = c(CRAN = "https://cloud.r-project.org/")) - } - - cfg <- rprojroot::has_file_pattern("^_config.y*ml$") - root <- rprojroot::find_root(cfg) - - required_pkgs <- unique(c( - ## Packages for episodes - renv::dependencies(file.path(root, "_episodes_rmd"), progress = FALSE, error = "ignore")$Package, - ## Pacakges for tools - renv::dependencies(file.path(root, "bin"), progress = FALSE, error = "ignore")$Package - )) - - missing_pkgs <- setdiff(required_pkgs, rownames(installed.packages())) - - if (length(missing_pkgs)) { - message("Installing missing required packages: ", - paste(missing_pkgs, collapse=", ")) - install.packages(missing_pkgs) - } - - if (require("knitr") && packageVersion("knitr") < '1.9.19') - stop("knitr must be version 1.9.20 or higher") - ## get the Rmd file to process from the command line, and generate the path ## for their respective outputs args <- commandArgs(trailingOnly = TRUE) -- 2.30.2