
Validate Hub config files against hubverse schema
Source:R/ci_validate_hub_config.R
ci_validate_hub_config.RdA continuous integration helper, superseded by the hubverse
validate-config action,
which no longer calls it.
Usage
ci_validate_hub_config(
hub_path = Sys.getenv("HUB_PATH"),
gh_output = Sys.getenv("GITHUB_OUTPUT"),
diff = stdout(),
...
)Arguments
- hub_path
path to the hub. Defaults to the value of the
HUB_PATHenvironment variable.- gh_output
path to a file that can record variables for use by other actions. This defaults to the value of the
GITHUB_OUTPUTenvironment variable.- diff
path to a file (defaults to
stdout()) that will contain a user facing message with a time stamp that shows if the hub was correctly configured along with the errors table rendered byrender_config_val_errors_html()(if any). The table is capped to fit a pull request comment and a note gives the number of errors left out.- ...
Arguments passed on to
validate_hub_configschema_versionCharacter string specifying the json schema version to be used for validation. The default value
"from_config"will use the version specified in theschema_versionproperty of the config file."latest"will use the latest version available in the hubverse schemas repository. Alternatively, a specific version of a schema (e.g."v0.0.1") can be specified.branchThe branch of the hubverse schemas repository from which to fetch schema. Defaults to
"main". Can be set through global option "hubAdmin.branch".
Value
Returns a list of the results of validation, one for each hub-config
file validated. A value of TRUE for a given file indicates that validation
was successful.
A value of FALSE for a given file indicates that validation errors were
detected. Details of errors will be appended as a data.frame to an errors attribute.
To access the errors table for a given element use attr(x, "errors")
where x is the any element of the output of the function that is FALSE.
You can print a more concise and easier to view version of an errors table with
view_config_val_errors().
Details
This function is to be used within a continuous integration context, in a workflow that checks the validity of a hub's configuration files.
The hubverse validate-config action
is the recommended way to validate a hub's config on pull requests. It posts
the report as a comment, writes it to the job summary as well and handles
pull requests from forks. To add it to a hub, use
hubCI::use_hub_github_action('validate-config').
Below is an excerpt of steps on GitHub Actions using this function directly,
where the environment variables PR_NUMBER and HUB_PATH have been
defined:
- uses: actions/checkout@v4
- uses: r-lib/actions/setup-r@v2
with:
install-r: false
use-public-rspm: true
extra-repositories: 'https://hubverse-org.r-universe.dev'
- uses: r-lib/actions/setup-r-dependencies@v2
with:
cache: 'always'
packages: |
any::hubAdmin
any::sessioninfo
- name: Run validations
id: validate
run: |
diff_path <- file.path(Sys.getenv("HUB_PATH"), "diff.md")
hubAdmin::ci_validate_hub_config(diff = diff_path)
shell: Rscript {0}
- name: "Comment on PR"
id: comment-diff
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: carpentries/actions/comment-diff@main
with:
pr: ${{ env.PR_NUMBER }}
path: ${{ env.HUB_PATH }}/diff.md
- name: Error on Failure
if: ${{ steps.validate.outputs.result == 'false' }}
run: |
echo "::error title=Invalid Configuration::Errors were detected"
exit 1Examples
# setup ------------
hubdir <- tempfile()
out <- tempfile()
diff <- tempfile()
on.exit({
unlink(hubdir, recursive = TRUE)
unlink(out)
unlink(diff)
})
dir.create(hubdir)
# Results from a valid hub -----------------------------------------
file.copy(
from = system.file("testhubs/simple/", package = "hubUtils"),
to = hubdir,
recursive = TRUE
)
#> [1] TRUE
hub <- file.path(hubdir, "simple")
ci_validate_hub_config(hub_path = hub, gh_output = out, diff = diff)
#> ✔ Hub correctly configured!
#> tasks.json, admin.json, and model-metadata-schema.json all valid.
#> ℹ schema version v2.0.0
#> (<https://github.com/hubverse-org/schemas/tree/main/v2.0.0>)
#>
#> ── $tasks
#> [1] TRUE
#> ✔ ok: hub-config/tasks.json (<file:///tmp/RtmpSWDQHx/file1b113fda2a50/simple/hub-config/tasks.json>) (via tasks-schema v2.0.0 (<https://raw.githubusercontent.com/hubverse-org/schemas/main/v2.0.0/tasks-schema.json>))
#>
#> ── $admin
#> [1] TRUE
#> ✔ ok: hub-config/admin.json (<file:///tmp/RtmpSWDQHx/file1b113fda2a50/simple/hub-config/admin.json>) (via admin-schema v2.0.0 (<https://raw.githubusercontent.com/hubverse-org/schemas/main/v2.0.0/admin-schema.json>))
#>
#> ── $model-metadata-schema
#> [1] TRUE
#> ✔ ok: hub-config/model-metadata-schema.json (<file:///tmp/RtmpSWDQHx/file1b113fda2a50/simple/hub-config/model-metadata-schema.json>) (from default json schema (<file:///tmp/RtmpSWDQHx/file1b113fda2a50/simple/hub-config/model-metadata-schema.json>))
# result is true
readLines(out)
#> [1] "result=true"
# message to user shows success and a timestamp
readLines(diff)
#> [1] ":white_check_mark: Hub correctly configured!"
#> [2] ""
#> [3] "2026-09-30 08:44:19 UTC"
# Results from an invalid hub --------------------------------------
# reset output file
out <- tempfile()
# make the the simple hub invalid by adding a character where
# a number should be
tasks_path <- file.path(hub, "hub-config", "tasks.json")
tasks <- readLines(tasks_path)
writeLines(sub('minimum": 0', 'minimum": "0"', tasks), tasks_path)
# validate
ci_validate_hub_config(hub_path = hub, gh_output = out, diff = diff)
#> Warning: ✖ Errors detected in tasks.json config file.
#> ℹ Use `view_config_val_errors()` on the output of `validate_hub_config` to
#> review errors.
#> ℹ schema version v2.0.0
#> (<https://github.com/hubverse-org/schemas/tree/main/v2.0.0>)
#>
#> ── $tasks
#> [1] FALSE
#> ! 4 schema errors: hub-config/tasks.json
#> (<file:///tmp/RtmpSWDQHx/file1b113fda2a50/simple/hub-config/tasks.json>) (via
#> tasks-schema v2.0.0
#> (<https://raw.githubusercontent.com/hubverse-org/schemas/main/v2.0.0/tasks-schema.json>))
#> ℹ use `view_config_val_errors()` to view table of error details.
#>
#> ── $admin
#> [1] TRUE
#> ✔ ok: hub-config/admin.json (<file:///tmp/RtmpSWDQHx/file1b113fda2a50/simple/hub-config/admin.json>) (via admin-schema v2.0.0 (<https://raw.githubusercontent.com/hubverse-org/schemas/main/v2.0.0/admin-schema.json>))
#>
#> ── $model-metadata-schema
#> [1] TRUE
#> ✔ ok: hub-config/model-metadata-schema.json (<file:///tmp/RtmpSWDQHx/file1b113fda2a50/simple/hub-config/model-metadata-schema.json>) (from default json schema (<file:///tmp/RtmpSWDQHx/file1b113fda2a50/simple/hub-config/model-metadata-schema.json>))
# result is now false
readLines(out)
#> [1] "result=false"
# message to user now shows a table
head(readLines(diff))
#> [1] "## :x: Invalid Configuration"
#> [2] ""
#> [3] "Errors were detected in one or more config files in `hub-config/`. Details about the exact locations of the errors can be found in the table below."
#> [4] ""
#> [5] "<p>Report for directory <code>/tmp/RtmpSWDQHx/file1b113fda2a50/simple/hub-config</code> using schema version <a href=\"https://github.com/hubverse-org/schemas/tree/main/v2.0.0\"><b>v2.0.0</b></a></p>"
#> [6] "<table>"
tail(readLines(diff))
#> [1] "<tr><td>tasks.json</td><td><strong>rounds</strong><br>└<strong>2</strong><br>└─<strong>model_tasks</strong><br>└──<strong>1</strong><br>└───<strong>output_type</strong><br>└────<strong>quantile</strong><br>└─────<strong>value</strong><br>└──────<strong>minimum</strong></td><td>properties<br>└<strong>rounds</strong><br>└─items<br>└──properties<br>└───<strong>model_tasks</strong><br>└────items<br>└─────properties<br>└──────<strong>output_type</strong><br>└───────properties<br>└────────<strong>quantile</strong><br>└─────────properties<br>└──────────<strong>value</strong><br>└───────────properties<br>└────────────<strong>minimum</strong><br>└─────────────<strong>type</strong></td><td>type</td><td>❌ must be number,integer</td><td>number, integer</td><td>0</td></tr>"
#> [2] "</tbody>"
#> [3] "</table>"
#> [4] ""
#> [5] "For more information, please consult the [**`hubDocs` documentation**](https://docs.hubverse.io/en/latest/)."
#> [6] "2026-09-30 08:44:19 UTC"