fix(audio-rooms): clone kixelated/moq + run generate-certs in harness
The previous --recurse-submodules fix turned out to be moot: nostrnests's docker-compose-moq.yml references `./moq` as a build context, but the moq directory is NOT in the nostrnests repo and is NOT a submodule — each developer is expected to clone kixelated/moq into ./moq themselves before running compose. Confirmed against the upstream README + repo listing (nostrnests/nests has moq-auth/, nests-relay/, NestsUI-v2/ but no moq/ directory). Two new harness steps before `docker compose up -d`: - ensureMoqSource — clone https://github.com/kixelated/moq.git into <nests-cache>/moq on first run; fetch + checkout DEFAULT_MOQ_REVISION on every run so the build is reproducible. Override the pin via -DnestsInteropMoqRev=<sha-or-branch>. - ensureDevCerts — run dev-config/generate-certs.sh to produce the self-signed TLS chain moq-relay mounts read-only at /certs. The script is idempotent (bails when fullchain.pem exists) so we always invoke it; a chmod +x defensively handles Windows / odd CI checkouts. Reverted the spurious --recurse-submodules + submodule update path since the repo doesn't have submodules at all — the original `git clone` was correct, just incomplete.
This commit is contained in:
+59
-9
@@ -75,6 +75,16 @@ class NostrNestsHarness private constructor(
|
|||||||
const val MOQ_HOST_PORT = 4443
|
const val MOQ_HOST_PORT = 4443
|
||||||
|
|
||||||
private const val REPO_URL = "https://github.com/nostrnests/nests.git"
|
private const val REPO_URL = "https://github.com/nostrnests/nests.git"
|
||||||
|
private const val MOQ_REPO_URL = "https://github.com/kixelated/moq.git"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pin the upstream `kixelated/moq` revision so test runs are
|
||||||
|
* reproducible even if upstream main changes a wire-level detail
|
||||||
|
* we depend on (e.g. moq-lite framing). Override at runtime via
|
||||||
|
* `-DnestsInteropMoqRev=<sha-or-branch>`.
|
||||||
|
*/
|
||||||
|
const val DEFAULT_MOQ_REVISION = "main"
|
||||||
|
|
||||||
private const val COMPOSE_FILE = "docker-compose-moq.yml"
|
private const val COMPOSE_FILE = "docker-compose-moq.yml"
|
||||||
private const val PORT_READY_TIMEOUT_MS = 90_000L
|
private const val PORT_READY_TIMEOUT_MS = 90_000L
|
||||||
private const val PORT_PROBE_INTERVAL_MS = 500L
|
private const val PORT_PROBE_INTERVAL_MS = 500L
|
||||||
@@ -90,6 +100,14 @@ class NostrNestsHarness private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val workDir = ensureRepo()
|
val workDir = ensureRepo()
|
||||||
|
// The compose file `build:`s `./moq` — the upstream moq-rs
|
||||||
|
// sources — but nostrnests does NOT ship that directory; it
|
||||||
|
// expects each developer to clone `kixelated/moq` into it.
|
||||||
|
ensureMoqSource(workDir)
|
||||||
|
// moq-relay needs TLS certs to bring up its WebTransport
|
||||||
|
// listener; nostrnests ships a self-signed-cert generator
|
||||||
|
// we run on first invocation.
|
||||||
|
ensureDevCerts(workDir)
|
||||||
// Bring everything up detached. The compose file's services log
|
// Bring everything up detached. The compose file's services log
|
||||||
// to stdout; we don't tail them — failures surface via
|
// to stdout; we don't tail them — failures surface via
|
||||||
// port-probe timeouts.
|
// port-probe timeouts.
|
||||||
@@ -152,22 +170,54 @@ class NostrNestsHarness private constructor(
|
|||||||
val rev = System.getProperty("nestsInteropRev") ?: DEFAULT_REVISION
|
val rev = System.getProperty("nestsInteropRev") ?: DEFAULT_REVISION
|
||||||
val target = cacheRoot().resolve("nests").toFile()
|
val target = cacheRoot().resolve("nests").toFile()
|
||||||
if (!target.exists()) {
|
if (!target.exists()) {
|
||||||
// Recurse-submodules pulls in the `moq` (kixelated/moq-rs)
|
runProcess(cacheRoot().toFile(), "git", "clone", REPO_URL, "nests")
|
||||||
// and `moq-auth` build contexts that docker-compose-moq.yml
|
|
||||||
// references via `build: ./moq` / `./moq-auth`. Without
|
|
||||||
// them docker compose fails with "unable to prepare
|
|
||||||
// context: path '<repo>/moq' not found".
|
|
||||||
runProcess(cacheRoot().toFile(), "git", "clone", "--recurse-submodules", REPO_URL, "nests")
|
|
||||||
}
|
}
|
||||||
// Always fetch + checkout the requested revision so test runs
|
// Always fetch + checkout the requested revision so test runs
|
||||||
// are reproducible even if `main` advances. Sync submodules to
|
// are reproducible even if `main` advances.
|
||||||
// whatever the checked-out commit pins.
|
|
||||||
runProcess(target, "git", "fetch", "origin", "--quiet")
|
runProcess(target, "git", "fetch", "origin", "--quiet")
|
||||||
runProcess(target, "git", "checkout", "--quiet", rev)
|
runProcess(target, "git", "checkout", "--quiet", rev)
|
||||||
runProcess(target, "git", "submodule", "update", "--init", "--recursive")
|
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone (and refresh) the upstream `kixelated/moq` repo into
|
||||||
|
* `nestsRepo/moq`. The nostrnests compose file `build:`s
|
||||||
|
* `./moq` directly, but the directory is NOT shipped in the
|
||||||
|
* nostrnests repo (and is NOT a submodule); each developer is
|
||||||
|
* expected to set it up. We do that automatically here.
|
||||||
|
*/
|
||||||
|
private fun ensureMoqSource(nestsRepo: File) {
|
||||||
|
val moqDir = File(nestsRepo, "moq")
|
||||||
|
val rev = System.getProperty("nestsInteropMoqRev") ?: DEFAULT_MOQ_REVISION
|
||||||
|
if (!moqDir.exists()) {
|
||||||
|
runProcess(nestsRepo, "git", "clone", MOQ_REPO_URL, "moq")
|
||||||
|
}
|
||||||
|
// Reproducible runs: pin to the requested revision.
|
||||||
|
runProcess(moqDir, "git", "fetch", "origin", "--quiet")
|
||||||
|
runProcess(moqDir, "git", "checkout", "--quiet", rev)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run `dev-config/generate-certs.sh` if `dev-config/certs/`
|
||||||
|
* doesn't already hold a chain — moq-relay's container mounts
|
||||||
|
* that directory read-only and refuses to start without it.
|
||||||
|
* The script is idempotent (it bails out if the certs already
|
||||||
|
* exist), so we always invoke it; logs go through [runProcess]
|
||||||
|
* so a failure surfaces as a clear `IllegalStateException`.
|
||||||
|
*/
|
||||||
|
private fun ensureDevCerts(nestsRepo: File) {
|
||||||
|
val certs = File(nestsRepo, "dev-config/certs")
|
||||||
|
if (certs.exists() && File(certs, "fullchain.pem").exists()) return
|
||||||
|
val script = File(nestsRepo, "dev-config/generate-certs.sh")
|
||||||
|
check(script.exists()) {
|
||||||
|
"expected dev-config/generate-certs.sh in the nostrnests checkout but it's missing"
|
||||||
|
}
|
||||||
|
// chmod +x defensively (ownerOnly = false) in case git
|
||||||
|
// didn't preserve the bit on Windows / some CI checkouts.
|
||||||
|
script.setExecutable(true, false)
|
||||||
|
runProcess(File(nestsRepo, "dev-config"), "./generate-certs.sh")
|
||||||
|
}
|
||||||
|
|
||||||
private fun runDocker(
|
private fun runDocker(
|
||||||
workDir: File,
|
workDir: File,
|
||||||
vararg args: String,
|
vararg args: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user