Skip to content

Commit 04445d2

Browse files
committed
feat(demo): one quickstart, three provider modes
## Summary ### Why? The repository had two divergent local paths, and the quickstart documented the wrong one. `make local-submitqueue-start` brought up an all-fake stack — fake change provider, fake CI, **noop merger** — and `doc/howto/QUICKSTART.md` (#591) described that. It reached `landed` in seconds with no credentials, but nothing was ever pushed, so it proved the pipeline's choreography and nothing about merging. `make local-provider-start` ran the real thing, but was GitHub-only: it hardcoded the token-requiring overlay, so the credential-free provider configuration that already existed could not be reached by hand at all. `PROVIDER=local` failed at `docker compose up` on a missing `GITHUB_TOKEN`, and would have merged nothing past that, since the overlay it needs bind-mounts a repository the other one has never heard of. Those two are not variants of one thing. Faking every edge and merging into a real repository answer different questions, and calling both "local" is what made them hard to keep apart. Three further confusions came out of reading the result back: - **Two stack families did the same thing.** Once `fake` was a first-class provider, `local-submitqueue-start` and `local-provider-start` were the same run under *different compose project names* — which had already produced a wrong instruction, since `make local-submitqueue-ps` inspects project `submitqueue` and reports "not running" for a stack started as `submitqueue-provider`. - **One document mixed two audiences.** `PROVIDER-E2E.md` opened with a tier table pairing bazel test targets with hand-run demo commands, as though `make e2e-test` and "open a pull request and watch it land" were rungs of one ladder. Automated suites belong to testing, which `TESTING.md` already documents. - **`demo-pr` was named for something two of the three modes do not have.** A fake change is a URI and a git change is a branch; neither is a pull request. ### What? `PROVIDER` now names three modes, and is the only thing that changes between them: | `PROVIDER` | A change is | Landing it | Needs | |---|---|---|---| | `fake` (default) | a URI, and nothing else | reports success without touching a repository | nothing | | `git` | a branch in a bare repository on disk | a real fetch, cherry-pick and push | nothing | | `github` | a real pull request | a real push to a real repository | a repository and a token | **Provider directories.** `demo/provider/local/` becomes `demo/provider/git/` — both old names were "local" — and gains a `demo-queue` entry so the default `QUEUE` works there. It needs its own `checkoutPath`: Runway refuses two queues that share a checkout with differing merger configuration, and `demo-queue` squash-rebases where `e2e-git-queue` rebases. A new `demo/provider/fake/` spells out the all-fake mode rather than leaving it implied by absent configuration. `e2e-git-queue` is untouched, and `make e2e-git-test` is the gate that proves it. **One stack target.** `local-submitqueue-start` takes `PROVIDER` and layers that mode's overlay; `local-provider-start`, `-stop` and `-clean` are gone. One compose project again, so `ps`, `logs`, `stop` and `clean` all describe whatever is running. Which overlay a mode needs is a Makefile map, since it is not something the two config files can express — `github` requires a credential, `git` requires the sandbox mounted, `fake` neither — and a new `docker-compose.fake.yml` covers the third. **One demo document.** `PROVIDER-E2E.md` is merged into `QUICKSTART.md`, which walks all three rungs in order and carries what only that document had: the token permission table, the GitHub configuration, why a landed pull request shows as *Merged*, wiring real GitHub Actions, and the GitHub-specific failure modes. Its provider-neutral operational material — `land-list` / `land-watch`, `SQ_TOKEN`, service logs, `QUEUE_LOG_LEVEL` — moves with it, into the document people read first. No test target is mentioned in any of it. **`make demo-requests`** (was `demo-pr`, in `service/submitqueue/demo/requests`) works without GitHub. `createOne` was the only function that touched the provider; it now describes a change and hands it to a `changeSource`. Three implement it: `fakeSource` (no I/O at all — mints a reproducible `git://` URI), `gitSource` (pushes real branches with the pinned `@git//:git`, serializing its commands because one working tree cannot take concurrent checkouts), and `githubSource` (the REST client, extracted unchanged). `GITHUB_TOKEN` is read only when it is needed. **Folder overlap, made real.** A change writes all of its files into one folder under `demo/`, and states the paths it touched on its change URI (`sq-files=`, beside the existing `sq-fake=`) for the fake change provider to report back. All three profiles then use `pathoverlap` by directory, so a run shows both halves of the queue's behaviour: changes sharing a folder are batched in order and speculate on each other, changes in different folders go out beside each other. How many folders there are is `FOLDERS`, defaulting to a number between five and ten picked per run and printed with the run's opening line. It is the dial on what a run demonstrates: `FOLDERS=1` serializes everything, a number well above `COUNT` keeps everything apart. The previous layout could do neither — it hashed each file's own name into two nested levels of 256, which put a twelve-file run's odds of any collision at roughly one in a thousand and scattered a single change across as many directories as it had files. What changed is the bucket count and what gets hashed, not the naming. **Matching stack lifecycle targets.** `local-submitqueue-stop` did not exist — the only way to stop the stack was `local-stop`, which stops every domain's. It exists now, and `local-submitqueue-clean` removes the git sandbox and the overlay's volumes rather than only the base file's, which is what the documentation already claimed it did. **`tool/gitsandbox`** provisions the bare repository `PROVIDER=git` merges into, idempotently, so a restart keeps whatever landed. **`platform/gitexec`** locates git and strips the ambient environment, so a developer's hooks or signing key cannot fail a demo. Three fixes fell out of getting this to work at all: - Runway's checkout directory moves to a named volume unless a path is given. It is where git clones, cherry-picks and commits, and on macOS a freshly written loose object read back over a bind mount can report `loose object … is corrupt` — which failed the first land against every new stack. The E2E still passes a path and still gets a bind mount. - The Runway image now creates `/var/runway/checkouts`, so a named volume mounted there starts with a mode the service can write. Without it the service failed at boot with `mkdir: permission denied` whenever it ran as a non-root user. - Change URIs are storage keys capped at 255 bytes, so the file marker names one path per directory rather than every file — for a directory-keyed analyzer that is the same set of keys — and drops paths that would not fit rather than truncating one into a different directory. ## Test Plan Every command in the rewritten quickstart was run by hand against a live stack, and the output quoted in it is what it printed. - ✅ `make local-submitqueue-start` (defaults to `fake`) then `make demo-requests COUNT=6` — all six landed - ✅ inspected `batch_dependent` across three runs. `FOLDERS=1` produced a full chain — every batch depending on every later one. `FOLDERS=50` produced four batches with no dependents at all. The default picked eight folders, put two of six changes in the same one, and recorded a dependency between exactly those two and nothing else - ✅ `make local-submitqueue-stop` leaves the sandbox and its data; `make local-submitqueue-clean` removes the sandbox, the volumes and the images, verified by looking for leftovers afterwards - ✅ `PROVIDER=git make local-submitqueue-start` from a clean slate, then `PROVIDER=git make demo-requests` — real branches and multi-file commits, verified with `git -C /tmp/sq-sandbox/sandbox.git log --oneline main` - ✅ `PROVIDER=git make demo-requests STACKED=true` — three changes, exactly one more entry in the target's reflog, so the stack landed atomically - ✅ first land against a brand-new stack, repeatedly, which is the case the named volume fixes - ✅ the 255-byte limit is a real one this hit first: an eight-file change was rejected with `change URI exceeds 255 bytes` before the marker was budgeted. Covered now by a unit test that builds a URI from `changeFilePath` output and asserts both the length and that it still parses - ✅ `make test` (105 targets), `make lint`, `make check-gazelle`, `make check-tidy` - ✅ `make e2e-test` and `make e2e-git-test`, after the rename and again after the compose change `PROVIDER=github` is unchanged in behaviour but needs a token, so it has not been re-run; the GitHub source is the previous code path moved behind the interface. ## Note for reviewers `make local-provider-start` is gone — use `make local-submitqueue-start`, which with no arguments now means `fake` where the old provider target meant GitHub. `make local-stop` still stops every domain's stack; `make local-submitqueue-stop` is the new one that stops only this.
1 parent c34c87f commit 04445d2

