Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a9deb8cdb | ||
|
|
4653b17e18 | ||
|
|
bdb927f83d | ||
|
|
49ee611847 | ||
|
|
72ea2988be | ||
|
|
9294defef8 |
@@ -0,0 +1,17 @@
|
|||||||
|
package asks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// live-acceptance.sh is run by a person at the terminal and by no test: its syntax is judged here, as the lab's script
|
||||||
|
// judged it with `sh -n` (novox/hq ADR 0529).
|
||||||
|
func TestTheLiveAcceptanceScriptIsValidShell(t *testing.T) {
|
||||||
|
if _, err := exec.LookPath("sh"); err != nil {
|
||||||
|
t.Skip("NOT TESTED HERE: no sh on the path")
|
||||||
|
}
|
||||||
|
if out, err := exec.Command("sh", "-n", "live-acceptance.sh").CombinedOutput(); err != nil {
|
||||||
|
t.Fatalf("live-acceptance.sh is not valid shell: %v\n%s", err, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# mesh-check-toolchain: go
|
|
||||||
#
|
|
||||||
# The proof of the operator's answers (novox/hq ADR 0259), the Go part of the lab's own check: run by the
|
|
||||||
# build seat in the mesh's Go toolchain, its own container, because the lab's merge-check.sh declares it
|
|
||||||
# (`# mesh-check-also: go asks/merge-check.sh`) — and by hand: `sh asks/merge-check.sh`.
|
|
||||||
#
|
|
||||||
# Formatted, vetted, and run against the clones beside the lab: on the build seat those are the controller,
|
|
||||||
# the runtime and the catalogue **the mesh runs**, so every pull request of the lab proves the answers the
|
|
||||||
# operator would get today. By hand, MESH_LAB_REPOS, or MESH_LAB_CONTROLLER, MESH_LAB_TOOLS and
|
|
||||||
# MESH_LAB_CATALOGUE, point it at branches under review. It takes about four minutes when it runs.
|
|
||||||
#
|
|
||||||
# **Said, never passed silently**: where a clone is missing, or the controller predates the proof's fixture,
|
|
||||||
# it says NOT RUN and why, in capitals, and passes; a proof that runs and fails, fails the check.
|
|
||||||
set -eu
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
export GOPRIVATE=git.novox.be
|
|
||||||
|
|
||||||
unformatted=$(gofmt -l .)
|
|
||||||
if [ -n "$unformatted" ]; then
|
|
||||||
echo "not gofmt'd:"
|
|
||||||
echo "$unformatted"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
sh -n live-acceptance.sh
|
|
||||||
go vet ./...
|
|
||||||
out=$(mktemp)
|
|
||||||
status=0
|
|
||||||
go test -count=1 -timeout 25m -v -run '^(TestTheOperatorsAnswerEndToEnd|TestTheFakePhoneShowsHTMLAsTelegramDoes)$' . >"$out" 2>&1 || status=$?
|
|
||||||
grep -E '^(--- | --- |ok|FAIL|PASS)' "$out" || true
|
|
||||||
if grep -q 'NOT RUN' "$out"; then
|
|
||||||
echo "NOT RUN: THE PROOF OF THE OPERATOR'S ANSWERS DID NOT RUN HERE:"
|
|
||||||
grep -o 'NOT RUN: .*' "$out" | head -3
|
|
||||||
fi
|
|
||||||
[ "$status" -eq 0 ] || tail -60 "$out"
|
|
||||||
rm -f "$out"
|
|
||||||
exit "$status"
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
package asks
|
package asks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# mesh-check-toolchain: typescript
|
|
||||||
# mesh-check-also: go replays/merge-check.sh
|
|
||||||
# mesh-check-also: go asks/merge-check.sh
|
|
||||||
#
|
|
||||||
# The lab's own check (novox/hq ADR 0237 as amended): the second layer of a pull request's merge check,
|
|
||||||
# `mesh/repo-check`, run by the build seat — and by hand.
|
|
||||||
#
|
|
||||||
# The mesh builds no module from the lab, so no gate runs for its pull requests (`mesh/merge-gate` says the
|
|
||||||
# change touches no module of the graph); this is all that is checked before a change to it merges. The lab
|
|
||||||
# is in two languages, and each part runs in its own toolchain's container (novox/hq issue 302):
|
|
||||||
#
|
|
||||||
# - this script, in the TypeScript toolchain: installed from the lock file, type-checked, sources and
|
|
||||||
# tests, and the unit suite;
|
|
||||||
# - replays/merge-check.sh, in the Go toolchain, declared above: the replays register and its prover
|
|
||||||
# formatted, vetted and compiled, and the register's own tests;
|
|
||||||
# - asks/merge-check.sh, in the Go toolchain, declared above: the proof of the operator's answers, run
|
|
||||||
# against the controller, runtime and catalogue cloned beside the lab (novox/hq ADR 0259).
|
|
||||||
#
|
|
||||||
# **Said, never passed silently**: the integration suite raises a lab on a workstation, and the replays
|
|
||||||
# raise containers through the container runtime — neither is given to code nobody has approved. The
|
|
||||||
# replays run from the lab's main, reviewed, in every gate of a core change; a change to them is proven by
|
|
||||||
# `go run ./replays/cmd/prove` by hand before it merges.
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
npm ci --no-audit --no-fund --loglevel=error
|
|
||||||
npm run typecheck
|
|
||||||
npm test
|
|
||||||
|
|
||||||
# By hand, with Go at hand, the Go part runs here too; on the build seat it runs in the Go toolchain.
|
|
||||||
if command -v go >/dev/null 2>&1; then
|
|
||||||
sh replays/merge-check.sh
|
|
||||||
sh asks/merge-check.sh
|
|
||||||
else
|
|
||||||
echo "replays/ and asks/ (Go) are checked by their merge-check.sh, which the build seat runs in the Go toolchain"
|
|
||||||
fi
|
|
||||||
echo "NOT RUN HERE: the integration suite and the replays — they need a lab and the container runtime"
|
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
||||||
|
"pretest": "npm run typecheck",
|
||||||
"test": "node --test --experimental-strip-types 'test/*.test.ts'",
|
"test": "node --test --experimental-strip-types 'test/*.test.ts'",
|
||||||
"test:integration": "node --experimental-strip-types src/cli.ts suite",
|
"test:integration": "node --experimental-strip-types src/cli.ts suite",
|
||||||
"check": "npm run typecheck && npm test && npm run test:integration",
|
"check": "npm run typecheck && npm test && npm run test:integration",
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
|
package replays
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// **R-studio — a check that asks an address the program does not bind fails the bed, not a machine**
|
||||||
|
// (novox/hq ADR 0240 Phase D, done when). The hosted database suite's studio binds the address the runtime
|
||||||
|
// puts in HOSTNAME, so it answered only on its network address while its image's own check asked localhost:
|
||||||
|
// unhealthy for ever while working, until the module set HOSTNAME=0.0.0.0. Adopted by name without proof, it
|
||||||
|
// would have put back a good build.
|
||||||
|
//
|
||||||
|
// The replay is that image in miniature: a web server that binds $HOSTNAME's address, and an image check that
|
||||||
|
// asks localhost. Adopted as the module declared it before the fix, the bed fails it; with the fix, it proves
|
||||||
|
// it. The image is built here and removed after, with everything the bed made.
|
||||||
|
func TestBedFailsTheStudiosFalseUnhealthy(t *testing.T) {
|
||||||
|
docker, ok := DockerFromEnv()
|
||||||
|
if !ok {
|
||||||
|
t.Skip("no container runtime: the studio is a container")
|
||||||
|
}
|
||||||
|
ctx, cancel := context.WithTimeout(t.Context(), 5*time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
if err := docker.Pull(ctx, "busybox:1.36"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
tag := fmt.Sprintf("mesh-replay-studio:%d", time.Now().UnixNano())
|
||||||
|
if err := docker.Build(ctx, tag, StudioDockerfile); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer docker.RemoveImage(context.Background(), tag)
|
||||||
|
was := BedFloor
|
||||||
|
BedFloor = 15 * time.Second
|
||||||
|
defer func() { BedFloor = was }()
|
||||||
|
|
||||||
|
studio := func(env map[string]any) BedResource {
|
||||||
|
r := map[string]any{"id": "studio", "type": "container", "name": "supabase-studio", "image": tag,
|
||||||
|
"health": map[string]any{"kind": "runtime", "grace": "10s"}}
|
||||||
|
if env != nil {
|
||||||
|
r["env"] = env
|
||||||
|
}
|
||||||
|
return BedResource{Module: "supabase", ID: "studio", Resource: r, Listens: map[string]int{}}
|
||||||
|
}
|
||||||
|
before := docker.Prove(ctx, studio(nil), nil)
|
||||||
|
if !before.Failed || !strings.Contains(before.Said, "does not see it") {
|
||||||
|
t.Fatalf("the studio's false unhealthy was not failed on the bed: %+v", before)
|
||||||
|
}
|
||||||
|
t.Logf("before the fix: %s", before.Said)
|
||||||
|
after := docker.Prove(ctx, studio(map[string]any{"HOSTNAME": "0.0.0.0"}), nil)
|
||||||
|
if !after.Proved {
|
||||||
|
t.Fatalf("the studio with HOSTNAME=0.0.0.0 was not proved: %+v", after)
|
||||||
|
}
|
||||||
|
t.Logf("with the fix: %s", after.Said)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StudioDockerfile is the studio in miniature: it serves on the address HOSTNAME names, and its own check
|
||||||
|
// asks localhost, as the studio's image does.
|
||||||
|
const StudioDockerfile = `FROM busybox:1.36
|
||||||
|
RUN mkdir -p /www && echo studio > /www/index.html
|
||||||
|
HEALTHCHECK --interval=5s --timeout=2s --retries=2 CMD wget -q -O /dev/null http://localhost:3000/ || exit 1
|
||||||
|
CMD addr=$(grep -w "$HOSTNAME" /etc/hosts | head -n 1 | cut -f 1); exec httpd -f -p "${addr:-$HOSTNAME}:3000" -h /www
|
||||||
|
`
|
||||||
+7
-57
@@ -2,7 +2,6 @@ package replays
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -58,62 +57,6 @@ func TestBedProvesEveryChangedHealthCheck(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// **R-studio — a check that asks an address the program does not bind fails the bed, not a machine**
|
|
||||||
// (novox/hq ADR 0240 Phase D, done when). The hosted database suite's studio binds the address the runtime
|
|
||||||
// puts in HOSTNAME, so it answered only on its network address while its image's own check asked localhost:
|
|
||||||
// unhealthy for ever while working, until the module set HOSTNAME=0.0.0.0. Adopted by name without proof, it
|
|
||||||
// would have put back a good build.
|
|
||||||
//
|
|
||||||
// The replay is that image in miniature: a web server that binds $HOSTNAME's address, and an image check that
|
|
||||||
// asks localhost. Adopted as the module declared it before the fix, the bed fails it; with the fix, it proves
|
|
||||||
// it. The image is built here and removed after, with everything the bed made.
|
|
||||||
func TestBedFailsTheStudiosFalseUnhealthy(t *testing.T) {
|
|
||||||
docker, ok := DockerFromEnv()
|
|
||||||
if !ok {
|
|
||||||
t.Skip("no container runtime: the studio is a container")
|
|
||||||
}
|
|
||||||
ctx, cancel := context.WithTimeout(t.Context(), 5*time.Minute)
|
|
||||||
defer cancel()
|
|
||||||
if err := docker.Pull(ctx, "busybox:1.36"); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
tag := fmt.Sprintf("mesh-replay-studio:%d", time.Now().UnixNano())
|
|
||||||
if err := docker.Build(ctx, tag, StudioDockerfile); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer docker.RemoveImage(context.Background(), tag)
|
|
||||||
was := BedFloor
|
|
||||||
BedFloor = 15 * time.Second
|
|
||||||
defer func() { BedFloor = was }()
|
|
||||||
|
|
||||||
studio := func(env map[string]any) BedResource {
|
|
||||||
r := map[string]any{"id": "studio", "type": "container", "name": "supabase-studio", "image": tag,
|
|
||||||
"health": map[string]any{"kind": "runtime", "grace": "10s"}}
|
|
||||||
if env != nil {
|
|
||||||
r["env"] = env
|
|
||||||
}
|
|
||||||
return BedResource{Module: "supabase", ID: "studio", Resource: r, Listens: map[string]int{}}
|
|
||||||
}
|
|
||||||
before := docker.Prove(ctx, studio(nil), nil)
|
|
||||||
if !before.Failed || !strings.Contains(before.Said, "does not see it") {
|
|
||||||
t.Fatalf("the studio's false unhealthy was not failed on the bed: %+v", before)
|
|
||||||
}
|
|
||||||
t.Logf("before the fix: %s", before.Said)
|
|
||||||
after := docker.Prove(ctx, studio(map[string]any{"HOSTNAME": "0.0.0.0"}), nil)
|
|
||||||
if !after.Proved {
|
|
||||||
t.Fatalf("the studio with HOSTNAME=0.0.0.0 was not proved: %+v", after)
|
|
||||||
}
|
|
||||||
t.Logf("with the fix: %s", after.Said)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StudioDockerfile is the studio in miniature: it serves on the address HOSTNAME names, and its own check
|
|
||||||
// asks localhost, as the studio's image does.
|
|
||||||
const StudioDockerfile = `FROM busybox:1.36
|
|
||||||
RUN mkdir -p /www && echo studio > /www/index.html
|
|
||||||
HEALTHCHECK --interval=5s --timeout=2s --retries=2 CMD wget -q -O /dev/null http://localhost:3000/ || exit 1
|
|
||||||
CMD addr=$(grep -w "$HOSTNAME" /etc/hosts | head -n 1 | cut -f 1); exec httpd -f -p "${addr:-$HOSTNAME}:3000" -h /www
|
|
||||||
`
|
|
||||||
|
|
||||||
// What the bed proves is what the change touches: a long-running container whose declared check or image
|
// What the bed proves is what the change touches: a long-running container whose declared check or image
|
||||||
// changed, or that is new; never a step, never one left as it was.
|
// changed, or that is new; never a step, never one left as it was.
|
||||||
func TestTheBedProvesWhatTheChangeTouches(t *testing.T) {
|
func TestTheBedProvesWhatTheChangeTouches(t *testing.T) {
|
||||||
@@ -159,3 +102,10 @@ func TestTheBedProvesWhatTheChangeTouches(t *testing.T) {
|
|||||||
t.Fatalf("the bed would prove %v; want the new module's checked container and the one whose image moved", got)
|
t.Fatalf("the bed would prove %v; want the new module's checked container and the one whose image moved", got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func orDefault(s, fallback string) string {
|
||||||
|
if s == "" {
|
||||||
|
return fallback
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
package replays
|
package replays
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
package replays
|
package replays
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -111,13 +113,6 @@ func statementOf(path string) string {
|
|||||||
return string(raw)
|
return string(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func orDefault(s, fallback string) string {
|
|
||||||
if s == "" {
|
|
||||||
return fallback
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func firstLineOf(s string) string {
|
func firstLineOf(s string) string {
|
||||||
line, _, _ := strings.Cut(strings.TrimSpace(s), "\n")
|
line, _, _ := strings.Cut(strings.TrimSpace(s), "\n")
|
||||||
if len(line) > 400 {
|
if len(line) > 400 {
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# mesh-check-toolchain: go
|
|
||||||
#
|
|
||||||
# The Go part of the lab's own check (novox/hq issue 302): the replays register and its prover, run by the
|
|
||||||
# build seat in the mesh's Go toolchain, its own container, because the lab's merge-check.sh declares it
|
|
||||||
# (`# mesh-check-also: go replays/merge-check.sh`) — and by hand, from anywhere:
|
|
||||||
# `sh replays/merge-check.sh`.
|
|
||||||
#
|
|
||||||
# 1. formatted and vetted — the register, the replays and the prover compile, tests included;
|
|
||||||
# 2. the tests that need nothing but Go and git: every replay registered whole (TestEveryReplayIsWhole),
|
|
||||||
# and the bed's reading of what a change touches.
|
|
||||||
#
|
|
||||||
# **Said, never passed silently**: the replays themselves raise containers and a bus of the release the mesh
|
|
||||||
# runs; this container holds no container runtime, so they are not run here. They run from the lab's main,
|
|
||||||
# reviewed, in the gate of every core change, and a change to one is proven by `go run ./cmd/prove` before
|
|
||||||
# it merges.
|
|
||||||
set -eu
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
|
|
||||||
unformatted=$(gofmt -l .)
|
|
||||||
if [ -n "$unformatted" ]; then
|
|
||||||
echo "not gofmt'd:"
|
|
||||||
echo "$unformatted"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
go vet ./...
|
|
||||||
go test -count=1 -run '^(TestEveryReplayIsWhole|TestTheBedProvesWhatTheChangeTouches)$' .
|
|
||||||
echo "NOT RUN HERE: the replays themselves — they raise containers, and this container holds no container runtime"
|
|
||||||
@@ -607,6 +607,48 @@ var Register = []Replay{
|
|||||||
"registered as built and builds recorded with what they stood on",
|
"registered as built and builds recorded with what they stood on",
|
||||||
Package: "./cmd/mesh-controller", Test: "TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles",
|
Package: "./cmd/mesh-controller", Test: "TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles",
|
||||||
Files: []string{"cmd/mesh-controller/replay614_test.go"}},
|
Files: []string{"cmd/mesh-controller/replay614_test.go"}},
|
||||||
|
// A mesh-host change and a mesh-controller change of one delivery group that need each other could not both pass
|
||||||
|
// their own merge checks (2026-10-16, issue 867): each was read beside the other's repository at the commit the mesh
|
||||||
|
// runs, which holds neither change. The fix (mesh-controller #348, hq ADR 0382) asks mesh-delivery's groups once per
|
||||||
|
// check and reads each sibling's repository at its merge. TestReplay867 runs the whole path — the forge's
|
||||||
|
// announcement, the controller's ask, the build seat's check with a container runtime that runs on this machine —
|
||||||
|
// for the pair, written with only what the controller and the build seat had before. Needs a store:
|
||||||
|
// MESH_TEST_POSTGRES. R-issue867-recheck, R-issue867-recheck-verb and R-issue867-release-group are the three defects found live in the same fix, each with its own merge.
|
||||||
|
{ID: "R867", Issue: 867, Kind: InRepository, Repository: "mesh-controller",
|
||||||
|
Fix: "a47976be4e699c35681be87c48ecfedd793374cd",
|
||||||
|
What: "a mesh-host change and a mesh-controller change of one delivery group, each needing the other, could not " +
|
||||||
|
"both pass their own merge check: each was read beside the other at the commit the mesh runs",
|
||||||
|
Asserts: "each member of a delivery group passes its own merge check, read beside the other member's head " +
|
||||||
|
"merged onto its base",
|
||||||
|
Package: "./cmd/mesh-controller", Test: "TestReplay867", Files: []string{"cmd/mesh-controller/replay867_test.go"}},
|
||||||
|
// A recheck announces the pull request without its head branch, so its group was not found and the verdict said
|
||||||
|
// nothing of its siblings (mesh-controller #350): the group is found by repository and number.
|
||||||
|
{ID: "R-issue867-recheck", Issue: 867, Kind: InRepository, Repository: "mesh-controller",
|
||||||
|
Fix: "af60d2719c0c6c2f1ff44347037280d6ba5e72b4",
|
||||||
|
What: "a recheck of a group member read no siblings: it carries no head branch name, and the group was found by it",
|
||||||
|
Asserts: "a pull request announced as a recheck is, without its head branch, found in its group by repository " +
|
||||||
|
"and number, and passes beside its sibling",
|
||||||
|
Package: "./cmd/mesh-controller", Test: "TestReplay867Recheck", Files: []string{"cmd/mesh-controller/replay867_test.go"}},
|
||||||
|
// `delivery check` runs as a command of its own, where the controller is not the serving one: it asked mesh-delivery
|
||||||
|
// on no bus ("this controller is not on the bus") and read no siblings (mesh-controller #351).
|
||||||
|
{ID: "R-issue867-recheck-verb", Issue: 867, Kind: InRepository, Repository: "mesh-controller",
|
||||||
|
Fix: "a07dd78c3e90335bbe06970799e9b36a142f68c9",
|
||||||
|
What: "the recheck verb asked mesh-delivery for the group on no bus connection and read no siblings",
|
||||||
|
Asserts: "`delivery check` with one member, on a test bus with a mesh-delivery answering groups, learns the " +
|
||||||
|
"sibling, asking once",
|
||||||
|
Package: "./cmd/mesh-controller", Test: "TestTheRecheckVerbAsksMeshDeliveryOnABusOfItsOwn",
|
||||||
|
Files: []string{"cmd/mesh-controller/replay867_test.go"}},
|
||||||
|
// A release-branch group's composed check took the release judge, which cannot build a pair consistent only
|
||||||
|
// together (mesh-controller #352, hq ADR 0239 §14): the group's own controller judges, with the host member's
|
||||||
|
// validator. Both tests: the controller member primary, and the node-engine member primary with Judge validator.
|
||||||
|
{ID: "R-issue867-release-group", Issue: 867, Kind: InRepository, Repository: "mesh-controller",
|
||||||
|
Fix: "d70bb1f38867fad3595c96c7f7f2deb0b3ff501a",
|
||||||
|
What: "the composed check of a delivery group into a release branch was judged by the release branch's " +
|
||||||
|
"controller, which does not build with the pair's validator",
|
||||||
|
Asserts: "a group's composed check into a release branch is judged by the group's own controller with the " +
|
||||||
|
"mesh-host member's validator, and passes",
|
||||||
|
Package: "./cmd/mesh-controller", Test: "TestAGroupsComposition",
|
||||||
|
Files: []string{"cmd/mesh-controller/replay867_test.go"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find is the replay of that id, or of that issue.
|
// Find is the replay of that id, or of that issue.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
package replays
|
package replays
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
package replays
|
package replays
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
package replays
|
package replays
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
Reference in New Issue
Block a user