Reference configs

apache/arrow: six languages' package layouts in one config

Arrow's bindings each have their own layout: Ruby gems, GLib libraries, a Python and an R package, around the shared format/ spec. No linter sees them together; this config checks them in one pass, next to RAT's exclude list. This config was written to test alint; Arrow doesn't use alint.

What alint found

The bundled GitHub Actions rules (alint 0.16.1, on the workflows as of 7 May 2026) flag 146 action references not pinned to a commit, and 2 release workflows that grant contents: write at the workflow level.

The config

Arrow has implementations in C++, C GLib, Python, R, Ruby and MATLAB, all of them built on the schemas in format/. The config checks what the languages share, which no single linter sees: a README in each language directory, the spec files, the files every Ruby gem ships and a meson.build in each GLib library. It extends seven bundled rulesets, among them apache/governance and compliance/apache-2, and runs the per-language linters from command rules.

.alint.yml
- id: arrow-ruby-gem-required-meta-files
  kind: for_each_file
  select: "ruby/red-*/Rakefile"
  require:
    - kind: file_exists
      paths: "{dir}/LICENSE.txt"
    - kind: file_exists
      paths: "{dir}/NOTICE.txt"
    - kind: file_exists
      paths: "{dir}/README.md"
    - kind: file_exists
      paths: "{dir}/Gemfile"
    - kind: dir_exists
      paths: "{dir}/lib"
    - kind: dir_exists
      paths: "{dir}/test"
  level: error

Every gem under ruby/red-* ships its license, notice, README and Gemfile, with lib/ and test/ next to them. A second rule checks each gem's gemspec.

.alint.yml
- id: arrow-c-glib-sublibrary-has-meson-build
  kind: for_each_dir
  select: "c_glib/{arrow,arrow-cuda,arrow-dataset,arrow-flight,arrow-flight-sql,gandiva,parquet}-glib"
  require:
    - kind: file_exists
      paths: "{path}/meson.build"
  level: error

The top-level meson.build in c_glib/ includes each of these seven libraries, so each needs its own.

.alint.yml
- id: arrow-rat-exclude-entries-resolve
  kind: registry_paths_resolve
  source: dev/release/rat_exclude_files.txt
  extract: { lines: {} }
  entries_are_globs: true
  level: warning

Every pattern in RAT's exclude list has to match something, so a deleted or renamed file doesn't leave an exemption behind.

What stays outside alint

The languages' own tools, RAT and the release process stay as they are:

  • the linters themselves: clang-format, cpplint, rubocop, flake8, lintr and the rest of the pre-commit hooks, which the config runs but doesn't replace;
  • Apache RAT's classification of files, and the release process in dev/release/;
  • the dev/archery integration tests, which check at runtime that every implementation reads and writes the same data;
  • checking that every type in format/Schema.fbs has a test fixture in each language. alint has no rule kind for that.