patchdrill 0.1.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.
Files changed (169) hide show
  1. package/.patchdrill.yml +33 -0
  2. package/CHANGELOG.md +150 -0
  3. package/CONTRIBUTING.md +59 -0
  4. package/LICENSE +21 -0
  5. package/README.md +601 -0
  6. package/SECURITY.md +28 -0
  7. package/action.yml +338 -0
  8. package/dist/baseline.d.ts +9 -0
  9. package/dist/baseline.js +38 -0
  10. package/dist/baseline.js.map +1 -0
  11. package/dist/cli.d.ts +19 -0
  12. package/dist/cli.js +662 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/codeowners.d.ts +14 -0
  15. package/dist/codeowners.js +104 -0
  16. package/dist/codeowners.js.map +1 -0
  17. package/dist/command-plan.d.ts +3 -0
  18. package/dist/command-plan.js +26 -0
  19. package/dist/command-plan.js.map +1 -0
  20. package/dist/demo.d.ts +5 -0
  21. package/dist/demo.js +525 -0
  22. package/dist/demo.js.map +1 -0
  23. package/dist/dependency.d.ts +4 -0
  24. package/dist/dependency.js +1424 -0
  25. package/dist/dependency.js.map +1 -0
  26. package/dist/doctor.d.ts +26 -0
  27. package/dist/doctor.js +183 -0
  28. package/dist/doctor.js.map +1 -0
  29. package/dist/evidence.d.ts +64 -0
  30. package/dist/evidence.js +352 -0
  31. package/dist/evidence.js.map +1 -0
  32. package/dist/git.d.ts +16 -0
  33. package/dist/git.js +349 -0
  34. package/dist/git.js.map +1 -0
  35. package/dist/i18n-catalog.d.ts +8 -0
  36. package/dist/i18n-catalog.js +446 -0
  37. package/dist/i18n-catalog.js.map +1 -0
  38. package/dist/i18n.d.ts +20 -0
  39. package/dist/i18n.js +67 -0
  40. package/dist/i18n.js.map +1 -0
  41. package/dist/init.d.ts +13 -0
  42. package/dist/init.js +312 -0
  43. package/dist/init.js.map +1 -0
  44. package/dist/markdown-links.d.ts +18 -0
  45. package/dist/markdown-links.js +180 -0
  46. package/dist/markdown-links.js.map +1 -0
  47. package/dist/package-scripts.d.ts +3 -0
  48. package/dist/package-scripts.js +55 -0
  49. package/dist/package-scripts.js.map +1 -0
  50. package/dist/planner.d.ts +8 -0
  51. package/dist/planner.js +2351 -0
  52. package/dist/planner.js.map +1 -0
  53. package/dist/policy.d.ts +12 -0
  54. package/dist/policy.js +255 -0
  55. package/dist/policy.js.map +1 -0
  56. package/dist/project.d.ts +2 -0
  57. package/dist/project.js +1085 -0
  58. package/dist/project.js.map +1 -0
  59. package/dist/release-readiness.d.ts +25 -0
  60. package/dist/release-readiness.js +426 -0
  61. package/dist/release-readiness.js.map +1 -0
  62. package/dist/report-annotations.d.ts +3 -0
  63. package/dist/report-annotations.js +28 -0
  64. package/dist/report-annotations.js.map +1 -0
  65. package/dist/report-contract.d.ts +2 -0
  66. package/dist/report-contract.js +82 -0
  67. package/dist/report-contract.js.map +1 -0
  68. package/dist/report-html.d.ts +7 -0
  69. package/dist/report-html.js +706 -0
  70. package/dist/report-html.js.map +1 -0
  71. package/dist/report-sarif.d.ts +2 -0
  72. package/dist/report-sarif.js +90 -0
  73. package/dist/report-sarif.js.map +1 -0
  74. package/dist/report.d.ts +14 -0
  75. package/dist/report.js +310 -0
  76. package/dist/report.js.map +1 -0
  77. package/dist/risk.d.ts +19 -0
  78. package/dist/risk.js +1226 -0
  79. package/dist/risk.js.map +1 -0
  80. package/dist/runner.d.ts +8 -0
  81. package/dist/runner.js +113 -0
  82. package/dist/runner.js.map +1 -0
  83. package/dist/scan.d.ts +2 -0
  84. package/dist/scan.js +195 -0
  85. package/dist/scan.js.map +1 -0
  86. package/dist/schema.d.ts +12 -0
  87. package/dist/schema.js +30 -0
  88. package/dist/schema.js.map +1 -0
  89. package/dist/stack-coverage.d.ts +8 -0
  90. package/dist/stack-coverage.js +94 -0
  91. package/dist/stack-coverage.js.map +1 -0
  92. package/dist/types.d.ts +206 -0
  93. package/dist/types.js +2 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/verification.d.ts +11 -0
  96. package/dist/verification.js +108 -0
  97. package/dist/verification.js.map +1 -0
  98. package/docs/ANNOTATIONS.md +34 -0
  99. package/docs/ARCHITECTURE.md +79 -0
  100. package/docs/BASELINES.md +32 -0
  101. package/docs/CASE_STUDIES.md +106 -0
  102. package/docs/CODEOWNERS.md +23 -0
  103. package/docs/DASHBOARD.md +87 -0
  104. package/docs/EVIDENCE.md +55 -0
  105. package/docs/LAUNCH_PLAYBOOK.md +103 -0
  106. package/docs/MONOREPOS.md +74 -0
  107. package/docs/POLICY.md +98 -0
  108. package/docs/PROOF_PACKS.md +57 -0
  109. package/docs/PR_COMMENTS.md +56 -0
  110. package/docs/RELEASE.md +35 -0
  111. package/docs/ROADMAP.md +152 -0
  112. package/docs/RULE_CATALOG.md +90 -0
  113. package/docs/SARIF.md +74 -0
  114. package/docs/SCHEMAS.md +49 -0
  115. package/docs/SECURITY_POSTURE.md +32 -0
  116. package/docs/STACK_COVERAGE.md +20 -0
  117. package/docs/assets/patchdrill-demo.svg +21 -0
  118. package/docs/media/patchdrill-dashboard.png +0 -0
  119. package/docs/media/patchdrill-demo.gif +0 -0
  120. package/examples/case-studies/README.md +20 -0
  121. package/examples/demo/README.md +21 -0
  122. package/examples/demo/patchdrill-demo-summary.md +35 -0
  123. package/examples/demo/patchdrill-demo.html +623 -0
  124. package/examples/demo/patchdrill-demo.json +355 -0
  125. package/examples/demo/patchdrill-demo.md +120 -0
  126. package/examples/demo/patchdrill-demo.sarif +195 -0
  127. package/examples/report.md +128 -0
  128. package/examples/risky-agent-pr/README.md +15 -0
  129. package/examples/risky-agent-pr/patchdrill-demo-summary.md +41 -0
  130. package/examples/risky-agent-pr/patchdrill-demo.html +681 -0
  131. package/examples/risky-agent-pr/patchdrill-demo.json +483 -0
  132. package/examples/risky-agent-pr/patchdrill-demo.md +140 -0
  133. package/examples/risky-agent-pr/patchdrill-demo.sarif +398 -0
  134. package/fixtures/stacks/README.md +4 -0
  135. package/fixtures/stacks/android-gradle/fixture.json +33 -0
  136. package/fixtures/stacks/aspnet-core-service/fixture.json +36 -0
  137. package/fixtures/stacks/bazel-workspace/fixture.json +30 -0
  138. package/fixtures/stacks/buck2-workspace/fixture.json +30 -0
  139. package/fixtures/stacks/cargo-workspace/fixture.json +48 -0
  140. package/fixtures/stacks/django-app/fixture.json +25 -0
  141. package/fixtures/stacks/docker-compose/fixture.json +17 -0
  142. package/fixtures/stacks/dockerfile-service/fixture.json +17 -0
  143. package/fixtures/stacks/dotnet-service/fixture.json +36 -0
  144. package/fixtures/stacks/dotnet-solution-filter/fixture.json +62 -0
  145. package/fixtures/stacks/fastapi-app/fixture.json +29 -0
  146. package/fixtures/stacks/go-workspace/fixture.json +48 -0
  147. package/fixtures/stacks/java-gradle/fixture.json +29 -0
  148. package/fixtures/stacks/java-maven/fixture.json +32 -0
  149. package/fixtures/stacks/kubernetes-helm/fixture.json +25 -0
  150. package/fixtures/stacks/kubernetes-kustomize/fixture.json +21 -0
  151. package/fixtures/stacks/nested-go-workspace/fixture.json +51 -0
  152. package/fixtures/stacks/nextjs-app/fixture.json +34 -0
  153. package/fixtures/stacks/node-turbo-workspace/fixture.json +39 -0
  154. package/fixtures/stacks/pants-python/fixture.json +33 -0
  155. package/fixtures/stacks/php-composer/fixture.json +31 -0
  156. package/fixtures/stacks/python-service/fixture.json +21 -0
  157. package/fixtures/stacks/rails-app/fixture.json +25 -0
  158. package/fixtures/stacks/spring-boot-gradle/fixture.json +29 -0
  159. package/fixtures/stacks/spring-boot-maven/fixture.json +43 -0
  160. package/fixtures/stacks/swift-package/fixture.json +21 -0
  161. package/fixtures/stacks/terraform-module/fixture.json +17 -0
  162. package/fixtures/stacks/uv-python-service/fixture.json +47 -0
  163. package/fixtures/stacks/xcode-app/fixture.json +72 -0
  164. package/package.json +80 -0
  165. package/schemas/patchdrill-doctor.schema.json +171 -0
  166. package/schemas/patchdrill-evidence.schema.json +239 -0
  167. package/schemas/patchdrill-policy.schema.json +170 -0
  168. package/schemas/patchdrill-release-check.schema.json +78 -0
  169. package/schemas/patchdrill-report.schema.json +647 -0
