@oddessentials/repo-standards 1.2.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -101,7 +101,7 @@ Each checklist item includes:
101
101
  The `version` field indicates schema compatibility:
102
102
 
103
103
  - `1` — Original schema
104
- - `2` — Adds `anyOfFiles` and `pinningNotes` fields (additive, non-breaking)
104
+ - `2` — Adds `bazelHints`, `meta.bazelIntegration` for Bazel support, `anyOfFiles`, `pinningNotes`
105
105
 
106
106
  Consumers should ignore unknown fields for forward compatibility.
107
107
 
@@ -144,6 +144,84 @@ Required secrets:
144
144
 
145
145
  ---
146
146
 
147
+ ## Bazel Integration
148
+
149
+ This framework supports Bazel as an **optional build executor** for quality checks.
150
+
151
+ ### Key Concepts
152
+
153
+ - **Bazel is optional** — Stack-native commands (npm, cargo, etc.) remain the default
154
+ - **Hints are advisory** — `bazelHints` are suggestions, not required execution paths
155
+ - **Commands are illustrative** — Actual Bazel commands are repo-defined; examples show patterns only
156
+ - **Detection is root-level** — Only `MODULE.bazel` / `WORKSPACE*` at repo root triggers Bazel mode
157
+
158
+ ### Detection Rules
159
+
160
+ Repos are detected as Bazel-managed if the **repository root** contains:
161
+
162
+ 1. `MODULE.bazel` (bzlmod, preferred)
163
+ 2. `WORKSPACE.bazel` or `WORKSPACE` (legacy)
164
+
165
+ Optional markers: `.bazelrc`, `.bazelversion`
166
+
167
+ > Nested `BUILD.bazel` files (e.g., from vendored deps) do NOT trigger Bazel detection.
168
+
169
+ ### Bazel Commands (Not Assumed Targets)
170
+
171
+ The `bazelHints.commands` field contains **actual commands to run**:
172
+
173
+ | Check | Stack-native | Bazel Command |
174
+ | ------------ | ---------------------- | -------------------------------- |
175
+ | Lint | `npm run lint` | `bazel test //... --aspects=...` |
176
+ | Format Check | `npm run format:check` | `bazel run //tools/format:check` |
177
+ | Type Check | `npm run typecheck` | `bazel build //...` |
178
+ | Test | `npm test` | `bazel test //...` |
179
+ | Coverage | `npm run coverage` | `bazel coverage //...` |
180
+
181
+ > **Note**: Bazel commands shown are **illustrative patterns**. Actual targets (e.g., `//tools/lint:lint`, `//...:format_test`) are repo-defined and may not exist without explicit Bazel setup. `bazelHints` are advisory—consumers should prefer stack-native commands unless explicitly adopting Bazel.
182
+
183
+ ### Minimal `.bazelrc` for CI
184
+
185
+ ```bazelrc
186
+ # .bazelrc
187
+ build:ci --nokeep_going
188
+ build:ci --test_output=errors
189
+ ```
190
+
191
+ ### Example GitHub Actions
192
+
193
+ ```yaml
194
+ - uses: bazel-contrib/setup-bazel@0.14.0
195
+ with:
196
+ bazelisk-cache: true
197
+
198
+ - run: bazel test //... --config=ci
199
+ ```
200
+
201
+ ### Example Azure DevOps
202
+
203
+ ```yaml
204
+ - script: |
205
+ curl -Lo bazelisk https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64
206
+ chmod +x bazelisk && mv bazelisk /usr/local/bin/bazel
207
+ displayName: "Install Bazelisk"
208
+
209
+ - script: bazel test //... --config=ci
210
+ displayName: "Run Bazel Tests"
211
+ ```
212
+
213
+ > Remote cache is optional and not required for basic CI.
214
+
215
+ ### Opt-Out
216
+
217
+ To disable Bazel hints for a repo that contains Bazel files but uses npm for quality checks:
218
+
219
+ ```json
220
+ { "meta": { "bazelIntegration": { "enabled": false } } }
221
+ ```
222
+
223
+ ---
224
+
147
225
  ## Generating Stack-Specific JSON
148
226
 
149
227
  The generator reads the master spec and produces filtered, deterministic outputs.
