README.md (2662B)
1 # 06 — Sub-pipelines 2 3 Run only the CI steps that matter for each commit by detecting which parts of a 4 monorepo actually changed. 5 6 ## The problem 7 8 In a monorepo with independent services—say `python-app/`, `js-app/`, and 9 `go-app/`—running every linter, build, and test suite on every commit wastes 10 time. A one-line docs fix in `python-app/` shouldn’t trigger the Go compiler. 11 12 ## The pattern 13 14 ``` 15 git diff --name-only HEAD~1 HEAD 16 ``` 17 18 gives you the list of files touched in the latest commit. Grep that list for 19 each top-level folder and conditionally execute the matching sub-pipeline: 20 21 ```bash 22 changed=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || true) 23 24 if echo "$changed" | grep -q '^python-app/'; then 25 # run python lint + tests 26 fi 27 ``` 28 29 When the diff is empty (first commit, shallow clone, force-push) the script 30 falls back to running **all** sub-pipelines so nothing is silently skipped. 31 32 ## What the script does 33 34 | Folder changed | Actions performed | Results file | 35 |----------------|------------------------------------|-----------------------| 36 | `python-app/` | Lint (ruff/flake8) + pytest | `python-results.txt` | 37 | `js-app/` | npm install + eslint | `js-results.txt` | 38 | `go-app/` | `go build` + `go test` | `go-results.txt` | 39 40 Each sub-pipeline writes its output to a dedicated results file in 41 `$JCI_OUTPUT_DIR` so you can inspect them independently. 42 43 ## Adapting this to your project 44 45 - **Add more folders** — copy a sub-pipeline block and change the grep pattern. 46 - **Use path globs** — match `docs/` or `*.md` to trigger a docs-build step. 47 - **Parallel execution** — background each sub-pipeline and `wait` to run them 48 concurrently. 49 - **Deeper diffs** — use `HEAD~N` or compare against a base branch 50 (`git diff origin/main...HEAD`) for pull-request workflows. 51 52 ## File layout 53 54 ``` 55 06-sub-pipelines/ 56 ├── .jci/ 57 │ └── run.sh # Main CI entry point 58 ├── python-app/ 59 │ ├── app.py # Tiny Python module (add, greet) 60 │ └── test_app.py # pytest tests 61 ├── js-app/ 62 │ ├── index.js # Node module (add, greet) 63 │ └── package.json # Minimal package manifest 64 ├── go-app/ 65 │ ├── main.go # Go package (Add, Greet) 66 │ ├── main_test.go # Go tests 67 │ └── go.mod # Go module definition 68 └── README.md # This file 69 ``` 70 71 Each sub-app is a self-contained, minimal demo—no external dependencies 72 required. They exist purely to give the sub-pipeline script something real to 73 lint, build, and test.