#' Build and deploy individual site components to a remote branch
#'
#' These are the internal functions which provision and deploy lesson
#' components to orphan git branches. These are called by [ci_deploy()].
#' **These functions have the side-effect of creating and updating orphan
#' branches on a remote repository. It is assumed that you have access to your
#' remote**.
#'
#' @inheritParams ci_deploy
#' @param branch the branch name containing the output:
#' - `ci_build_markdown()`: defaults to `md-output`, corresponds to
#' `md_branch` in [ci_deploy()]
#' - `ci_build_site()`: defaults to `gh-pages`, corresponds to `site_branch`
#' in [ci_deploy()]
#' @note `ci_build_markdown()` will set the `sandpaper.use_renv`
#' option to TRUE, which means that it will _always_ use the {renv}
#' package cache if the lesson uses R Markdown.
#' @returns
#' - `ci_build_markdown()`: an [expression()] that is evaluated to tear down
#' the worktree that was created.
#' - `ci_build_site()`: nothing, it is used for its side-effect.
#'
#' @details
#'
#' The only place these two functions are used are within [ci_deploy()], which
#' has the de-facto use-case for these functions, thus, this page has no
#' examples. Both of these functions do the same general process:
#'
#' 1. provision a git worktree in the appropriate folder with
#' [git_worktree_setup()]
#' 2. build the requisite content in that folder
#' 3. commit and push the contents to the worktree with
#' [github_worktree_commit()]
#'
#' There are caveats for each of the two functions as listed in the sections
#' below.
#'
#' ## `ci_build_markdown()`
#'
#' This will not clean up after itself by default. You must save the output in
#' an object and run `eval(obj)` to run the clean up process. This is in place
#' so that `ci_build_site()` can use the worktree from the markdown outputs in
#' order to build the site.
#'
#' @keywords internal
#' @rdname ci_build
ci_build_markdown <- function(path = ".", branch = "md-outputs", remote = "origin", reset = FALSE) {
options(sandpaper.use_renv = renv_is_allowed())
# Set episodes to rebuild if the lockfile has changed.
oc <- package_cache_trigger()
on.exit(package_cache_trigger(oc), add = TRUE)
package_cache_trigger(TRUE)
# step 0: build_lesson defaults to a local build
path <- set_source_path(path)
on.exit(reset_build_paths())
current <- gert::git_branch(repo = path)
create_site(path)
built <- path_built(path)
has_withr <- requireNamespace("withr", quietly = TRUE)
if (has_git() && has_withr) { withr::with_dir(path, {
# Set up the worktrees and make sure to remove them when the function exits
# (gracefully or ungracefully so)
del_md <- git_worktree_setup(path, built,
branch = branch, remote = remote
)
if (reset) {
ci_group("Reset Lesson")
git_clean_everything(built)
cli::cat_line("::endgroup::")
}
ci_group("Build Markdown Sources")
build_markdown(path = path, quiet = FALSE, rebuild = FALSE)
cli::cat_line("::endgroup::")
ci_group("Commit Markdown Sources")
github_worktree_commit(built,
message_source("markdown source builds", current, dir = path),
remote, branch
)
cli::cat_line("::endgroup::")
})}
return(del_md)
}
#' @param md the branch name that contains the markdown outputs
#'
#' @details
#'
#' ## `ci_build_site()`
#'
#' In addition to the steps listed above, this function needs to verify that it
#' has the materials necessary to build the HTML site.
#'
#' It first checks for the presence of `site/built/`. This folder can be
#' generated by `ci_build_markdown()` or by [build_markdown()]. If the folder
#' does not exist or it is empty, then this function will attempt to fetch the
#' folder from the branch in `md`.
#'
#' Once everything is built and pushed, this function will additionally destroy
#' the work tree.
#'
#' @rdname ci_build
ci_build_site <- function(path = ".", branch = "gh-pages", md = "md-outputs", remote = "origin", reset = FALSE) {
# step 0: build_lesson defaults to a local build
path <- set_source_path(path)
current <- gert::git_branch(path)
on.exit(reset_build_paths())
create_site(path)
built <- path_built(path)
html <- fs::path(path_site(path), "docs")
has_withr <- requireNamespace("withr", quietly = TRUE)
if (has_git() && has_withr) { withr::with_dir(path, {
# ------------ markdown worktree
# We need to first check if the markdown source files exist locally. If they
# do not, we need to fetch them as a throwaway branch
need_markdown_sources <- nrow(get_built_db()) == 0L
if (need_markdown_sources) {
del_md <- git_worktree_setup(path, built,
branch = md, remote = remote
)
on.exit(eval(del_md), add = TRUE)
}
# ------------ site worktree
del_site <- git_worktree_setup(path, html,
branch = branch, remote = remote
)
# remove the worktree at the end since this is the last step
on.exit(eval(del_site), add = TRUE)
if (reset) {
ci_group("Reset Site")
git_clean_everything(html)
cli::cat_line("::endgroup::")
}
# Build the site quickly using the markdown files as-is
ci_group("Build Lesson Website")
build_site(path = path, quiet = FALSE, preview = FALSE)
cli::cat_line("::endgroup::")
# Commit using the markdown branch as a reference
ci_group("Commit Lesson Website")
github_worktree_commit(html,
message_source("site deploy", md, dir = built),
remote, branch
)
cli::cat_line("::endgroup::")
})}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.