Jaypore CI

> Jaypore CI: Minimal, Offline, Local CI system.
Log | Files | Refs | README | LICENSE

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.