39 files changed

Lines changed: 2709 additions & 974 deletions

Makefile

Lines changed: 78 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ COMPOSE = docker-compose
66

77
# SubmitQueue compose files
88
COMPOSE_FILE = service/submitqueue/docker-compose.yml
9-
PROVIDER_COMPOSE_FILE = service/submitqueue/docker-compose.provider.yml
109
GATEWAY_COMPOSE_FILE = service/submitqueue/gateway/server/docker-compose.yml
1110
ORCHESTRATOR_COMPOSE_FILE = service/submitqueue/orchestrator/server/docker-compose.yml
1211

@@ -46,15 +45,40 @@ PROTO_PACKAGES = api/base/change api/base/mergestrategy api/base/messagequeue ap
4645
# Set REPO_ROOT for docker-compose
4746
export REPO_ROOT := $(shell pwd)
4847

49-
# Which provider the demo stack targets. Selects a configuration directory rather
50-
# than a code path, so adding a provider means adding a directory — see
48+
# Which provider the demo stack targets, and the only difference between a free
49+
# local run and a live one. Selects a configuration directory rather than a code
50+
# path, so adding a provider is mostly adding a directory — see
5151
# service/submitqueue/demo/provider/README.md.
52-
PROVIDER ?= github
52+
#
53+
# fake a change is a URI; nothing merges anywhere. Needs nothing.
54+
# git branches in a bare repository on disk; real fetch, cherry-pick, push.
55+
# github real pull requests. Needs a repository and GITHUB_TOKEN.
56+
PROVIDER ?= fake
5357
export SQ_PROVIDER_CONFIG_DIR ?= $(REPO_ROOT)/service/submitqueue/demo/provider/$(PROVIDER)
5458

