diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index ec223d7..8e613b0 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -77,3 +77,19 @@ ggplot(mtcars, aes(x = wt, y = mpg)) + labs(x = "Weight (1000 lbs)", y = "Miles per Gallon") ``` ```` + +## Quality Assurance + +### Testing Renders + +Before requesting review or marking work as complete: + +- **Test your changes locally** by running `quarto render` (or rendering only the touched page with `quarto render .qmd --to html` while iterating). +- **Check the rendered output** in `_site/` to verify: + - All content displays correctly + - No broken links or missing images + - Formatting is as expected +- **Review the PR preview** at the preview URL to confirm everything works in the deployed version. +- **Fix any rendering issues** before requesting review. + +This ensures reviewers see working, polished output rather than discovering basic rendering problems. diff --git a/.github/prompts/quarto-review.prompt.md b/.github/prompts/quarto-review.prompt.md new file mode 100644 index 0000000..4e70dea --- /dev/null +++ b/.github/prompts/quarto-review.prompt.md @@ -0,0 +1,46 @@ +--- +mode: agent +description: Quarto-first PR review for this repository — content, rendering correctness, links, and validation gaps. Use when preparing or checking a PR that touches pages, rendering logic, or workflow files. +--- + +Review the requested changes as a Quarto-first code review for this repository. + +Scope: + +- Prioritize changed `.qmd`, `.R`, `.Rmd`, `.yml`, and `.yaml` files. +- Treat files under `_extensions/` as vendored third-party code. Read them for + context if needed, but do not flag or request changes there. +- Focus on behavior, rendering correctness, broken links or references, and + validation gaps. + +Review checklist: + +1. Links point to source `.qmd` targets, not rendered `.html` files; cross-refs + (`@fig-`, `@tbl-`, `@sec-`) resolve to defined labels. +2. Lists of three or more items use bullets with a blank line above them. +3. `code-fold: true` is used where the *output* is the point and avoided on + tutorial code; chunk options use `#|` directives, not inline `r, opt = val`. +4. Narrative text does not hard-code computed values — they are computed in a + chunk and referenced with inline R. +5. Citations and attribution are present where adapted content or factual + claims appear, and only sources in `references.bib` are used. +6. No new R package or Quarto extension is added without a clear reason (this is + a template — every dependency lands in every downstream book). +7. No generated files are edited (`README.md` from `README.Rmd`; `_site/`, + `_freeze/`, `.quarto/`), and spell/link-check failures are fixed at the + source (wordlist or content), not suppressed. +8. The author ran the required local validation: + - render of the touched page + - `lintr` + - `spelling::spell_check_package()` + +Output format: + +- Findings first, ordered by severity, with file references. +- Then open questions or assumptions. +- Then a short change summary only if useful. +- If there are no findings, say so explicitly and note any residual testing gaps. + +Base the review on [copilot-instructions.md](../copilot-instructions.md) and +[CLAUDE.md](../../CLAUDE.md), plus any path-scoped rules under +`.github/instructions/` (if present) that apply to the changed files. diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 1608577..a7a94e7 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -11,14 +11,25 @@ name: "Copilot Setup Steps" -# Automatically run the setup steps when they are changed to allow for easy validation, -# and allow manual testing through the repository's "Actions" tab +# This workflow has two independent invocation paths: +# +# 1. Copilot agent provisioning: GitHub's Copilot coding agent runs the +# `copilot-setup-steps` job DIRECTLY to build its environment when it +# starts a task. That invocation is NOT governed by the `on:` triggers +# below — so the `paths:` filter does not affect it. The `skip-cp-setup` +# label short-circuits the heavy install (checkout only) in that context, +# so a PR Copilot is working on can opt out of the full setup cost. +# 2. Validation CI: the `on:` triggers below run the workflow as an ordinary +# job, gated to changes of THIS file so we can validate edits to it +# without paying the setup cost on every unrelated PR. The +# `labeled`/`unlabeled` types let toggling the label re-run a validation. on: workflow_dispatch: push: paths: - .github/workflows/copilot-setup-steps.yml pull_request: + types: [opened, synchronize, reopened, labeled, unlabeled] paths: - .github/workflows/copilot-setup-steps.yml @@ -31,18 +42,42 @@ jobs: # Copilot will be given its own token for its operations. permissions: contents: read - + pull-requests: read # read PR labels for the skip-cp-setup check + # Timeout after 55 minutes (max is 59 for copilot-setup-steps) timeout-minutes: 55 - + steps: + # Skip the heavy install when a PR carries the `skip-cp-setup` label + # (e.g. metadata- or workflow-only PRs). Non-PR events always run setup. + - name: Check if setup should be skipped + id: check_label + # Pass the expression result through env (GitHub-recommended) rather + # than interpolating it directly into the shell, to avoid the + # expression-injection anti-pattern in code that downstream books copy. + env: + EVENT_NAME: ${{ github.event_name }} + LABELS_CONTAIN_SKIP: ${{ contains(github.event.pull_request.labels.*.name, 'skip-cp-setup') }} + shell: bash + run: | + if [[ "$EVENT_NAME" != 'pull_request' ]]; then + echo "Not a pull request, running full setup" + echo "skip=false" >> "$GITHUB_OUTPUT" + elif [[ "$LABELS_CONTAIN_SKIP" == 'true' ]]; then + echo "skip-cp-setup label present, skipping setup steps" + echo "skip=true" >> "$GITHUB_OUTPUT" + else + echo "skip-cp-setup label not present, running full setup" + echo "skip=false" >> "$GITHUB_OUTPUT" + fi + # Checkout code - Copilot will do this automatically if we don't, # but we need it for any repository-specific setup - name: Checkout code uses: actions/checkout@v4 with: submodules: true - + # Install system dependencies needed for this project, including: # # - C/C++ libraries required by R packages (libcurl, libssl, libxml2, etc.) @@ -51,6 +86,7 @@ jobs: # - A computer algebra system (maxima) for symbolic math computations # - Python pip for additional tooling - name: Install system dependencies + if: steps.check_label.outputs.skip != 'true' run: | sudo apt-get update sudo apt-get install -y \ @@ -74,11 +110,13 @@ jobs: # Set up pandoc for documentation - name: Set up Pandoc + if: steps.check_label.outputs.skip != 'true' uses: r-lib/actions/setup-pandoc@v2 - + # Set up R using the standard GitHub Actions setup # Using 'release' to get the latest R version - name: Set up R + if: steps.check_label.outputs.skip != 'true' uses: r-lib/actions/setup-r@v2 with: r-version: 'release' @@ -86,6 +124,7 @@ jobs: # Install R packages needed for linting and Quarto rendering - name: Install R packages + if: steps.check_label.outputs.skip != 'true' run: | install.packages( c("lintr", "rmarkdown"), @@ -95,12 +134,14 @@ jobs: # Set up Quarto - required for rendering the website - name: Set up Quarto + if: steps.check_label.outputs.skip != 'true' uses: quarto-dev/quarto-actions/setup@v2 with: tinytex: true - + # Verify development environment is properly configured - name: Verify development environment + if: steps.check_label.outputs.skip != 'true' run: | echo "=== Development Environment Status ===" diff --git a/CLAUDE.md b/CLAUDE.md index 3500b0d..1d09595 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,7 +33,7 @@ Mirrors [`.github/copilot-instructions.md`](.github/copilot-instructions.md). Ke ## Working in this repo - **Don't edit generated files**: `README.md` is built from `README.Rmd`; `_site/` and `_freeze/` are build outputs. -- **Local preview**: `quarto preview` (live reload). Full build: `quarto render`. +- **Local preview**: `quarto preview` (live reload). Full build: `quarto render`. When verifying a single edited page, render just that page (`quarto render .qmd --to html`) rather than the whole site — the `/render` command is for the full build. - **Submodules**: `macros/` is the only git submodule (see `.gitmodules`). Run `git submodule update --init --recursive` after cloning. - **Spell check**: words go in `inst/WORDLIST` (see `.github/workflows/check-spelling.yaml`). Update the wordlist instead of disabling the check. - **Link check**: tuned in `lychee.toml`; prefer fixing broken links over adding exceptions.