@@ -0,0 +1,398 @@
1
+ {
2
+ "version": "2.1.0",
3
+ "$schema": "https://json.schemastore.org/sarif-2.1.0.json",
4
+ "runs": [
5
+ {
6
+ "tool": {
7
+ "driver": {
8
+ "name": "PatchDrill",
9
+ "informationUri": "https://github.com/seungdori/patchdrill",
10
+ "rules": [
11
+ {
12
+ "id": "workflow.pull-request-target-head-checkout",
13
+ "name": "Privileged workflow checks out pull request code",
14
+ "shortDescription": {
15
+ "text": "Privileged workflow checks out pull request code"
16
+ },
17
+ "help": {
18
+ "text": "Use pull_request for untrusted code, remove PR-head checkout, or split the privileged publishing step behind an environment gate."
19
+ },
20
+ "properties": {
21
+ "severity": "critical",
22
+ "tags": [
23
+ "ci",
24
+ "supply-chain",
25
+ "github-actions"
26
+ ]
27
+ }
28
+ },
29
+ {
30
+ "id": "secret.generic-assignment",
31
+ "name": "Secret-looking value added",
32
+ "shortDescription": {
33
+ "text": "Secret-looking value added"
34
+ },
35
+ "help": {
36
+ "text": "Remove the value, rotate the credential if it was real, and use a non-secret placeholder such as <redacted>."
37
+ },
38
+ "properties": {
39
+ "severity": "critical",
40
+ "tags": [
41
+ "secret",
42
+ "credentials"
43
+ ]
44
+ }
45
+ },
46
+ {
47
+ "id": "agent.control-file",
48
+ "name": "Agent instructions changed",
49
+ "shortDescription": {
50
+ "text": "Agent instructions changed"
51
+ },
52
+ "help": {
53
+ "text": "Review instruction changes separately and require maintainer approval before agent-visible rules change."
54
+ },
55
+ "properties": {
56
+ "severity": "high",
57
+ "tags": [
58
+ "agentic-coding",
59
+ "review"
60
+ ]
61
+ }
62
+ },
63
+ {
64
+ "id": "file.high-impact-area",
65
+ "name": "High-impact product area changed",
66
+ "shortDescription": {
67
+ "text": "High-impact product area changed"
68
+ },
69
+ "help": {
70
+ "text": "Attach targeted billing regression tests and owner approval."
71
+ },
72
+ "properties": {
73
+ "severity": "high",
74
+ "tags": [
75
+ "billing",
76
+ "payments"
77
+ ]
78
+ }
79
+ },
80
+ {
81
+ "id": "package-script.disabled-verification",
82
+ "name": "Verification script disabled: test",
83
+ "shortDescription": {
84
+ "text": "Verification script disabled: test"
85
+ },
86
+ "help": {
87
+ "text": "Restore the real verification command or explain why this repository no longer has that check."
88
+ },
89
+ "properties": {
90
+ "severity": "high",
91
+ "tags": [
92
+ "testing",
93
+ "ci",
94
+ "package-script"
95
+ ]
96
+ }
97
+ },
98
+ {
99
+ "id": "package-script.lifecycle",
100
+ "name": "Package lifecycle script changed: postinstall",
101
+ "shortDescription": {
102
+ "text": "Package lifecycle script changed: postinstall"
103
+ },
104
+ "help": {
105
+ "text": "Review the script as executable supply-chain surface. Prefer explicit CI steps or documented commands over implicit install-time behavior."
106
+ },
107
+ "properties": {
108
+ "severity": "high",
109
+ "tags": [
110
+ "dependencies",
111
+ "supply-chain",
112
+ "package-script"
113
+ ]
114
+ }
115
+ },
116
+ {
117
+ "id": "test.source-without-test-change",
118
+ "name": "Source changed without matching test changes",
119
+ "shortDescription": {
120
+ "text": "Source changed without matching test changes"
121
+ },
122
+ "help": {
123
+ "text": "Add or update tests covering signed webhook verification, failed payment paths, and entitlement updates."
124
+ },
125
+ "properties": {
126
+ "severity": "medium",
127
+ "tags": [
128
+ "tests"
129
+ ]
130
+ }
131
+ },
132
+ {
133
+ "id": "file.lockfile",
134
+ "name": "Dependency lockfile changed",
135
+ "shortDescription": {
136
+ "text": "Dependency lockfile changed"
137
+ },
138
+ "help": {
139
+ "text": "Review release notes and verify transitive dependency impact."
140
+ },
141
+ "properties": {
142
+ "severity": "low",
143
+ "tags": [
144
+ "dependencies"
145
+ ]
146
+ }
147
+ }
148
+ ]
149
+ }
150
+ },
151
+ "invocations": [
152
+ {
153
+ "executionSuccessful": false,
154
+ "properties": {
155
+ "status": "fail",
156
+ "riskScore": 94,
157
+ "confidenceScore": 21
158
+ }
159
+ }
160
+ ],
161
+ "results": [
162
+ {
163
+ "ruleId": "workflow.pull-request-target-head-checkout",
164
+ "level": "error",
165
+ "message": {
166
+ "text": "Privileged workflow checks out pull request code: A pull_request_target workflow can run untrusted pull request code while write tokens or repository secrets are available. Remediation: Use pull_request for untrusted code, remove PR-head checkout, or split the privileged publishing step behind an environment gate."
167
+ },
168
+ "locations": [
169
+ {
170
+ "physicalLocation": {
171
+ "artifactLocation": {
172
+ "uri": ".github/workflows/release.yml"
173
+ },
174
+ "region": {
175
+ "startLine": 19
176
+ }
177
+ }
178
+ }
179
+ ],
180
+ "properties": {
181
+ "severity": "critical",
182
+ "tags": [
183
+ "ci",
184
+ "supply-chain",
185
+ "github-actions"
186
+ ]
187
+ },
188
+ "partialFingerprints": {
189
+ "patchdrillFinding": "dd62de8821265a5bce0d09b31b7d674fad3eeeeb9321ad6787b49ce39fb6968e"
190
+ }
191
+ },
192
+ {
193
+ "ruleId": "secret.generic-assignment",
194
+ "level": "error",
195
+ "message": {
196
+ "text": "Secret-looking value added: A newly added environment example contains a value with a live-key shape. The demo redacts the actual token body. Remediation: Remove the value, rotate the credential if it was real, and use a non-secret placeholder such as <redacted>."
197
+ },
198
+ "locations": [
199
+ {
200
+ "physicalLocation": {
201
+ "artifactLocation": {
202
+ "uri": ".env.example"
203
+ },
204
+ "region": {
205
+ "startLine": 8
206
+ }
207
+ }
208
+ }
209
+ ],
210
+ "properties": {
211
+ "severity": "critical",
212
+ "tags": [
213
+ "secret",
214
+ "credentials"
215
+ ]
216
+ },
217
+ "partialFingerprints": {
218
+ "patchdrillFinding": "7cce2c7a32196fafdb1cd236916f34fb87c4809d0d0f9b6711b9746cb047ddb4"
219
+ }
220
+ },
221
+ {
222
+ "ruleId": "agent.control-file",
223
+ "level": "error",
224
+ "message": {
225
+ "text": "Agent instructions changed: Repository-level coding-agent instructions changed in the same patch as release and billing code. Remediation: Review instruction changes separately and require maintainer approval before agent-visible rules change."
226
+ },
227
+ "locations": [
228
+ {
229
+ "physicalLocation": {
230
+ "artifactLocation": {
231
+ "uri": "AGENTS.md"
232
+ },
233
+ "region": {
234
+ "startLine": 1
235
+ }
236
+ }
237
+ }
238
+ ],
239
+ "properties": {
240
+ "severity": "high",
241
+ "tags": [
242
+ "agentic-coding",
243
+ "review"
244
+ ]
245
+ },
246
+ "partialFingerprints": {
247
+ "patchdrillFinding": "152935f9d990a29a16471df2c81a179d3c1e4c49f056bff3ccf629362d22d014"
248
+ }
249
+ },
250
+ {
251
+ "ruleId": "file.high-impact-area",
252
+ "level": "error",
253
+ "message": {
254
+ "text": "High-impact product area changed: Billing checkout and webhook code changed, which can affect payment capture, refunds, and entitlement state. Remediation: Attach targeted billing regression tests and owner approval."
255
+ },
256
+ "locations": [
257
+ {
258
+ "physicalLocation": {
259
+ "artifactLocation": {
260
+ "uri": "apps/web/src/billing/checkout.ts"
261
+ },
262
+ "region": {
263
+ "startLine": 1
264
+ }
265
+ }
266
+ }
267
+ ],
268
+ "properties": {
269
+ "severity": "high",
270
+ "tags": [
271
+ "billing",
272
+ "payments"
273
+ ]
274
+ },
275
+ "partialFingerprints": {
276
+ "patchdrillFinding": "2fd95cd4c8bf6a886b6a8c77850232bda70c8c5559f4e603d58bb93a8b104859"
277
+ }
278
+ },
279
+ {
280
+ "ruleId": "package-script.disabled-verification",
281
+ "level": "error",
282
+ "message": {
283
+ "text": "Verification script disabled: test: package.json verification script \"test\" now appears to exit successfully without running meaningful checks. Remediation: Restore the real verification command or explain why this repository no longer has that check."
284
+ },
285
+ "locations": [
286
+ {
287
+ "physicalLocation": {
288
+ "artifactLocation": {
289
+ "uri": "package.json"
290
+ },
291
+ "region": {
292
+ "startLine": 1
293
+ }
294
+ }
295
+ }
296
+ ],
297
+ "properties": {
298
+ "severity": "high",
299
+ "tags": [
300
+ "testing",
301
+ "ci",
302
+ "package-script"
303
+ ]
304
+ },
305
+ "partialFingerprints": {
306
+ "patchdrillFinding": "f659ab1a5d6066ca9afb587095764ba745ca4ea1dcf74a4544c45d73a656e6c8"
307
+ }
308
+ },
309
+ {
310
+ "ruleId": "package-script.lifecycle",
311
+ "level": "error",
312
+ "message": {
313
+ "text": "Package lifecycle script changed: postinstall: package.json lifecycle script \"postinstall\" was added, creating code that can run during install, prepare, pack, or publish flows. Remediation: Review the script as executable supply-chain surface. Prefer explicit CI steps or documented commands over implicit install-time behavior."
314
+ },
315
+ "locations": [
316
+ {
317
+ "physicalLocation": {
318
+ "artifactLocation": {
319
+ "uri": "package.json"
320
+ },
321
+ "region": {
322
+ "startLine": 1
323
+ }
324
+ }
325
+ }
326
+ ],
327
+ "properties": {
328
+ "severity": "high",
329
+ "tags": [
330
+ "dependencies",
331
+ "supply-chain",
332
+ "package-script"
333
+ ]
334
+ },
335
+ "partialFingerprints": {
336
+ "patchdrillFinding": "99a9a7495c0512a3b640ab4d14d78fb359968ef544025231d6154da6b5a0cafc"
337
+ }
338
+ },
339
+ {
340
+ "ruleId": "test.source-without-test-change",
341
+ "level": "warning",
342
+ "message": {
343
+ "text": "Source changed without matching test changes: Billing source files changed, but no matching checkout or webhook test files changed. Remediation: Add or update tests covering signed webhook verification, failed payment paths, and entitlement updates."
344
+ },
345
+ "locations": [
346
+ {
347
+ "physicalLocation": {
348
+ "artifactLocation": {
349
+ "uri": "apps/web/src/billing/checkout.ts"
350
+ },
351
+ "region": {
352
+ "startLine": 1
353
+ }
354
+ }
355
+ }
356
+ ],
357
+ "properties": {
358
+ "severity": "medium",
359
+ "tags": [
360
+ "tests"
361
+ ]
362
+ },
363
+ "partialFingerprints": {
364
+ "patchdrillFinding": "07dddbd9eebea7fef9b24ccb8c66e70be0936ed69cc404f657ec6a3d2feb87ac"
365
+ }
366
+ },
367
+ {
368
+ "ruleId": "file.lockfile",
369
+ "level": "note",
370
+ "message": {
371
+ "text": "Dependency lockfile changed: @acme/payments changed from 4.2.0 to 4.3.0. Remediation: Review release notes and verify transitive dependency impact."
372
+ },
373
+ "locations": [
374
+ {
375
+ "physicalLocation": {
376
+ "artifactLocation": {
377
+ "uri": "package-lock.json"
378
+ },
379
+ "region": {
380
+ "startLine": 1
381
+ }
382
+ }
383
+ }
384
+ ],
385
+ "properties": {
386
+ "severity": "low",
387
+ "tags": [
388
+ "dependencies"
389
+ ]
390
+ },
391
+ "partialFingerprints": {
392
+ "patchdrillFinding": "5cdefc8ce238a88cde78ab92957d8d0b3f84483f99a431e5dd9af6c80012c92d"
393
+ }
394
+ }
395
+ ]
396
+ }
397
+ ]
398
+ }
@@ -0,0 +1,4 @@
1
+ # Stack Fixtures
2
+
3
+ These fixtures are small, committed repository shapes that PatchDrill scans in tests. Each fixture defines base files, changed files, and the expected verification plan. They keep ecosystem detection and monorepo targeting behavior stable as the planner grows.
4
+
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "android-gradle",
3
+ "expectedEcosystems": ["android"],
4
+ "expectedCommands": ["./gradlew testDebugUnitTest", "./gradlew assembleDebug", "./gradlew lintDebug"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "settings.gradle",
8
+ "lines": ["pluginManagement { repositories { google(); mavenCentral(); gradlePluginPortal() } }", "dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS); repositories { google(); mavenCentral() } }", "rootProject.name = 'MobileApp'", "include ':app'"]
9
+ },
10
+ {
11
+ "path": "app/build.gradle",
12
+ "lines": ["plugins {", " id 'com.android.application'", "}", "android {", " namespace 'com.acme.mobile'", " compileSdk 35", " defaultConfig { applicationId 'com.acme.mobile'; minSdk 24; targetSdk 35; versionCode 1; versionName '1.0' }", "}"]
13
+ },
14
+ {
15
+ "path": "gradlew",
16
+ "lines": ["#!/bin/sh", "echo gradle wrapper"]
17
+ },
18
+ {
19
+ "path": "app/src/main/AndroidManifest.xml",
20
+ "lines": ["<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" />"]
21
+ },
22
+ {
23
+ "path": "app/src/main/java/com/acme/mobile/MainActivity.kt",
24
+ "lines": ["package com.acme.mobile", "class MainActivity { fun ready() = true }"]
25
+ }
26
+ ],
27
+ "changeFiles": [
28
+ {
29
+ "path": "app/src/main/res/values/strings.xml",
30
+ "lines": ["<resources>", " <string name=\"app_name\">PatchDrill Mobile</string>", "</resources>"]
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "aspnet-core-service",
3
+ "expectedEcosystems": ["dotnet"],
4
+ "expectedCommands": [
5
+ "dotnet test tests/Api.Tests/Api.Tests.csproj",
6
+ "dotnet build src/Api/Api.csproj --no-restore",
7
+ "dotnet publish src/Api/Api.csproj --no-restore"
8
+ ],
9
+ "baseFiles": [
10
+ {
11
+ "path": "src/Api/Api.csproj",
12
+ "lines": ["<Project Sdk=\"Microsoft.NET.Sdk.Web\">", " <PropertyGroup>", " <TargetFramework>net8.0</TargetFramework>", " <Nullable>enable</Nullable>", " </PropertyGroup>", "</Project>"]
13
+ },
14
+ {
15
+ "path": "tests/Api.Tests/Api.Tests.csproj",
16
+ "lines": [
17
+ "<Project Sdk=\"Microsoft.NET.Sdk\">",
18
+ " <ItemGroup>",
19
+ " <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.10.0\" />",
20
+ " <ProjectReference Include=\"../../src/Api/Api.csproj\" />",
21
+ " </ItemGroup>",
22
+ "</Project>"
23
+ ]
24
+ },
25
+ {
26
+ "path": "src/Api/Program.cs",
27
+ "lines": ["var builder = WebApplication.CreateBuilder(args);", "var app = builder.Build();", "app.MapGet(\"/health\", () => Results.Ok(new { ok = true }));", "app.Run();"]
28
+ }
29
+ ],
30
+ "changeFiles": [
31
+ {
32
+ "path": "src/Api/Program.cs",
33
+ "lines": ["var builder = WebApplication.CreateBuilder(args);", "var app = builder.Build();", "app.MapGet(\"/health\", () => Results.Ok(new { ok = false }));", "app.Run();"]
34
+ }
35
+ ]
36
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "bazel-workspace",
3
+ "expectedEcosystems": ["bazel"],
4
+ "expectedCommands": [
5
+ "bazel test //src/app/...",
6
+ "bazel build //src/app/...",
7
+ "bazel query 'rdeps(//..., set(//src/app/...))'",
8
+ "targets=\"$(bazel query 'tests(rdeps(//..., set(//src/app/...)))')\" && if [ -n \"$targets\" ]; then bazel test $targets; else echo 'No downstream Bazel tests found'; fi"
9
+ ],
10
+ "baseFiles": [
11
+ {
12
+ "path": "MODULE.bazel",
13
+ "lines": ["module(name = \"api\")"]
14
+ },
15
+ {
16
+ "path": "src/app/BUILD.bazel",
17
+ "lines": ["java_library(", " name = \"app\",", " srcs = [\"App.java\"],", ")"]
18
+ },
19
+ {
20
+ "path": "src/app/App.java",
21
+ "lines": ["package app;", "public class App { public boolean ok() { return true; } }"]
22
+ }
23
+ ],
24
+ "changeFiles": [
25
+ {
26
+ "path": "src/app/App.java",
27
+ "lines": ["package app;", "public class App { public boolean ok() { return false; } }"]
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "buck2-workspace",
3
+ "expectedEcosystems": ["buck"],
4
+ "expectedCommands": [
5
+ "buck2 test //src/app/...",
6
+ "buck2 build //src/app/...",
7
+ "buck2 uquery 'rdeps(//..., set(//src/app/...))'",
8
+ "targets=\"$(buck2 uquery 'testsof(rdeps(//..., set(//src/app/...)))')\" && if [ -n \"$targets\" ]; then buck2 test $targets; else echo 'No downstream Buck tests found'; fi"
9
+ ],
10
+ "baseFiles": [
11
+ {
12
+ "path": ".buckconfig",
13
+ "lines": ["[cells]", " root = ."]
14
+ },
15
+ {
16
+ "path": "src/app/BUCK",
17
+ "lines": ["python_library(", " name = \"app\",", " srcs = [\"app.py\"],", ")"]
18
+ },
19
+ {
20
+ "path": "src/app/app.py",
21
+ "lines": ["def ok():", " return True"]
22
+ }
23
+ ],
24
+ "changeFiles": [
25
+ {
26
+ "path": "src/app/app.py",
27
+ "lines": ["def ok():", " return False"]
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "cargo-workspace",
3
+ "expectedEcosystems": ["rust"],
4
+ "expectedAffectedPackages": ["core-lib", "api-server"],
5
+ "expectedCommands": [
6
+ "cargo test -p core-lib --all-targets",
7
+ "cargo clippy -p core-lib --all-targets -- -D warnings",
8
+ "cargo test -p api-server --all-targets",
9
+ "cargo clippy -p api-server --all-targets -- -D warnings"
10
+ ],
11
+ "baseFiles": [
12
+ {
13
+ "path": "Cargo.toml",
14
+ "lines": ["[workspace]", "members = [\"crates/*\"]"]
15
+ },
16
+ {
17
+ "path": "crates/core/Cargo.toml",
18
+ "lines": ["[package]", "name = \"core-lib\"", "version = \"0.1.0\"", "edition = \"2021\""]
19
+ },
20
+ {
21
+ "path": "crates/core/src/lib.rs",
22
+ "lines": ["pub fn core() -> bool { true }"]
23
+ },
24
+ {
25
+ "path": "crates/api/Cargo.toml",
26
+ "lines": [
27
+ "[package]",
28
+ "name = \"api-server\"",
29
+ "version = \"0.1.0\"",
30
+ "edition = \"2021\"",
31
+ "",
32
+ "[dependencies]",
33
+ "core-lib = { path = \"../core\" }"
34
+ ]
35
+ },
36
+ {
37
+ "path": "crates/api/src/lib.rs",
38
+ "lines": ["pub fn api() -> bool { core_lib::core() }"]
39
+ }
40
+ ],
41
+ "changeFiles": [
42
+ {
43
+ "path": "crates/core/src/lib.rs",
44
+ "lines": ["pub fn core() -> bool { false }"]
45
+ }
46
+ ]
47
+ }
48
+
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "django-app",
3
+ "expectedEcosystems": ["python"],
4
+ "expectedCommands": ["python manage.py test", "python manage.py check", "python -m compileall ."],
5
+ "baseFiles": [
6
+ {
7
+ "path": "manage.py",
8
+ "lines": ["#!/usr/bin/env python", "import sys", "if __name__ == \"__main__\":", " from django.core.management import execute_from_command_line", " execute_from_command_line(sys.argv)"]
9
+ },
10
+ {
11
+ "path": "requirements.txt",
12
+ "lines": ["Django==5.0.0"]
13
+ },
14
+ {
15
+ "path": "app/views.py",
16
+ "lines": ["def home(request):", " return \"ok\""]
17
+ }
18
+ ],
19
+ "changeFiles": [
20
+ {
21
+ "path": "app/views.py",
22
+ "lines": ["def home(request):", " return \"changed\""]
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "docker-compose",
3
+ "expectedEcosystems": ["docker"],
4
+ "expectedCommands": ["docker compose -f compose.yaml config"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "compose.yaml",
8
+ "lines": ["services:", " api:", " image: node:22-alpine", " command: node server.js"]
9
+ }
10
+ ],
11
+ "changeFiles": [
12
+ {
13
+ "path": "compose.yaml",
14
+ "lines": ["services:", " api:", " image: node:22-alpine", " command: node server.js", " restart: unless-stopped"]
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "dockerfile-service",
3
+ "expectedEcosystems": ["docker"],
4
+ "expectedCommands": ["docker build services/api"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "services/api/Dockerfile",
8
+ "lines": ["FROM node:22-alpine", "WORKDIR /app", "COPY . .", "CMD [\"node\", \"server.js\"]"]
9
+ }
10
+ ],
11
+ "changeFiles": [
12
+ {
13
+ "path": "services/api/Dockerfile",
14
+ "lines": ["FROM node:22-alpine", "WORKDIR /app", "COPY package.json .", "COPY . .", "CMD [\"node\", \"server.js\"]"]
15
+ }
16
+ ]
17
+ }