@@ -35,6 +35,12 @@
35
35
  "id": "linting",
36
36
  "label": "Linting",
37
37
  "stack": {
38
+ "bazelHints": {
39
+ "commands": [
40
+ "bazel build //... --aspects=@rules_dotnet//dotnet:analyzers.bzl%analyzer_aspect"
41
+ ],
42
+ "notes": "Use rules_dotnet analyzer aspects for Roslyn-based linting in Bazel."
43
+ },
38
44
  "exampleConfigFiles": [
39
45
  ".editorconfig",
40
46
  "Directory.Build.props"
@@ -66,6 +72,12 @@
66
72
  "id": "unit-test-runner",
67
73
  "label": "Unit Test Runner",
68
74
  "stack": {
75
+ "bazelHints": {
76
+ "commands": [
77
+ "bazel test //..."
78
+ ],
79
+ "notes": "Use rules_dotnet to define test targets for xUnit/NUnit/MSTest projects."
80
+ },
69
81
  "exampleConfigFiles": [
70
82
  "*.Tests.csproj"
71
83
  ],
@@ -160,6 +172,12 @@
160
172
  "id": "unit-test-reporter",
161
173
  "label": "Unit Test Reporter / Coverage",
162
174
  "stack": {
175
+ "bazelHints": {
176
+ "commands": [
177
+ "bazel coverage //..."
178
+ ],
179
+ "notes": "Use rules_dotnet with coverage instrumentation enabled."
180
+ },
163
181
  "exampleConfigFiles": [
164
182
  "*.csproj"
165
183
  ],
@@ -181,6 +199,13 @@
181
199
  "id": "ci-quality-gates",
182
200
  "label": "CI Quality Gates",
183
201
  "stack": {
202
+ "bazelHints": {
203
+ "commands": [
204
+ "bazel build //...",
205
+ "bazel test //..."
206
+ ],
207
+ "notes": "Bazel handles all analysis, testing, and packaging via defined targets."
208
+ },
184
209
  "exampleConfigFiles": [
185
210
  ".github/workflows/*",
186
211
  "azure-pipelines.yml"
@@ -200,6 +225,12 @@
200
225
  "id": "code-formatter",
201
226
  "label": "Code Formatter",
202
227
  "stack": {
228
+ "bazelHints": {
229
+ "commands": [
230
+ "bazel run //tools/format:dotnet_format -- --verify-no-changes"
231
+ ],
232
+ "notes": "Wrap dotnet format as a Bazel run target."
233
+ },
203
234
  "exampleConfigFiles": [
204
235
  ".editorconfig"
205
236
  ],
@@ -240,6 +271,12 @@
240
271
  "id": "type-checking",
241
272
  "label": "Type Checking",
242
273
  "stack": {
274
+ "bazelHints": {
275
+ "commands": [
276
+ "bazel build //..."
277
+ ],
278
+ "notes": "C# type errors surface during bazel build with rules_dotnet. No separate typecheck step needed."
279
+ },
243
280
  "exampleConfigFiles": [
244
281
  ".editorconfig",
245
282
  "Directory.Build.props",
@@ -530,6 +567,43 @@
530
567
  "azure-devops"
531
568
  ],
532
569
  "meta": {
570
+ "bazelIntegration": {
571
+ "advisoryNotice": "bazelHints are suggestions, not required execution paths. Consumers should prefer stack-native commands unless explicitly adopting Bazel.",
572
+ "ciContract": {
573
+ "configFlag": "--config=ci (define in .bazelrc)",
574
+ "deterministicFlags": [
575
+ "--nokeep_going",
576
+ "--test_output=errors"
577
+ ],
578
+ "remoteCache": "Optional; not required for CI",
579
+ "versionPinning": "Use .bazelversion file for Bazelisk"
580
+ },
581
+ "description": "Bazel build executor support for quality checks. All hints are ADVISORY—stack-native commands remain the default execution path.",
582
+ "detectionRules": {
583
+ "notes": "Detection uses repo-root markers only. Nested BUILD files do not trigger Bazel mode.",
584
+ "optionalMarkers": [
585
+ ".bazelrc",
586
+ ".bazelversion"
587
+ ],
588
+ "rootMarkers": [
589
+ "MODULE.bazel",
590
+ "WORKSPACE.bazel",
591
+ "WORKSPACE"
592
+ ]
593
+ },
594
+ "optOut": {
595
+ "configPath": "meta.bazelIntegration.enabled",
596
+ "description": "Set meta.bazelIntegration.enabled = false in repo config to disable Bazel hints"
597
+ },
598
+ "targetConventions": {
599
+ "build": "bazel build //...",
600
+ "coverage": "bazel coverage //...",
601
+ "description": "Recommended target naming (not assumed to exist). These are illustrative patterns; actual targets are repo-defined.",
602
+ "format": "bazel run //tools/format:check",
603
+ "lint": "//tools/lint:lint or bazel test //... with lint aspects",
604
+ "test": "bazel test //..."
605
+ }
606
+ },
533
607
  "complexityChecks": {
534
608
  "description": "When supported by the stack, run cyclomatic complexity or similar metrics in CI as a warning-only check initially.",
535
609
  "enabledByDefault": true
@@ -35,6 +35,12 @@
35
35
  "id": "linting",
36
36
  "label": "Linting",
37
37
  "stack": {
38
+ "bazelHints": {
39
+ "commands": [
40
+ "bazel build //... --aspects=@rules_dotnet//dotnet:analyzers.bzl%analyzer_aspect"
41
+ ],
42
+ "notes": "Use rules_dotnet analyzer aspects for Roslyn-based linting in Bazel."
43
+ },
38
44
  "exampleConfigFiles": [
39
45
  ".editorconfig",
40
46
  "Directory.Build.props"
@@ -66,6 +72,12 @@
66
72
  "id": "unit-test-runner",
67
73
  "label": "Unit Test Runner",
68
74
  "stack": {
75
+ "bazelHints": {
76
+ "commands": [
77
+ "bazel test //..."
78
+ ],
79
+ "notes": "Use rules_dotnet to define test targets for xUnit/NUnit/MSTest projects."
80
+ },
69
81
  "exampleConfigFiles": [
70
82
  "*.Tests.csproj"
71
83
  ],
@@ -160,6 +172,12 @@
160
172
  "id": "unit-test-reporter",
161
173
  "label": "Unit Test Reporter / Coverage",
162
174
  "stack": {
175
+ "bazelHints": {
176
+ "commands": [
177
+ "bazel coverage //..."
178
+ ],
179
+ "notes": "Use rules_dotnet with coverage instrumentation enabled."
180
+ },
163
181
  "exampleConfigFiles": [
164
182
  "*.csproj"
165
183
  ],
@@ -181,6 +199,13 @@
181
199
  "id": "ci-quality-gates",
182
200
  "label": "CI Quality Gates",
183
201
  "stack": {
202
+ "bazelHints": {
203
+ "commands": [
204
+ "bazel build //...",
205
+ "bazel test //..."
206
+ ],
207
+ "notes": "Bazel handles all analysis, testing, and packaging via defined targets."
208
+ },
184
209
  "exampleConfigFiles": [
185
210
  ".github/workflows/*",
186
211
  "azure-pipelines.yml"
@@ -200,6 +225,12 @@
200
225
  "id": "code-formatter",
201
226
  "label": "Code Formatter",
202
227
  "stack": {
228
+ "bazelHints": {
229
+ "commands": [
230
+ "bazel run //tools/format:dotnet_format -- --verify-no-changes"
231
+ ],
232
+ "notes": "Wrap dotnet format as a Bazel run target."
233
+ },
203
234
  "exampleConfigFiles": [
204
235
  ".editorconfig"
205
236
  ],
@@ -240,6 +271,12 @@
240
271
  "id": "type-checking",
241
272
  "label": "Type Checking",
242
273
  "stack": {
274
+ "bazelHints": {
275
+ "commands": [
276
+ "bazel build //..."
277
+ ],
278
+ "notes": "C# type errors surface during bazel build with rules_dotnet. No separate typecheck step needed."
279
+ },
243
280
  "exampleConfigFiles": [
244
281
  ".editorconfig",
245
282
  "Directory.Build.props",
@@ -530,6 +567,43 @@
530
567
  "github-actions"
531
568
  ],
532
569
  "meta": {
570
+ "bazelIntegration": {
571
+ "advisoryNotice": "bazelHints are suggestions, not required execution paths. Consumers should prefer stack-native commands unless explicitly adopting Bazel.",
572
+ "ciContract": {
573
+ "configFlag": "--config=ci (define in .bazelrc)",
574
+ "deterministicFlags": [
575
+ "--nokeep_going",
576
+ "--test_output=errors"
577
+ ],
578
+ "remoteCache": "Optional; not required for CI",
579
+ "versionPinning": "Use .bazelversion file for Bazelisk"
580
+ },
581
+ "description": "Bazel build executor support for quality checks. All hints are ADVISORY—stack-native commands remain the default execution path.",
582
+ "detectionRules": {
583
+ "notes": "Detection uses repo-root markers only. Nested BUILD files do not trigger Bazel mode.",
584
+ "optionalMarkers": [
585
+ ".bazelrc",
586
+ ".bazelversion"
587
+ ],
588
+ "rootMarkers": [
589
+ "MODULE.bazel",
590
+ "WORKSPACE.bazel",
591
+ "WORKSPACE"
592
+ ]
593
+ },
594
+ "optOut": {
595
+ "configPath": "meta.bazelIntegration.enabled",
596
+ "description": "Set meta.bazelIntegration.enabled = false in repo config to disable Bazel hints"
597
+ },
598
+ "targetConventions": {
599
+ "build": "bazel build //...",
600
+ "coverage": "bazel coverage //...",
601
+ "description": "Recommended target naming (not assumed to exist). These are illustrative patterns; actual targets are repo-defined.",
602
+ "format": "bazel run //tools/format:check",
603
+ "lint": "//tools/lint:lint or bazel test //... with lint aspects",
604
+ "test": "bazel test //..."
605
+ }
606
+ },
533
607
  "complexityChecks": {
534
608
  "description": "When supported by the stack, run cyclomatic complexity or similar metrics in CI as a warning-only check initially.",
535
609
  "enabledByDefault": true
@@ -41,6 +41,12 @@
41
41
  "id": "linting",
42
42
  "label": "Linting",
43
43
  "stack": {
44
+ "bazelHints": {
45
+ "commands": [
46
+ "bazel build //... --aspects=@rules_dotnet//dotnet:analyzers.bzl%analyzer_aspect"
47
+ ],
48
+ "notes": "Use rules_dotnet analyzer aspects for Roslyn-based linting in Bazel."
49
+ },
44
50
  "exampleConfigFiles": [
45
51
  ".editorconfig",
46
52
  "Directory.Build.props"
@@ -75,6 +81,12 @@
75
81
  "id": "unit-test-runner",
76
82
  "label": "Unit Test Runner",
77
83
  "stack": {
84
+ "bazelHints": {
85
+ "commands": [
86
+ "bazel test //..."
87
+ ],
88
+ "notes": "Use rules_dotnet to define test targets for xUnit/NUnit/MSTest projects."
89
+ },
78
90
  "exampleConfigFiles": [
79
91
  "*.Tests.csproj"
80
92
  ],
@@ -181,6 +193,12 @@
181
193
  "id": "unit-test-reporter",
182
194
  "label": "Unit Test Reporter / Coverage",
183
195
  "stack": {
196
+ "bazelHints": {
197
+ "commands": [
198
+ "bazel coverage //..."
199
+ ],
200
+ "notes": "Use rules_dotnet with coverage instrumentation enabled."
201
+ },
184
202
  "exampleConfigFiles": [
185
203
  "*.csproj"
186
204
  ],
@@ -205,6 +223,13 @@
205
223
  "id": "ci-quality-gates",
206
224
  "label": "CI Quality Gates",
207
225
  "stack": {
226
+ "bazelHints": {
227
+ "commands": [
228
+ "bazel build //...",
229
+ "bazel test //..."
230
+ ],
231
+ "notes": "Bazel handles all analysis, testing, and packaging via defined targets."
232
+ },
208
233
  "exampleConfigFiles": [
209
234
  ".github/workflows/*",
210
235
  "azure-pipelines.yml"
@@ -227,6 +252,12 @@
227
252
  "id": "code-formatter",
228
253
  "label": "Code Formatter",
229
254
  "stack": {
255
+ "bazelHints": {
256
+ "commands": [
257
+ "bazel run //tools/format:dotnet_format -- --verify-no-changes"
258
+ ],
259
+ "notes": "Wrap dotnet format as a Bazel run target."
260
+ },
230
261
  "exampleConfigFiles": [
231
262
  ".editorconfig"
232
263
  ],
@@ -273,6 +304,12 @@
273
304
  "id": "type-checking",
274
305
  "label": "Type Checking",
275
306
  "stack": {
307
+ "bazelHints": {
308
+ "commands": [
309
+ "bazel build //..."
310
+ ],
311
+ "notes": "C# type errors surface during bazel build with rules_dotnet. No separate typecheck step needed."
312
+ },
276
313
  "exampleConfigFiles": [
277
314
  ".editorconfig",
278
315
  "Directory.Build.props",
@@ -599,6 +636,43 @@
599
636
  "github-actions"
600
637
  ],
601
638
  "meta": {
639
+ "bazelIntegration": {
640
+ "advisoryNotice": "bazelHints are suggestions, not required execution paths. Consumers should prefer stack-native commands unless explicitly adopting Bazel.",
641
+ "ciContract": {
642
+ "configFlag": "--config=ci (define in .bazelrc)",
643
+ "deterministicFlags": [
644
+ "--nokeep_going",
645
+ "--test_output=errors"
646
+ ],
647
+ "remoteCache": "Optional; not required for CI",
648
+ "versionPinning": "Use .bazelversion file for Bazelisk"
649
+ },
650
+ "description": "Bazel build executor support for quality checks. All hints are ADVISORY—stack-native commands remain the default execution path.",
651
+ "detectionRules": {
652
+ "notes": "Detection uses repo-root markers only. Nested BUILD files do not trigger Bazel mode.",
653
+ "optionalMarkers": [
654
+ ".bazelrc",
655
+ ".bazelversion"
656
+ ],
657
+ "rootMarkers": [
658
+ "MODULE.bazel",
659
+ "WORKSPACE.bazel",
660
+ "WORKSPACE"
661
+ ]
662
+ },
663
+ "optOut": {
664
+ "configPath": "meta.bazelIntegration.enabled",
665
+ "description": "Set meta.bazelIntegration.enabled = false in repo config to disable Bazel hints"
666
+ },
667
+ "targetConventions": {
668
+ "build": "bazel build //...",
669
+ "coverage": "bazel coverage //...",
670
+ "description": "Recommended target naming (not assumed to exist). These are illustrative patterns; actual targets are repo-defined.",
671
+ "format": "bazel run //tools/format:check",
672
+ "lint": "//tools/lint:lint or bazel test //... with lint aspects",
673
+ "test": "bazel test //..."
674
+ }
675
+ },
602
676
  "complexityChecks": {
603
677
  "description": "When supported by the stack, run cyclomatic complexity or similar metrics in CI as a warning-only check initially.",
604
678
  "enabledByDefault": true
@@ -35,6 +35,12 @@
35
35
  "id": "linting",
36
36
  "label": "Linting",
37
37
  "stack": {
38
+ "bazelHints": {
39
+ "commands": [
40
+ "bazel test //... --@io_bazel_rules_go//go/config:nogo=@//:nogo"
41
+ ],
42
+ "notes": "Use nogo for static analysis via rules_go. Configure nogo target with desired analyzers."
43
+ },
38
44
  "exampleConfigFiles": [
39
45
  ".golangci.yml",
40
46
  ".golangci.yaml"
@@ -64,6 +70,12 @@
64
70
  "id": "unit-test-runner",
65
71
  "label": "Unit Test Runner",
66
72
  "stack": {
73
+ "bazelHints": {
74
+ "commands": [
75
+ "bazel test //..."
76
+ ],
77
+ "notes": "rules_go go_test targets wrap 'go test' with Bazel's caching and hermeticity."
78
+ },
67
79
  "exampleConfigFiles": [
68
80
  "go.mod"
69
81
  ],
@@ -157,6 +169,12 @@
157
169
  "id": "unit-test-reporter",
158
170
  "label": "Unit Test Reporter / Coverage",
159
171
  "stack": {
172
+ "bazelHints": {
173
+ "commands": [
174
+ "bazel coverage //..."
175
+ ],
176
+ "notes": "rules_go supports coverage via bazel coverage. Use --combined_report=lcov for aggregated output."
177
+ },
160
178
  "exampleConfigFiles": [
161
179
  "go.mod"
162
180
  ],
@@ -178,6 +196,13 @@
178
196
  "id": "ci-quality-gates",
179
197
  "label": "CI Quality Gates",
180
198
  "stack": {
199
+ "bazelHints": {
200
+ "commands": [
201
+ "bazel build //...",
202
+ "bazel test //..."
203
+ ],
204
+ "notes": "rules_go go_binary and go_test targets provide hermetic builds and tests."
205
+ },
181
206
  "exampleConfigFiles": [
182
207
  ".github/workflows/*",
183
208
  "azure-pipelines.yml"
@@ -197,6 +222,12 @@
197
222
  "id": "code-formatter",
198
223
  "label": "Code Formatter",
199
224
  "stack": {
225
+ "bazelHints": {
226
+ "commands": [
227
+ "bazel run @go_sdk//:bin/gofmt -- -d ."
228
+ ],
229
+ "notes": "Run gofmt via the Bazel-managed Go SDK for hermetic formatting checks."
230
+ },
200
231
  "exampleConfigFiles": [],
201
232
  "exampleTools": [
202
233
  "gofmt",
@@ -238,6 +269,12 @@
238
269
  "id": "type-checking",
239
270
  "label": "Type Checking",
240
271
  "stack": {
272
+ "bazelHints": {
273
+ "commands": [
274
+ "bazel build //..."
275
+ ],
276
+ "notes": "Go type checking is inherent to compilation. bazel build with rules_go enforces type safety."
277
+ },
241
278
  "exampleConfigFiles": [
242
279
  "go.mod"
243
280
  ],
@@ -515,6 +552,43 @@
515
552
  "azure-devops"
516
553
  ],
517
554
  "meta": {
555
+ "bazelIntegration": {
556
+ "advisoryNotice": "bazelHints are suggestions, not required execution paths. Consumers should prefer stack-native commands unless explicitly adopting Bazel.",
557
+ "ciContract": {
558
+ "configFlag": "--config=ci (define in .bazelrc)",
559
+ "deterministicFlags": [
560
+ "--nokeep_going",
561
+ "--test_output=errors"
562
+ ],
563
+ "remoteCache": "Optional; not required for CI",
564
+ "versionPinning": "Use .bazelversion file for Bazelisk"
565
+ },
566
+ "description": "Bazel build executor support for quality checks. All hints are ADVISORY—stack-native commands remain the default execution path.",
567
+ "detectionRules": {
568
+ "notes": "Detection uses repo-root markers only. Nested BUILD files do not trigger Bazel mode.",
569
+ "optionalMarkers": [
570
+ ".bazelrc",
571
+ ".bazelversion"
572
+ ],
573
+ "rootMarkers": [
574
+ "MODULE.bazel",
575
+ "WORKSPACE.bazel",
576
+ "WORKSPACE"
577
+ ]
578
+ },
579
+ "optOut": {
580
+ "configPath": "meta.bazelIntegration.enabled",
581
+ "description": "Set meta.bazelIntegration.enabled = false in repo config to disable Bazel hints"
582
+ },
583
+ "targetConventions": {
584
+ "build": "bazel build //...",
585
+ "coverage": "bazel coverage //...",
586
+ "description": "Recommended target naming (not assumed to exist). These are illustrative patterns; actual targets are repo-defined.",
587
+ "format": "bazel run //tools/format:check",
588
+ "lint": "//tools/lint:lint or bazel test //... with lint aspects",
589
+ "test": "bazel test //..."
590
+ }
591
+ },
518
592
  "complexityChecks": {
519
593
  "description": "When supported by the stack, run cyclomatic complexity or similar metrics in CI as a warning-only check initially.",
520
594
  "enabledByDefault": true