55-
# Defaults for `make land` / `make demo-pr` against the provider demo stack.
59+
# Which compose overlay each mode needs. This cannot live in the provider
60+
# directory: the two config files say how the services are configured, not what
61+
# has to be mounted or which credential has to be present for them to start.
62+
PROVIDER_COMPOSE_FILE_fake = service/submitqueue/docker-compose.fake.yml
63+
PROVIDER_COMPOSE_FILE_git = service/submitqueue/docker-compose.git.yml
64+
PROVIDER_COMPOSE_FILE_github = service/submitqueue/docker-compose.provider.yml
65+
PROVIDER_COMPOSE_FILE = $(PROVIDER_COMPOSE_FILE_$(PROVIDER))
66+
67+
# Where PROVIDER=git keeps the bare repository it merges into. Outside the
68+
# repository, so a demo leaves nothing in a checkout, and bind-mounted rather
69+
# than kept in a volume so `git log` on the host can show what landed.
70+
#
71+
# SQ_RUNWAY_CHECKOUT_DIR is deliberately not set: unset, Runway's working trees
72+
# live in a named volume instead of on the host. See docker-compose.git.yml.
73+
export SQ_GIT_SANDBOX_DIR ?= /tmp/sq-sandbox
74+
75+
# Defaults for `make land` / `make demo-requests` against the provider demo stack.
5676
DEMO_REPO ?= behinddwalls/sq-demo
5777
COUNT ?= 3
78+
# How many folders demo-requests spreads its changes across, which decides how
79+
# much they conflict: changes sharing a folder are batched in order, changes in
80+
# different folders go out together. 0 picks one per run.
81+
FOLDERS ?= 0
5882
FILES ?= 3
5983
CONCURRENCY ?= 5
6084
STACKED ?= false
@@ -77,7 +101,7 @@ define assert_clean
77101
fi
78102
endef
79103

