Skip to content

Continuous integration

ry is one binary with no R dependency, so a CI job is a download and two commands. Nothing to install, no package cache, no matrix over R versions.

.github/workflows/ry.yml
name: ry
on: [push, pull_request]
jobs:
ry:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install ry
env:
RY_VERSION: 0.3.0-alpha
run: |
curl -sSL "https://github.com/felix-andreas/ry/releases/download/${RY_VERSION}/ry-x86_64-unknown-linux-gnu.tar.gz" \
| tar xz
sudo mv ry /usr/local/bin/
- name: Check
run: ry check
- name: Format
run: ry fmt --check

Both commands exit 1 on findings, which is what fails the job. Neither needs R installed.

Pin the version. Every release so far is marked a pre-release, so releases/latest/download/… resolves to an old stable tag rather than the newest build — and the type system is still gaining capability, so a newer version can report findings an older one did not. Name the tag explicitly, as above. See project status.

Asset names follow the Rust target triple — ry-aarch64-apple-darwin.tar.gz, ry-x86_64-pc-windows-gnu.zip — and each archive contains the single ry binary.

The default is strict: warnings fail the job. A run with nothing but unused warnings still exits 1.

That is usually right for a project that starts clean, and wrong for one adopting ry on an existing codebase. To gate on errors only while you work through a backlog:

Terminal window
ry check --min-severity error

The filter applies before the exit code is decided, so warnings still print but no longer fail anything.

You wantCommand
Everything to matterry check
Only errors to block the buildry check --min-severity error
Formatting enforcedry fmt --check
To see the diff CI would applyry fmt --diff

Be careful reading exit code 2 as “worse than 1” — it is a different failure. It means the run could not be completed: an unparseable ry.toml, a path that does not exist, an unreadable file. A job that treats any non-zero as “findings” will report a broken config as a code problem. The full table is in the CLI reference.

Terminal window
ry check --output json

writes JSON Lines to stdout — one object per finding, nothing else on the stream, and no summary line. In JSON mode stderr stays empty, so you can pipe stdout straight into a tool without filtering anything out.

{"code":"type-mismatch","column":21,"endColumn":27,"endLine":4,"line":4,"message":"expected `integer`, found `character`","path":"/home/you/demo/main.R","related":[],"severity":"error"}

Every field is documented in the CLI reference, and the field names are a contract — they are covered by tests that fail when they change, so a script built on them will not break silently.

Counting errors for a summary line, without jq:

Terminal window
ry check --output json | grep -c '"severity":"error"'

Do not start by putting ry check in front of a merge gate on a codebase that has never run it. Land the tool first, gate second. Adopting an existing codebase walks through the order that works.