Update DESCRIPTION to use latest 'easystats' dependencies
#389
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # GitHub Copilot Environment Setup for report R Package | |
| # This workflow sets up the development environment before Copilot starts working | |
| # Based on: https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/customize-the-agent-environment | |
| name: copilot-setup-steps | |
| on: | |
| workflow_dispatch: | |
| # This workflow is automatically triggered by GitHub Copilot | |
| # before the agent starts working in the repository | |
| pull_request: | |
| types: [opened, synchronize] | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| issues: read | |
| jobs: | |
| copilot-setup-steps: | |
| # Optional: only run on Copilot agent commits; remove this if you also want your own pushes to trigger it | |
| if: > | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'pull_request' && | |
| github.actor == 'github-copilot') | |
| runs-on: ubuntu-latest | |
| env: | |
| GITHUB_PAT: ${{ github.token }} | |
| R_KEEP_PKG_SOURCE: yes | |
| _R_CHECK_CRAN_INCOMING_: false | |
| _R_CHECK_FORCE_SUGGESTS_: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| - name: Debug event/PR | |
| run: | | |
| echo "event_name=$GITHUB_EVENT_NAME" | |
| echo "sha=$GITHUB_SHA" | |
| echo "event payload:" | |
| jq -r '. | {pull_request: .pull_request?.number, number: .number, action: .action}' "$GITHUB_EVENT_PATH" | |
| - name: Wait for PR (and setup labels) up to 3 min | |
| id: wait_pr | |
| uses: actions/github-script@v9 | |
| with: | |
| github-token: ${{ github.token }} | |
| script: | | |
| const {owner, repo} = context.repo | |
| const sha = context.sha | |
| const branch = process.env.GITHUB_REF_NAME | |
| const REQUIRED = ['copilot-setup-full','copilot-setup-light'] | |
| const end = Date.now() + 3 * 60 * 1000 | |
| // 1) get PR number (works for dynamic + PR events) | |
| let prNumber = context.payload.pull_request?.number || null | |
| async function findPR() { | |
| if (prNumber) return prNumber | |
| // by commit | |
| const byCommit = await github.request( | |
| 'GET /repos/{owner}/{repo}/commits/{sha}/pulls', | |
| { owner, repo, sha } | |
| ) | |
| prNumber = byCommit.data[0]?.number || null | |
| if (prNumber) return prNumber | |
| // by head branch | |
| if (branch) { | |
| const byHead = await github.request( | |
| 'GET /repos/{owner}/{repo}/pulls', | |
| { owner, repo, state: 'open', head: `${owner}:${branch}` } | |
| ) | |
| prNumber = byHead.data[0]?.number || null | |
| } | |
| return prNumber | |
| } | |
| while (!await findPR() && Date.now() < end) { | |
| core.info('PR not created yet; waiting 5s…') | |
| await new Promise(r => setTimeout(r, 5000)) | |
| } | |
| if (!prNumber) { core.info('No PR found before timeout; continuing.'); return } | |
| core.info(`Found PR #${prNumber}`) | |
| core.setOutput('pr', String(prNumber)) | |
| // 2) (optional) wait briefly for one of the setup labels | |
| const labelsEnd = Date.now() + 90_000 | |
| while (Date.now() < labelsEnd) { | |
| const {data} = await github.rest.issues.listLabelsOnIssue({ owner, repo, issue_number: prNumber }) | |
| const names = data.map(l => l.name) | |
| if (REQUIRED.some(r => names.includes(r))) { | |
| core.info(`Setup labels present: [${names.join(', ')}]`) | |
| core.setOutput('labels', names.join(',')) | |
| return | |
| } | |
| core.info(`Waiting for setup labels… current: [${names.join(', ')}]`) | |
| await new Promise(r => setTimeout(r, 5000)) | |
| } | |
| core.warning('Timed out waiting for setup labels; continuing anyway.') | |
| - name: Determine if R setup is needed | |
| id: check_r_needed | |
| env: | |
| API_TOKEN: ${{ github.token }} | |
| PR_NUMBER_FROM_WAIT: ${{ steps.wait_pr.outputs.pr }} | |
| run: | | |
| set -euo pipefail | |
| PR_NUMBER="${PR_NUMBER_FROM_WAIT:-}" | |
| R_NEEDED=true | |
| EXPLICIT_DECISION="" | |
| # If we didn’t get one (very early run), try once more by commit | |
| if [ -z "$PR_NUMBER" ]; then | |
| PRS=$( | |
| curl -sS --fail-with-body \ | |
| -H "Authorization: Bearer ${API_TOKEN}" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}/pulls" | |
| ) | |
| PR_NUMBER=$(echo "$PRS" | jq -r '.[0].number // empty') | |
| fi | |
| if [ -n "$PR_NUMBER" ]; then | |
| # read labels from Issues endpoint | |
| PR_LABELS=$( | |
| curl -sS --fail-with-body \ | |
| -H "Authorization: Bearer ${API_TOKEN}" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" \ | |
| | jq -r '.[].name' | tr '[:upper:]' '[:lower:]' | |
| ) | |
| echo "PR labels: ${PR_LABELS:-<none>}" | |
| if echo "$PR_LABELS" | grep -q '\bcopilot-setup-full\b'; then | |
| EXPLICIT_DECISION=full; R_NEEDED=true | |
| elif echo "$PR_LABELS" | grep -q '\bcopilot-setup-light\b'; then | |
| EXPLICIT_DECISION=light; R_NEEDED=false | |
| fi | |
| fi | |
| # …(keep your file-heuristics fallback if EXPLICIT_DECISION is empty)… | |
| # Fallback heuristics when no explicit label decided | |
| if [ -z "$EXPLICIT_DECISION" ]; then | |
| if [ -n "$PR_NUMBER" ]; then | |
| echo "Analyzing changed files in PR #$PR_NUMBER…" | |
| FILES=$( | |
| curl -sS --fail-with-body \ | |
| -H "Authorization: Bearer ${API_TOKEN}" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files?per_page=100" \ | |
| | jq -r '.[].filename' | |
| ) | |
| echo "${FILES}" > /tmp/pr_files.txt | |
| else | |
| echo "No PR; diffing against default branch." | |
| DEFAULT_BRANCH=$( | |
| curl -sS --fail-with-body \ | |
| -H "Authorization: Bearer ${API_TOKEN}" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}" \ | |
| | jq -r '.default_branch' | |
| ) | |
| git fetch --no-tags --depth=200 origin "$DEFAULT_BRANCH" | |
| BASE=$(git merge-base HEAD "origin/${DEFAULT_BRANCH}") | |
| git diff --name-only "${BASE}...HEAD" > /tmp/pr_files.txt | |
| fi | |
| echo "Files to examine:"; cat /tmp/pr_files.txt || true | |
| if grep -E '\.(R|Rmd|Rd)$' /tmp/pr_files.txt >/dev/null || \ | |
| grep -E '^(R/|tests/|man/|vignettes/|src/)' /tmp/pr_files.txt >/dev/null; then | |
| R_NEEDED=true | |
| else | |
| if grep -v -E '^(\.github/copilot-instructions\.md|\.github/workflows/|README\.md|\.gitignore|\.Rbuildignore|NEWS\.md|CONTRIBUTING\.md|LICENSE|CITATION\.cff|DESCRIPTION|cran-comments\.md|.+\.md$|.+\.ya?ml$)$' /tmp/pr_files.txt | grep -E '.' >/dev/null; then | |
| R_NEEDED=true | |
| else | |
| R_NEEDED=false | |
| fi | |
| fi | |
| fi | |
| echo "R_NEEDED=${R_NEEDED}" | tee -a "$GITHUB_OUTPUT" | |
| echo "" | |
| echo "=== FINAL DECISION ===" | |
| if [ "$R_NEEDED" = "true" ]; then | |
| echo "✓ R setup WILL be run" | |
| [ -n "$EXPLICIT_DECISION" ] && echo "Reason: explicit label ($EXPLICIT_DECISION)" || echo "Reason: heuristics" | |
| else | |
| echo "✓ R setup WILL BE SKIPPED" | |
| [ -n "$EXPLICIT_DECISION" ] && echo "Reason: explicit label ($EXPLICIT_DECISION)" || echo "Reason: heuristics" | |
| fi | |
| echo "Decision: R_NEEDED=$R_NEEDED" | |
| - name: Setup R | |
| if: steps.check_r_needed.outputs.R_NEEDED == 'true' | |
| uses: r-lib/actions/setup-r@v2 | |
| with: | |
| r-version: 'release' | |
| use-public-rspm: true | |
| - name: Setup pandoc (required for building vignettes and reprex) | |
| if: steps.check_r_needed.outputs.R_NEEDED == 'true' | |
| uses: r-lib/actions/setup-pandoc@v2 | |
| - name: Install system dependencies | |
| if: steps.check_r_needed.outputs.R_NEEDED == 'true' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libcurl4-openssl-dev \ | |
| libssl-dev \ | |
| libxml2-dev | |
| - name: Setup R user library | |
| if: steps.check_r_needed.outputs.R_NEEDED == 'true' | |
| run: | | |
| mkdir -p ~/R/library | |
| echo 'R_LIBS_USER=~/R/library' >> ~/.Renviron | |
| shell: bash | |
| - name: Install R dependencies using pak | |
| if: steps.check_r_needed.outputs.R_NEEDED == 'true' | |
| uses: r-lib/actions/setup-r-dependencies@v2 | |
| with: | |
| # Use stable pak for reliable dependency resolution | |
| dependencies: '"hard"' | |
| # Install core package dependencies and essential development tools | |
| extra-packages: | | |
| local::. | |
| any::testthat | |
| any::roxygen2 | |
| any::devtools | |
| any::reprex | |
| any::knitr | |
| any::rmarkdown | |
| any::clipr | |
| any::cyclocomp | |
| r-lib/lintr | |
| r-lib/styler | |
| needs: check | |
| # Let r-lib/actions handle caching automatically (more efficient than manual cache) | |
| # NOTE: Suggested packages are NOT installed during setup to save time. | |
| # Only core dependencies (Imports/Depends) and essential development tools are installed. | |
| # Additional packages are installed on-demand based on specific PR requirements. | |
| # See copilot-instructions.md for targeted installation guidance. | |
| # NOTE: The local package (report) is automatically built and installed | |
| # by setup-r-dependencies@v2 when using 'local::.', eliminating the need | |
| # for manual build/install steps | |
| - name: Verify R installation and packages | |
| if: steps.check_r_needed.outputs.R_NEEDED == 'true' | |
| run: | | |
| cat("=== R Version ===\n") | |
| print(R.version.string) | |
| cat("\n=== Core Development Packages ===\n") | |
| required_packages <- c("testthat", "lintr", "styler", "roxygen2", "reprex") | |
| for (pkg in required_packages) { | |
| if (requireNamespace(pkg, quietly = TRUE)) { | |
| cat("✓", pkg, "- version", as.character(packageVersion(pkg)), "\n") | |
| } else { | |
| cat("✗", pkg, "- NOT AVAILABLE\n") | |
| } | |
| } | |
| cat("\n=== report Package (auto-installed by setup-r-dependencies) ===\n") | |
| if (requireNamespace("report", quietly = TRUE)) { | |
| library(report) | |
| cat("✓ report - version", as.character(packageVersion("report")), "\n") | |
| } else { | |
| cat("✗ report - NOT AVAILABLE\n") | |
| } | |
| shell: Rscript {0} | |
| - name: Display environment summary | |
| run: | | |
| echo "=== GitHub Copilot Environment Setup Complete ===" | |
| echo "" | |
| if [ "${{ steps.check_r_needed.outputs.R_NEEDED }}" == "true" ]; then | |
| echo "✓ Optimized R development environment configured using pak:" | |
| echo " - R and essential system dependencies installed" | |
| echo " - Core package dependencies (Imports/Depends) installed via setup-r-dependencies" | |
| echo " - report package automatically built and installed" | |
| echo " - Essential development tools (lintr, styler, roxygen2, devtools)" | |
| echo " - reprex dependencies ready (reprex + knitr + rmarkdown + pandoc)" | |
| echo " - Efficient pak-based dependency resolution with automatic caching" | |
| echo " - Suggested packages NOT installed (install as needed per PR)" | |
| echo "" | |
| echo "The environment is ready for R package development work." | |
| echo "Copilot can now build, test, lint, and create reproducible examples." | |
| else | |
| echo "✓ Minimal environment configured:" | |
| echo " - Repository checked out and ready" | |
| echo " - R setup SKIPPED - only documentation/config changes detected" | |
| echo "" | |
| if [ "${GITHUB_EVENT_NAME:-}" = "pull_request" ]; then | |
| echo "Decision based on PR labels and/or file analysis using GitHub API" | |
| else | |
| echo "Decision based on git diff analysis" | |
| fi | |
| echo "The environment is ready for documentation and configuration work." | |
| echo "Perfect for version bumps, NEWS.md updates, and text editing tasks." | |
| fi | |
| shell: bash |