-
Notifications
You must be signed in to change notification settings - Fork 156
feat: project level themes #8344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
9cc03ee
318838c
8096cd2
99c1981
947f509
e0b77e6
9f5362d
fe684d6
603610f
b28d23d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -342,6 +342,7 @@ message Instance { | |
| map<string, string> annotations = 14; | ||
| string ai_instructions = 23; | ||
| string frontend_url = 24; | ||
| string theme = 26; | ||
| } | ||
|
|
||
| message Connector { | ||
|
|
@@ -397,6 +398,7 @@ message CreateInstanceRequest { | |
| map<string, string> variables = 7; | ||
| map<string, string> annotations = 9; | ||
| string frontend_url = 18; | ||
| string theme = 19; | ||
| } | ||
|
|
||
| // Response message for RuntimeService.CreateInstance | ||
|
|
@@ -425,6 +427,7 @@ message EditInstanceRequest { | |
| map<string, string> variables = 15; | ||
| map<string, string> annotations = 10; | ||
| optional string frontend_url = 19; | ||
| optional string theme = 20; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as above |
||
| } | ||
|
|
||
| // Response message for RuntimeService.EditInstance | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| ALTER TABLE instances ADD COLUMN theme TEXT NOT NULL DEFAULT ''; | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -297,34 +297,88 @@ func (r *ProjectParserReconciler) reconcileParser(ctx context.Context, inst *dri | |
| } | ||
| } | ||
|
|
||
| // Set an error without returning to mark if there are parse errors (if not, force error to nil in case there previously were parse errors) | ||
| var parseErrsErr error | ||
| if len(parser.Errors) > 0 { | ||
| parseErrsErr = ErrParserHasParseErrors | ||
| } | ||
| err = r.C.UpdateError(ctx, self.Meta.Name, parseErrsErr) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
Comment on lines
-300
to
-308
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think moving this is safe – it will prevent parse errors from showing up in Rill Developer |
||
|
|
||
| // If RillYAML is missing, don't reconcile anything | ||
| if parser.RillYAML == nil { | ||
| // Set an error without returning to mark if there are parse errors | ||
| var parseErrsErr error | ||
| if len(parser.Errors) > 0 { | ||
| parseErrsErr = ErrParserHasParseErrors | ||
| } | ||
| err = r.C.UpdateError(ctx, self.Meta.Name, parseErrsErr) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| return parseErrsErr | ||
| } | ||
|
|
||
| // Check if theme referenced theme changed | ||
| themeChanged := false | ||
| if parser.RillYAML.Theme != "" && diff != nil { | ||
| referencedTheme := parserpkg.ResourceName{Kind: parserpkg.ResourceKindTheme, Name: parser.RillYAML.Theme} | ||
| for _, n := range diff.Added { | ||
| if n.Normalized() == referencedTheme.Normalized() { | ||
| themeChanged = true | ||
| break | ||
| } | ||
| } | ||
| if !themeChanged { | ||
| for _, n := range diff.Modified { | ||
| if n.Normalized() == referencedTheme.Normalized() { | ||
| themeChanged = true | ||
| break | ||
| } | ||
| } | ||
| } | ||
| if !themeChanged { | ||
| for _, n := range diff.Deleted { | ||
| if n.Normalized() == referencedTheme.Normalized() { | ||
| themeChanged = true | ||
| break | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+314
to
+340
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is needed? It does a full re-parse of the project when |
||
|
|
||
| // not setting restartController=true when diff is actually nil prevents infinite restarts | ||
| updateConfig := diff == nil || diff.ModifiedDotEnv || diff.Reloaded | ||
| updateConfig := diff == nil || diff.ModifiedDotEnv || diff.Reloaded || themeChanged | ||
| if updateConfig { | ||
| restartController := diff != nil | ||
| err := r.reconcileProjectConfig(ctx, parser, restartController) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| if restartController { | ||
| // Check if this error already exists to avoid duplicates | ||
| errMsg := err.Error() | ||
| alreadyExists := false | ||
| for _, e := range parser.Errors { | ||
| if e.FilePath == "/rill.yaml" && e.Message == errMsg { | ||
| alreadyExists = true | ||
| break | ||
| } | ||
| } | ||
| if !alreadyExists { | ||
| parser.Errors = append(parser.Errors, &runtimev1.ParseError{ | ||
| FilePath: "/rill.yaml", | ||
| Message: errMsg, | ||
| }) | ||
| pp.State.ParseErrors = parser.Errors | ||
| if err := r.C.UpdateState(ctx, self.Meta.Name, self); err != nil { | ||
| return err | ||
| } | ||
| } | ||
| } else if restartController { | ||
| return nil | ||
| } | ||
| } | ||
|
|
||
| // Set an error without returning to mark if there are parse errors (if not, force error to nil in case there previously were parse errors) | ||
| var parseErrsErr error | ||
| if len(parser.Errors) > 0 { | ||
| parseErrsErr = ErrParserHasParseErrors | ||
| } | ||
| err = r.C.UpdateError(ctx, self.Meta.Name, parseErrsErr) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Reconcile resources. | ||
| // The lock serves to delay the controller from triggering reconciliation until all resources have been updated. | ||
| // By delaying reconciliation until all resources have been updated, we don't need to worry about making changes in DAG order here. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -184,6 +184,17 @@ func (r *Runtime) UpdateInstanceWithRillYAML(ctx context.Context, instanceID str | |
| inst.PublicPaths = rillYAML.PublicPaths | ||
| inst.AIInstructions = rillYAML.AIInstructions | ||
| inst.ProjectAIConnector = rillYAML.AIConnector | ||
|
|
||
| // Validate theme references an existing theme resource | ||
| if rillYAML.Theme != "" { | ||
| // Check if theme exists in parsed resources using normalized name (case-insensitive) | ||
| themeName := parser.ResourceName{Kind: parser.ResourceKindTheme, Name: rillYAML.Theme} | ||
| if _, ok := p.Resources[themeName.Normalized()]; !ok { | ||
| return fmt.Errorf("theme references theme %q which does not exist", rillYAML.Theme) | ||
| } | ||
| } | ||
|
|
||
| inst.Theme = rillYAML.Theme | ||
|
Comment on lines
186
to
+197
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should just assign the expressed theme without doing validation. This is not a safe place to do validation – validation has to be done when parsing or when reconciling/consuming the value. It'll be difficult to validate this at parse time because So I suggest you validate this when consuming the setting in the AI chat UI. I.e. show an error if the theme doesn't exist. |
||
| return r.EditInstance(ctx, inst, restartController) | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the option here? Since the field gets populated from
rill.yaml, it should not be possible to pass it over the APIsCreateInstanceorEditInstance(because the YAML parser runs continuously and would quickly overwrite anything passed through the API)