80-
.PHONY: build build-all-linux build-runway-linux build-submitqueue-gateway-client build-submitqueue-gateway-linux build-submitqueue-gateway-server build-submitqueue-orchestrator-linux build-stovepipe-linux build-stovepipe-linux-debug check-gazelle check-mocks check-tidy clean clean-proto deps e2e-test fmt gazelle integration-test integration-test-submitqueue-consumer integration-test-extensions integration-test-submitqueue-gateway integration-test-submitqueue-orchestrator license-fix lint lint-binary lint-fmt lint-license local-init-runway-queue-schema local-init-stovepipe-schemas local-runway-start local-runway-stop local-submitqueue-clean local-submitqueue-gateway-start local-submitqueue-gateway-stop local-init-submitqueue-schemas local-submitqueue-logs local-submitqueue-orchestrator-start local-submitqueue-orchestrator-stop local-submitqueue-ps local-submitqueue-restart local-submitqueue-start local-stop local-stovepipe-debug-start local-stovepipe-logs local-stovepipe-start local-stovepipe-stop mocks proto query-deps query-targets run-client-runway run-client-submitqueue-gateway run-client-submitqueue-orchestrator run-client-stovepipe run-queue-admin test test-no-cache tidy tidy-bazel tidy-go help
104+
.PHONY: build build-all-linux build-runway-linux build-submitqueue-gateway-client build-submitqueue-gateway-linux build-submitqueue-gateway-server build-submitqueue-orchestrator-linux build-stovepipe-linux build-stovepipe-linux-debug check-gazelle check-mocks check-tidy clean clean-proto demo-requests deps e2e-test fmt gazelle integration-test integration-test-submitqueue-consumer integration-test-extensions integration-test-submitqueue-gateway integration-test-submitqueue-orchestrator license-fix lint lint-binary lint-fmt lint-license local-init-runway-queue-schema local-init-stovepipe-schemas local-runway-start local-runway-stop local-submitqueue-stop local-submitqueue-clean local-submitqueue-gateway-start local-submitqueue-gateway-stop local-init-submitqueue-schemas local-submitqueue-logs local-submitqueue-orchestrator-start local-submitqueue-orchestrator-stop local-submitqueue-ps local-submitqueue-restart local-submitqueue-start local-stop local-stovepipe-debug-start local-stovepipe-logs local-stovepipe-start local-stovepipe-stop mocks proto query-deps query-targets run-client-runway run-client-submitqueue-gateway run-client-submitqueue-orchestrator run-client-stovepipe run-queue-admin test test-no-cache tidy tidy-bazel tidy-go help
81105

82106

