From 467a72bf390b7a8504b2ac86f7be78ed8f0c0052 Mon Sep 17 00:00:00 2001 From: Nicolo Massari Date: Tue, 9 Sep 2025 10:02:35 +0200 Subject: [PATCH 1/9] fix: workflow trigger on PR --- .github/workflows/deploy-quiz.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-quiz.yml b/.github/workflows/deploy-quiz.yml index 9c39a64..51f6a08 100644 --- a/.github/workflows/deploy-quiz.yml +++ b/.github/workflows/deploy-quiz.yml @@ -1,9 +1,9 @@ name: Deploy Quiz to shinyapps.io on: - push: - branches: [main, dev] - workflow_dispatch: # Allow manual deployment + pull_request: + types: [opened, synchronize, ready_for_review] + workflow_dispatch: jobs: deploy: From a39cb96c145da82e94b2811821d035a1cc669c2c Mon Sep 17 00:00:00 2001 From: Nicolo Massari Date: Tue, 9 Sep 2025 10:40:05 +0200 Subject: [PATCH 2/9] fix: system file logic didn't bundle csv. must add csv to appFile, feat: added little helper function in build to simplify deploy of new quizzes --- build.R | 32 +++++++++++++------ modules/_github_username.Rmd | 4 +-- .../extdata => modules}/github_usernames.csv | 0 3 files changed, 24 insertions(+), 12 deletions(-) rename {inst/extdata => modules}/github_usernames.csv (100%) diff --git a/build.R b/build.R index b5eeea2..0be36cd 100644 --- a/build.R +++ b/build.R @@ -1,18 +1,30 @@ +# HELPER + +deploy_quiz <- function(module_name) { + module_path <- paste0(file.path("modules", module_name), ".Rmd") + rsconnect::deployDoc( + doc = module_path, + appFiles = c( + "modules/_github_username.Rmd", + "modules/_submission.Rmd", + module_path, + "modules/github_usernames.csv" + ), + appName = module_name, + forceUpdate = TRUE + ) +} + + +# QUIZ DEPLOYMENT + rsconnect::deployApp( appName = "openwashdata-quiz-hub", forceUpdate = TRUE ) -rsconnect::deployDoc( - doc = "modules/md-01-quiz.Rmd", - appName = "openwashdata-module1-quiz", - forceUpdate = TRUE -) +deploy_quiz("md-01-quiz") # Example of what to add when creating new quiz: -#rsconnect::deployDoc( -# doc = "modules/md-02-quiz.Rmd", -# appName = "openwashdata-module2-quiz", -# forceUpdate = TRUE -#) +#deploy_quiz("md-02-quiz") diff --git a/modules/_github_username.Rmd b/modules/_github_username.Rmd index e44e018..ca29334 100644 --- a/modules/_github_username.Rmd +++ b/modules/_github_username.Rmd @@ -1,7 +1,7 @@ ```{r github-username-setup, include=FALSE} # Read GitHub usernames from CSV tryCatch({ - csv_path <- system.file("extdata", "github_usernames.csv", package = "quiz") + csv_path <- "modules/github_usernames.csv" github_users <- read.csv(csv_path, stringsAsFactors = FALSE) # Create choices with display format: "First Last (username)" username_choices <- setNames( @@ -41,7 +41,7 @@ div( # Read GitHub usernames in server context username_choices <- reactive({ tryCatch({ - csv_path <- system.file("extdata", "github_usernames.csv", package = "quiz") + csv_path <- "modules/github_usernames.csv" github_users <- read.csv(csv_path, stringsAsFactors = FALSE) # Create choices with display format: "First Last (username)" setNames( diff --git a/inst/extdata/github_usernames.csv b/modules/github_usernames.csv similarity index 100% rename from inst/extdata/github_usernames.csv rename to modules/github_usernames.csv From 863c969d672b232525cbc3d148d7d28f3eddf3cf Mon Sep 17 00:00:00 2001 From: Nicolo Massari Date: Tue, 9 Sep 2025 10:45:44 +0200 Subject: [PATCH 3/9] fix: install tidyverse to allo for all tidyverse libraries in quiz excercies --- DESCRIPTION | 2 +- modules/md-01-quiz.Rmd | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3aa495c..ebea5bf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -13,7 +13,7 @@ URL: https://github.com/ds4owd-dev/quiz, BugReports: https://github.com/ds4owd-dev/quiz/issues Imports: learnr, - dplyr, + tidyverse, gapminder, gt, gradethis, diff --git a/modules/md-01-quiz.Rmd b/modules/md-01-quiz.Rmd index f31cab6..48dbdf2 100644 --- a/modules/md-01-quiz.Rmd +++ b/modules/md-01-quiz.Rmd @@ -9,7 +9,7 @@ tutorial: ```{r setup, include=FALSE} library(learnr) -library(dplyr) +library(tidyverse) library(gapminder) library(knitr) library(gradethis) @@ -88,7 +88,7 @@ question("Which chunk options would you use to hide both code and messages when Use the gapminder dataset to create a summary table showing the average life expectancy by continent in 2007: ```{r create-table-setup} -library(dplyr) +library(tidyverse) library(gapminder) library(knitr) ``` @@ -131,7 +131,7 @@ grade_this_code() Calculate the mean GDP per capita for Switzerland in 2007: ```{r inline-code-setup} -library(dplyr) +library(tidyverse) library(gapminder) ``` @@ -164,7 +164,7 @@ grade_this_code() Create a line plot showing the life expectancy over time for African countries with a population greater than 30 million in 2007: ```{r visualization-setup} -library(dplyr) +library(tidyverse) library(gapminder) # Identify African countries with population > 30 million in 2007 From 993f763f530a1092977f4c78365f84c841541731 Mon Sep 17 00:00:00 2001 From: Nicolo Massari Date: Tue, 9 Sep 2025 10:49:21 +0200 Subject: [PATCH 4/9] fix: deployDoc doesn't have appFiles as arg --- build.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.R b/build.R index 0be36cd..e53ecdf 100644 --- a/build.R +++ b/build.R @@ -2,14 +2,14 @@ deploy_quiz <- function(module_name) { module_path <- paste0(file.path("modules", module_name), ".Rmd") - rsconnect::deployDoc( - doc = module_path, + rsconnect::deployApp( appFiles = c( "modules/_github_username.Rmd", "modules/_submission.Rmd", module_path, "modules/github_usernames.csv" ), + appPrimaryDoc = module_path, appName = module_name, forceUpdate = TRUE ) From ed42e31b60384acc993a02e52547149aed33a600 Mon Sep 17 00:00:00 2001 From: Nicolo Massari Date: Tue, 9 Sep 2025 11:10:10 +0200 Subject: [PATCH 5/9] fix: add appMode = "rmd-shiny" --- build.R | 1 + 1 file changed, 1 insertion(+) diff --git a/build.R b/build.R index e53ecdf..325d86d 100644 --- a/build.R +++ b/build.R @@ -11,6 +11,7 @@ deploy_quiz <- function(module_name) { ), appPrimaryDoc = module_path, appName = module_name, + appMode = "rmd-shiny", forceUpdate = TRUE ) } From a556364614efba5c873f1d84a76ac3f917148a33 Mon Sep 17 00:00:00 2001 From: Nicolo Massari Date: Tue, 9 Sep 2025 11:54:24 +0200 Subject: [PATCH 6/9] feat: add config.R as only file that needs editing to deploy quizzes, fix: wrong link --- DESCRIPTION | 3 +- README.md | 159 ++++++++++++----------------------------- app.R | 72 ++++++++++++++----- build.R | 13 ++-- config.R | 16 +++++ modules/md-01-quiz.Rmd | 10 +-- 6 files changed, 130 insertions(+), 143 deletions(-) create mode 100644 config.R diff --git a/DESCRIPTION b/DESCRIPTION index ebea5bf..a6470ec 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,7 +23,8 @@ Imports: rmarkdown, shiny, bslib, - rsconnect + rsconnect, + yaml Suggests: pkgdown Remotes: diff --git a/README.md b/README.md index 1566db8..94d1f0e 100644 --- a/README.md +++ b/README.md @@ -6,26 +6,26 @@ This directory contains interactive learnr quizzes for the openwashdata course a ## Structure -- `app.R` - Quiz landing page that links to all deployed quizzes +- `app.R` - Quiz landing page that automatically displays all configured quizzes +- `build.R` - Deployment script with helper functions for automated deployment +- `config.R` - Shared configuration file defining all available quizzes - `modules/` - Directory containing all quiz files - `md-01-quiz.Rmd` - Module 1 quiz on Quarto basics (learnr tutorial) - - `_github_username.Rmd` - Reusable component for GitHub username input + - `_github_username.Rmd` - Reusable component for GitHub username input with CSV data - `_submission.Rmd` - Reusable component for quiz submission + - `github_usernames.csv` - Student GitHub username database - Additional quiz files can be added as `md-XX-quiz.Rmd` ## Required Packages Make sure these packages are installed: +All required packages are defined in `DESCRIPTION` and automatically installed during deployment. For local development: + ```r -install.packages(c("learnr", "tidyverse", "gapminder", "knitr", "rsconnect", "httr", "digest")) - -# Install packages from GitHub -if (!requireNamespace("remotes", quietly = TRUE)) { - install.packages("remotes") -} -remotes::install_github("rstudio/gradethis") -remotes::install_github("rundel/learnrhash") +# Install from DESCRIPTION file +install.packages("remotes") +remotes::install_deps() ``` ## ShinyApps.io Authentication @@ -53,7 +53,6 @@ The quizzes now include automatic submission to Google Forms for tracking studen - **GitHub username collection**: Students enter their GitHub username at the start - **Learnrhash generation**: Quiz responses are encoded using learnrhash - **Automatic submission**: Results are submitted to Google Form via POST request -- **Error handling**: Provides fallback hash if submission fails - **Modular components**: Reusable username and submission components ### Google Form Setup @@ -66,15 +65,6 @@ The quizzes now include automatic submission to Google Forms for tracking studen - Hash column: Complete learnrhash for decoding - Username column: GitHub username for filtering - Module column: Module identifier (fetched from tutorial ID metadata) -- **Authentication**: None required - form accepts responses from anyone with the link - -### Advantages of Google Forms -- **No authentication needed**: Forms can accept anonymous submissions -- **Tidy data format**: Each field in its own column for easy analysis -- **Reliable**: Google handles all the backend infrastructure -- **Easy to view**: Responses automatically appear in Google Sheets -- **Error-resistant**: Works even with network issues -- **Easy filtering**: Separate columns for username and module ## Deployment Process @@ -97,13 +87,11 @@ Quizzes are automatically deployed to shinyapps.io via GitHub Actions when chang - `SHINYAPPS_SECRET`: The secret from shinyapps.io 3. **Add new quizzes to automated deployment**: - - Edit `build.R` and add your new quiz: + - Edit `config.R` and add your new quiz: ```r - # Deploy new quiz module - rsconnect::deployDoc( - doc = "modules/md-02-quiz.Rmd", - appName = "openwashdata-module2-quiz", - forceUpdate = TRUE + quiz_names <- c( + "md-01-quiz", + "md-02-quiz" # Add new quiz here ) ``` @@ -118,49 +106,26 @@ The GitHub Action (`.github/workflows/deploy-quiz.yml`): ### Manual Deployment -This quiz system uses a two-part deployment approach: - -### 1. Deploy Individual Quizzes - -Each quiz is deployed as a separate learnr tutorial using `deployDoc()`: - -```r -# Deploy Module 1 quiz -rsconnect::deployDoc( - doc = "modules/md-01-quiz.Rmd", - appName = "openwashdata-module1-quiz", - forceUpdate = TRUE -) -``` +For manual deployment, simply run the build script which handles everything automatically: -For additional quizzes: ```r -# Deploy Module 2 quiz (when created) -rsconnect::deployDoc( - doc = "modules/md-02-quiz.Rmd", - appName = "openwashdata-module2-quiz", - forceUpdate = TRUE -) +# Deploy all quizzes and landing page +source("build.R") ``` -### 2. Deploy the Landing Page - -The landing page is deployed as a regular Shiny app using `deployApp()`: - -```r -rsconnect::deployApp( - appName = "openwashdata-quiz-hub", - forceUpdate = TRUE -) -``` +The deployment system features: +- **Automatic file bundling**: CSV files and dependencies are automatically included +- **Streamlined process**: One script deploys everything configured in `config.R` ## Adding New Quizzes -To add a new quiz module: +The system now uses automatic configuration - adding a new quiz is simple: -1. **Create the quiz file** (e.g., `modules/md-02-quiz.Rmd`) using this template: +### 1. Create the Quiz File -```r +Create `modules/md-02-quiz.Rmd` with the standardized YAML header: + +```yaml --- title: "Module 2: Your Title" output: learnr::tutorial @@ -169,68 +134,34 @@ description: "Your quiz description" tutorial: id: "module2-your-id" --- +``` -`​``{r setup, include=FALSE} -library(learnr) -library(tidyverse) -library(gradethis) -library(learnrhash) -library(httr) - -tutorial_options( - exercise.eval = FALSE, - exercise.checker = gradethis::grade_learnr -) - -knitr::opts_chunk$set(echo = FALSE) - -# Google Form setup -form_url <- "https://docs.google.com/forms/d/e/1FAIpQLScnw9R8wMU5SfFqNVXGeEkiIygLTB_Dc6jWBmbwEeHuekBDzg/formResponse" -`​`` - -## Introduction - -Your introduction text here. +Add your quiz content following the existing pattern, including: +- GitHub username collection: `{r github-username, child='_github_username.Rmd'}` +- Quiz submission: `{r submission-section, child='_submission.Rmd'}` -`​``{r github-username, child='_github_username.Rmd'} -`​`` +### 2. Update Configuration -## Your Quiz Content +Edit `config.R` to include your new quiz: -Add your questions and exercises here... +```r +quiz_names <- c( + "md-01-quiz", + "md-02-quiz" # Add new quiz here +) +``` -`​``{r submission-section, child='_submission.Rmd'} -`​`` +### 3. Deploy -## Summary +Run the build script to deploy everything: -Your summary here. +```r +source("build.R") ``` -2. **Deploy the quiz**: - ```r - rsconnect::deployDoc( - doc = "md-02-quiz.Rmd", - appName = "openwashdata-module2-quiz", - forceUpdate = TRUE - ) - ``` -3. **Update the landing page** by adding the new quiz to the `quizzes` list in `app.R`: - ```r - list( - id = "module2", - title = "Module 2: Your Title", - description = "Quiz description", - url = "https://your-account.shinyapps.io/openwashdata-module2-quiz/", - available = TRUE - ) - ``` -4. **Redeploy the landing page**: - ```r - rsconnect::deployApp( - appName = "openwashdata-quiz-hub", - forceUpdate = TRUE - ) - ``` + +This will: +- Automatically deploy the new quiz +- Update the landing page to show the new quiz ## Local Testing diff --git a/app.R b/app.R index 8bece61..5557542 100644 --- a/app.R +++ b/app.R @@ -2,25 +2,61 @@ library(shiny) library(bslib) +library(yaml) -# Define available quizzes with their deployed URLs -quizzes <- list( - list( - id = "module1", - title = "Module 1: Quarto Basics", - description = "Test your understanding of Quarto basics for openwashdata package documentation", - url = "https://hjj91u-nicolo-massari.shinyapps.io/openwashdata-module1-quiz/", - available = TRUE - ) - # Add more quizzes here as you deploy them - # list( - # id = "module2", - # title = "Module 2: Data Visualization", - # description = "Learn about creating effective visualizations", - # url = "https://hjj91u-nicolo-massari.shinyapps.io/openwashdata-module2-quiz/", - # available = FALSE - # ) -) +# Load configuration +source("config.R") + +# Function to extract quiz metadata from Rmd files +extract_quiz_metadata <- function(quiz_name) { + rmd_path <- file.path("modules", paste0(quiz_name, ".Rmd")) + + if (!file.exists(rmd_path)) { + return(NULL) + } + + # Read the Rmd file and extract YAML header + rmd_content <- readLines(rmd_path) + yaml_start <- which(rmd_content == "---")[1] + yaml_end <- which(rmd_content == "---")[2] + + if (is.na(yaml_start) || is.na(yaml_end) || yaml_start >= yaml_end) { + return(NULL) + } + + yaml_content <- paste(rmd_content[(yaml_start + 1):(yaml_end - 1)], collapse = "\n") + yaml_data <- yaml::yaml.load(yaml_content) + + # Extract title and description + title <- yaml_data$title %||% paste("Quiz:", quiz_name) + description <- yaml_data$description %||% "Interactive quiz module" + + return(list(title = title, description = description)) +} + +# Auto-generate quiz list from quiz names +generate_quiz_list <- function(quiz_names) { + # Generate quiz list with metadata + quiz_list <- lapply(quiz_names, function(quiz_name) { + metadata <- extract_quiz_metadata(quiz_name) + + # Generate URL based on quiz name + quiz_url <- paste0(base_url, quiz_name, "/") + + list( + id = quiz_name, + title = metadata$title %||% paste("Quiz:", quiz_name), + description = metadata$description %||% "Interactive quiz module", + url = quiz_url, + available = TRUE + ) + }) + + return(quiz_list) +} + +# Generate quiz list automatically from config +quizzes <- generate_quiz_list(quiz_names) # UI ui <- page_navbar( diff --git a/build.R b/build.R index 325d86d..d5a3e1d 100644 --- a/build.R +++ b/build.R @@ -1,3 +1,6 @@ +# Load configuration +source("config.R") + # HELPER deploy_quiz <- function(module_name) { @@ -20,12 +23,12 @@ deploy_quiz <- function(module_name) { # QUIZ DEPLOYMENT rsconnect::deployApp( - appName = "openwashdata-quiz-hub", + appName = main_app_name, forceUpdate = TRUE ) -deploy_quiz("md-01-quiz") - -# Example of what to add when creating new quiz: +for (quiz in quiz_names) { + deploy_quiz(quiz) +} -#deploy_quiz("md-02-quiz") +# To add new quizzes, edit config.R diff --git a/config.R b/config.R new file mode 100644 index 0000000..44b9ee4 --- /dev/null +++ b/config.R @@ -0,0 +1,16 @@ +# Quiz Configuration +# Shared configuration file for build.R and app.R + +# List of quiz modules to deploy and display +quiz_names <- c( + "md-01-quiz" + # Add new quizzes here: + # "md-02-quiz", + # "md-03-quiz" +) + +# Base URL for deployed quizzes +base_url <- "https://hjj91u-nicolo-massari.shinyapps.io/" + +# Main app configuration +main_app_name <- "openwashdata-quiz-hub" \ No newline at end of file diff --git a/modules/md-01-quiz.Rmd b/modules/md-01-quiz.Rmd index 48dbdf2..c26e880 100644 --- a/modules/md-01-quiz.Rmd +++ b/modules/md-01-quiz.Rmd @@ -1,5 +1,5 @@ --- -title: "Module 1 Quiz: Quarto Basics for openwashdata" +title: "Module 1: Quarto Basics" output: learnr::tutorial runtime: shiny_prerendered description: "Test your understanding of Quarto basics for openwashdata package documentation" @@ -43,10 +43,10 @@ This quiz tests your understanding of Quarto basics for openwashdata package doc ```{r yaml-question} question("Which of the following is the correct YAML header for an openwashdata package README?", - answer("---\noutput: html_document\n---"), - answer("---\noutput: github_document\n---", correct = TRUE), - answer("---\nformat: html\n---"), - answer("---\nformat: markdown\n---"), + answer("`---`\n`output: html_document`\n`---`"), + answer("`---`\n`output: github_document`\n`---`", correct = TRUE), + answer("`---`\n`format: html`\n`---`"), + answer("`---`\n`format: markdown`\n`---`"), allow_retry = TRUE, incorrect = "Think about what output format is typically used for GitHub README files.", correct = "Correct! The github_document output format is used for README files that will be displayed on GitHub." From 0b1c649377ab5c5429afd2fa23bacd8e51daf895 Mon Sep 17 00:00:00 2001 From: Nicolo Massari Date: Tue, 9 Sep 2025 12:19:51 +0200 Subject: [PATCH 7/9] fix: load dplyr only to avoid timeout --- DESCRIPTION | 2 +- README.md | 3 +-- build.R | 3 ++- modules/md-01-quiz.Rmd | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a6470ec..b92e383 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -13,7 +13,7 @@ URL: https://github.com/ds4owd-dev/quiz, BugReports: https://github.com/ds4owd-dev/quiz/issues Imports: learnr, - tidyverse, + dplyr, gapminder, gt, gradethis, diff --git a/README.md b/README.md index 94d1f0e..488dcae 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,7 @@ All required packages are defined in `DESCRIPTION` and automatically installed d ```r # Install from DESCRIPTION file -install.packages("remotes") -remotes::install_deps() +devtools::install_github("ds4owd-dev/quiz") ``` ## ShinyApps.io Authentication diff --git a/build.R b/build.R index d5a3e1d..09f8b9e 100644 --- a/build.R +++ b/build.R @@ -15,7 +15,8 @@ deploy_quiz <- function(module_name) { appPrimaryDoc = module_path, appName = module_name, appMode = "rmd-shiny", - forceUpdate = TRUE + forceUpdate = TRUE, + logLevel = "verbose" ) } diff --git a/modules/md-01-quiz.Rmd b/modules/md-01-quiz.Rmd index c26e880..7214496 100644 --- a/modules/md-01-quiz.Rmd +++ b/modules/md-01-quiz.Rmd @@ -9,7 +9,7 @@ tutorial: ```{r setup, include=FALSE} library(learnr) -library(tidyverse) +library(dplyr) library(gapminder) library(knitr) library(gradethis) @@ -88,7 +88,7 @@ question("Which chunk options would you use to hide both code and messages when Use the gapminder dataset to create a summary table showing the average life expectancy by continent in 2007: ```{r create-table-setup} -library(tidyverse) +library(dplyr) library(gapminder) library(knitr) ``` @@ -131,7 +131,7 @@ grade_this_code() Calculate the mean GDP per capita for Switzerland in 2007: ```{r inline-code-setup} -library(tidyverse) +library(dplyr) library(gapminder) ``` @@ -164,7 +164,7 @@ grade_this_code() Create a line plot showing the life expectancy over time for African countries with a population greater than 30 million in 2007: ```{r visualization-setup} -library(tidyverse) +library(dplyr) library(gapminder) # Identify African countries with population > 30 million in 2007 From d7f2b9816cd00647eb3277b60845945504dbe152 Mon Sep 17 00:00:00 2001 From: Nicolo Massari Date: Tue, 9 Sep 2025 12:39:11 +0200 Subject: [PATCH 8/9] fix: try reverting to deploydoc to avoid container timeout --- build.R | 11 ++--------- modules/md-01-quiz.Rmd | 4 ++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/build.R b/build.R index 09f8b9e..97df4b8 100644 --- a/build.R +++ b/build.R @@ -5,16 +5,9 @@ source("config.R") deploy_quiz <- function(module_name) { module_path <- paste0(file.path("modules", module_name), ".Rmd") - rsconnect::deployApp( - appFiles = c( - "modules/_github_username.Rmd", - "modules/_submission.Rmd", - module_path, - "modules/github_usernames.csv" - ), - appPrimaryDoc = module_path, + rsconnect::deployDoc( + doc = module_path, appName = module_name, - appMode = "rmd-shiny", forceUpdate = TRUE, logLevel = "verbose" ) diff --git a/modules/md-01-quiz.Rmd b/modules/md-01-quiz.Rmd index 7214496..461b3ae 100644 --- a/modules/md-01-quiz.Rmd +++ b/modules/md-01-quiz.Rmd @@ -3,6 +3,10 @@ title: "Module 1: Quarto Basics" output: learnr::tutorial runtime: shiny_prerendered description: "Test your understanding of Quarto basics for openwashdata package documentation" +resource_files: + - github_usernames.csv + - _github_username.Rmd + - _submission.Rmd tutorial: id: "module1-quarto-basics" --- From 86671c629028cdf958ddaf40c2e6157faebfb919 Mon Sep 17 00:00:00 2001 From: Nicolo Massari Date: Tue, 9 Sep 2025 14:14:27 +0200 Subject: [PATCH 9/9] fix: path to root --- modules/_github_username.Rmd | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/_github_username.Rmd b/modules/_github_username.Rmd index ca29334..ace5310 100644 --- a/modules/_github_username.Rmd +++ b/modules/_github_username.Rmd @@ -1,7 +1,11 @@ ```{r github-username-setup, include=FALSE} # Read GitHub usernames from CSV tryCatch({ - csv_path <- "modules/github_usernames.csv" + # Try deployed path first, then fallback to local path + csv_path <- "github_usernames.csv" + if (!file.exists(csv_path)) { + csv_path <- "modules/github_usernames.csv" + } github_users <- read.csv(csv_path, stringsAsFactors = FALSE) # Create choices with display format: "First Last (username)" username_choices <- setNames( @@ -41,7 +45,11 @@ div( # Read GitHub usernames in server context username_choices <- reactive({ tryCatch({ - csv_path <- "modules/github_usernames.csv" + # Try deployed path first, then fallback to local path + csv_path <- "github_usernames.csv" + if (!file.exists(csv_path)) { + csv_path <- "modules/github_usernames.csv" + } github_users <- read.csv(csv_path, stringsAsFactors = FALSE) # Create choices with display format: "First Last (username)" setNames(