Skip to content

v1.1.0

Choose a tag to compare

@jonthegeek jonthegeek released this 24 Feb 15:11
936f46d

Overview

New features and tools to help you track user acceptance testing, and to help you use AI agents to get started with qcthat.

New features

Experimental functions for tracking user-acceptance testing (UAT):

  • ExpectUserAccepts() enables tracking of user acceptance by connecting testthat tests to GitHub issues. Once the UAT issue is closed, the test will pass (#65, #111, #113, #115, #120).
  • TriggerUAT() triggers the UAT test cycle for a closed issue. This function is used by the improved GitHub Actions framework, installable via Action_qcthat() (#65, #111, #114, #115, #116, #157).

Improved onboarding:

  • use_qcthat() calls SetupGHLabels() and Action_qcthat(), to set up your repository with GitHub Actions workflows and labels used for QC tracking (#129, #141, #143, #161, #165, #181, #198).
  • Experimental AI agent features: Skill_TagTestsWithIssues() installs an AI agent skill to tag tests with issues, using new functions ExtractTestsFromFiles(), MapTestFilesToPotentialIssues(), and PrepareTestIssueContext() (#52, #53, #200, #201, #233).

Other changes

  • Additional improvements to QC reports, such as links to the GitHub Actions run (#150), timestamps (#172), and attaching QC Reports to releases within the release description (#152). Additional changes are tracked in the parent issues (#123, #160).
  • The pkgdown site for qcthat now includes a slide deck to introduce the package and the associated system (#166, #167, #168, #169).

Bug fixes

  • Ignored issues are filtered out of reports (#118).
  • Reports work properly when the active branch is associated with multiple PRs (#132), when the PRs contain a lot of commits (#133), and after PRs are merged (#149).
  • GetGHOwner() and GetGHRepo() should now work for forks, even if the local repo name does not match the upstream repo name (#199).

What's Changed

Full Changelog: v1.0.0...v1.1.0

{qcthat} Reports

Milestone

✅ A qcthat issue test matrix with 1 milestone, 43 issues, and 128 tests
└─█─Milestone: v1.1.0 (43 issues, 128 tests)
  ├─☑️─Requirement 233: AI Agent for qcthat Onboarding
  │ └─✅─Skill_TagTestsWithIssues targets the expected skill (#53, #233)
  ├─☑️─Bug 201: Provide full path in Skill-related functions
  │ ├─✅─ExtractTestsFromFiles parses tests and issues from test dirs (#52, #201)
  │ ├─✅─MapTestFilesToPotentialIssues finds potential issues via commits (#53, #201)
  │ ├─✅─MapTestsToCommits adds commit SHAs for each test (#53, #201)
  │ ├─✅─GetRelativePackagePath finds the relative path (#201)
  │ ├─✅─PrepareTestIssueContext passes parameters (#53, #201)
  │ └─✅─ReadTestCode reads test code from file (#53, #201)
  ├─☑️─Bug 200: Commits column of `MapRepoIssuesToCommits()` should expand to list of characters when empty
  │ └─✅─MapRepoIssuesToCommits handles empty input (#200)
  ├─☑️─Bug 199: Use upstream when available in `GetGHOwner()`
  │ └─✅─GetGHRemote uses upstream when available (#199)
  ├─☑️─Feature 198: Universal `Action_qcthat()` function
  │ └─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
  ├─☑️─Technical Task 181: Verify `qcthat.yaml` works for releases
  │ └─✅─AttachReleaseReports runs properly on release (#181)
  ├─☑️─Feature 172: Add timestamps to comments
  │ ├─✅─CommentIssue compiles the body as expected (#83, #172)
  │ └─✅─PrettyTimestamp works (#172)
  ├─☑️─Documentation Task 169: Deck draft 2: Final-ish
  │ └─✅─The pkgdown site has an intro slide deck (#166, #167, #168, #169)
  ├─☑️─Documentation Task 168: Draft the real slide deck
  │ └─✅─The pkgdown site has an intro slide deck (#166, #167, #168, #169)
  ├─☑️─Technical Task 167: Add a basic slide deck to pkgdown
  │ └─✅─The pkgdown site has an intro slide deck (#166, #167, #168, #169)
  ├─☑️─Requirement 166: Introduce {qcthat}
  │ └─✅─The pkgdown site has an intro slide deck (#166, #167, #168, #169)
  ├─☑️─Feature 165: Combined `CommentPRReports()` function
  │ ├─✅─FormatReportBody finalizes reports (#165)
  │ ├─✅─FormatReportType generates a report type (#165)
  │ ├─✅─CommentAllReports generates the expected calls (#165)
  │ ├─✅─All qcthat reports are combined in a single GHA (#129, #165, #152)
  │ ├─✅─GuessMilestones returns NULL for bad arg (#165)
  │ ├─✅─GuessMilestones extracts milestones from lGHEventPayload when available (#165)
  │ └─✅─GuessMilestones returns NULL for bad extracted milestones (#165)
  ├─☑️─Feature 164: Functions to manage envQcthat$UATIssues
  │ └─✅─SaveUATIssues saves UAT issues and LoadUATIssues loads them (#164)
  ├─☑️─Feature 163: Use GitHub Event for `GetGHAPRNumber()`
  │ ├─✅─GetGHAPRNumber returns NULL for bad arg (#84, #163)
  │ ├─✅─GetGHAPRNumber extracts PR number from lGHEventPayload when available (#84, #163)
  │ └─✅─GetGHAPRNumber returns NULL for bad extracted PR number (#84, #163)
  ├─☑️─Feature 162: GuessIssueNumber()
  │ ├─✅─GuessIssueNumber returns NULL for bad arg (#162)
  │ ├─✅─GuessIssueNumber extracts issue number from lGHEventPayload when available (#162)
  │ ├─✅─GuessIssueNumber returns NULL for bad extracted issue number (#162)
  │ ├─✅─LoadGHEventPayload returns NULL when envvar is empty (#162)
  │ ├─✅─LoadGHEventPayload returns NULL for bad path (#162)
  │ ├─✅─LoadGHEventPayload returns NULL for bad payload (#162)
  │ └─✅─LoadGHEventPayload returns the payload if it's readable (#162)
  ├─☑️─Feature 161: Single `use_qcthat()` function for all actions
  │ └─✅─use_qcthat calls the expected functions (#161)
  ├─☑️─Requirement 160: Improved QC Tracking for Releases
  │ └─✅─AttachReleaseReports makes the expected calls (#152, #160)
  ├─☑️─Feature 157: Automated UAT Verification Loop: Workflow
  │ ├─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
  │ └─✅─The UAT workflow triggers properly when all UAT issues connected to a PR are closed (#65, #157)
  ├─☑️─Feature 152: Add reports to release description (not as attachment)
  │ ├─✅─UpdateReleaseBody makes the expected call (#152)
  │ ├─✅─UpdateReleaseBody uses existing body if available (#152)
  │ ├─✅─AttachReleaseReports makes the expected calls (#152, #160)
  │ ├─✅─CompileReleaseReportsMarkdown stitches together parts for releases (#152)
  │ ├─✅─All qcthat reports are combined in a single GHA (#129, #165, #152)
  │ ├─✅─GuessReleaseID returns NULL for bad arg (#152)
  │ ├─✅─GuessReleaseID extracts release from lGHEventPayload when available (#152)
  │ ├─✅─GuessReleaseID converts tag name to release id when necessary (#152)
  │ └─✅─FetchRawReleaseByTagName generates the expected call (#152)
  ├─☑️─Feature 150: Link to GHA Run in Report
  │ ├─✅─CommentIssue includes run URL when available (#150)
  │ ├─✅─FetchRunURL returns the expected URL (#150)
  │ ├─✅─FetchRunJobsRaw makes the expected call (#150)
  │ ├─✅─FetchRunInfoRaw makes the expected call (#150)
  │ └─✅─CommentIssue includes session info (#150)
  ├─☑️─Bug 149: `QCPR()` should work after PRs are merged
  │ ├─✅─FetchAllMergeIssueNumbers returns unique, sorted issue numbers (#149)
  │ └─✅─FetchPRRefs returns source and target refs (#84, #133, #149)
  ├─☑️─Technical Task 146: Lower R Version Requirement
  │ └─✅─The required R version is within the normal support window (#146)
  ├─☑️─Bug 143: Properly reference qcthat in actions
  │ └─✅─qcthat is namespaced in GHA (#143)
  ├─☑️─Bug 141: Fix milestone action
  │ └─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
  ├─☑️─Bug 133: Big PRs fail to generate PR-associated issues report
  │ ├─✅─FetchRepoIssueClosers returns an empty df when no issues are found (#133)
  │ ├─✅─FetchRepoIssueClosers processes raw data correctly (#133)
  │ ├─✅─FetchRepoIssueClosersRaw processes pagination correctly (#133)
  │ ├─✅─IsIssueCloserFromRepo filters cross-repo PRs (#133)
  │ ├─✅─FetchRepoIssueClosersRawBatch generates the expected calls (#133)
  │ ├─✅─FetchMergeCommitSHAs returns unique, sorted SHAs (#84, #133)
  │ ├─✅─BuildCommitPRQuery builds the expected query (#133)
  │ ├─✅─FetchAllPRIssueNumbers returns unique, sorted issue numbers (#133)
  │ ├─✅─BuildPRIssuesQuery builds the expected query (#133)
  │ └─✅─FetchPRRefs returns source and target refs (#84, #133, #149)
  ├─☑️─Bug 132: Deal with multiple PRs
  │ ├─✅─FetchRefPRNumber fetches PR number for a branch (#84, #132)
  │ └─✅─ChooseRefPRNumber() deals with corner cases (#132)
  ├─☑️─Technical Task 129: Single qcthat GHA
  │ └─✅─All qcthat reports are combined in a single GHA (#129, #165, #152)
  ├─☑️─Requirement 123: Cleaner reports
  │ ├─✅─CommentIssue updates when told to do so (#83, #100, #123)
  │ └─✅─filter also removes ignored issues (#118, #123)
  ├─☑️─Feature 120: Don't attempt to create issues without proper permissions
  │ └─✅─CreateUAIssue returns NULL when it can't create an issue (#120)
  ├─☑️─Bug 118: Filter ignored issues in reports
  │ └─✅─filter also removes ignored issues (#118, #123)
  ├─☑️─Technical Task 116: Bust gh cache for child issues
  │ └─✅─CreateRepoIssueRaw clears the cache when an issue is created (#116)
  ├─☑️─Feature 115: PR UAT Dashboard
  │ ├─✅─CommentUAT generates the expected call with 0 pending issues (#115)
  │ ├─✅─CommentUAT generates the expected call (#115)
  │ └─✅─LogUAT logs UAT status (#115)
  ├─☑️─Feature 114: Automated UAT Verification Loop: R side
  │ ├─✅─FetchAllIssuePRRefs returns correct PR information (#114)
  │ ├─✅─FetchAllIssuePRRefs filters by state correctly (#114)
  │ ├─✅─FetchAllIssuePRRefsRaw generates the expected calls (#114)
  │ ├─✅─BuildIssuePRRefsQuery generates correct GQL (#114)
  │ ├─✅─TriggerUAT calls MaybeRerunAllQCPRWorkflows if open PRs exist (#114)
  │ ├─✅─TriggerUAT does nothing if no open PRs exist (#114)
  │ ├─✅─MaybeRerunAllQCPRWorkflows triggers rerun if conditions met (#114)
  │ ├─✅─FetchPRUATCommentIssues extracts issues correctly (#114)
  │ ├─✅─MaybeRerunQCPRWorkflow delegates to RerunWorkflowIfFinished (#114)
  │ ├─✅─MaybeRerunQCPRWorkflow does nothing if no runs found (#114)
  │ ├─✅─FetchPRActionRuns calls API and filters correctly (#114)
  │ ├─✅─RerunWorkflowIfFinished reruns only if none in progress (#114)
  │ ├─✅─RerunWorkflowAtSHA picks correct run (#114)
  │ └─✅─RerunWorkflow calls API correctly (#114)
  ├─☑️─Technical Task 113: Add infrastructure to detect where the tests are happening
  │ ├─✅─OnCran returns FALSE when envvar unset or true (#113)
  │ └─✅─OnCran returns TRUE when envvar set to false (#113)
  ├─☑️─Technical Task 112: Create condition infrastructure
  │ ├─✅─CompileConditionClasses compiles classes as expected (#112)
  │ └─✅─qcthatAbort creates an error condition with expected classes and message (#112)
  ├─☑️─Feature 111: Minimal User-Acceptance Testing Framework
  │ ├─✅─CreateUAIssue constructs the expected call (#111)
  │ ├─✅─CreateChildIssue uses the expected process (#111)
  │ ├─✅─CreateRepoIssueRaw hits the expected endpoint (#111)
  │ ├─✅─ConnectChildIssueByID returns the URL to the parent (#111)
  │ ├─✅─ExpectUserAccepts returns the input strDescription (#111)
  │ ├─✅─ExpectUserAccepts passes when the issue is closed (#65, #111)
  │ ├─✅─ExpectUserAccepts fails when the issue isn't closed and strFailureMode is 'fail' (#65, #111)
  │ ├─✅─ExpectUserAccepts returns silently when the issue isn't closed and lglIgnore is TRUE (#111)
  │ ├─✅─IsCheckingUAT reports whether the qcthat_UAT envvar is true (#111)
  │ ├─✅─FetchUAIssue returns the issue as a list if found (#111)
  │ ├─✅─FetchUAIssue returns the issue as a list if created (#111)
  │ ├─✅─FetchIssueUAChildren fetches 'qcthat-uat'-labeled child issues (#111)
  │ ├─✅─FetchIssueChildren returns a DF of issue children (#111)
  │ └─✅─TitleUAIssue gives the expected title (#111)
  ├─☑️─Feature 110: Export GitHub Helpers
  │ ├─✅─GetGHOwner and GetGHRepo work (#110)
  │ └─✅─UsesGit works in any situation (#110)
  ├─☑️─Technical Task 100: Update report comments
  │ └─✅─CommentIssue updates when told to do so (#83, #100, #123)
  ├─☑️─Technical Task 99: Better print of footer on GitHub
  │ └─✅─CommentReport generates the expected call (#99, #72)
  ├─☑️─Feature 83: Comment on GH PR or issue
  │ ├─✅─Additional user acceptance sub-issue is generated in the qcthat User Acceptance report (#83)
  │ ├─✅─CommentIssue compiles the body as expected (#83, #172)
  │ ├─✅─CommentIssue updates when told to do so (#83, #100, #123)
  │ ├─✅─UpdateIssueComment updates when a comment exists (#83)
  │ ├─✅─UpdateIssueComment creates when a comment doesn't exist (#83)
  │ ├─✅─FetchIssueCommentGHID returns the correct GH ID when found (#83)
  │ ├─✅─FetchIssueCommentGHID returns nothing when no matching comment found (#83)
  │ ├─✅─UpdateCommentRaw calls the API as expected (#83)
  │ ├─✅─CommentIssueRaw calls the API as expected (#83)
  │ ├─✅─CommentIssue updates a comment as expected (#83)
  │ ├─✅─FetchIssueComments returns an empty df when no issues found (#83)
  │ └─✅─FetchIssueComments returns a formatted df for real issues (#83)
  ├─☑️─Requirement 65: Track user (manual) testing
  │ ├─✅─ExpectUserAccepts passes when the issue is closed (#65, #111)
  │ ├─✅─ExpectUserAccepts fails when the issue isn't closed and strFailureMode is 'fail' (#65, #111)
  │ └─✅─The UAT workflow triggers properly when all UAT issues connected to a PR are closed (#65, #157)
  ├─☑️─Feature 53: Find issues associated with tests
  │ ├─✅─FetchIssueDetails fetches issue details (#53)
  │ ├─✅─FetchIssueDetails handles empty input (#53)
  │ ├─✅─FetchIssueDetails deduplicates API calls but preserves order (#53)
  │ ├─✅─FetchIssueDetails passes GitHub parameters (#53)
  │ ├─✅─MapRepoIssuesToCommits handles commit closers (#53)
  │ ├─✅─MapRepoIssuesToCommits handles PR closers (#53)
  │ ├─✅─MapRepoIssuesToCommits handles mixed closers (#53)
  │ ├─✅─MapTestFilesToPotentialIssues finds potential issues via commits (#53, #201)
  │ ├─✅─MapTestFilesToPotentialIssues filters out tests tagged with #noissue (#53)
  │ ├─✅─MapTestFilesToPotentialIssues handles tests with no matching commits (#53)
  │ ├─✅─MapTestFilesToPotentialIssues handles tests with tagged issues (#53)
  │ ├─✅─MapTestsToCommits adds commit SHAs for each test (#53, #201)
  │ ├─✅─PrepareTestIssueContext enriches test data (#53)
  │ ├─✅─PrepareTestIssueContext handles empty input (#53)
  │ ├─✅─PrepareTestIssueContext passes parameters (#53, #201)
  │ ├─✅─ReadTestCode reads test code from file (#53, #201)
  │ ├─✅─ReadTestCode fails for invalid ranges (#53)
  │ ├─✅─InstallSkill calls InstallFile with expected parts (#53)
  │ └─✅─Skill_TagTestsWithIssues targets the expected skill (#53, #233)
  └─☑️─Feature 52: Find untagged tests
    └─✅─ExtractTestsFromFiles parses tests and issues from test dirs (#52, #201)
# Issue state: 📥 = open, ☑️ = closed (completed), ⛔ = closed (won't fix)
# Test disposition: ✅ = passed, ❌ = failed, 🚫 = skipped
✅ All tests passed

🟢 All issues have at least one test

🙈 2 issues with label "qcthat-nocov" were ignored


Completed Issues

✅ A qcthat issue test matrix with 4 milestones, 74 issues, and 203 tests
├─█─Milestone: ForTesting (1 issue, 1 test)
│ └─☑️─Technical Task 179: For Testing
│   └─✅─This package works for certain issues unconnected to actual features (#179)
├─█─Milestone: v0.2.0 (11 issues, 23 tests)
│ ├─☑️─Bug 61: Show "won't fix" for "duplicate"
│ │ └─✅─Issues closed as duplicates display the proper symbol (#61)
│ ├─☑️─Feature 60: Show summary of report
│ │ ├─✅─MakeKeyItem works (#60)
│ │ ├─✅─Printing an IssueTestMatrix outputs a user-friendly tree (#31, #36, #60, #85)
│ │ └─✅─Disposition indicators deal with all cases (#60)
│ ├─☑️─Technical Task 49: Unnest IssueTestMatrix for easier filtering
│ │ ├─✅─CompileIssueTestMatrix combines issues and test results into an IssueTestMatrix tibble (#35, #49)
│ │ ├─✅─Printing a generic qcthat_object returns input invisibly (#49)
│ │ ├─✅─FinalizeTree adds tree characters correctly (#49)
│ │ ├─✅─Printing a Milestone returns input invisibly (#49)
│ │ ├─✅─Printing a Milestone outputs a user-friendly tree (#49)
│ │ ├─✅─Printing a SingleIssueTestResults returns input invisibly (#49)
│ │ └─✅─Printing a SingleIssueTestResults outputs a user-friendly tree (#49)
│ ├─☑️─Bug 47: Fetch *all* repo issues
│ │ └─✅─FetchRepoIssues fetches all repo issues (#47)
│ ├─☑️─Bug 45: Deal with length-0 results
│ │ └─✅─ExtractDisposition() helper errors informatively for missing results within lTestResult object (#45)
│ ├─☑️─Technical Task 37: Package QC Report GHA
│ │ └─✅─Reports generated via GHA include information about the issues (#77, #37)
│ ├─☑️─Feature 36: Print IssueTestMatrix
│ │ └─✅─Printing an IssueTestMatrix outputs a user-friendly tree (#31, #36, #60, #85)
│ ├─☑️─Feature 35: Generate Issue-Test Matrix
│ │ ├─✅─CompileIssueTestMatrix returns an empty IssueTestMatrix with empty input (#35)
│ │ └─✅─CompileIssueTestMatrix combines issues and test results into an IssueTestMatrix tibble (#35, #49)
│ ├─☑️─Feature 34: Get repo issues
│ │ ├─✅─FetchRepoIssues returns an empty df when no issues found (#34)
│ │ └─✅─FetchRepoIssues returns a formatted df for real issues (#34)
│ ├─☑️─Feature 32: Extract test information from test results
│ │ ├─✅─CompileTestResults errors informatively for bad input (#32)
│ │ ├─✅─CompileTestResults works for empty testthat_results (#32)
│ │ ├─✅─CompileTestResults returns the expected object (#32)
│ │ ├─✅─ExtractDisposition() helper counts warnings as errors (#32)
│ │ └─✅─ExtractDisposition() helper errors informatively for weird results (#32)
│ └─☑️─Requirement 31: Generate package QC report
│   ├─✅─Printing an IssueTestMatrix returns input invisibly (#31)
│   └─✅─Printing an IssueTestMatrix outputs a user-friendly tree (#31, #36, #60, #85)
├─█─Milestone: v1.0.0 (19 issues, 61 tests)
│ ├─☑️─Technical Task 101: Switch `lglShowIgnoredLabels` default to TRUE
│ │ └─✅─Ignored issues are shown by default (#101)
│ ├─☑️─Bug 96: Don't include ignored labels in `QCIssues()` warnings
│ │ └─✅─QCIssues doesn't warn about ignored issues (#96)
│ ├─☑️─Bug 95: Install qcthat as part of Action installation
│ │ └─✅─qcthat is installed as part of the GHA (#95)
│ ├─☑️─Feature 90: Function to create qcthat-nocov label
│ │ ├─✅─CreateGHLabel reports success conditional on lglVerbose (#90)
│ │ ├─✅─CreateGHLabel throws an error if the API doesn't report the expected result (#90)
│ │ ├─✅─CreateGHLabel attempts to update existing label (#90)
│ │ ├─✅─MaybeUpdateGHLabel decides based on lglUpdate (#90)
│ │ ├─✅─UpdateGHLabel makes the expected call (#90)
│ │ ├─✅─UpdateGHLabel throws an error if the API doesn't report the expected result (#90)
│ │ ├─✅─EmptyLabelsDF returns the expected structure (#90)
│ │ ├─✅─EnframeGHLabels returns NULL for empty list (#90)
│ │ ├─✅─EnframeGHLabels converts raw labels to data frame (#90)
│ │ ├─✅─EnframeGHLabels adds hash to color codes (#90)
│ │ ├─✅─FetchGHLabelsRaw calls the correct API endpoint (#90)
│ │ ├─✅─FetchGHLabels returns empty data frame when no labels exist (#90)
│ │ ├─✅─FetchGHLabels returns data frame with labels (#90)
│ │ ├─✅─FetchGHLabelNames returns character vector of label names (#90)
│ │ ├─✅─FetchGHLabelNames returns empty character vector when no labels exist (#90)
│ │ ├─✅─Default helpers return expected values (#90)
│ │ ├─✅─SetupGHLabels creates missing labels (#90)
│ │ ├─✅─PrepareDFLabels normalizes correctly (#90)
│ │ ├─✅─Helper functions normalize strings correctly (#90)
│ │ └─✅─ValidateDFLabels checks for required columns (#90)
│ ├─☑️─Feature 88: Report by Milestone
│ │ ├─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
│ │ ├─✅─QCMilestones reports on specific milestones (#88, #68)
│ │ ├─✅─QCMilestones warns about unknown milestones (#88)
│ │ └─✅─QCMilestones errors with no valid milestones (#88)
│ ├─☑️─Feature 86: Function to report on specific issues
│ │ ├─✅─QCIssues reports on specific issues (#86)
│ │ ├─✅─QCIssues warns about unknown issues (#86)
│ │ └─✅─QCIssues errors with no valid issues (#86)
│ ├─☑️─Feature 85: Report Issue-Test Coverage in Footer
│ │ ├─✅─Printing an IssueTestMatrix outputs a user-friendly tree (#31, #36, #60, #85)
│ │ └─✅─MakeITRCoverageFooter deals with all cases (#85)
│ ├─☑️─Feature 84: Function(s) to filter report to issues associated with PR/branch
│ │ ├─✅─FetchRepoPRs returns an empty df when no issues found (#84)
│ │ ├─✅─FetchRepoPRs returns a formatted df for real PRs (#84)
│ │ ├─✅─GuessPRNumber delegates to its sub-functions (#84)
│ │ ├─✅─GetGHAPRNumber returns NULL for bad arg (#84, #163)
│ │ ├─✅─GetGHAPRNumber extracts PR number from lGHEventPayload when available (#84, #163)
│ │ ├─✅─GetGHAPRNumber returns NULL for bad extracted PR number (#84, #163)
│ │ ├─✅─FetchRefPRNumber fetches PR number for a branch (#84, #132)
│ │ ├─✅─QCMergeGH filters to merge-associated issues (#68, #84)
│ │ ├─✅─FetchMergeCommitSHAs returns unique, sorted SHAs (#84, #133)
│ │ ├─✅─FetchAllMergePRNumbers returns unique, sorted PR numbers (#84)
│ │ ├─✅─FetchAllMergePRNumbers returns empty vector for no matching PRs (#84)
│ │ ├─✅─QCMergeLocal filters to ref-specific issues (#68, #84)
│ │ ├─✅─FindKeywordIssues extracts issues that will be closed by commits (#84)
│ │ ├─✅─QCPR errors informatively for bad intPRNumber (#84)
│ │ ├─✅─QCPR filters to PR-related issues (#68, #84)
│ │ ├─✅─FetchPRRefs returns source and target refs (#84, #133, #149)
│ │ ├─✅─PrepareGQLQuery constructs a query (#84)
│ │ └─✅─GQLWrapper wraps a query correctly (#84)
│ ├─☑️─Requirement 81: Report issue test coverage
│ │ └─✅─Can report ignored issue counts (#67, #81)
│ ├─☑️─Feature 80: Filter main qcthat report to only "closed (completed)"
│ │ └─✅─QCCompletedIssues filters to completed issues (#80, #69)
│ ├─☑️─Bug 77: GHA-generated report stability
│ │ └─✅─Reports generated via GHA include information about the issues (#77, #37)
│ ├─☑️─Feature 73: Add qcthis.yaml to a package
│ │ ├─✅─InstallAction calls InstallFile with expected parts (#73)
│ │ ├─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
│ │ ├─✅─qcthatPath constructs paths (#73)
│ │ └─✅─InstallFile copies files as expected (#73)
│ ├─☑️─Technical Task 72: Add qc report to triggering PR as comment
│ │ └─✅─CommentReport generates the expected call (#99, #72)
│ ├─☑️─Requirement 69: Package QC Report Usability
│ │ ├─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
│ │ ├─✅─Can print without milestone info (#40, #69)
│ │ ├─✅─QCPackage wraps the core qcthat functions (#46, #69)
│ │ └─✅─QCCompletedIssues filters to completed issues (#80, #69)
│ ├─☑️─Requirement 68: PR/Branch Report
│ │ ├─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
│ │ ├─✅─QCMergeGH filters to merge-associated issues (#68, #84)
│ │ ├─✅─QCMergeLocal filters to ref-specific issues (#68, #84)
│ │ ├─✅─QCPR filters to PR-related issues (#68, #84)
│ │ └─✅─QCMilestones reports on specific milestones (#88, #68)
│ ├─☑️─Feature 67: Ignore issues with `qcthat-nocov` label
│ │ ├─✅─CompileIssueTestMatrix excludes issues in chrIgnoredLabels (#67)
│ │ ├─✅─ExtractDisposition() helper counts test errors as failures (#67)
│ │ └─✅─Can report ignored issue counts (#67, #81)
│ ├─☑️─Feature 55: GHA: Report of associated issues
│ │ └─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
│ ├─☑️─Feature 46: Wrapper to run everything
│ │ └─✅─QCPackage wraps the core qcthat functions (#46, #69)
│ └─☑️─Feature 40: Print Without Milestones
│   └─✅─Can print without milestone info (#40, #69)
└─█─Milestone: v1.1.0 (43 issues, 128 tests)
  ├─☑️─Requirement 233: AI Agent for qcthat Onboarding
  │ └─✅─Skill_TagTestsWithIssues targets the expected skill (#53, #233)
  ├─☑️─Bug 201: Provide full path in Skill-related functions
  │ ├─✅─ExtractTestsFromFiles parses tests and issues from test dirs (#52, #201)
  │ ├─✅─MapTestFilesToPotentialIssues finds potential issues via commits (#53, #201)
  │ ├─✅─MapTestsToCommits adds commit SHAs for each test (#53, #201)
  │ ├─✅─GetRelativePackagePath finds the relative path (#201)
  │ ├─✅─PrepareTestIssueContext passes parameters (#53, #201)
  │ └─✅─ReadTestCode reads test code from file (#53, #201)
  ├─☑️─Bug 200: Commits column of `MapRepoIssuesToCommits()` should expand to list of characters when empty
  │ └─✅─MapRepoIssuesToCommits handles empty input (#200)
  ├─☑️─Bug 199: Use upstream when available in `GetGHOwner()`
  │ └─✅─GetGHRemote uses upstream when available (#199)
  ├─☑️─Feature 198: Universal `Action_qcthat()` function
  │ └─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
  ├─☑️─Technical Task 181: Verify `qcthat.yaml` works for releases
  │ └─✅─AttachReleaseReports runs properly on release (#181)
  ├─☑️─Feature 172: Add timestamps to comments
  │ ├─✅─CommentIssue compiles the body as expected (#83, #172)
  │ └─✅─PrettyTimestamp works (#172)
  ├─☑️─Documentation Task 169: Deck draft 2: Final-ish
  │ └─✅─The pkgdown site has an intro slide deck (#166, #167, #168, #169)
  ├─☑️─Documentation Task 168: Draft the real slide deck
  │ └─✅─The pkgdown site has an intro slide deck (#166, #167, #168, #169)
  ├─☑️─Technical Task 167: Add a basic slide deck to pkgdown
  │ └─✅─The pkgdown site has an intro slide deck (#166, #167, #168, #169)
  ├─☑️─Requirement 166: Introduce {qcthat}
  │ └─✅─The pkgdown site has an intro slide deck (#166, #167, #168, #169)
  ├─☑️─Feature 165: Combined `CommentPRReports()` function
  │ ├─✅─FormatReportBody finalizes reports (#165)
  │ ├─✅─FormatReportType generates a report type (#165)
  │ ├─✅─CommentAllReports generates the expected calls (#165)
  │ ├─✅─All qcthat reports are combined in a single GHA (#129, #165, #152)
  │ ├─✅─GuessMilestones returns NULL for bad arg (#165)
  │ ├─✅─GuessMilestones extracts milestones from lGHEventPayload when available (#165)
  │ └─✅─GuessMilestones returns NULL for bad extracted milestones (#165)
  ├─☑️─Feature 164: Functions to manage envQcthat$UATIssues
  │ └─✅─SaveUATIssues saves UAT issues and LoadUATIssues loads them (#164)
  ├─☑️─Feature 163: Use GitHub Event for `GetGHAPRNumber()`
  │ ├─✅─GetGHAPRNumber returns NULL for bad arg (#84, #163)
  │ ├─✅─GetGHAPRNumber extracts PR number from lGHEventPayload when available (#84, #163)
  │ └─✅─GetGHAPRNumber returns NULL for bad extracted PR number (#84, #163)
  ├─☑️─Feature 162: GuessIssueNumber()
  │ ├─✅─GuessIssueNumber returns NULL for bad arg (#162)
  │ ├─✅─GuessIssueNumber extracts issue number from lGHEventPayload when available (#162)
  │ ├─✅─GuessIssueNumber returns NULL for bad extracted issue number (#162)
  │ ├─✅─LoadGHEventPayload returns NULL when envvar is empty (#162)
  │ ├─✅─LoadGHEventPayload returns NULL for bad path (#162)
  │ ├─✅─LoadGHEventPayload returns NULL for bad payload (#162)
  │ └─✅─LoadGHEventPayload returns the payload if it's readable (#162)
  ├─☑️─Feature 161: Single `use_qcthat()` function for all actions
  │ └─✅─use_qcthat calls the expected functions (#161)
  ├─☑️─Requirement 160: Improved QC Tracking for Releases
  │ └─✅─AttachReleaseReports makes the expected calls (#152, #160)
  ├─☑️─Feature 157: Automated UAT Verification Loop: Workflow
  │ ├─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
  │ └─✅─The UAT workflow triggers properly when all UAT issues connected to a PR are closed (#65, #157)
  ├─☑️─Feature 152: Add reports to release description (not as attachment)
  │ ├─✅─UpdateReleaseBody makes the expected call (#152)
  │ ├─✅─UpdateReleaseBody uses existing body if available (#152)
  │ ├─✅─AttachReleaseReports makes the expected calls (#152, #160)
  │ ├─✅─CompileReleaseReportsMarkdown stitches together parts for releases (#152)
  │ ├─✅─All qcthat reports are combined in a single GHA (#129, #165, #152)
  │ ├─✅─GuessReleaseID returns NULL for bad arg (#152)
  │ ├─✅─GuessReleaseID extracts release from lGHEventPayload when available (#152)
  │ ├─✅─GuessReleaseID converts tag name to release id when necessary (#152)
  │ └─✅─FetchRawReleaseByTagName generates the expected call (#152)
  ├─☑️─Feature 150: Link to GHA Run in Report
  │ ├─✅─CommentIssue includes run URL when available (#150)
  │ ├─✅─FetchRunURL returns the expected URL (#150)
  │ ├─✅─FetchRunJobsRaw makes the expected call (#150)
  │ ├─✅─FetchRunInfoRaw makes the expected call (#150)
  │ └─✅─CommentIssue includes session info (#150)
  ├─☑️─Bug 149: `QCPR()` should work after PRs are merged
  │ ├─✅─FetchAllMergeIssueNumbers returns unique, sorted issue numbers (#149)
  │ └─✅─FetchPRRefs returns source and target refs (#84, #133, #149)
  ├─☑️─Technical Task 146: Lower R Version Requirement
  │ └─✅─The required R version is within the normal support window (#146)
  ├─☑️─Bug 143: Properly reference qcthat in actions
  │ └─✅─qcthat is namespaced in GHA (#143)
  ├─☑️─Bug 141: Fix milestone action
  │ └─✅─Action_qcthat targets the expected action (#55, #68, #69, #73, #88, #141, #157, #198)
  ├─☑️─Bug 133: Big PRs fail to generate PR-associated issues report
  │ ├─✅─FetchRepoIssueClosers returns an empty df when no issues are found (#133)
  │ ├─✅─FetchRepoIssueClosers processes raw data correctly (#133)
  │ ├─✅─FetchRepoIssueClosersRaw processes pagination correctly (#133)
  │ ├─✅─IsIssueCloserFromRepo filters cross-repo PRs (#133)
  │ ├─✅─FetchRepoIssueClosersRawBatch generates the expected calls (#133)
  │ ├─✅─FetchMergeCommitSHAs returns unique, sorted SHAs (#84, #133)
  │ ├─✅─BuildCommitPRQuery builds the expected query (#133)
  │ ├─✅─FetchAllPRIssueNumbers returns unique, sorted issue numbers (#133)
  │ ├─✅─BuildPRIssuesQuery builds the expected query (#133)
  │ └─✅─FetchPRRefs returns source and target refs (#84, #133, #149)
  ├─☑️─Bug 132: Deal with multiple PRs
  │ ├─✅─FetchRefPRNumber fetches PR number for a branch (#84, #132)
  │ └─✅─ChooseRefPRNumber() deals with corner cases (#132)
  ├─☑️─Technical Task 129: Single qcthat GHA
  │ └─✅─All qcthat reports are combined in a single GHA (#129, #165, #152)
  ├─☑️─Requirement 123: Cleaner reports
  │ ├─✅─CommentIssue updates when told to do so (#83, #100, #123)
  │ └─✅─filter also removes ignored issues (#118, #123)
  ├─☑️─Feature 120: Don't attempt to create issues without proper permissions
  │ └─✅─CreateUAIssue returns NULL when it can't create an issue (#120)
  ├─☑️─Bug 118: Filter ignored issues in reports
  │ └─✅─filter also removes ignored issues (#118, #123)
  ├─☑️─Technical Task 116: Bust gh cache for child issues
  │ └─✅─CreateRepoIssueRaw clears the cache when an issue is created (#116)
  ├─☑️─Feature 115: PR UAT Dashboard
  │ ├─✅─CommentUAT generates the expected call with 0 pending issues (#115)
  │ ├─✅─CommentUAT generates the expected call (#115)
  │ └─✅─LogUAT logs UAT status (#115)
  ├─☑️─Feature 114: Automated UAT Verification Loop: R side
  │ ├─✅─FetchAllIssuePRRefs returns correct PR information (#114)
  │ ├─✅─FetchAllIssuePRRefs filters by state correctly (#114)
  │ ├─✅─FetchAllIssuePRRefsRaw generates the expected calls (#114)
  │ ├─✅─BuildIssuePRRefsQuery generates correct GQL (#114)
  │ ├─✅─TriggerUAT calls MaybeRerunAllQCPRWorkflows if open PRs exist (#114)
  │ ├─✅─TriggerUAT does nothing if no open PRs exist (#114)
  │ ├─✅─MaybeRerunAllQCPRWorkflows triggers rerun if conditions met (#114)
  │ ├─✅─FetchPRUATCommentIssues extracts issues correctly (#114)
  │ ├─✅─MaybeRerunQCPRWorkflow delegates to RerunWorkflowIfFinished (#114)
  │ ├─✅─MaybeRerunQCPRWorkflow does nothing if no runs found (#114)
  │ ├─✅─FetchPRActionRuns calls API and filters correctly (#114)
  │ ├─✅─RerunWorkflowIfFinished reruns only if none in progress (#114)
  │ ├─✅─RerunWorkflowAtSHA picks correct run (#114)
  │ └─✅─RerunWorkflow calls API correctly (#114)
  ├─☑️─Technical Task 113: Add infrastructure to detect where the tests are happening
  │ ├─✅─OnCran returns FALSE when envvar unset or true (#113)
  │ └─✅─OnCran returns TRUE when envvar set to false (#113)
  ├─☑️─Technical Task 112: Create condition infrastructure
  │ ├─✅─CompileConditionClasses compiles classes as expected (#112)
  │ └─✅─qcthatAbort creates an error condition with expected classes and message (#112)
  ├─☑️─Feature 111: Minimal User-Acceptance Testing Framework
  │ ├─✅─CreateUAIssue constructs the expected call (#111)
  │ ├─✅─CreateChildIssue uses the expected process (#111)
  │ ├─✅─CreateRepoIssueRaw hits the expected endpoint (#111)
  │ ├─✅─ConnectChildIssueByID returns the URL to the parent (#111)
  │ ├─✅─ExpectUserAccepts returns the input strDescription (#111)
  │ ├─✅─ExpectUserAccepts passes when the issue is closed (#65, #111)
  │ ├─✅─ExpectUserAccepts fails when the issue isn't closed and strFailureMode is 'fail' (#65, #111)
  │ ├─✅─ExpectUserAccepts returns silently when the issue isn't closed and lglIgnore is TRUE (#111)
  │ ├─✅─IsCheckingUAT reports whether the qcthat_UAT envvar is true (#111)
  │ ├─✅─FetchUAIssue returns the issue as a list if found (#111)
  │ ├─✅─FetchUAIssue returns the issue as a list if created (#111)
  │ ├─✅─FetchIssueUAChildren fetches 'qcthat-uat'-labeled child issues (#111)
  │ ├─✅─FetchIssueChildren returns a DF of issue children (#111)
  │ └─✅─TitleUAIssue gives the expected title (#111)
  ├─☑️─Feature 110: Export GitHub Helpers
  │ ├─✅─GetGHOwner and GetGHRepo work (#110)
  │ └─✅─UsesGit works in any situation (#110)
  ├─☑️─Technical Task 100: Update report comments
  │ └─✅─CommentIssue updates when told to do so (#83, #100, #123)
  ├─☑️─Technical Task 99: Better print of footer on GitHub
  │ └─✅─CommentReport generates the expected call (#99, #72)
  ├─☑️─Feature 83: Comment on GH PR or issue
  │ ├─✅─Additional user acceptance sub-issue is generated in the qcthat User Acceptance report (#83)
  │ ├─✅─CommentIssue compiles the body as expected (#83, #172)
  │ ├─✅─CommentIssue updates when told to do so (#83, #100, #123)
  │ ├─✅─UpdateIssueComment updates when a comment exists (#83)
  │ ├─✅─UpdateIssueComment creates when a comment doesn't exist (#83)
  │ ├─✅─FetchIssueCommentGHID returns the correct GH ID when found (#83)
  │ ├─✅─FetchIssueCommentGHID returns nothing when no matching comment found (#83)
  │ ├─✅─UpdateCommentRaw calls the API as expected (#83)
  │ ├─✅─CommentIssueRaw calls the API as expected (#83)
  │ ├─✅─CommentIssue updates a comment as expected (#83)
  │ ├─✅─FetchIssueComments returns an empty df when no issues found (#83)
  │ └─✅─FetchIssueComments returns a formatted df for real issues (#83)
  ├─☑️─Requirement 65: Track user (manual) testing
  │ ├─✅─ExpectUserAccepts passes when the issue is closed (#65, #111)
  │ ├─✅─ExpectUserAccepts fails when the issue isn't closed and strFailureMode is 'fail' (#65, #111)
  │ └─✅─The UAT workflow triggers properly when all UAT issues connected to a PR are closed (#65, #157)
  ├─☑️─Feature 53: Find issues associated with tests
  │ ├─✅─FetchIssueDetails fetches issue details (#53)
  │ ├─✅─FetchIssueDetails handles empty input (#53)
  │ ├─✅─FetchIssueDetails deduplicates API calls but preserves order (#53)
  │ ├─✅─FetchIssueDetails passes GitHub parameters (#53)
  │ ├─✅─MapRepoIssuesToCommits handles commit closers (#53)
  │ ├─✅─MapRepoIssuesToCommits handles PR closers (#53)
  │ ├─✅─MapRepoIssuesToCommits handles mixed closers (#53)
  │ ├─✅─MapTestFilesToPotentialIssues finds potential issues via commits (#53, #201)
  │ ├─✅─MapTestFilesToPotentialIssues filters out tests tagged with #noissue (#53)
  │ ├─✅─MapTestFilesToPotentialIssues handles tests with no matching commits (#53)
  │ ├─✅─MapTestFilesToPotentialIssues handles tests with tagged issues (#53)
  │ ├─✅─MapTestsToCommits adds commit SHAs for each test (#53, #201)
  │ ├─✅─PrepareTestIssueContext enriches test data (#53)
  │ ├─✅─PrepareTestIssueContext handles empty input (#53)
  │ ├─✅─PrepareTestIssueContext passes parameters (#53, #201)
  │ ├─✅─ReadTestCode reads test code from file (#53, #201)
  │ ├─✅─ReadTestCode fails for invalid ranges (#53)
  │ ├─✅─InstallSkill calls InstallFile with expected parts (#53)
  │ └─✅─Skill_TagTestsWithIssues targets the expected skill (#53, #233)
  └─☑️─Feature 52: Find untagged tests
    └─✅─ExtractTestsFromFiles parses tests and issues from test dirs (#52, #201)
# Issue state: 📥 = open, ☑️ = closed (completed), ⛔ = closed (won't fix)
# Test disposition: ✅ = passed, ❌ = failed, 🚫 = skipped
✅ All tests passed

🟢 All issues have at least one test

🙈 15 issues with label "qcthat-nocov" were ignored; 14 issues with label "qcthat-uat" were ignored


This report was generated by this GitHub Actions run.

Last updated: 2026-02-24 15:16:05 UTC

Session Info ─ Session info ───────────────────────────────────────────────────────────────

setting value

version R version 4.5.2 (2025-10-31)

os Ubuntu 24.04.3 LTS

system x86_64, linux-gnu

ui X11

language (EN)

collate C.UTF-8

ctype C.UTF-8

tz UTC

date 2026-02-24

pandoc NA

quarto 1.8.27 @ /usr/local/bin/quarto

─ Packages ───────────────────────────────────────────────────────────────────

package * version date (UTC) lib source

askpass 1.2.1 2024-10-04 [1] RSPM

base * 4.5.2 2025-10-31 [3] local

base64enc 0.1-6 2026-02-02 [1] RSPM

boot 1.3-32 2025-08-29 [3] CRAN (R 4.5.2)

brio 1.1.5 2024-04-24 [1] RSPM

bslib 0.10.0 2026-01-26 [1] RSPM

cachem 1.1.0 2024-05-16 [1] RSPM

callr 3.7.6 2024-03-25 [1] RSPM

class 7.3-23 2025-01-01 [3] CRAN (R 4.5.2)

cli 3.6.5 2025-04-23 [1] RSPM

clipr 0.8.0 2022-02-22 [1] RSPM

cluster 2.1.8.1 2025-03-12 [3] CRAN (R 4.5.2)

codetools 0.2-20 2024-03-31 [3] CRAN (R 4.5.2)

compiler 4.5.2 2025-10-31 [3] local

crayon 1.5.3 2024-06-20 [1] RSPM

credentials 2.0.3 2025-09-12 [1] RSPM

curl 7.0.0 2025-08-19 [1] RSPM

datasets * 4.5.2 2025-10-31 [3] local

desc 1.4.3 2023-12-10 [1] RSPM

diffobj 0.3.6 2025-04-21 [1] RSPM

digest 0.6.39 2025-11-19 [1] RSPM

downlit 0.4.5 2025-11-14 [1] RSPM

dplyr 1.2.0 2026-02-03 [1] RSPM

emoji 16.0.0 2024-10-28 [1] RSPM

evaluate 1.0.5 2025-08-27 [1] RSPM

fansi 1.0.7 2025-11-19 [1] RSPM

fastmap 1.2.0 2024-05-15 [1] RSPM

fontawesome 0.5.3 2024-11-16 [1] RSPM

foreign 0.8-90 2025-03-31 [3] CRAN (R 4.5.2)

fs 1.6.6 2025-04-12 [1] RSPM

generics 0.1.4 2025-05-09 [1] RSPM

gert 2.3.1 2026-01-11 [1] RSPM

gh 1.5.0 2025-05-26 [1] RSPM

git2r 0.36.2 2025-03-29 [1] RSPM

gitcreds 0.1.2 2022-09-08 [1] RSPM

glue 1.8.0 2024-09-30 [1] RSPM

graphics * 4.5.2 2025-10-31 [3] local

grDevices * 4.5.2 2025-10-31 [3] local

grid 4.5.2 2025-10-31 [3] local

highr 0.11 2024-05-26 [1] RSPM

htmltools 0.5.9 2025-12-04 [1] RSPM

httr2 1.2.2 2025-12-08 [1] RSPM

ini 0.3.1 2018-05-20 [1] RSPM

jquerylib 0.1.4 2021-04-26 [1] RSPM

jsonlite 2.0.0 2025-03-27 [1] RSPM

KernSmooth 2.23-26 2025-01-01 [3] CRAN (R 4.5.2)

knitr 1.51 2025-12-20 [1] RSPM

later 1.4.6 2026-02-13 [1] RSPM

lattice 0.22-7 2025-04-02 [3] CRAN (R 4.5.2)

lifecycle 1.0.5 2026-01-08 [1] RSPM

magrittr 2.0.4 2025-09-12 [1] RSPM

MASS 7.3-65 2025-02-28 [3] CRAN (R 4.5.2)

Matrix 1.7-4 2025-08-28 [3] CRAN (R 4.5.2)

memoise 2.0.1 2021-11-26 [1] RSPM

methods * 4.5.2 2025-10-31 [3] local

mgcv 1.9-3 2025-04-04 [3] CRAN (R 4.5.2)

mime 0.13 2025-03-17 [1] RSPM

nlme 3.1-168 2025-03-31 [3] CRAN (R 4.5.2)

nnet 7.3-20 2025-01-01 [3] CRAN (R 4.5.2)

openssl 2.3.4 2025-09-30 [1] RSPM

pak 0.9.2 2026-01-07 [2] local

parallel 4.5.2 2025-10-31 [3] local

pillar 1.11.1 2025-09-17 [1] RSPM

pkgbuild 1.4.8 2025-05-26 [1] RSPM

pkgconfig 2.0.3 2019-09-22 [1] RSPM

pkgdown 2.2.0 2025-11-06 [1] any (@2.2.0)

pkgload 1.5.0 2026-02-03 [1] RSPM

praise 1.0.0 2015-08-11 [1] RSPM

processx 3.8.6 2025-02-21 [1] RSPM

ps 1.9.1 2025-04-12 [1] RSPM

purrr 1.2.1 2026-01-09 [1] RSPM

qcthat 1.1.0 2026-02-24 [1] local

quarto 1.5.1 2025-09-04 [1] RSPM

R6 2.6.1 2025-02-15 [1] RSPM

ragg 1.5.0 2025-09-02 [1] RSPM

rappdirs 0.3.4 2026-01-17 [1] RSPM

Rcpp 1.1.1 2026-01-10 [1] RSPM

rlang 1.1.7 2026-01-09 [1] RSPM

rmarkdown 2.30 2025-09-28 [1] RSPM

rpart 4.1.24 2025-01-07 [3] CRAN (R 4.5.2)

rprojroot 2.1.1 2025-08-26 [1] RSPM

rstudioapi 0.18.0 2026-01-16 [1] RSPM

sass 0.4.10 2025-04-11 [1] RSPM

sessioninfo 1.2.3 2025-02-05 [1] any (@1.2.3)

spatial 7.3-18 2025-01-01 [3] CRAN (R 4.5.2)

splines 4.5.2 2025-10-31 [3] local

stats * 4.5.2 2025-10-31 [3] local

stats4 4.5.2 2025-10-31 [3] local

stringi 1.8.7 2025-03-27 [1] RSPM

stringr 1.6.0 2025-11-04 [1] RSPM

survival 3.8-3 2024-12-17 [3] CRAN (R 4.5.2)

sys 3.4.3 2024-10-04 [1] RSPM

systemfonts 1.3.1 2025-10-01 [1] RSPM

tcltk 4.5.2 2025-10-31 [3] local

testthat 3.3.2 2026-01-11 [1] RSPM

textshaping 1.0.4 2025-10-10 [1] RSPM

tibble 3.3.1 2026-01-11 [1] RSPM

tidyr 1.3.2 2025-12-19 [1] RSPM

tidyselect 1.2.1 2024-03-11 [1] RSPM

tinytex 0.58 2025-11-19 [1] RSPM

tools 4.5.2 2025-10-31 [3] local

usethis 3.2.1 2025-09-06 [1] RSPM

utf8 1.2.6 2025-06-08 [1] RSPM

utils * 4.5.2 2025-10-31 [3] local

vctrs 0.7.1 2026-01-23 [1] RSPM

waldo 0.6.2 2025-07-11 [1] RSPM

whisker 0.4.1 2022-12-05 [1] RSPM

withr 3.0.2 2024-10-28 [1] RSPM

xfun 0.56 2026-01-18 [1] RSPM

xml2 1.5.2 2026-01-17 [1] RSPM

yaml 2.3.12 2025-12-10 [1] RSPM

zip 2.3.3 2025-05-13 [1] RSPM

[1] /home/runner/work/_temp/Library

[2] /opt/R/4.5.2/lib/R/site-library

[3] /opt/R/4.5.2/lib/R/library

  • ── Packages attached to the search path.

──────────────────────────────────────────────────────────────────────────────