83107
build: ## Build all services and examples
@@ -172,10 +196,13 @@ clean-proto: ## Clean generated proto files
172196
@rm -f $(foreach p,$(PROTO_PACKAGES),$(p)/protopb/*.pb.go $(p)/protopb/*.pb.yarpc.go)
173197
@echo "Proto clean complete!"
174198

175-
demo-pr: ## Create N PRs in the demo repo, enqueue each as it is created, and watch (COUNT=3 FILES=3 CONCURRENCY=5; needs GITHUB_TOKEN)
176-
@$(BAZEL) run //service/submitqueue/demo/pr -- \
199+
demo-requests: ## Create N changes, enqueue each as it is created, and watch (PROVIDER=fake|git|github COUNT=3 FOLDERS=0 FILES=3 CONCURRENCY=5)
200+
@$(BAZEL) run //service/submitqueue/demo/requests -- \
201+
-provider $(PROVIDER) \
177202
-repo $(DEMO_REPO) \
203+
-sandbox-dir $(SQ_GIT_SANDBOX_DIR) \
178204
-count $(COUNT) \
205+
-folders $(FOLDERS) \
179206
-files $(FILES) \
180207
-concurrency $(CONCURRENCY) \
181208
-stacked=$(STACKED) \
@@ -277,10 +304,13 @@ lint-message-id: ## Check queue messages are only constructed through platform/p
277304
lint-queue-shard: ## Check every table's primary key leads with the queue column
278305
@$(BAZEL) run //tool/linter/queueshard
279306

280-
local-submitqueue-clean: ## Stop and remove all local services, volumes, and images
307+
local-submitqueue-clean: ## Stop the stack and remove its volumes, images, and PROVIDER=git's sandbox
281308
@echo "Cleaning all services and data..."
282-
@$(COMPOSE) -f $(COMPOSE_FILE) -p $(SUBMITQUEUE_LOCAL_PROJECT) down -v --rmi local
283-
@echo "All services, volumes, and images removed."
309+
@# The overlay is named so that volumes it declares — Runway's checkouts —
310+
@# are removed too, rather than surviving as an orphan.
311+
@$(COMPOSE) -f $(COMPOSE_FILE) -f $(PROVIDER_COMPOSE_FILE) -p $(SUBMITQUEUE_LOCAL_PROJECT) down -v --rmi local
312+
@rm -rf "$(SQ_GIT_SANDBOX_DIR)"
313+
@echo "All services, volumes, images, and $(SQ_GIT_SANDBOX_DIR) removed."
284314

285315
local-submitqueue-gateway-start: build-submitqueue-gateway-linux ## Start Gateway service locally (Gateway + 2 MySQL databases)
286316
@echo "Starting Gateway with docker-compose..."
@@ -301,26 +331,6 @@ local-submitqueue-gateway-stop: ## Stop Gateway service
301331
@$(COMPOSE) -f $(GATEWAY_COMPOSE_FILE) -p $(SUBMITQUEUE_LOCAL_PROJECT) down
302332
@echo "Gateway services stopped."
303333

304-
local-provider-start: build-all-linux ## Start the full stack against a real provider (PROVIDER=github; needs GITHUB_TOKEN)
305-
@echo "Starting full stack against provider '$(PROVIDER)' ($(SQ_PROVIDER_CONFIG_DIR))..."
306-
@test -f "$(SQ_PROVIDER_CONFIG_DIR)/merge.yaml" \
307-
|| { echo "No such provider '$(PROVIDER)': $(SQ_PROVIDER_CONFIG_DIR)/merge.yaml not found"; exit 2; }
308-
@$(COMPOSE) -f $(COMPOSE_FILE) -f $(PROVIDER_COMPOSE_FILE) -p $(PROVIDER_LOCAL_PROJECT) up -d --build --wait
309-
@echo "Applying database schemas..."
310-
@$(MAKE) -s local-init-submitqueue-schemas SUBMITQUEUE_LOCAL_PROJECT=$(PROVIDER_LOCAL_PROJECT)
311-
@echo ""
312-
@echo "✅ Stack is running against provider '$(PROVIDER)'."
313-
@echo ""
314-
@echo "Gateway gRPC port: $$(docker port $(PROVIDER_LOCAL_PROJECT)-gateway-service-1 8080 2>/dev/null | cut -d: -f2 || echo 'unknown')"
315-
@echo ""
316-
@echo "Land a change with:"
317-
@echo " make land PR=https://github.com/owner/repo/pull/7 GATEWAY_ADDR=localhost:<gateway port>"
318-
319-
local-provider-stop: ## Stop the provider demo stack
320-
@echo "Stopping provider stack..."
321-
@$(COMPOSE) -f $(COMPOSE_FILE) -f $(PROVIDER_COMPOSE_FILE) -p $(PROVIDER_LOCAL_PROJECT) down
322-
@echo "Provider stack stopped."
323-
324334
local-init-submitqueue-schemas: ## Manually apply all database schemas
325335
@echo "Applying storage schema to mysql-app..."
326336
@for file in submitqueue/extension/storage/mysql/schema/*.sql; do \
@@ -429,17 +439,48 @@ local-submitqueue-restart: build-all-linux ## Restart all services (rebuild and
429439
@echo "Services restarted!"
430440
@make local-submitqueue-ps
431441

432-
local-submitqueue-start: build-all-linux ## Start full stack (Gateway + Orchestrator + MySQL)
433-
@echo "Starting full stack with docker-compose..."
434-
@$(COMPOSE) -f $(COMPOSE_FILE) -p $(SUBMITQUEUE_LOCAL_PROJECT) up -d --build --wait
442+
local-submitqueue-start: build-all-linux ## Start full stack (PROVIDER=fake|git|github; github needs GITHUB_TOKEN)
443+
@echo "Starting full stack against provider '$(PROVIDER)' ($(SQ_PROVIDER_CONFIG_DIR))..."
444+
@test -f "$(SQ_PROVIDER_CONFIG_DIR)/merge.yaml" \
445+
|| { echo "No such provider '$(PROVIDER)': $(SQ_PROVIDER_CONFIG_DIR)/merge.yaml not found"; exit 2; }
446+
@test -n "$(PROVIDER_COMPOSE_FILE)" \
447+
|| { echo "Provider '$(PROVIDER)' has no compose overlay; add PROVIDER_COMPOSE_FILE_$(PROVIDER) to the Makefile"; exit 2; }
448+
@if [ "$(PROVIDER)" = "git" ]; then \
449+
$(BAZEL) run //tool/gitsandbox -- -sandbox-dir "$(SQ_GIT_SANDBOX_DIR)" || exit 1; \
450+
fi
451+
@# Rootless Docker maps container root to the host user; rootful Docker needs
452+
@# the host UID:GID explicitly, or the services write files into the sandbox
453+
@# bind mount that the host user cannot then read or remove. Resolved here
454+
@# rather than at parse time, so `make help` does not shell out to Docker.
455+
@set -e; \
456+
if docker info --format '{{json .SecurityOptions}}' 2>/dev/null | grep -q 'name=rootless'; then \
457+
export SQ_CONTAINER_USER=0:0; \
458+
else \
459+
export SQ_CONTAINER_USER=$$(id -u):$$(id -g); \
460+
fi; \
461+
$(COMPOSE) -f $(COMPOSE_FILE) -f $(PROVIDER_COMPOSE_FILE) -p $(SUBMITQUEUE_LOCAL_PROJECT) up -d --build --wait
435462
@echo "Applying database schemas..."
436463
@$(MAKE) -s local-init-submitqueue-schemas
437464
@echo ""
438-
@echo "✅ Full stack is running!"
465+
@echo "✅ Stack is running against provider '$(PROVIDER)'."
466+
@echo ""
467+
@echo "Gateway gRPC port: $$(docker port $(SUBMITQUEUE_LOCAL_PROJECT)-gateway-service-1 8080 2>/dev/null | cut -d: -f2 || echo 'unknown')"
468+
@if [ "$(PROVIDER)" = "git" ]; then \
469+
echo "Merge target: $(SQ_GIT_SANDBOX_DIR)/sandbox.git"; \
470+
fi
439471
@echo ""
440-
@make local-submitqueue-ps
472+
@echo "Generate traffic with:"
473+
@echo " make demo-requests GATEWAY_ADDR=localhost:<gateway port>"
474+
475+
local-submitqueue-stop: ## Stop the SubmitQueue stack (keeps data and PROVIDER=git's sandbox)
476+
@echo "Stopping SubmitQueue services..."
477+
@$(COMPOSE) -f $(COMPOSE_FILE) -f $(PROVIDER_COMPOSE_FILE) -p $(SUBMITQUEUE_LOCAL_PROJECT) down
478+
@echo "SubmitQueue services stopped. Data volumes preserved."
479+
@if [ -d "$(SQ_GIT_SANDBOX_DIR)" ]; then \
480+
echo "Sandbox repository left at $(SQ_GIT_SANDBOX_DIR); remove it with 'make local-submitqueue-clean'."; \
481+
fi
441482

442-
local-stop: ## Stop all services (keep data)
483+
local-stop: ## Stop every local stack — SubmitQueue, Stovepipe, and Runway (keep data)
443484
@echo "Stopping all services..."
444485
@$(COMPOSE) -f $(COMPOSE_FILE) -p $(SUBMITQUEUE_LOCAL_PROJECT) down
445486
@$(COMPOSE) -f $(STOVEPIPE_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) down

README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Cross-domain Go code (errors, metrics, consumer framework, HTTP helpers, shared
1515

1616
## Quick Start
1717

18-
Land a change and watch it reach `landed`. Requires Docker and Docker Compose, and nothing else — no repository, no account, no token. See [Development Setup](doc/howto/DEVELOPMENT.md) for full prerequisites.
18+
Put traffic through the queue and watch it land. Requires Docker and Docker Compose, and nothing else — no repository, no account, no token. See [Development Setup](doc/howto/DEVELOPMENT.md) for full prerequisites.
1919

2020
```bash
2121
# Start the full stack (Gateway + Orchestrator + Runway + MySQL)
@@ -25,28 +25,33 @@ make local-submitqueue-start
2525
make local-submitqueue-ps
2626
export GATEWAY_ADDR=localhost:<gateway port>
2727

28-
# Submit a change, and follow the receipt it returns
29-
make land QUEUE=test-queue \
30-
URI='git://git.example.com/demo/refs%2Fheads%2Ffeature-a/1111111111111111111111111111111111111111'
31-
make land-status QUEUE=test-queue SQID=test-queue/1
28+
# Create changes, enqueue each as it is created, and watch them settle
29+
make demo-requests
3230

3331
# Stop services
34-
make local-stop
32+
make local-submitqueue-stop
3533
```
3634

37-
Every integration at the edges is faked — the change provider, CI, and the merge itself — so the run is free and finishes in seconds. The queue's own logic is real: validation, batching, conflict analysis, and speculation all run, and the request log records the full trail from `accepted` to `landed`. Nothing is pushed to any repository.
35+
`PROVIDER` decides where changes come from and what landing them does, and it is the only thing that changes between them:
3836

39-
[Quickstart](doc/howto/QUICKSTART.md) explains the change URI, how to make a change fail on demand, and what this does and does not prove. From there, `make e2e-git-test` adds a real git merge (still no credentials), and [PROVIDER-E2E.md](doc/howto/PROVIDER-E2E.md) adds a live provider. See [service/README.md](service/README.md) for running individual services and clients.
37+
| `PROVIDER` | A change is | Landing it | Needs |
38+
|---|---|---|---|
39+
| **`fake`** (default) | a URI, and nothing else | reports success without touching a repository | nothing |
40+
| **`git`** | a branch in a bare repository on disk | a real fetch, cherry-pick and push | nothing |
41+
| **`github`** | a real pull request | a real push to a real repository | a repository and a token |
42+
43+
The queue's own logic is real in all three: validation, batching, conflict analysis, speculation, and a request log recording the full trail from `accepted` to `landed`. `PROVIDER=git make local-submitqueue-start` is the first rung where a commit actually reaches a branch, and it still needs no credential.
44+
45+
[Quickstart](doc/howto/QUICKSTART.md) walks all three rungs — proving a change landed with `git log`, making one fail on demand, and what a live provider needs. See [service/README.md](service/README.md) for running individual services and clients.
4046

4147
## Documentation
4248

4349
| Document | Description |
4450
|----------|-------------|
45-
| [Quickstart](doc/howto/QUICKSTART.md) | Land a change locally with no credentials |
51+
| [Quickstart](doc/howto/QUICKSTART.md) | Run the stack and land changes — fake, local git, or GitHub |
4652
| [Development Setup](doc/howto/DEVELOPMENT.md) | Prerequisites, build, environment, IDE setup |
4753
| [Contributing](CONTRIBUTING.md) | How to contribute, workflow, guidelines |
4854
| [Testing Guide](doc/howto/TESTING.md) | Unit, integration, and E2E testing patterns |
49-
| [Landing real changes](doc/howto/PROVIDER-E2E.md) | Running the pipeline against a live provider |
5055
| [Architecture Guide](CLAUDE.md) | Project layout, patterns, conventions |
5156
| [Examples](service/README.md) | Running services, clients, API reference |
5257
| [RFCs](doc/rfc/index.md) | Design documents and proposals |

doc/howto/DEVELOPMENT.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,14 @@ make local-submitqueue-start
6464
make local-submitqueue-ps
6565
export GATEWAY_ADDR=localhost:<gateway port>
6666

67-
# 4. Land a change and follow it to a terminal status
68-
make land QUEUE=test-queue \
69-
URI='git://git.example.com/demo/refs%2Fheads%2Ffeature-a/1111111111111111111111111111111111111111'
70-
make land-status QUEUE=test-queue SQID=test-queue/1
67+
# 4. Create changes, enqueue them, and watch them land
68+
make demo-requests
7169

7270
# 5. Stop services
7371
make local-stop
7472
```
7573

76-
[QUICKSTART.md](QUICKSTART.md) walks through the same run in detail — what the change URI has to look like, how to make a change fail on demand, and which parts of the pipeline are faked.
74+
[QUICKSTART.md](QUICKSTART.md) walks through the same run in detail, and on to `PROVIDER=git`, which lands real commits into a repository on disk — still with no credential.
7775

7876
If any step fails, see [Troubleshooting](#troubleshooting) below.
7977

0 commit comments

Comments
 (0)