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,36 @@
1
+ {
2
+ "name": "dotnet-service",
3
+ "expectedEcosystems": ["dotnet"],
4
+ "expectedCommands": ["dotnet test tests/Api.Tests/Api.Tests.csproj", "dotnet build src/Api/Api.csproj --no-restore"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "global.json",
8
+ "lines": ["{", " \"sdk\": {", " \"version\": \"8.0.100\"", " }", "}"]
9
+ },
10
+ {
11
+ "path": "src/Api/Api.csproj",
12
+ "lines": ["<Project Sdk=\"Microsoft.NET.Sdk\">", " <PropertyGroup>", " <TargetFramework>net8.0</TargetFramework>", " </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/Service.cs",
27
+ "lines": ["namespace Api;", "public class Service { public bool Ok() => true; }"]
28
+ }
29
+ ],
30
+ "changeFiles": [
31
+ {
32
+ "path": "src/Api/Service.cs",
33
+ "lines": ["namespace Api;", "public class Service { public bool Ok() => false; }"]
34
+ }
35
+ ]
36
+ }
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "dotnet-solution-filter",
3
+ "expectedEcosystems": ["dotnet"],
4
+ "expectedCommands": ["dotnet test Api.slnf", "dotnet build Api.slnf --no-restore"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "App.sln",
8
+ "lines": ["Microsoft Visual Studio Solution File"]
9
+ },
10
+ {
11
+ "path": "Api.slnf",
12
+ "lines": [
13
+ "{",
14
+ " \"solution\": {",
15
+ " \"path\": \"App.sln\",",
16
+ " \"projects\": [\"src/Api/Api.csproj\", \"tests/Api.Tests/Api.Tests.csproj\"]",
17
+ " }",
18
+ "}"
19
+ ]
20
+ },
21
+ {
22
+ "path": "All.slnf",
23
+ "lines": [
24
+ "{",
25
+ " \"solution\": {",
26
+ " \"path\": \"App.sln\",",
27
+ " \"projects\": [\"src/Api/Api.csproj\", \"src/Admin/Admin.csproj\", \"tests/Api.Tests/Api.Tests.csproj\"]",
28
+ " }",
29
+ "}"
30
+ ]
31
+ },
32
+ {
33
+ "path": "src/Api/Api.csproj",
34
+ "lines": ["<Project Sdk=\"Microsoft.NET.Sdk\">", " <PropertyGroup>", " <TargetFramework>net8.0</TargetFramework>", " </PropertyGroup>", "</Project>"]
35
+ },
36
+ {
37
+ "path": "src/Admin/Admin.csproj",
38
+ "lines": ["<Project Sdk=\"Microsoft.NET.Sdk\">", " <PropertyGroup>", " <TargetFramework>net8.0</TargetFramework>", " </PropertyGroup>", "</Project>"]
39
+ },
40
+ {
41
+ "path": "tests/Api.Tests/Api.Tests.csproj",
42
+ "lines": [
43
+ "<Project Sdk=\"Microsoft.NET.Sdk\">",
44
+ " <ItemGroup>",
45
+ " <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.10.0\" />",
46
+ " <ProjectReference Include=\"../../src/Api/Api.csproj\" />",
47
+ " </ItemGroup>",
48
+ "</Project>"
49
+ ]
50
+ },
51
+ {
52
+ "path": "src/Api/Service.cs",
53
+ "lines": ["namespace Api;", "public class Service { public bool Ok() => true; }"]
54
+ }
55
+ ],
56
+ "changeFiles": [
57
+ {
58
+ "path": "src/Api/Service.cs",
59
+ "lines": ["namespace Api;", "public class Service { public bool Ok() => false; }"]
60
+ }
61
+ ]
62
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "fastapi-app",
3
+ "expectedEcosystems": ["python"],
4
+ "expectedCommands": [
5
+ "python -m pytest tests/test_main.py",
6
+ "python -m compileall .",
7
+ "python -c \"import importlib, sys; sys.path[:0] = ['src', '.']; target = 'app.main:app'; module, attr = target.split(':', 1); getattr(importlib.import_module(module), attr)\""
8
+ ],
9
+ "baseFiles": [
10
+ {
11
+ "path": "requirements.txt",
12
+ "lines": ["fastapi==0.110.0", "pytest==8.0.0"]
13
+ },
14
+ {
15
+ "path": "app/main.py",
16
+ "lines": ["from fastapi import FastAPI", "app = FastAPI()", "@app.get(\"/health\")", "def health():", " return {\"ok\": True}"]
17
+ },
18
+ {
19
+ "path": "tests/test_main.py",
20
+ "lines": ["def test_health_contract():", " assert True"]
21
+ }
22
+ ],
23
+ "changeFiles": [
24
+ {
25
+ "path": "app/main.py",
26
+ "lines": ["from fastapi import FastAPI", "app = FastAPI()", "@app.get(\"/health\")", "def health():", " return {\"ok\": False}"]
27
+ }
28
+ ]
29
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "go-workspace",
3
+ "expectedEcosystems": ["go"],
4
+ "expectedAffectedPackages": ["example.com/core", "example.com/api"],
5
+ "expectedCommands": [
6
+ "go test ./modules/core/...",
7
+ "go vet ./modules/core/...",
8
+ "go test ./modules/api/...",
9
+ "go vet ./modules/api/..."
10
+ ],
11
+ "baseFiles": [
12
+ {
13
+ "path": "go.work",
14
+ "lines": ["go 1.22", "", "use (", " ./modules/core", " ./modules/api", ")"]
15
+ },
16
+ {
17
+ "path": "modules/core/go.mod",
18
+ "lines": ["module example.com/core", "", "go 1.22"]
19
+ },
20
+ {
21
+ "path": "modules/core/core.go",
22
+ "lines": ["package core", "", "func OK() bool { return true }"]
23
+ },
24
+ {
25
+ "path": "modules/api/go.mod",
26
+ "lines": [
27
+ "module example.com/api",
28
+ "",
29
+ "go 1.22",
30
+ "",
31
+ "require example.com/core v0.0.0",
32
+ "",
33
+ "replace example.com/core => ../core"
34
+ ]
35
+ },
36
+ {
37
+ "path": "modules/api/api.go",
38
+ "lines": ["package api", "", "import \"example.com/core\"", "", "func OK() bool { return core.OK() }"]
39
+ }
40
+ ],
41
+ "changeFiles": [
42
+ {
43
+ "path": "modules/core/core.go",
44
+ "lines": ["package core", "", "func OK() bool { return false }"]
45
+ }
46
+ ]
47
+ }
48
+
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "java-gradle",
3
+ "expectedEcosystems": ["java"],
4
+ "expectedCommands": ["./gradlew test"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "settings.gradle",
8
+ "lines": ["pluginManagement { repositories { gradlePluginPortal() } }", "rootProject.name = 'api'"]
9
+ },
10
+ {
11
+ "path": "build.gradle",
12
+ "lines": ["plugins {", " id 'java'", "}"]
13
+ },
14
+ {
15
+ "path": "gradlew",
16
+ "lines": ["#!/bin/sh", "echo gradle wrapper"]
17
+ },
18
+ {
19
+ "path": "src/main/java/com/acme/Api.java",
20
+ "lines": ["package com.acme;", "public class Api { public boolean ok() { return true; } }"]
21
+ }
22
+ ],
23
+ "changeFiles": [
24
+ {
25
+ "path": "src/main/java/com/acme/Api.java",
26
+ "lines": ["package com.acme;", "public class Api { public boolean ok() { return false; } }"]
27
+ }
28
+ ]
29
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "java-maven",
3
+ "expectedEcosystems": ["java"],
4
+ "expectedCommands": ["./mvnw test"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "pom.xml",
8
+ "lines": [
9
+ "<project xmlns=\"http://maven.apache.org/POM/4.0.0\">",
10
+ " <modelVersion>4.0.0</modelVersion>",
11
+ " <groupId>com.acme</groupId>",
12
+ " <artifactId>api</artifactId>",
13
+ " <version>1.0.0</version>",
14
+ "</project>"
15
+ ]
16
+ },
17
+ {
18
+ "path": "mvnw",
19
+ "lines": ["#!/bin/sh", "echo maven wrapper"]
20
+ },
21
+ {
22
+ "path": "src/main/java/com/acme/Api.java",
23
+ "lines": ["package com.acme;", "public class Api { public boolean ok() { return true; } }"]
24
+ }
25
+ ],
26
+ "changeFiles": [
27
+ {
28
+ "path": "src/main/java/com/acme/Api.java",
29
+ "lines": ["package com.acme;", "public class Api { public boolean ok() { return false; } }"]
30
+ }
31
+ ]
32
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "kubernetes-helm",
3
+ "expectedEcosystems": ["kubernetes"],
4
+ "expectedCommands": ["helm lint ."],
5
+ "baseFiles": [
6
+ {
7
+ "path": "Chart.yaml",
8
+ "lines": ["apiVersion: v2", "name: api", "version: 0.1.0"]
9
+ },
10
+ {
11
+ "path": "values.yaml",
12
+ "lines": ["replicaCount: 2", "image:", " repository: ghcr.io/acme/api", " tag: 1.0.0"]
13
+ },
14
+ {
15
+ "path": "templates/deployment.yaml",
16
+ "lines": ["apiVersion: apps/v1", "kind: Deployment", "metadata:", " name: api"]
17
+ }
18
+ ],
19
+ "changeFiles": [
20
+ {
21
+ "path": "templates/deployment.yaml",
22
+ "lines": ["apiVersion: apps/v1", "kind: Deployment", "metadata:", " name: api", "spec:", " replicas: {{ .Values.replicaCount }}"]
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "kubernetes-kustomize",
3
+ "expectedEcosystems": ["kubernetes"],
4
+ "expectedCommands": ["kubectl kustomize k8s/overlays/prod"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "k8s/overlays/prod/kustomization.yaml",
8
+ "lines": ["resources:", " - deployment.yaml"]
9
+ },
10
+ {
11
+ "path": "k8s/overlays/prod/deployment.yaml",
12
+ "lines": ["apiVersion: apps/v1", "kind: Deployment", "metadata:", " name: api"]
13
+ }
14
+ ],
15
+ "changeFiles": [
16
+ {
17
+ "path": "k8s/overlays/prod/deployment.yaml",
18
+ "lines": ["apiVersion: apps/v1", "kind: Deployment", "metadata:", " name: api", "spec:", " replicas: 3"]
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "nested-go-workspace",
3
+ "expectedEcosystems": ["node", "go"],
4
+ "expectedAffectedPackages": ["example.com/core", "example.com/api"],
5
+ "expectedCommands": [
6
+ "cd services/go && go test ./modules/core/...",
7
+ "cd services/go && go vet ./modules/core/...",
8
+ "cd services/go && go test ./modules/api/...",
9
+ "cd services/go && go vet ./modules/api/..."
10
+ ],
11
+ "baseFiles": [
12
+ {
13
+ "path": "package.json",
14
+ "lines": ["{\"private\": true}"]
15
+ },
16
+ {
17
+ "path": "services/go/go.work",
18
+ "lines": ["go 1.22", "", "use (", " ./modules/core", " ./modules/api", ")"]
19
+ },
20
+ {
21
+ "path": "services/go/modules/core/go.mod",
22
+ "lines": ["module example.com/core", "", "go 1.22"]
23
+ },
24
+ {
25
+ "path": "services/go/modules/core/core.go",
26
+ "lines": ["package core", "", "func OK() bool { return true }"]
27
+ },
28
+ {
29
+ "path": "services/go/modules/api/go.mod",
30
+ "lines": [
31
+ "module example.com/api",
32
+ "",
33
+ "go 1.22",
34
+ "",
35
+ "require example.com/core v0.0.0",
36
+ "",
37
+ "replace example.com/core => ../core"
38
+ ]
39
+ },
40
+ {
41
+ "path": "services/go/modules/api/api.go",
42
+ "lines": ["package api", "", "import \"example.com/core\"", "", "func OK() bool { return core.OK() }"]
43
+ }
44
+ ],
45
+ "changeFiles": [
46
+ {
47
+ "path": "services/go/modules/core/core.go",
48
+ "lines": ["package core", "", "func OK() bool { return false }"]
49
+ }
50
+ ]
51
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "nextjs-app",
3
+ "expectedEcosystems": ["node"],
4
+ "expectedCommands": ["npm run lint", "npm run test", "npm run build"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "package.json",
8
+ "lines": [
9
+ "{",
10
+ " \"scripts\": {",
11
+ " \"lint\": \"next lint\",",
12
+ " \"test\": \"vitest run\",",
13
+ " \"build\": \"next build\"",
14
+ " },",
15
+ " \"dependencies\": {",
16
+ " \"next\": \"^15.0.0\",",
17
+ " \"react\": \"^19.0.0\"",
18
+ " }",
19
+ "}"
20
+ ]
21
+ },
22
+ {
23
+ "path": "app/page.tsx",
24
+ "lines": ["export default function Page() {", " return <main>Hello</main>;", "}"]
25
+ }
26
+ ],
27
+ "changeFiles": [
28
+ {
29
+ "path": "app/page.tsx",
30
+ "lines": ["export default function Page() {", " return <main>Changed</main>;", "}"]
31
+ }
32
+ ]
33
+ }
34
+
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "node-turbo-workspace",
3
+ "expectedEcosystems": ["node"],
4
+ "expectedAffectedPackages": ["@acme/api"],
5
+ "expectedCommands": ["npx turbo run test --filter=@acme/api"],
6
+ "baseFiles": [
7
+ {
8
+ "path": "package.json",
9
+ "lines": [
10
+ "{",
11
+ " \"private\": true,",
12
+ " \"workspaces\": [\"packages/*\"],",
13
+ " \"devDependencies\": {",
14
+ " \"turbo\": \"^2.0.0\"",
15
+ " }",
16
+ "}"
17
+ ]
18
+ },
19
+ {
20
+ "path": "turbo.json",
21
+ "lines": ["{", " \"tasks\": {", " \"test\": {}", " }", "}"]
22
+ },
23
+ {
24
+ "path": "packages/api/package.json",
25
+ "lines": ["{", " \"name\": \"@acme/api\",", " \"scripts\": {", " \"test\": \"vitest run\"", " }", "}"]
26
+ },
27
+ {
28
+ "path": "packages/api/src/index.ts",
29
+ "lines": ["export const api = true;"]
30
+ }
31
+ ],
32
+ "changeFiles": [
33
+ {
34
+ "path": "packages/api/src/index.ts",
35
+ "lines": ["export const api = 'changed';"]
36
+ }
37
+ ]
38
+ }
39
+
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "pants-python",
3
+ "expectedEcosystems": ["pants"],
4
+ "expectedCommands": [
5
+ "pants --changed-since=HEAD --changed-dependents=transitive test",
6
+ "pants --changed-since=HEAD --changed-dependents=transitive lint",
7
+ "pants --changed-since=HEAD --changed-dependents=transitive check"
8
+ ],
9
+ "baseFiles": [
10
+ {
11
+ "path": "pants.toml",
12
+ "lines": [
13
+ "[GLOBAL]",
14
+ "pants_version = \"2.32.0\"",
15
+ "backend_packages = [\"pants.backend.python\"]"
16
+ ]
17
+ },
18
+ {
19
+ "path": "src/python/app/BUILD",
20
+ "lines": ["python_sources()"]
21
+ },
22
+ {
23
+ "path": "src/python/app/service.py",
24
+ "lines": ["def ok():", " return True"]
25
+ }
26
+ ],
27
+ "changeFiles": [
28
+ {
29
+ "path": "src/python/app/service.py",
30
+ "lines": ["def ok():", " return False"]
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "php-composer",
3
+ "expectedEcosystems": ["php"],
4
+ "expectedCommands": ["composer test"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "composer.json",
8
+ "lines": [
9
+ "{",
10
+ " \"scripts\": {",
11
+ " \"test\": \"phpunit\"",
12
+ " },",
13
+ " \"require\": {",
14
+ " \"php\": \">=8.2\"",
15
+ " }",
16
+ "}"
17
+ ]
18
+ },
19
+ {
20
+ "path": "src/Service.php",
21
+ "lines": ["<?php", "final class Service {", " public function ok(): bool { return true; }", "}"]
22
+ }
23
+ ],
24
+ "changeFiles": [
25
+ {
26
+ "path": "src/Service.php",
27
+ "lines": ["<?php", "final class Service {", " public function ok(): bool { return false; }", "}"]
28
+ }
29
+ ]
30
+ }
31
+
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "python-service",
3
+ "expectedEcosystems": ["python"],
4
+ "expectedCommands": ["python -m pytest", "python -m compileall ."],
5
+ "baseFiles": [
6
+ {
7
+ "path": "requirements.txt",
8
+ "lines": ["fastapi==0.110.0", "pytest==8.0.0"]
9
+ },
10
+ {
11
+ "path": "app/main.py",
12
+ "lines": ["def ok():", " return True"]
13
+ }
14
+ ],
15
+ "changeFiles": [
16
+ {
17
+ "path": "app/main.py",
18
+ "lines": ["def ok():", " return False"]
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "rails-app",
3
+ "expectedEcosystems": ["ruby"],
4
+ "expectedCommands": ["bin/rails test"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "Gemfile",
8
+ "lines": ["source \"https://rubygems.org\"", "gem \"rails\", \"~> 7.2\""]
9
+ },
10
+ {
11
+ "path": "bin/rails",
12
+ "lines": ["#!/usr/bin/env ruby", "APP_PATH = File.expand_path(\"../config/application\", __dir__)"]
13
+ },
14
+ {
15
+ "path": "app/models/user.rb",
16
+ "lines": ["class User", " def active?", " true", " end", "end"]
17
+ }
18
+ ],
19
+ "changeFiles": [
20
+ {
21
+ "path": "app/models/user.rb",
22
+ "lines": ["class User", " def active?", " false", " end", "end"]
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "spring-boot-gradle",
3
+ "expectedEcosystems": ["java"],
4
+ "expectedCommands": ["./gradlew test", "./gradlew bootJar"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "settings.gradle",
8
+ "lines": ["pluginManagement { repositories { gradlePluginPortal() } }", "rootProject.name = 'api'"]
9
+ },
10
+ {
11
+ "path": "build.gradle",
12
+ "lines": ["plugins {", " id 'java'", " id 'org.springframework.boot' version '3.3.0'", "}", "dependencies {", " implementation 'org.springframework.boot:spring-boot-starter-web'", "}"]
13
+ },
14
+ {
15
+ "path": "gradlew",
16
+ "lines": ["#!/bin/sh", "echo gradle wrapper"]
17
+ },
18
+ {
19
+ "path": "src/main/java/com/acme/ApiApplication.java",
20
+ "lines": ["package com.acme;", "public class ApiApplication { public boolean ready() { return true; } }"]
21
+ }
22
+ ],
23
+ "changeFiles": [
24
+ {
25
+ "path": "src/main/java/com/acme/ApiApplication.java",
26
+ "lines": ["package com.acme;", "public class ApiApplication { public boolean ready() { return false; } }"]
27
+ }
28
+ ]
29
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "spring-boot-maven",
3
+ "expectedEcosystems": ["java"],
4
+ "expectedCommands": ["./mvnw test", "./mvnw package -DskipTests"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "pom.xml",
8
+ "lines": [
9
+ "<project xmlns=\"http://maven.apache.org/POM/4.0.0\">",
10
+ " <modelVersion>4.0.0</modelVersion>",
11
+ " <groupId>com.acme</groupId>",
12
+ " <artifactId>api</artifactId>",
13
+ " <version>1.0.0</version>",
14
+ " <parent>",
15
+ " <groupId>org.springframework.boot</groupId>",
16
+ " <artifactId>spring-boot-starter-parent</artifactId>",
17
+ " <version>3.3.0</version>",
18
+ " </parent>",
19
+ " <dependencies>",
20
+ " <dependency>",
21
+ " <groupId>org.springframework.boot</groupId>",
22
+ " <artifactId>spring-boot-starter-web</artifactId>",
23
+ " </dependency>",
24
+ " </dependencies>",
25
+ "</project>"
26
+ ]
27
+ },
28
+ {
29
+ "path": "mvnw",
30
+ "lines": ["#!/bin/sh", "echo maven wrapper"]
31
+ },
32
+ {
33
+ "path": "src/main/java/com/acme/ApiApplication.java",
34
+ "lines": ["package com.acme;", "public class ApiApplication { public boolean ready() { return true; } }"]
35
+ }
36
+ ],
37
+ "changeFiles": [
38
+ {
39
+ "path": "src/main/java/com/acme/ApiApplication.java",
40
+ "lines": ["package com.acme;", "public class ApiApplication { public boolean ready() { return false; } }"]
41
+ }
42
+ ]
43
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "swift-package",
3
+ "expectedEcosystems": ["swift"],
4
+ "expectedCommands": ["swift test", "swift build"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "Package.swift",
8
+ "lines": ["// swift-tools-version: 5.10", "import PackageDescription", "let package = Package(name: \"App\", products: [.library(name: \"App\", targets: [\"App\"])], targets: [.target(name: \"App\")])"]
9
+ },
10
+ {
11
+ "path": "Sources/App/App.swift",
12
+ "lines": ["public struct App {", " public func ok() -> Bool { true }", "}"]
13
+ }
14
+ ],
15
+ "changeFiles": [
16
+ {
17
+ "path": "Sources/App/App.swift",
18
+ "lines": ["public struct App {", " public func ok() -> Bool { false }", "}"]
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "terraform-module",
3
+ "expectedEcosystems": ["terraform"],
4
+ "expectedCommands": ["terraform fmt -check && terraform validate"],
5
+ "baseFiles": [
6
+ {
7
+ "path": "main.tf",
8
+ "lines": ["resource \"null_resource\" \"example\" {", " triggers = {", " value = \"initial\"", " }", "}"]
9
+ }
10
+ ],
11
+ "changeFiles": [
12
+ {
13
+ "path": "main.tf",
14
+ "lines": ["resource \"null_resource\" \"example\" {", " triggers = {", " value = \"changed\"", " }", "}"]
15
+ }
16
+ ]
17
+ }