Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# R specific hooks: https://github.com/lorenzwalthert/precommit
repos:
- repo: https://github.com/lorenzwalthert/precommit
rev: v0.4.3.9034
rev: v0.4.3.9033
hooks:
- id: style-files
args: [--style_pkg=styler, --style_fun=tidyverse_style, --cache-root=styler-perm]
Expand Down
95 changes: 79 additions & 16 deletions R/setup.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#' to fail if there are such hooks. "allow" will run these along with
#' pre-commit. "remove" will delete them.
#' @param open Whether or not to open `.pre-commit-config.yaml` after
#' it's been placed in your repo as well as
#' [pre-commit.ci](https://pre-commit.ci) (if `ci = "native"`). The default is
#' it's been placed in your repo, and the CI service's setup page
#' (see `open` in [use_ci()] for details). The default is
#' `TRUE` when working in RStudio.
#' @param autoupdate Whether or not to run [autoupdate()] as part of this
#' function call.
Expand Down Expand Up @@ -46,7 +46,7 @@ use_precommit <- function(config_source = getOption("precommit.config_source"),
legacy_hooks = "forbid",
open = rstudioapi::isAvailable(),
install_hooks = TRUE,
ci = getOption("precommit.ci", "native"),
ci = getOption("precommit.ci", "lite"),
autoupdate = install_hooks,
root = here::here()) {
rlang::arg_match(legacy_hooks, c("forbid", "allow", "remove"))
Expand All @@ -70,21 +70,35 @@ use_precommit <- function(config_source = getOption("precommit.config_source"),
#' Use continuous integration with pre-commit
#'
#' Sets up continuous integration, or prompts the user to do it manually.
#' See `vignette("ci", package = "precommit")` for a detailed comparison of
#' the available options.
#'
#' @param ci Specifies which continuous integration service to use. See
#' `vignette("ci", package = "precommit")` for details. Defaults to
#' `getOption("precommit.ci", "native")`, which is set to
#' `"native"` on package loading (if unset). `"native"` sets up
#' [pre-commit.ci](https://pre-commit.ci). Alternatively, `"gha"` can be used
#' to set up [GitHub Actions](https://github.com/features/actions). Set value
#' to `NA` if you don't want to use a continuous integration.
#' @param force Whether or not to overwrite an existing ci config file (only
#' relevant for `ci = "gha"`).
#' @param open Whether or not to open [pre-commit.ci](https://pre-commit.ci)
#' (if `ci = "native"`). The default is `TRUE` when working in RStudio.
#' @param ci Specifies which continuous integration service to use. Defaults to
#' `getOption("precommit.ci", "lite")`, which is set to `"lite"` on package
#' loading (if unset). Valid values:
#'
#' - `"lite"`: Sets up [pre-commit.ci lite](https://github.com/apps/pre-commit-ci-lite),
#' a GitHub App that runs hooks on GitHub Actions and auto-fixes PRs.
#' Copies two workflow files to `.github/workflows/` and opens the app
#' installation page. **Recommended default.**
#' - `"native"`: Sets up the fully managed [pre-commit.ci](https://pre-commit.ci)
#' service. No workflow files are added; the user is prompted to
#' authenticate via the browser.
#' - `"gha"`: Sets up a self-contained
#' [GitHub Actions](https://github.com/features/actions) workflow copied
#' to `.github/workflows/pre-commit.yaml`. Auto-fixing requires additional
#' credential setup.
#' - `NA`: Skip CI setup entirely.
#'
#' @param force Whether or not to overwrite existing CI workflow files (only
#' relevant for `ci = "lite"` and `ci = "gha"`).
#' @param open Whether or not to open the CI service's setup page in the
#' browser (`ci = "lite"` opens the GitHub App page;
#' `ci = "native"` opens [pre-commit.ci](https://pre-commit.ci)).
#' The default is `TRUE` when working in RStudio.
#' @inheritParams fallback_doc
#' @export
use_ci <- function(ci = getOption("precommit.ci", "native"),
use_ci <- function(ci = getOption("precommit.ci", "lite"),
force = FALSE,
open = rstudioapi::isAvailable(),
root = here::here()) {
Expand All @@ -99,6 +113,13 @@ use_ci <- function(ci = getOption("precommit.ci", "native"),
} else if (ci == "gha") {
dest <- fs::path(root, ".github/workflows/pre-commit.yaml")
fs::dir_create(fs::path_dir(dest))
if (fs::file_exists(dest) && !force) {
cli::cli_alert_info(paste0(
"There is already a GitHub Actions workflow file at ",
"{.code .github/workflows/pre-commit.yaml}. Use {.code force = TRUE} to overwrite."
))
return(invisible(NULL))
}
fs::file_copy(
system.file("pre-commit-gha.yaml", package = "precommit"),
dest,
Expand All @@ -110,6 +131,48 @@ use_ci <- function(ci = getOption("precommit.ci", "native"),
"run on pull requests. If workflow fails, please file an issue in ",
"{.code https://github.com/lorenzwalthert/precommit}."
))
} else if (ci == "lite") {
dest <- fs::path(root, ".github/workflows/pre-commit.yml")
dest_autoupdate <- fs::path(root, ".github/workflows/pre-commit-autoupdate.yml")
fs::dir_create(fs::path_dir(dest))
if (fs::file_exists(dest) && !force) {
cli::cli_alert_info(paste0(
"There is already a pre-commit.ci lite workflow file at ",
"{.code .github/workflows/pre-commit.yml}. Use {.code force = TRUE} to overwrite."
))
return(invisible(NULL))
}
fs::file_copy(
system.file("pre-commit-lite.yaml", package = "precommit"),
dest,
overwrite = force
)
fs::file_copy(
system.file("pre-commit-lite-autoupdate.yaml", package = "precommit"),
dest_autoupdate,
overwrite = force
)
cli::cli_alert_success(paste0(
"Added pre-commit.ci lite workflow templates to ",
"{.code .github/workflows/pre-commit.yml} and ",
"{.code .github/workflows/pre-commit-autoupdate.yml}."
))
cli::cli_ul(c(
paste0(
"Install the {.href [pre-commit.ci lite GitHub App](https://github.com/apps/pre-commit-ci-lite)} ",
"on your repository to enable automatic fixing of pull requests, ",
"then come back to complete the set-up process."
),
paste0(
"To enable monthly autoupdates of hook versions, go to ",
"{.emph Settings \u2192 Actions \u2192 General \u2192 Workflow permissions} and enable ",
"{.emph Allow GitHub Actions to create and approve pull requests}."
)
))
Sys.sleep(2)
if (open) {
utils::browseURL("https://github.com/apps/pre-commit-ci-lite")
}
} else if (ci == "native") {
cli::cli_ul(paste0(
"Sign in with GitHub to authenticate {.url https://pre-commit.ci} and ",
Expand All @@ -121,7 +184,7 @@ use_ci <- function(ci = getOption("precommit.ci", "native"),
}
} else {
rlang::abort(
'Argument `ci` must be one of `"native"` (default), `"gha"` or `NULL`.'
'Argument `ci` must be one of `"lite"` (default), `"native"`, `"gha"` or `NA`.'
)
}
config <- readLines(fs::path(root, ".pre-commit-config.yaml"))
Expand Down
2 changes: 1 addition & 1 deletion R/zzz.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
op.precommit <- list(
precommit.executable = path_derive_precommit_exec(),
precommit.block_install_hooks = FALSE,
precommit.ci = "native"
precommit.ci = "lite"
)
toset <- !(names(op.precommit) %in% names(op))
if (any(toset)) options(op.precommit[toset])
Expand Down
6 changes: 6 additions & 0 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ prec
precommit
precommithooks
proj
PRs
purrr
py
qmd
Expand Down Expand Up @@ -236,3 +237,8 @@ yaml
yihui
yml
Za
️
⚠
✅
❌
🔜
29 changes: 29 additions & 0 deletions inst/pre-commit-lite-autoupdate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
on:
schedule:
- cron: '0 0 1 * *' # monthly, 1st of each month
workflow_dispatch:

jobs:
autoupdate:
runs-on: ubuntu-latest
# Requires: Settings → Actions → General → Workflow permissions →
# "Allow GitHub Actions to create and approve pull requests"
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: 3.x
- run: pip install pre-commit && pre-commit autoupdate
- uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11
id: create-pr
with:
commit-message: 'pre-commit autoupdate'
title: 'pre-commit autoupdate'
branch: pre-commit-autoupdate
- name: Check PR creation result
if: failure()
run: |
echo "::error::Failed to create pull request. If you see a permissions error, go to Settings → Actions → General → Workflow permissions and enable 'Allow GitHub Actions to create and approve pull requests'."
19 changes: 19 additions & 0 deletions inst/pre-commit-lite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
on:
pull_request:
push:
branches: [main]

jobs:
pre-commit:
runs-on: ubuntu-latest
env:
RENV_CONFIG_CACHE_ENABLED: 'FALSE'
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: 3.x
- uses: r-lib/actions/setup-r@f9a764fea8d5c63df6ef9a5c7795bf7deb5d7e05 # v2.14.0
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
- uses: pre-commit-ci/lite-action@062bca0919bc9d6e66755cc05074b70c77e111fc # v1.2.0
if: always()
38 changes: 26 additions & 12 deletions man/use_ci.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 22 additions & 12 deletions man/use_precommit.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 25 additions & 1 deletion tests/testthat/test-setup.R
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,30 @@ test_that("Pre-commit CI GitHub Action template is parsable", {
)
})

test_that("Pre-commit CI lite setup works", {
local_test_setup(
git = FALSE, use_precommit = FALSE, package = TRUE, install_hooks = FALSE
)
use_precommit_config(
root = getwd(),
open = FALSE, verbose = FALSE
)
use_ci("lite", root = getwd(), open = FALSE)
expect_true(file_exists(".github/workflows/pre-commit.yml"))
expect_true(file_exists(".github/workflows/pre-commit-autoupdate.yml"))
})

test_that("Pre-commit CI lite workflow templates are parsable", {
expect_error(
yaml::read_yaml(system.file("pre-commit-lite.yaml", package = "precommit")),
NA
)
expect_error(
yaml::read_yaml(system.file("pre-commit-lite-autoupdate.yaml", package = "precommit")),
NA
)
})

test_that("Pre-commit CI setup works", {
local_test_setup(
git = FALSE, use_precommit = FALSE, package = TRUE, install_hooks = FALSE
Expand All @@ -102,7 +126,7 @@ test_that("Pre-commit CI setup works", {
root = getwd(),
open = FALSE, verbose = FALSE
)
use_ci(root = getwd(), open = FALSE)
use_ci("native", root = getwd(), open = FALSE)
expect_false(file_exists(".github/workflows/pre-commit.yaml"))
})

Expand Down
2 changes: 2 additions & 0 deletions vignettes/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
**/*.quarto_ipynb
*.R
*.html
/.quarto/
Loading
Loading