Monorepo management for opam overlays
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add cram tests for push workflow

Tests cover the full push pipeline with a real monopam workspace:
- Basic push: monorepo → checkout → upstream
- Incremental push: fast-forward extends checkout
- Author preservation: split commits keep original author/committer
- Unrelated changes skipped: other-package commits don't appear
- Diverged history (tree containment): auto-forces when checkout
tree is a subset of the split chain

+149
+149
test/push.t
··· 1 + Push Workflow Tests 2 + =================== 3 + 4 + Test the subtree split/push pipeline: monorepo → local checkout → upstream. 5 + 6 + Setup 7 + ----- 8 + 9 + $ export NO_COLOR=1 10 + $ export GIT_AUTHOR_NAME="Alice" 11 + $ export GIT_AUTHOR_EMAIL="alice@example.com" 12 + $ export GIT_AUTHOR_DATE="2025-01-01T00:00:00+00:00" 13 + $ export GIT_COMMITTER_NAME="Alice" 14 + $ export GIT_COMMITTER_EMAIL="alice@example.com" 15 + $ export GIT_COMMITTER_DATE="2025-01-01T00:00:00+00:00" 16 + $ export HOME="$PWD/home" 17 + $ mkdir -p "$HOME" 18 + 19 + Create a minimal workspace: monorepo with one package "mylib" whose 20 + upstream repo is named "ocaml-mylib" (matching the subtree directory). 21 + 22 + $ WS="$PWD/ws" 23 + $ mkdir -p "$WS"/{mono,src} 24 + 25 + Create the upstream bare repo: 26 + 27 + $ git init -q --bare "$WS/upstream/ocaml-mylib" 28 + 29 + Create the opam-repo with the package registered: 30 + 31 + $ mkdir -p "$WS/opam-repo/packages/mylib/mylib.dev" 32 + $ cat > "$WS/opam-repo/packages/mylib/mylib.dev/opam" <<EOF 33 + > opam-version: "2.0" 34 + > name: "mylib" 35 + > version: "dev" 36 + > synopsis: "Test library" 37 + > dev-repo: "git+file://$WS/upstream/ocaml-mylib" 38 + > EOF 39 + $ cd "$WS/opam-repo" && git init -q && git add . && git commit -q -m "init" 40 + 41 + Create the monorepo with the package: 42 + 43 + $ cd "$WS/mono" && git init -q 44 + $ mkdir -p ocaml-mylib/lib 45 + $ cat > ocaml-mylib/dune-project <<EOF 46 + > (lang dune 3.0) 47 + > (name mylib) 48 + > EOF 49 + $ cat > "ocaml-mylib/mylib.opam" <<EOF 50 + > opam-version: "2.0" 51 + > name: "mylib" 52 + > version: "dev" 53 + > synopsis: "Test library" 54 + > dev-repo: "git+file://$WS/upstream/ocaml-mylib" 55 + > EOF 56 + $ echo "let x = 1" > ocaml-mylib/lib/main.ml 57 + $ git add . && git commit -q -m "mylib: v1" 58 + 59 + Configure monopam: 60 + 61 + $ mkdir -p "$HOME/.config/monopam" 62 + $ cat > "$HOME/.config/monopam/opamverse.toml" <<EOF 63 + > [workspace] 64 + > root = "$WS" 65 + > 66 + > [identity] 67 + > handle = "test.example.org" 68 + > knot = "git.example.org" 69 + > EOF 70 + 71 + Basic push 72 + ---------- 73 + 74 + First push should create the checkout and push to upstream: 75 + 76 + $ monopam push mylib 2>&1 | tail -1 77 + ✓ Changes pushed to upstream in 0.1s. 78 + 79 + $ test -d "$WS/src/ocaml-mylib/.git" && echo "checkout exists" 80 + checkout exists 81 + 82 + $ cd "$WS/src/ocaml-mylib" && git log --format="%an %s" && cd "$WS/mono" 83 + Alice mylib: v1 84 + 85 + Incremental push (fast-forward) 86 + ------------------------------- 87 + 88 + $ echo "let x = 2" > ocaml-mylib/lib/main.ml 89 + $ git add . && git commit -q -m "mylib: v2" 90 + $ monopam push mylib 2>&1 | tail -1 91 + ✓ Changes pushed to upstream in 0.1s. 92 + 93 + $ cd "$WS/src/ocaml-mylib" && git log --format="%s" && cd "$WS/mono" 94 + mylib: v2 95 + mylib: v1 96 + 97 + Author preservation 98 + ------------------- 99 + 100 + $ export GIT_AUTHOR_NAME="Bob" 101 + $ export GIT_AUTHOR_EMAIL="bob@example.com" 102 + $ echo "let x = 3" > ocaml-mylib/lib/main.ml 103 + $ git add . && git commit -q -m "mylib: v3 by Bob" 104 + $ monopam push mylib 2>&1 | tail -1 105 + ✓ Changes pushed to upstream in 0.1s. 106 + 107 + $ cd "$WS/src/ocaml-mylib" && git log -1 --format="%an <%ae> %s" && cd "$WS/mono" 108 + Bob <bob@example.com> mylib: v3 by Bob 109 + 110 + $ export GIT_AUTHOR_NAME="Alice" 111 + $ export GIT_AUTHOR_EMAIL="alice@example.com" 112 + 113 + Unrelated changes are skipped 114 + ----------------------------- 115 + 116 + $ mkdir -p ocaml-other/lib 117 + $ echo "let y = 1" > ocaml-other/lib/other.ml 118 + $ git add . && git commit -q -m "other: unrelated change" 119 + 120 + $ cd "$WS/src/ocaml-mylib" && git log --format="%s" | wc -l | tr -d ' ' && cd "$WS/mono" 121 + 3 122 + 123 + Still 3 commits — the unrelated change was correctly skipped. 124 + 125 + Diverged history: tree containment 126 + ----------------------------------- 127 + 128 + Simulate diverged commit hashes (same tree, different commits) — what 129 + happens after filter-repo or split algorithm changes. 130 + 131 + $ cd "$WS/src/ocaml-mylib" 132 + $ export GIT_COMMITTER_DATE="2025-06-01T00:00:00+00:00" 133 + $ TREE=$(git rev-parse HEAD^{tree}) 134 + $ NEW=$(git commit-tree "$TREE" -m "same tree, different commit") 135 + $ git update-ref refs/heads/main "$NEW" 136 + $ export GIT_COMMITTER_DATE="2025-01-01T00:00:00+00:00" 137 + $ cd "$WS/mono" 138 + 139 + Push should detect that the checkout's tree is in the split chain 140 + and auto-force the local checkout: 141 + 142 + $ echo "let x = 4" > ocaml-mylib/lib/main.ml 143 + $ git add . && git commit -q -m "mylib: v4" 144 + $ monopam push mylib 2>&1 | tail -1 145 + ✓ Changes pushed to upstream in 0.1s. 146 + 147 + $ cd "$WS/src/ocaml-mylib" && git log --format="%s" | head -2 && cd "$WS/mono" 148 + mylib: v4 149 + mylib: v3 by Bob