github.com/GoogleContainerTools/skaffold/v2@v2.13.2/docs-v2/design_proposals/user_survey_hooks.md (about) 1 # Title 2 3 * Author(s): Tejal Desai 4 * Design Shepherd: Brian de Alwis 5 * Date: 07/11/2021 6 * Status: Completed 7 8 ## Background 9 10 Currently, we get feedback on Skaffold via Skaffold HaTS survey. 11 However, in this survey we cannot prompt users for feedback on existing features or new proposed features. 12 It is difficult for us to solicit feedback on existing features and the impact of proposed changes. 13 For example, with render v2, we are changing how deploy works. This may affect our existing helm deployer users. 14 See [#6166](https://github.com/GoogleContainerTools/skaffold/issues/6166) 15 16 ## Design 17 18 This document proposes to extend the existing HaTS survey framework to incorporate a set of user surveys. 19 20 ### User survey definition 21 In order to make sure only relevant surveys are shown to user, we have added a survey config. 22 ``` 23 type config struct { 24 id string 25 // promptText is shown to the user and should be formatted so each line should fit in < 80 characters. 26 // For example: `As a Helm user, we are requesting your feedback on a proposed change to Skaffold's integration with Helm.` 27 promptText string 28 // startsAt mentions the date after the users survey should be prompted. This will ensure, skaffold team can finalize the survey 29 // even after release date. 30 startsAt time.Time 31 // expiresAt places a time limit of the user survey. As users are only prompted every two weeks 32 // by design, this time limit should be at least 4 weeks after the upcoming release date to account 33 // for release propagation lag to Cloud SDK and Cloud Shell. 34 expiresAt time.Time 35 isRelevantFn func([]util.VersionedConfig) bool 36 URL string 37 } 38 39 ``` 40 The survey config has two key fields 41 1) expiresAt - This decided the lifetime of the survey. e.g. if we are collecting user feedback to get feedback on helm deployer re-design, then it makes sense to target the survey towards helm deployer user for a limited time until the re-design requirement phase is complete. 42 2) isRelevantFn - This function determines if the user is a target audience for the survey. For the above example, it only makes sense to show the survey for helm deployer users, like this. 43 ``` 44 { 45 id: helmID, 46 expiresAt: time.Date(2021, time.August, 14, 00, 00, 00, 0, time.UTC), 47 isRelevantFn: func(cfgs []util.VersionedConfig, command string) bool { 48 for _, cfg := range cfgs { 49 if v1Cfg, ok := cfg.(*latestV1.SkaffoldConfig) ; ok { 50 if h := v1Cfg.Deploy.HelmDeploy; h != nil { 51 return true 52 } 53 } 54 } 55 return false 56 }, 57 URL: helmURL, 58 }, 59 60 ``` 61 For multi-module users, we could use something like the following: 62 ``` 63 isRelevantFn: func(cfgs []util.VersionedConfig, _ string) bool { 64 return len(cfgs) > 1 65 }, 66 ``` 67 68 ### How to prompt users to take user surveys 69 70 #### Rules to show survey prompt 71 When prompting users with surveys, we need to keep in mind 2 important rules 72 1) *Don't prompt users too often.* 73 Currently, we only prompt users to fill in HaTs survey every two weeks until they fill. 74 2) *Don't prompt users if they have already taken the survey.* 75 Currently, we only prompt users to fill in HaTS Survey if they haven't taken it in last 3 months. 76 77 For non HaTS surveys or user surveys, we will follow the same rules, 78 1) Prompt users to fill in the survey once 2 weeks if its relevant to them until they fill it. 79 2) Stop prompting once they have taken the survey. 80 81 The user survey information will be tracked in the existing `Survey` config in the skaffold global config 82 ``` 83 // SurveyConfig is the survey config information 84 type SurveyConfig struct { 85 DisablePrompt *bool `yaml:"disable-prompt,omitempty"` 86 LastTaken string `yaml:"last-taken,omitempty"` 87 LastPrompted string `yaml:"last-prompted,omitempty"` 88 + UserSurveys []*UseSurvey `yaml:"user-surveys,omitempty"` 89 } 90 91 type UserSurvey struct { 92 ID string `yaml:"id"` 93 Taken *bool `yaml:"taken,omitempty"` 94 } 95 ``` 96 97 98 ### Implementation details. 99 The current `ShouldDisplaySurveyPrompt` returns true only if 100 1) If survey prompt is not disabled and 101 2) If HaTS survey was not taken in last 3 months (stored in `SurveyConfig.LastTaken`) and 102 3) If survey prompt was not shown `SurveyConfig.LastPrompted` in last 2 weeks. 103 104 This behavior will be changed to `ShouldDisplaySurveyPrompt` returns true if 105 1) If survey prompt is not disabled and 106 2) If survey prompt was not shown `SurveyConfig.LastPrompted` in last 2 weeks and 107 3) If there is an active relevant user survey is available or HaTS survey was not taken in last 3 months 108 109 If both active relevant user survey is available or HaTS survey was not taken, then Skaffold will give preference to user survey over hats survey. 110 Since, HaTS survey never expire, 111 - if user takes the user survey this time, HaTS survey will be prompted the next time. 112 - if the user never takes the user survey, the HaTS survey will be prompted once the user survey expires. 113 **Note User surveys should not run longer than a quarter so that we don't reduce the volume of HaTS Survey, 114 115 ## Alternate Methods 116 Other methods to get feedback is manually via pinging slack users to fill in a survey. 117 However, this requires a core member to manually remind users from time to time to fill in a survey. 118 Another disadvantage is users could form a biased opinion due to the questions asked in the user survey and 119 rate low on the NPS score. 120 121 122 ## Implementation plan 123 - [X] add survey config struct 124 - [X] add `-id` flag to survey command with default as `hats` 125 - [X] add `UserSurvey` struct to skaffold global config 126 - [X] change prompt logic to show active relevant prompts 127 - [X] Change set and unset command to set user survey fields.