Skip to content

v1.1.2

Choose a tag to compare

@lauramaxwell lauramaxwell released this 20 Mar 16:54
d0958dc

Overview

This patch release focuses on introducing the world to qcthat.

Documentation improvements

  • Two new vignettes have been added, vignette("qcthat") and vignette("business_process"). They were split off and refined from information that was previously in the README (#98, #236).
  • The slide deck on the pkgdown site has been finalized ahead of PHUSE US Connect 2026 (#170).

Bug fixes

  • Warnings in tests now produce warnings rather than errors (#130).
  • Tests are no longer double-counted when they are associated with multiple issues (#180).

What's Changed

Full Changelog: v1.1.1...v1.1.2

{qcthat} Reports

Milestone

✅ A qcthat issue test matrix with 1 milestone, 5 issues, and 6 tests
└─█─Milestone: v1.1.2 (5 issues, 6 tests)
  ├─☑️─Documentation Task 236: Update README
  │ └─✅─README is straightforward (#236)
  ├─☑️─Bug 180: Better Test Counts
  │ └─✅─Test failure counts make sense (#180, #31)
  ├─☑️─Documentation Task 170: Final deck draft
  │ └─✅─The intro slide deck is ready to present (#170)
  ├─☑️─Bug 130: Warn for warnings
  │ ├─✅─CompileTestResults returns the expected object (#32, #130)
  │ └─✅─ExtractDisposition() helper counts warnings as warnings (#130)
  └─☑️─Documentation Task 98: Vignette: Getting Started
    └─✅─There's a vignette about getting started (#98)
# Issue state: 📥 = open, ☑️ = closed (completed), ⛔ = closed (won't fix)
# Test disposition: ✅ = passed, ❌ = failed, 🚫 = skipped
✅ All tests passed

🟢 All issues have at least one test


Completed Issues

✅ A qcthat issue test matrix with 7 milestones, 89 issues, and 252 tests
├─█─Milestone: ForTesting (1 issue, 1 test)
│ └─☑️─Technical Task 179: For Testing
│   └─✅─This package works for certain issues unconnected to actual features (#179)
├─█─Milestone: implementation (1 issue, 27 tests)
│ └─☑️─Feature 265: Add code context for tests
│   ├─✅─MapCoveredLinesToPotentialIssues maps source blame to issues (#265)
│   ├─✅─MapCoveredLinesToPotentialIssues handles empty input (#265)
│   ├─✅─MergePotentialIssues unions and deduplicates (#265)
│   ├─✅─MergePotentialIssues handles one empty side (#265)
│   ├─✅─MapTestFilesToPotentialIssues handles empty test directory (#265)
│   ├─✅─MapTestFilesToPotentialIssues handles all tests tagged with #noissue (#265)
│   ├─✅─MapTestFilesToPotentialIssues passes strTestDir parameter (#265)
│   ├─✅─MapTestFilesToPotentialIssues passes GitHub parameters (#265)
│   ├─✅─MapTestFilesToPotentialIssues merges source coverage issues when lglUseCoverage = TRUE (#265)
│   ├─✅─AugmentPotentialIssuesFromCoverage() passes strTestDir to LoadPkgEnv (#265)
│   ├─✅─AugmentPotentialIssuesFromCoverage() merges coverage issues with commit-based issues (#265)
│   ├─✅─ReadTestFileContents reads unique files into named list (#265)
│   ├─✅─ExtractTestWithPreamble includes preamble before first test (#265)
│   ├─✅─ExtractTestWithPreamble works when test starts at line 1 (#265)
│   ├─✅─NormalizeTallyPaths converts absolute paths to relative (#265)
│   ├─✅─CoverSingleTest returns covered lines from tally (#265)
│   ├─✅─CoverSingleTest returns NULL when no lines are covered (#265)
│   ├─✅─CoverSingleTest returns NULL on error (#265)
│   ├─✅─SetupTempSnapDir copies snapshot file to temp dir (#265)
│   ├─✅─SetupTempSnapDir works when no snapshot file exists (#265)
│   ├─✅─ExtractAllTestCode extracts code for all tests (#265)
│   ├─✅─ExtractAllTestCode handles namespaced and indented test_that (#265)
│   ├─✅─WriteAllTempTestFiles writes all files and returns paths (#265)
│   ├─✅─MapTestsToCoveredLines returns per-test covered lines (#265)
│   ├─✅─MapTestsToCoveredLines skips noissue tests (#265)
│   ├─✅─MapTestsToCoveredLines handles empty dfFileTests (#265)
│   └─✅─MapTestsToCoveredLines handles test with no coverage (#265)
├─█─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 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, #130)
│ │ └─✅─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)
│ │ └─✅─Test failure counts make sense (#180, #31)
│ ├─☑️─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)
├─█─Milestone: v1.0.0 (19 issues, 59 tests)
│ ├─☑️─Technical Task 101: Switch `lglShowIgnoredLabels` default to TRUE
│ │ └─✅─Ignored issues are shown by default (#101)
│ ├─☑️─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)
│ ├─☑️─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)
│ │ ├─✅─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
│ │ ├─✅─FetchMergeCommitSHAs returns unique, sorted SHAs (#84, #133)
│ │ ├─✅─FetchAllMergePRNumbers returns unique, sorted PR numbers (#84)
│ │ ├─✅─FetchAllMergePRNumbers returns empty vector for no matching PRs (#84)
│ │ ├─✅─FetchPRRefs returns source and target refs (#84, #133, #149)
│ │ ├─✅─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)
│ │ ├─✅─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)
│ │ ├─✅─PrepareGQLQuery constructs a query (#84)
│ │ └─✅─GQLWrapper wraps a query correctly (#84)
│ └─☑️─Requirement 81: Report issue test coverage
│   └─✅─Can report ignored issue counts (#67, #81)
├─█─Milestone: v1.1.0 (43 issues, 128 tests)
│ ├─☑️─Requirement 233: AI Agent for qcthat Onboarding
│ │ └─✅─Skill_TagTestsWithIssues targets the expected skill (#53, #233, #241)
│ ├─☑️─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)
│ ├─☑️─Bug 201: Provide full path in Skill-related functions
│ │ ├─✅─ExtractTestsFromFiles parses tests and issues from test dirs (#52, #201, #257)
│ │ ├─✅─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)
│ ├─☑️─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
│ │ ├─✅─FetchMergeIssueClosers 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
│ │ ├─✅─FetchMergeCommitSHAs returns unique, sorted SHAs (#84, #133)
│ │ ├─✅─BuildCommitPRQuery builds the expected query (#133)
│ │ ├─✅─BuildPRIssuesQuery builds the expected query (#133)
│ │ ├─✅─FetchAllPRIssueNumbers returns unique, sorted issue numbers (#133)
│ │ ├─✅─FetchPRRefs returns source and target refs (#84, #133, #149)
│ │ ├─✅─FetchRepoIssueClosers returns an empty df when no issues are found (#133)
│ │ ├─✅─FetchRepoIssueClosers processes raw data correctly (#133)
│ │ ├─✅─FetchRepoIssueClosersRaw processes pagination correctly (#133)
│ │ ├─✅─IsTimelineNodeFromRepo filters cross-repo ClosedEvent PRs (#133)
│ │ └─✅─FetchRepoIssueClosersRawBatch generates the expected calls (#133)
│ ├─☑️─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 special list when it can't create an issue (#120)
│ ├─☑️─Bug 200: Commits column of `MapRepoIssuesToCommits()` should expand to list of characters when empty
│ │ └─✅─MapRepoIssuesToCommits handles empty input (#200)
│ ├─☑️─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, #185)
│ │ └─✅─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 is open (#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)
│ ├─☑️─Bug 199: Use upstream when available in `GetGHOwner()`
│ │ └─✅─GetGHRemote uses upstream when available (#199)
│ ├─☑️─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 is open (#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, #251)
│ │ ├─✅─MapRepoIssuesToCommits handles mixed closers (#53, #251)
│ │ ├─✅─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, #241)
│ ├─☑️─Feature 52: Find untagged tests
│ │ └─✅─ExtractTestsFromFiles parses tests and issues from test dirs (#52, #201, #257)
│ ├─☑️─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)
├─█─Milestone: v1.1.1 (9 issues, 25 tests)
│ ├─☑️─Technical Task 257: Use astgrepr for test parsing
│ │ ├─✅─ExtractTestsFromFiles parses tests and issues from test dirs (#52, #201, #257)
│ │ └─✅─FindTests finds tests using testthat:: namespace prefix (#247, #257)
│ ├─☑️─Bug 251: Find more issue-test links via blame
│ │ ├─✅─FetchAllPRCommitSHAs returns empty list for empty input (#251)
│ │ ├─✅─FetchAllPRCommitSHAs batches PRs and returns one element per PR (#251)
│ │ ├─✅─MapRepoIssuesToCommits handles PR closers (#53, #251)
│ │ ├─✅─MapRepoIssuesToCommits handles mixed closers (#53, #251)
│ │ └─✅─MapRepoIssuesToCommits passes GitHub parameters to FetchAllPRCommitSHAs (#251)
│ ├─☑️─Bug 248: Properly get remotes with dots
│ │ └─✅─GetGHRemote handles dots in repo names (#248)
│ ├─☑️─Bug 247: Include namespaced tests in `ExtractTestsFromFiles()`
│ │ └─✅─FindTests finds tests using testthat:: namespace prefix (#247, #257)
│ ├─☑️─Bug 243: Fetch all repo issue closers
│ │ ├─✅─FetchRepoIssueClosers filters cross-repo events within a mixed-repo issue (#243)
│ │ ├─✅─IsTimelineNodeFromRepo filters ConnectedEvent and DisconnectedEvent by repo (#243)
│ │ ├─✅─TibblifyIssueCloser returns NULL for non-Commit/PR closers like ProjectV2 (#243)
│ │ ├─✅─TibblifyIssueCloser treats ConnectedEvent with merged PR as a closer (#243)
│ │ ├─✅─TibblifyIssueCloser annihilates ConnectedEvent with subsequent DisconnectedEvent (#243)
│ │ ├─✅─TibblifyIssueCloser handles partial annihilation with multiple ConnectedEvents (#243)
│ │ ├─✅─FetchRepoIssueClosers skips non-tibblifiable closers and returns all valid closers (#243)
│ │ └─✅─FetchRepoIssueClosers returns all valid closers when an issue has multiple (#243)
│ ├─☑️─Requirement 241: Improve the Test-Tagging Skill
│ │ └─✅─Skill_TagTestsWithIssues targets the expected skill (#53, #233, #241)
│ ├─☑️─Bug 230: Don't create extra UAT issues
│ │ ├─✅─FormatUATGH works for errors (#137, #185, #230)
│ │ ├─✅─ExpectUserAccepts errors when online but GitHub fetch fails (#230)
│ │ ├─✅─CompileIssuesDF errors for bad gh response (#230)
│ │ └─✅─FetchUAIssue returns closed child if multiple children (#230)
│ ├─☑️─Feature 185: Show all UAT items in UAT comment
│ │ ├─✅─CommentUAT generates the expected call (#115, #185)
│ │ ├─✅─FormatUATGH works for errors (#137, #185, #230)
│ │ └─✅─CommentUAT includes accepted UAT for this PR (#185)
│ └─☑️─Bug 137: {qcthat} Report: User Acceptance should indicate if the issue couldn't be created
│   ├─✅─FormatUATGH works for errors (#137, #185, #230)
│   ├─✅─ExpectUserAccepts fails when the child issue can't be created (#137)
│   └─✅─ExpectUserAccepts fails when weird things happen (#137)
└─█─Milestone: v1.1.2 (5 issues, 6 tests)
  ├─☑️─Documentation Task 236: Update README
  │ └─✅─README is straightforward (#236)
  ├─☑️─Bug 180: Better Test Counts
  │ └─✅─Test failure counts make sense (#180, #31)
  ├─☑️─Documentation Task 170: Final deck draft
  │ └─✅─The intro slide deck is ready to present (#170)
  ├─☑️─Bug 130: Warn for warnings
  │ ├─✅─CompileTestResults returns the expected object (#32, #130)
  │ └─✅─ExtractDisposition() helper counts warnings as warnings (#130)
  └─☑️─Documentation Task 98: Vignette: Getting Started
    └─✅─There's a vignette about getting started (#98)
# Issue state: 📥 = open, ☑️ = closed (completed), ⛔ = closed (won't fix)
# Test disposition: ✅ = passed, ❌ = failed, 🚫 = skipped
✅ All tests passed

🟢 All issues have at least one test

🙈 18 issues with label "qcthat-nocov" were ignored; 20 issues with label "qcthat-uat" were ignored


This report was generated by this GitHub Actions run.

Last updated: 2026-03-20 16:56:14 UTC

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

setting value

version R version 4.5.3 (2026-03-11)

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-03-20

pandoc 3.1.3 @ /usr/bin/pandoc

quarto 1.9.36 @ /usr/local/bin/quarto

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

package * version date (UTC) lib source

askpass 1.2.1 2024-10-04 [1] RSPM

astgrepr 0.1.1 2025-06-07 [1] RSPM

backports 1.5.0 2024-05-23 [1] RSPM

base * 4.5.3 2026-03-11 [3] local

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

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

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

checkmate 2.3.4 2026-02-03 [1] RSPM

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

cli 3.6.5 2025-04-23 [1] RSPM

clipr 0.8.0 2022-02-22 [1] RSPM

cluster 2.1.8.2 2026-02-05 [3] CRAN (R 4.5.3)

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

compiler 4.5.3 2026-03-11 [3] local

covr 3.6.5 2025-11-09 [1] RSPM

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.3 2026-03-11 [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-91 2026-01-29 [3] CRAN (R 4.5.3)

fs 1.6.7 2026-03-06 [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.3 2026-03-11 [3] local

grDevices * 4.5.3 2026-03-11 [3] local

grid 4.5.3 2026-03-11 [3] local

highr 0.12 2026-03-06 [1] RSPM

htmltools 0.5.9 2025-12-04 [1] RSPM

httr 1.4.8 2026-02-13 [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.3)

knitr 1.51 2025-12-20 [1] RSPM

later 1.4.8 2026-03-05 [1] RSPM

lattice 0.22-9 2026-02-09 [3] CRAN (R 4.5.3)

lazyeval 0.2.2 2019-03-15 [1] RSPM

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.3)

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

memoise 2.0.1 2021-11-26 [1] RSPM

methods * 4.5.3 2026-03-11 [3] local

mgcv 1.9-4 2025-11-07 [3] CRAN (R 4.5.3)

mime 0.13 2025-03-17 [1] RSPM

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

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

openssl 2.3.5 2026-02-26 [1] RSPM

pak 0.9.2 2026-01-07 [2] local

parallel 4.5.3 2026-03-11 [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.2 2026-03-20 [1] local

quarto 1.5.1 2025-09-04 [1] RSPM

R6 2.6.1 2025-02-15 [1] RSPM

ragg 1.5.1 2026-03-06 [1] RSPM

rappdirs 0.3.4 2026-01-17 [1] RSPM

Rcpp 1.1.1 2026-01-10 [1] RSPM

rex 1.2.1 2021-11-26 [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.3)

rprojroot 2.1.1 2025-08-26 [1] RSPM

rrapply 1.2.8 2025-11-25 [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] RSPM

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

splines 4.5.3 2026-03-11 [3] local

stats * 4.5.3 2026-03-11 [3] local

stats4 4.5.3 2026-03-11 [3] local

stringi 1.8.7 2025-03-27 [1] RSPM

stringr 1.6.0 2025-11-04 [1] RSPM

survival 3.8-6 2026-01-16 [3] CRAN (R 4.5.3)

sys 3.4.3 2024-10-04 [1] RSPM

systemfonts 1.3.2 2026-03-05 [1] RSPM

tcltk 4.5.3 2026-03-11 [3] local

testthat 3.3.2 2026-01-11 [1] RSPM

textshaping 1.0.5 2026-03-06 [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.3 2026-03-11 [3] local

usethis 3.2.1 2025-09-06 [1] RSPM

utf8 1.2.6 2025-06-08 [1] RSPM

utils * 4.5.3 2026-03-11 [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.3/lib/R/site-library

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

  • ── Packages attached to the search path.

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