Skip to content

Commit 499d903

Browse files
authored
Remove special tibblify version checks (#104)
Also apply air, and update workflows
1 parent 9a1a731 commit 499d903

34 files changed

Lines changed: 491 additions & 191 deletions

.Rbuildignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@
1414
^\.positai$
1515
^\.claude$
1616
^AGENTS\.md$
17+
^[.]?air[.]toml$
18+
^\.vscode$

.github/workflows/copilot-setup-steps.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ jobs:
4545
any::testthat
4646
any::usethis
4747
any::withr
48+
Gilead-BioStats/qcthat
4849
local::.
4950
5051
- name: Install air
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Workflow derived from https://github.com/posit-dev/setup-air/tree/main/examples
2+
3+
on:
4+
# Using `pull_request_target` over `pull_request` for elevated `GITHUB_TOKEN`
5+
# privileges, otherwise we can't set `pull-requests: write` when the pull
6+
# request comes from a fork, which is our main use case (external contributors).
7+
#
8+
# `pull_request_target` runs in the context of the target branch (`main`, usually),
9+
# rather than in the context of the pull request like `pull_request` does. Due
10+
# to this, we must explicitly checkout `ref: ${{ github.event.pull_request.head.sha }}`.
11+
# This is typically frowned upon by GitHub, as it exposes you to potentially running
12+
# untrusted code in a context where you have elevated privileges, but they explicitly
13+
# call out the use case of reformatting and committing back / commenting on the PR
14+
# as a situation that should be safe (because we aren't actually running the untrusted
15+
# code, we are just treating it as passive data).
16+
# https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
17+
pull_request_target:
18+
19+
name: format-suggest.yaml
20+
21+
jobs:
22+
format-suggest:
23+
name: format-suggest
24+
runs-on: ubuntu-latest
25+
26+
permissions:
27+
# Required to push suggestion comments to the PR
28+
pull-requests: write
29+
30+
steps:
31+
- uses: actions/checkout@v6
32+
with:
33+
ref: ${{ github.event.pull_request.head.sha }}
34+
35+
- name: Install
36+
uses: posit-dev/setup-air@v1
37+
38+
- name: Format
39+
run: air format .
40+
41+
- name: Suggest
42+
uses: reviewdog/action-suggester@v1
43+
with:
44+
level: error
45+
fail_level: error
46+
tool_name: air
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# This workflow removes the pkgdown preview directory when a PR is closed.
2+
name: Clean up pkgdown preview
3+
4+
on:
5+
pull_request:
6+
types: [closed]
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
clean-pr-preview:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout gh-pages branch
16+
uses: actions/checkout@v6
17+
with:
18+
repository: ${{ github.repository }}
19+
token: ${{ secrets.GITHUB_TOKEN }}
20+
ref: gh-pages
21+
22+
- name: Remove PR preview directory
23+
run: |
24+
pr_dir="pr/${{ github.event.number }}"
25+
if [ -d "$pr_dir" ]; then
26+
git config --local user.name "$GITHUB_ACTOR"
27+
git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com"
28+
git rm -rf "$pr_dir"
29+
git commit -m "Remove preview for PR #${{ github.event.number }}"
30+
git push
31+
else
32+
echo "Directory $pr_dir does not exist, skipping cleanup."
33+
fi

.github/workflows/pkgdown.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
use-container: "true"
3333
token: ${{ secrets.GITHUB_TOKEN }}
3434
needs: website
35-
extra-packages: any::pkgdown gilead-biostats/qcthat local::.
35+
extra-packages: any::pkgdown gilead-biostats/qcthat local::. any::glue
3636

3737
- name: Build site
3838
run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
@@ -54,7 +54,7 @@ jobs:
5454
strOwner <- tolower(qcthat::GetGHOwner())
5555
strRepo <- qcthat::GetGHRepo()
5656
strURL <- glue::glue(
57-
"https://{strOwner}.github.io/{strRepo}/pr/{intPRNumber}/dev"
57+
"https://{strOwner}.github.io/{strRepo}/pr/{intPRNumber}"
5858
)
5959
print(paste("🌐 URL:", strURL))
6060
qcthat::CommentIssue(

.github/workflows/qcthat.yaml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Workflow derived from
2+
# https://github.com/Gilead-BioStats/qcthat/tree/v1.1.1/inst/workflows/qcthat.yaml.
3+
on:
4+
pull_request:
5+
types: [opened, edited, reopened, synchronize, milestoned]
6+
release:
7+
types: [released]
8+
issues:
9+
types: [closed]
10+
workflow_dispatch:
11+
inputs:
12+
pr:
13+
description: PR number to which reports should be added (leave blank for none).
14+
required: false
15+
milestone:
16+
description: Milestone name to use for the milestone report (leave blank for none).
17+
required: false
18+
tag:
19+
description: Release tag to which the report should be attached (leave blank for none).
20+
required: false
21+
issueNumber:
22+
description: The closed issue number to process to update user acceptance testing information.
23+
required: false
24+
25+
name: qcthat Quality Control
26+
27+
permissions:
28+
# read: Required for generating reports and updating UAT status.
29+
# write: Required for initiating the UAT process.
30+
issues: write
31+
# read: Required for updating UAT status.
32+
# write: Required for adding reports to pull requests.
33+
pull-requests: write
34+
# write: Required for attaching reports to releases.
35+
contents: write
36+
# write: Required for updating UAT status.
37+
actions: write
38+
39+
# Configuration variables for controlling workflow behavior
40+
env:
41+
qcthat_UAT: true
42+
qcthat_PR_REPORT: true
43+
qcthat_COMPLETED_REPORT: true
44+
qcthat_MILESTONE_REPORT: true
45+
qcthat_RELEASE_REPORT: true
46+
qcthat_FAIL_FOR_TEST_FAILURES: true
47+
48+
jobs:
49+
qcthat:
50+
runs-on: ubuntu-latest
51+
container:
52+
image: ghcr.io/api2r/pkgskills-ci:release
53+
if: >-
54+
(github.event_name == 'issues' && contains(github.event.issue.labels.*.name, 'qcthat-uat')) ||
55+
github.event_name != 'issues'
56+
env:
57+
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
58+
steps:
59+
- uses: actions/checkout@v6
60+
61+
- uses: api2r/actions/install@v1
62+
with:
63+
use-container: "true"
64+
token: ${{ secrets.GITHUB_TOKEN }}
65+
extra-packages: Gilead-BioStats/qcthat@main local::.
66+
67+
- name: Manage User Acceptance Testing
68+
if: >-
69+
env.qcthat_UAT == 'true' && (
70+
(github.event_name == 'issues' && contains(github.event.issue.labels.*.name, 'qcthat-uat')) ||
71+
(github.event_name == 'workflow_dispatch' && inputs.issueNumber != '')
72+
)
73+
run: |
74+
Rscript -e "qcthat::TriggerUAT()"
75+
76+
- name: Generate Issue-Test Matrix
77+
if: >-
78+
(env.qcthat_PR_REPORT == 'true' || env.qcthat_RELEASE_REPORT == 'true' || env.qcthat_FAIL_FOR_TEST_FAILURES == 'true') && (
79+
github.event_name == 'pull_request' ||
80+
github.event_name == 'release' ||
81+
(github.event_name == 'workflow_dispatch' && inputs.issueNumber == '')
82+
)
83+
run: |
84+
# Generate the full matrix for the package
85+
IssueTestMatrix <- qcthat::QCPackage()
86+
print(IssueTestMatrix)
87+
88+
# Save the matrix and UAT data for subsequent steps
89+
saveRDS(IssueTestMatrix, "ITM.rds")
90+
qcthat::SaveUATIssues()
91+
shell: Rscript {0}
92+
93+
- name: Update PR Reports
94+
if: >-
95+
env.qcthat_PR_REPORT == 'true' && (
96+
github.event_name == 'pull_request' ||
97+
(github.event_name == 'workflow_dispatch' && inputs.pr != '')
98+
)
99+
run: |
100+
issueTestMatrix <- readRDS("ITM.rds")
101+
qcthat::LoadUATIssues()
102+
qcthat::CommentAllReports(
103+
dfITM = issueTestMatrix,
104+
lglPR = as.logical("${{ env.qcthat_PR_REPORT }}"),
105+
lglMilestone = as.logical("${{ env.qcthat_MILESTONE_REPORT }}"),
106+
lglCompleted = as.logical("${{ env.qcthat_COMPLETED_REPORT }}"),
107+
lglUAT = as.logical("${{ env.qcthat_UAT }}")
108+
)
109+
shell: Rscript {0}
110+
111+
- name: Update Release Reports
112+
if: >-
113+
env.qcthat_RELEASE_REPORT == 'true' && (
114+
github.event_name == 'release' || inputs.tag != ''
115+
)
116+
run: |
117+
issueTestMatrix <- readRDS("ITM.rds")
118+
qcthat::LoadUATIssues()
119+
qcthat::AttachReleaseReports(
120+
dfITM = issueTestMatrix,
121+
lglCompleted = as.logical("${{ env.qcthat_COMPLETED_REPORT }}"),
122+
lglMilestone = as.logical("${{ env.qcthat_MILESTONE_REPORT }}")
123+
)
124+
shell: Rscript {0}
125+
126+
- name: Flag failure for PR
127+
if: >-
128+
env.qcthat_FAIL_FOR_TEST_FAILURES == 'true' && (
129+
github.event_name == 'pull_request' ||
130+
(github.event_name == 'workflow_dispatch' && inputs.pr != '')
131+
)
132+
run: |
133+
issueTestMatrix <- readRDS("ITM.rds")
134+
dfPR <- qcthat::QCPR(dfITM = issueTestMatrix)
135+
if (any(dfPR$Disposition == "fail", na.rm = TRUE)) {
136+
cli::cli_abort(
137+
"One or more tests failed or were skipped for PR-associated issues."
138+
)
139+
}
140+
shell: Rscript {0}
141+
142+
- name: Flag failure for completed
143+
if: >-
144+
env.qcthat_FAIL_FOR_TEST_FAILURES == 'true' && (
145+
github.event_name == 'pull_request' ||
146+
github.event_name == 'release' ||
147+
(github.event_name == 'workflow_dispatch' && inputs.issueNumber == '')
148+
)
149+
run: |
150+
issueTestMatrix <- readRDS("ITM.rds")
151+
dfCompleted = qcthat::QCCompletedIssues(dfITM = issueTestMatrix)
152+
if (any(dfCompleted$Disposition == "fail", na.rm = TRUE)) {
153+
cli::cli_abort(
154+
"One or more tests failed or were skipped for completed issues."
155+
)
156+
}
157+
shell: Rscript {0}

.vscode/extensions.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"recommendations": [
3+
"Posit.air-vscode"
4+
]
5+
}

.vscode/settings.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"[r]": {
3+
"editor.formatOnSave": true,
4+
"editor.defaultFormatter": "Posit.air-vscode"
5+
},
6+
"[quarto]": {
7+
"editor.formatOnSave": true,
8+
"editor.defaultFormatter": "quarto.quarto"
9+
}
10+
}

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Imports:
2626
snakecase,
2727
stbl (>= 0.3.0),
2828
tibble,
29-
tibblify (>= 0.3.2),
29+
tibblify (>= 0.4.0),
3030
xml2,
3131
yaml
3232
Suggests:

R/components-schema.R

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,20 @@ class_schema <- S7::new_class(
4141
description = character_scalar_property("description"),
4242
format = character_scalar_property("format")
4343
),
44-
constructor = function(type = c(
45-
"string", "number", "integer",
46-
"boolean", "array", "object"
47-
),
48-
...,
49-
nullable = FALSE,
50-
description = character(),
51-
format = character()) {
44+
constructor = function(
45+
type = c(
46+
"string",
47+
"number",
48+
"integer",
49+
"boolean",
50+
"array",
51+
"object"
52+
),
53+
...,
54+
nullable = FALSE,
55+
description = character(),
56+
format = character()
57+
) {
5258
check_dots_empty()
5359
if (missing(type)) {
5460
type <- character()

0 commit comments

Comments
 (0)