From 645d06462612d8f6e62011583635d6e1eea0c366 Mon Sep 17 00:00:00 2001 From: Tomasz Turkowski Date: Fri, 26 Jun 2026 14:42:23 +0200 Subject: [PATCH 1/3] Measure duration time from start till end of setup guide --- internal/devtui/model_update.go | 12 +++++++++++- internal/devtui/setup_guide.go | 3 +++ internal/devtui/setup_guide_test.go | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/internal/devtui/model_update.go b/internal/devtui/model_update.go index 10b71e05..77ae821e 100644 --- a/internal/devtui/model_update.go +++ b/internal/devtui/model_update.go @@ -2,6 +2,7 @@ package devtui import ( "context" + "strconv" "time" "charm.land/bubbles/v2/textinput" @@ -11,6 +12,7 @@ import ( "github.com/shopware/shopware-cli/internal/envfile" "github.com/shopware/shopware-cli/internal/executor" "github.com/shopware/shopware-cli/internal/shop" + "github.com/shopware/shopware-cli/internal/tracking" ) func (m Model) updateKeyPress(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { @@ -266,7 +268,15 @@ func (m Model) saveSetupGuide() (tea.Model, tea.Cmd) { m.setupGuide.deploymentHelperAdded = changed m.setupGuide.step = setupStepDone - return m, nil + duration := time.Since(m.setupGuide.startedAt) + return m, func() tea.Msg { + ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond) + defer cancel() + tracking.Track(ctx, "migration_wizard_completed", map[string]string{ + "duration_ms": strconv.FormatInt(duration.Milliseconds(), 10), + }) + return nil + } } // mergeLocalProfilerSecrets copies profiler credential fields from the diff --git a/internal/devtui/setup_guide.go b/internal/devtui/setup_guide.go index 2ac47bcf..1ef527e9 100644 --- a/internal/devtui/setup_guide.go +++ b/internal/devtui/setup_guide.go @@ -3,6 +3,7 @@ package devtui import ( "path/filepath" "slices" + "time" "charm.land/bubbles/v2/textinput" tea "charm.land/bubbletea/v2" @@ -31,6 +32,7 @@ type setupGuide struct { password textinput.Model passwordErr string credFocus credFocus + startedAt time.Time err error } @@ -149,6 +151,7 @@ func (sg *setupGuide) updateWelcome(msg tea.KeyPressMsg) (setupGuide, tea.Cmd) { sg.confirmYes = !sg.confirmYes case keyEnter: if sg.confirmYes { + sg.startedAt = time.Now() sg.step = setupStepAdminUser return sg.focusAdminCred(credFocusUsername) } diff --git a/internal/devtui/setup_guide_test.go b/internal/devtui/setup_guide_test.go index d03c429f..5288335c 100644 --- a/internal/devtui/setup_guide_test.go +++ b/internal/devtui/setup_guide_test.go @@ -4,6 +4,7 @@ import ( "os" "path/filepath" "testing" + "time" "charm.land/bubbles/v2/textinput" tea "charm.land/bubbletea/v2" @@ -407,3 +408,16 @@ func TestSetupGuideStepNumbering(t *testing.T) { assert.Equal(t, 0, sg.stepNum(setupStepWelcome)) assert.Equal(t, 0, sg.stepNum(setupStepDone)) } + +func TestSetupGuideWelcome_EnterSetsStartedAt(t *testing.T) { + sg := newSetupGuide("") + sg.confirmYes = true + + before := time.Now() + next, _ := sg.update(tea.KeyPressMsg(tea.Key{Code: tea.KeyEnter})) + after := time.Now() + + assert.False(t, next.startedAt.IsZero(), "startedAt should be set after Enter on welcome") + assert.False(t, next.startedAt.Before(before), "startedAt should not be before test start") + assert.False(t, next.startedAt.After(after), "startedAt should not be after test end") +} From 12f93328d5b6f8bea07c321ed4d2bbd921bfc15b Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Tue, 30 Jun 2026 05:59:01 +0200 Subject: [PATCH 2/3] feat(setup): track PHP version along with duration in setup guide completion --- internal/devtui/model_update.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/devtui/model_update.go b/internal/devtui/model_update.go index 77ae821e..f2a75e49 100644 --- a/internal/devtui/model_update.go +++ b/internal/devtui/model_update.go @@ -269,11 +269,13 @@ func (m Model) saveSetupGuide() (tea.Model, tea.Cmd) { m.setupGuide.step = setupStepDone duration := time.Since(m.setupGuide.startedAt) + phpVersion := m.setupGuide.phpVersions[m.setupGuide.phpCursor] return m, func() tea.Msg { ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond) defer cancel() tracking.Track(ctx, "migration_wizard_completed", map[string]string{ "duration_ms": strconv.FormatInt(duration.Milliseconds(), 10), + "php_version": phpVersion, }) return nil } From e8352d91406b74b6313e836645403c3c8cdfda4e Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Tue, 30 Jun 2026 06:00:21 +0200 Subject: [PATCH 3/3] feat(setup): update tracking duration format to seconds in setup guide completion --- internal/devtui/model_update.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/devtui/model_update.go b/internal/devtui/model_update.go index f2a75e49..a9302421 100644 --- a/internal/devtui/model_update.go +++ b/internal/devtui/model_update.go @@ -274,7 +274,7 @@ func (m Model) saveSetupGuide() (tea.Model, tea.Cmd) { ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond) defer cancel() tracking.Track(ctx, "migration_wizard_completed", map[string]string{ - "duration_ms": strconv.FormatInt(duration.Milliseconds(), 10), + "took": strconv.FormatInt(int64(duration.Seconds()), 10), "php_version": phpVersion, }) return nil