Module: Rigor::CiDetector
- Defined in:
- lib/rigor/ci_detector.rb
Overview
Runtime CI-environment detection (ADR-51 WD7), modelled on OndraM/ci-detector (the library PHPStan uses). Reads
the well-known environment variables a CI provider sets and returns the matching Platform, classifying it into a
tier that decides how rigor check surfaces diagnostics there:
:native_stdout — Rigor has a native format that renders purely from
stdout, so it is auto-emitted on top of the human
output (GitHub Actions → `github`, TeamCity →
`teamcity`). These are the first-class platforms.
:native_artifact — Rigor has a native format but it needs a CI-wired
report artifact, not stdout (GitLab CI → `gitlab`).
First-class, but Rigor only *hints* the format.
:reviewdog — no native Rigor format; second-class, routed through
reviewdog (`checkstyle`/`sarif`) or `junit`. Hint
only.
Lives outside the CLI namespace because it is a pure function of the environment hash with no CLI dependency, and
non-CLI consumers exist: Rigor::Configuration#cache_validation_strict? resolves the auto cache-validation default
through it (a fresh CI checkout regenerates every stat tuple, so ADR-87's stat tier cannot work there).
Detection is fully testable; callers pass ENV.
RIGOR_CI_DETECT=0 (or false/no) disables it globally — the seam the spec suite uses for determinism.
Defined Under Namespace
Classes: Platform
Constant Summary collapse
- PROVIDERS =
The detection table, ordered most-specific first so the generic
CI=truecatch-all is last (a provider that also setsCIis still recognised by its own variable).matchis:truthy(value in 1/true/yes/on),:present(variable set non-empty), or:equals. [ { id: "github-actions", name: "GitHub Actions", format: "github", tier: :native_stdout, var: "GITHUB_ACTIONS", match: :truthy }, { id: "gitlab", name: "GitLab CI", format: "gitlab", tier: :native_artifact, var: "GITLAB_CI", match: :truthy }, { id: "teamcity", name: "TeamCity", format: "teamcity", tier: :native_stdout, var: "TEAMCITY_VERSION", match: :present }, { id: "circleci", name: "CircleCI", format: nil, tier: :reviewdog, var: "CIRCLECI", match: :truthy }, { id: "jenkins", name: "Jenkins", format: nil, tier: :reviewdog, var: "JENKINS_URL", match: :present }, { id: "travis", name: "Travis CI", format: nil, tier: :reviewdog, var: "TRAVIS", match: :truthy }, { id: "appveyor", name: "AppVeyor", format: nil, tier: :reviewdog, var: "APPVEYOR", match: :truthy }, { id: "azure-pipelines", name: "Azure Pipelines", format: nil, tier: :reviewdog, var: "TF_BUILD", match: :present }, { id: "bitbucket", name: "Bitbucket Pipelines", format: nil, tier: :reviewdog, var: "BITBUCKET_BUILD_NUMBER", match: :present }, { id: "buildkite", name: "Buildkite", format: nil, tier: :reviewdog, var: "BUILDKITE", match: :truthy }, { id: "drone", name: "Drone CI", format: nil, tier: :reviewdog, var: "DRONE", match: :truthy }, { id: "semaphore", name: "Semaphore", format: nil, tier: :reviewdog, var: "SEMAPHORE", match: :truthy }, { id: "codeship", name: "Codeship", format: nil, tier: :reviewdog, var: "CI_NAME", match: :equals, value: "codeship" }, { id: "ci", name: "CI", format: nil, tier: :reviewdog, var: "CI", match: :truthy } ].freeze
Class Method Summary collapse
-
.detect(env = ENV) ⇒ Object
Returns the detected Platform, or nil when no CI is recognised or detection is disabled via
RIGOR_CI_DETECT. - .disabled?(env) ⇒ Boolean
- .matches?(env, provider) ⇒ Boolean
Class Method Details
.detect(env = ENV) ⇒ Object
Returns the detected Platform, or nil when no CI is recognised or detection is disabled via RIGOR_CI_DETECT.
68 69 70 71 72 73 74 75 |
# File 'lib/rigor/ci_detector.rb', line 68 def detect(env = ENV) return nil if disabled?(env) row = PROVIDERS.find { |provider| matches?(env, provider) } return nil if row.nil? Platform.new(id: row[:id], name: row[:name], format: row[:format], tier: row[:tier]) end |
.disabled?(env) ⇒ Boolean
77 78 79 |
# File 'lib/rigor/ci_detector.rb', line 77 def disabled?(env) %w[0 false no off].include?(env["RIGOR_CI_DETECT"].to_s.strip.downcase) end |
.matches?(env, provider) ⇒ Boolean
81 82 83 84 85 86 87 88 |
# File 'lib/rigor/ci_detector.rb', line 81 def matches?(env, provider) value = env[provider[:var]].to_s.strip case provider[:match] when :truthy then %w[1 true yes on].include?(value.downcase) when :present then !value.empty? when :equals then value.downcase == provider[:value] end end |