fix(mirror): exit non-zero when create hits an admin-suspended mirror · Entire
fix(mirror): exit non-zero when create hits an admin-suspended mirror
60576d5→main·
toothbrush·2w ago·4 files·+15 added/-10 removed
A suspended mirror can't be used, so repo mirror create now fails (exit
non-zero) after printing the warning instead of exiting 0 — a script chaining
a clone shouldn't treat it as success. One-shot returns a SilentError (the
warning is the message); the wizard marks the mirror a failure so the batch
exits non-zero too.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
01bf244ea5d6View transcript
?\ Mirror Admin Suspension Warnings and CleanupClaude Code·1 step
Changes
4
cmd/entire/cli
Mrepo_mirror.go+4/-1
Mrepo_mirror_create_wizard.go+3/-3
Mrepo_mirror_create_wizard_test.go+4/-4
Mrepo_mirror_test.go+4/-2
297 unmodified lines
298
299
300
301
302
303
304
302
305
306
307
308
297 unmodified lines
fmt.Fprintf(out, " %s\n", created.MirrorUrl)
if created.Suspended {
// Echo the placement (above), warn, and exit non-zero: the mirror can't
// be used, so a script chaining a clone shouldn't treat this as success.
// SilentError keeps main.go from reprinting — the warning is the message.
fmt.Fprintln(errW, "\nWARNING: this mirror has been suspended by an admin and won't be usable.")
return nil
return NewSilentError(errMirrorSuspended)
}
if !outcome.polled {
Mcmd/entire/cli/repo_mirror.go+4/-1
516 unmodified lines
517
518
519
520
521
522
520
521
522
523
524
525
516 unmodified lines
if outcome.created.Suspended {
// An admin suspended this existing placement, so it won't be served.
// Surface it as a distinct status rather than a bare "registered"; it is
// non-fatal (no res.err), matching the one-shot's warning semantics.
res.status = mirrorStatusSuspended
// Surface it as a distinct status and set an error so the batch exits
// non-zero, matching the one-shot: a suspended mirror isn't a success.
res.status, res.err = mirrorStatusSuspended, errors.New("suspended by an admin; won't be usable")
report(mirrorStatusSuspended, true, false)
return res
}
Mcmd/entire/cli/repo_mirror_create_wizard.go+3/-3
12 unmodified lines
13
14
15
16
17
18
16
17
18
19
20
21
12 unmodified lines
34
35
36
37
37
38
39
40
12 unmodified lines
)// TestCreateOneMirror_Suspended pins the wizard's per-mirror handling of an
// admin-suspended existing placement: it surfaces the "suspended" status and,
// like the one-shot warning, stays non-fatal (no res.err) rather than being
// reported as a plain "registered" success or a hard failure.
// admin-suspended existing placement: it surfaces the "suspended" status and
// sets an error so the batch exits non-zero (matching the one-shot), rather
// than being reported as a plain "registered" success.
func TestCreateOneMirror_Suspended(t *testing.T) {
t.Parallel()
12 unmodified lines
})
require.Equal(t, mirrorStatusSuspended, res.status)
require.NoError(t, res.err, "a suspended placement is non-fatal in the wizard too")
require.Error(t, res.err, "a suspended placement must fail the batch (non-zero exit)")
require.Equal(t, mirrorStatusSuspended, final)
require.False(t, finalOK)
require.Equal(t, []string{mirrorsAPIPath}, *paths, "suspended must not poll GetMirror")
Mcmd/entire/cli/repo_mirror_create_wizard_test.go+4/-4
295 unmodified lines
296
297
298
299
299
300
301
302
303
304
304
305
306
307
308
309
295 unmodified lines
require.NotContains(t, out.String(), "git clone")
})
t.Run("suspended placement warns after the placement and succeeds", func(t *testing.T) {
t.Run("suspended placement warns after the placement and exits non-zero", func(t *testing.T) {
t.Parallel()
var out, errW bytes.Buffer
created := &coreapi.CreatedMirror{Created: false, MirrorId: id, MirrorUrl: mirrorURL, Suspended: true}
err := reportOneShotMirror(&out, &errW, mirrorCreateOutcome{created: created}, nil)
require.NoError(t, err, "a suspended re-create is a non-fatal warning")
var silent *SilentError
require.ErrorAs(t, err, &silent, "a suspended re-create must exit non-zero")
require.ErrorIs(t, err, errMirrorSuspended)
require.Contains(t, out.String(), "Mirror exists ("+id, "the placement is still echoed")
require.Contains(t, errW.String(), "WARNING: this mirror has been suspended by an admin and won't be usable.")
require.NotContains(t, out.String(), "git clone")
Mcmd/entire/cli/repo_mirror_test.go+4/-2