Skip to content

Commit c2f249e

Browse files
authored
Build and deploy the book automatically on GHA (#339)
1 parent 13cb7e9 commit c2f249e

15 files changed

+2691
-69
lines changed

.Rprofile

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# source("renv/activate.R")
12
if (file.exists('~/.Rprofile')) sys.source('~/.Rprofile', envir = environment())
23

34
options(

.github/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.html

.github/workflows/build-book.yaml

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
on:
2+
push:
3+
branches:
4+
- master
5+
pull_request:
6+
branches:
7+
- master
8+
9+
name: build-book
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest
14+
env:
15+
RSPM: https://packagemanager.rstudio.com/cran/__linux__/focal/latest
16+
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
17+
steps:
18+
- name: Checkout repo
19+
uses: actions/checkout@v2
20+
21+
- name: Setup R
22+
id: install-r
23+
uses: r-lib/actions/setup-r@v1
24+
25+
- name: Setup pandoc
26+
uses: r-lib/actions/setup-pandoc@v1
27+
with:
28+
pandoc-version: '2.13'
29+
30+
- name: Install TinyTeX
31+
uses: r-lib/actions/setup-tinytex@v1
32+
env:
33+
# install full prebuilt version
34+
TINYTEX_INSTALLER: TinyTeX
35+
36+
- name: Install pak and query dependencies
37+
run: |
38+
install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/")
39+
saveRDS(pak::local_dev_deps_tree(), ".github/r-depends.rds")
40+
shell: Rscript {0}
41+
42+
- name: Cache R packages
43+
uses: actions/cache@v2
44+
with:
45+
path: |
46+
${{ env.R_LIBS_USER }}/*
47+
!${{ env.R_LIBS_USER }}/pak
48+
key: ${{ runner.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }}
49+
restore-keys: ${{ runner.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-
50+
51+
- name: Install system dependencies
52+
if: runner.os == 'Linux'
53+
run: |
54+
pak::local_system_requirements(execute = TRUE)
55+
shell: Rscript {0}
56+
57+
- name: Install missing system dependencies
58+
if: runner.os == 'Linux'
59+
run: sudo apt-get install -y libgtk2.0-dev asymptote
60+
61+
- name: Install dependencies
62+
run: |
63+
pak::local_install_dev_deps(upgrade = TRUE)
64+
shell: Rscript {0}
65+
66+
- name: Install phantomjs
67+
run: |
68+
webshot::install_phantomjs()
69+
shell: Rscript {0}
70+
71+
- name: Build Gitbook
72+
if: github.event_name == 'pull_request'
73+
run: make gitbook
74+
75+
- name: Build and Deploy all book
76+
# if: github.event_name == 'push'
77+
env:
78+
CONNECT_API_KEY: ${{ secrets.RSC_BOOKDOWN_ORG_TOKEN }}
79+
CONTENT_ID: 7b3dedfa-fd98-45dd-bec4-75d915fb27dd
80+
run: make all
81+
82+
- uses: actions/github-script@v3
83+
env:
84+
URL: https://bookdown.org/yihui/rmarkdown-cookbook/
85+
with:
86+
github-token: ${{secrets.GITHUB_TOKEN}}
87+
script: |
88+
github.repos.createCommitStatus({
89+
owner: context.repo.owner,
90+
repo: context.repo.repo,
91+
sha: context.sha,
92+
state: "success",
93+
target_url: "${{ env.URL}}",
94+
description: "Book deployed!",
95+
context: "bookdown.org"
96+
})
97+
98+
- name: Upload book folder for debug
99+
if: failure()
100+
uses: actions/upload-artifact@main
101+
with:
102+
name: book-dir
103+
path: _book

.travis.yml

-23
This file was deleted.

15-languages.Rmd

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Next we show an example of an alternative Python engine^[In practice, you should
7272
knitr::knit_engines$set(py = function(options) {
7373
code <- paste(options$code, collapse = '\n')
7474
out <- system2(
75-
'python', c('-c', shQuote(code)), stdout = TRUE
75+
'python3', c('-c', shQuote(code)), stdout = TRUE
7676
)
7777
knitr::engine_output(options, code, out)
7878
})

18-references.Rmd

+5-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# References {-}
88
'`
99

10-
```{r include=FALSE, tidy=FALSE}
10+
```{r include=FALSE, tidy=FALSE, warning = FALSE}
1111
# list cited packages
1212
pkgs <- c(
1313
.packages(),
@@ -90,12 +90,10 @@ pkgs <- c(
9090
# JavaScript: 'DataTables'
9191
)
9292
93-
# install packages if missing
94-
lapply(pkgs, function(pkg) {
95-
if (system.file(package = pkg) != '') return()
96-
install.packages(pkg, repos = "https://cloud.r-project.org/")
97-
}
98-
)
93+
# Warn to add new deps in DESCRIPTION
94+
pkg2 <- setdiff(pkgs, knitr:::.base.pkgs)
95+
in_desc <- pkg2 %in% desc::desc_get_deps()$package
96+
if (any(!in_desc)) warning("To add to DESCRIPTION: ", paste0(pkg2[!in_desc], collapse = ", "))
9997
10098
# automatically create a bib database for R packages
10199
knitr::write_bib(pkgs, file = 'packages.bib', lib.loc = c(.libPaths(), '~/R-tmp'))

DESCRIPTION

+83-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,84 @@
1-
Package: placeholder
21
Type: Book
3-
Title: Does not matter.
4-
Version: 0.0.1
5-
Imports: bookdown, DiagrammeR, blogdown, webshot, fs, here, sass
6-
Remotes: yihui/xfun, yihui/knitr, rstudio/bookdown
2+
Package: rmarkdowncookbook
3+
Title: R Markdown Cookbook
4+
Version: 1.0.1
5+
Imports:
6+
animation,
7+
blastula,
8+
blogdown,
9+
bookdown,
10+
broom,
11+
Cairo,
12+
cairoDevice,
13+
condformat,
14+
dagitty,
15+
desc,
16+
diagram,
17+
DiagrammeR,
18+
distill,
19+
downloadthis,
20+
DT,
21+
equatiomatic,
22+
ezknitr,
23+
flair,
24+
flexdashboard,
25+
flextable,
26+
formatR,
27+
formattable,
28+
gganimate,
29+
ggdag,
30+
ggplot2,
31+
gifski,
32+
googledrive,
33+
govdown,
34+
gt,
35+
gtsummary,
36+
here,
37+
huxtable,
38+
jsonlite,
39+
kableExtra,
40+
knitcitations,
41+
knitr,
42+
learnr,
43+
magick,
44+
nomnoml,
45+
officedown,
46+
officer,
47+
pagedown,
48+
pander,
49+
pdftools,
50+
pixiedust,
51+
pkgdown,
52+
printr,
53+
r2d3,
54+
reactable,
55+
reticulate,
56+
revealjs,
57+
rgl,
58+
rhandsontable,
59+
rmarkdown,
60+
rmdformats,
61+
roxygen2,
62+
rsconnect,
63+
rticles,
64+
sass,
65+
spelling,
66+
stargazer,
67+
styler,
68+
svglite,
69+
tables,
70+
tangram,
71+
tikzDevice,
72+
tinytex,
73+
tufte,
74+
usethis,
75+
webshot,
76+
workflowr,
77+
xaringan,
78+
xfun,
79+
xtable,
80+
yaml,
81+
ztable
82+
Suggests:
83+
rsconnect
84+
Encoding: UTF-8

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ gitbook:
1313

1414
pdf2:
1515
BOOKDOWN_FULL_PDF=false Rscript --quiet _render.R "bookdown::pdf_book"
16+
17+
clean:
18+
Rscript -e 'bookdown::clean_book(TRUE)'

SETUP.md

+34-4
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,45 @@ When contribution to the book, it is a good practice to build it locally to ensu
1010

1111
### R Packages
1212

13-
To render the book, you must first install the `bookdown` R package.
13+
For this book, dependencies are required to execute R chunks and to generate references of others packages mentioned. Dependencies are tracked using a DESCRIPTION files.
1414

15-
Additional dependencies are installed automatically the first time you buid the book. Packages that are used within the book are listed in the [index.Rmd](https://github.com/yihui/rmarkdown-cookbook/blob/master/index.Rmd) file, and packages referenced in the book (and used to generate their own references) are listed in the [18-references.Rmd](https://github.com/yihui/rmarkdown-cookbook/blob/master/18-references.Rmd) file.
15+
To render the book, you can install the required packages using **renv**, **remotes** or **pak**
16+
17+
#### Using **renv**
18+
19+
This project contains a lockfile that you can use to reinstall packages in a project library, separated from your other global packages installation.
20+
21+
```r
22+
install.packages('renv')
23+
renv::activate()
24+
renv::restore()
25+
```
26+
27+
#### Using **remotes**
28+
29+
```r
30+
install.packages("remotes")
31+
remotes::install_deps(".")
32+
```
33+
34+
#### Using **pak**
35+
36+
**pak** benefits from a caching mechanism of installed packages and offers fast installation.
37+
38+
```r
39+
install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/")
40+
pak::local_install_dev_deps(upgrade = TRUE)
41+
```
42+
43+
This methods is used in CI.
1644

1745
### LaTeX Packages
1846

19-
The TinyTex LaTeX distribution is required to build the book. This is installed on the first render of [01-installation.Rmd](https://github.com/yihui/rmarkdown-cookbook/blob/master/18-references.Rmd) if not already installed (which can be done with `tinytex::install_tinytex()`).
47+
The TinyTeX LaTeX distribution is required to build the book. This can be done using `tinytex::install_tinytex()`.
48+
49+
This command will be run on the first render of [01-installation.Rmd](https://github.com/yihui/rmarkdown-cookbook/blob/master/01-installation.Rmd) TinyTeX is not already installed.
2050

21-
Additionally, the `pgf`, `preview`, and `xcolor` packages are required to build [11-chunk-options.Rmd](https://github.com/yihui/rmarkdown-cookbook/blob/master/11-chunk-options.Rmd) and will be installed as needed when running that chapter.
51+
Other required LaTeX packages should be installed automatically during the build of the book. Know required packages are the `pgf`, `preview`, and `xcolor` packages used in [11-chunk-options.Rmd](https://github.com/yihui/rmarkdown-cookbook/blob/master/11-chunk-options.Rmd) and they will be installed as needed when running that chapter.
2252

2353
### Other System Dependencies
2454

_render.R

+20-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
quiet = "--quiet" %in% commandArgs(FALSE)
22
formats = commandArgs(TRUE)
3-
travis = !is.na(Sys.getenv('CI', NA))
43

54
# provide default formats if necessary
65
if (length(formats) == 0) formats = c('bookdown::pdf_book', 'bookdown::gitbook')
@@ -12,15 +11,7 @@ for (fmt in formats) {
1211
}
1312
unlink('rmarkdown-cookbook.log')
1413

15-
r = '<body onload="window.location = \'https://bookdown.org/yihui\'+location.pathname">'
16-
if (travis) for (f in list.files('_book', '[.]html$', full.names = TRUE)) {
17-
x = readLines(f)
18-
if (length(i <- grep('^\\s*<body>\\s*$', x)) == 0) next
19-
# patch HTML files in gh-pages if built on Travis, to redirect to bookdown.org
20-
x[i[1]] = r
21-
writeLines(x, f)
22-
}
23-
14+
# creates redirects
2415
redirect = function(from, to) {
2516
to = paste0('https://bookdown.org/yihui/rmarkdown-cookbook/', to)
2617
writeLines(sprintf(
@@ -31,6 +22,23 @@ redirect = function(from, to) {
3122
redirect('r-markdown-components.html', 'rmarkdown-process.html')
3223
redirect('acknowledgements.html', 'acknowledgments.html')
3324

34-
if (length(formats) > 1 && Sys.getenv('USER') == 'yihui') {
35-
bookdown::publish_book(account = 'yihui', server = 'bookdown.org')
25+
26+
if (length(formats) > 1) {
27+
if (!is.na(Sys.getenv('CI', NA))) {
28+
xfun::pkg_load2("rsconnect")
29+
# On CI connect to server, using API KEY and deploy using appId
30+
rsconnect::addConnectServer('https://bookdown.org', 'bookdown.org')
31+
rsconnect::connectApiUser(
32+
account = 'GHA', server = 'bookdown.org',
33+
apiKey = Sys.getenv('CONNECT_API_KEY')
34+
)
35+
rsconnect::deploySite(
36+
appId = Sys.getenv('CONTENT_ID'),
37+
server = 'bookdown.org',
38+
render = 'none', logLevel = 'verbose',
39+
forceUpdate = TRUE)
40+
} else if (Sys.getenv('USER') == 'yihui') {
41+
# for local deployment when rsconnect/ is available
42+
bookdown::publish_book('rmarkdown-cookbook', server = 'bookdown.org', render = 'none')
43+
}
3644
}

index.Rmd

+1-17
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ cover-image: images/cover.png
2323
```{r setup, include=FALSE}
2424
set.seed(0728)
2525
26-
knitr::opts_chunk$set(tidy = TRUE)
26+
knitr::opts_chunk$set(tidy = TRUE, webshot = "webshot")
2727
2828
if (knitr::is_html_output()) {
2929
# ignore percentage widths for HTML output, unless they are used for multiple
@@ -35,22 +35,6 @@ if (knitr::is_html_output()) {
3535
})
3636
}
3737
38-
# packages only available on Github
39-
remote_pkgs = c(character()) # e.g., c(equatiomatic = 'datalorax')
40-
41-
lapply(c(
42-
'remotes', 'webshot', 'DiagrammeR', 'stargazer', 'gt', 'flextable', 'formatR',
43-
'equatiomatic', 'gifski', 'magick', 'pdftools', 'tikzDevice', 'xaringan',
44-
'kableExtra', 'blogdown', 'jsonlite', 'nomnoml'
45-
), function(pkg) {
46-
if (system.file(package = pkg) != '') return()
47-
repo = remote_pkgs[pkg]
48-
if (is.na(repo)) install.packages(pkg) else {
49-
remotes::install_github(paste(repo, pkg, sep = '/'))
50-
}
51-
}
52-
)
53-
5438
# screenshot HTML widgets
5539
if (is.null(webshot:::find_phantom())) webshot::install_phantomjs()
5640

0 commit comments

Comments
 (0)