Repository navigation
166 lines (154 loc) · 7.46 KB
/
Copy path_linter.yml
File metadata and controls
166 lines (154 loc) · 7.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
name: "Linter Checks"
on:
workflow_call:
inputs:
cache-mode:
description: "Cache mode override (empty = auto-compute from event context)."
type: string
default: ""
fetch-only:
description: "When true, runs --nobuild to fetch dependencies only."
type: string
default: "false"
secrets:
UBUNTU_SNAPSHOT_MIRROR_URL:
required: false
jobs:
lint:
name: ${{ matrix.id }}
runs-on: ubuntu-24.04
permissions:
contents: read
actions: write
security-events: write
strategy:
# Let every linter run to completion (and upload its own findings/SARIF)
# even if another one in the matrix fails.
fail-fast: false
matrix:
include:
- id: clang-tidy
bazel-config: clang-tidy
- id: clippy
bazel-config: clippy
- id: ruff
bazel-config: ruff
steps:
- uses: actions/checkout@v6.0.2
with:
fetch-depth: 0
- uses: ./.github/actions/00_infrastructure/prepare_bazel_environment
with:
disk-cache: ${{ inputs.fetch-only != 'true' && matrix.id || '' }}
cache-mode: ${{ inputs.cache-mode }}
ubuntu-snapshot-mirror-url: ${{ secrets.UBUNTU_SNAPSHOT_MIRROR_URL }}
- name: Install Aspect CLI
if: inputs.fetch-only != 'true'
# v2026.26.9 (https://github.com/aspect-build/setup-aspect/releases/tag/v2026.26.9)
uses: aspect-build/setup-aspect@2306377a61c45954ab2df7c7311698b109364352
with:
# Bazel/Bazelisk and disk/repository caching are already handled by
# the prepare_bazel_environment step above; avoid duplicating them
# here. No `aspect-api-token` is set, so this step never talks to
# Aspect's hosted backend.
bazelisk-cache: "false"
disk-cache: "false"
repository-cache: "false"
- name: Fetch dependencies (--nobuild)
if: inputs.fetch-only == 'true'
run: bazel build --nobuild --config=ci --config=${{ matrix.bazel-config }} //...
- name: Run ${{ matrix.id }} via aspect lint
if: inputs.fetch-only != 'true'
id: run-lint
run: |
# --bazel-flag=--config=${{ matrix.bazel-config }} reuses the same aspect + toolchain configuration as
# `bazel test --config=${{ matrix.bazel-config }}` (see quality/static_analysis/static_analysis.bazelrc) —
# the aspect is deliberately NOT also passed via `--aspect=` here, since Bazel rejects the same aspect
# being registered twice.
#
# --bazel-flag=--build_event_json_file writes a Build Event Protocol JSON stream alongside the build, letting
# us enumerate every emitted rules_lint_machine SARIF report file below without crawling bazel-bin with
# `find`.
#
# The three github-*:enabled=false flags disable Aspect CLI features that post PR comments / check runs /
# status comments directly via Aspect's own hosted backend (requires `aspect auth login` / an Aspect-managed
# GitHub App). We deliberately don't use those — findings are surfaced via the SARIF upload below instead,
# using only the standard GITHUB_TOKEN.
#
# --artifact-upload:enabled=false disables the CLI's own attempt to upload its internal Build Event artifact
# via GitHub's native ArtifactService (this uses GitHub's own OIDC token, not Aspect's backend, but would need
# `id-token: write` and isn't needed here since we collect/upload the SARIF report ourselves below).
#
# Ideally, merge gating for newly introduced findings would be handled by a branch ruleset that blocks PRs
# with Code Scanning alerts above a configured severity, using GitHub's own new-vs-baseline diff instead of
# Aspect's locally computed one. That's blocked for now on otterdog support for the `code_scanning` ruleset
# rule (see eclipse-csi/otterdog#639). Until that lands, fall back to gating via aspect's own exit code:
# `--strategy=hold-the-line` (fails only on error-severity diagnostics) for PR/push/merge_group runs, where
# the result should actually gate the job;
# `--strategy=soft` (never fails) for other triggers (e.g. nightly, manual dispatch), which only want the
# report/SARIF, not a pass/fail verdict.
case "${{ github.event_name }}" in
pull_request|push|merge_group) STRATEGY=hold-the-line ;;
*) STRATEGY=soft ;;
esac
set -o pipefail
aspect lint \
--bazel-flag=--config=ci \
--bazel-flag=--config=${{ matrix.bazel-config }} \
--bazel-flag=--@aspect_rules_lint//lint:fail_on_violation=false \
--bazel-flag=--build_event_json_file=/tmp/bep.json \
--github-lint-comments:enabled=false \
--github-status-checks:enabled=false \
--github-status-comments:enabled=false \
--artifact-upload:enabled=false \
--strategy="${STRATEGY}" \
-- //... 2>&1 | tee "${{ matrix.id }}_raw.log"
- name: Collect SARIF reports
if: ${{ !cancelled() && inputs.fetch-only != 'true' }}
id: sarif
uses: ./.github/actions/00_infrastructure/merge_sarif_reports
with:
bep-json: /tmp/bep.json
output-file: ${{ matrix.id }}.sarif
- name: Add rule IDs to Ruff SARIF results
# rules_lint's Ruff SARIF keeps the rule code only in the message text.
if: ${{ !cancelled() && inputs.fetch-only != 'true' && matrix.id == 'ruff' && steps.sarif.outcome == 'success' }}
run: |
jq '.runs |= map(
.results |= map(.ruleId //= ((.message.text | capture("^(?<id>[A-Z]+[0-9]+)") | .id) // "ruff"))
| .tool.driver.rules = ([.results[].ruleId] | unique | map({id: .}))
)' ruff.sarif > ruff.sarif.tmp
mv ruff.sarif.tmp ruff.sarif
- name: Upload SARIF reports to GitHub Code Scanning
if: ${{ !cancelled() && inputs.fetch-only != 'true' }}
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: ${{ matrix.id }}.sarif
category: ${{ matrix.id }}
# Block this step until GitHub has finished processing the
# uploaded SARIF (default, made explicit here) so that any
# downstream step relying on the resulting Code Scanning alerts
# (e.g. a required status check) sees them immediately.
wait-for-processing: true
- name: Upload ${{ matrix.id }} findings as artifact
if: ${{ !cancelled() && inputs.fetch-only != 'true' }}
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.id }}-findings
path: |
${{ matrix.id }}_raw.log
${{ matrix.id }}.sarif
if-no-files-found: ignore
retention-days: 7