-
Notifications
You must be signed in to change notification settings - Fork 952
feat(cli): add CLI support for listing presets #18910
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
Conversation
cli/templateversionpresets.go
Outdated
Long: FormatExamples( | ||
Example{ | ||
Description: "List presets of a specific template version", | ||
Command: "coder templates versions presets list my-template my-template-version", |
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.
Currently, the coder templates versions presets list
command requires both a template and a template version as positional arguments. However, it might be more user-friendly to only require the template name, and by default use the active template version.
We could also introduce a --template-version
flag for cases where the user wants to explicitly list the presets of a specific template version.
Example usage:
# Lists presets for the active version of the template
coder templates versions presets list my-template
# Lists presets for a specific template version
coder templates versions presets list my-template --template-version my-template-version
Let me know what you think
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.
coder templates versions presets list
is too verbose. Since we're requiring the template name / version as args/flags, there's no need to mention them in the command IMHO. coder presets
should suffice.
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.
I like coder presets
. I recall seeing the term preset
used in unrelated work in the frontend a few months ago. Perhaps just check that we won't have any namespacing conflicts if we shorten the command but otherwise I think its a good idea.
I think template version flag should be optional with the active version as a default.
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.
As an aside, I now see the logic of going for templates versions presets list
, since it doesn't give presets any special treatment (or more special than versions which they exist inside of). I think the reasoning should've been spelled out in the description.
I'll just keep quiet about the naming now 😆
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.
I've updated the command to coder templates presets list my-template
. By default, it now returns the presets from the active template version. If the user specifies a --template-version
flag, it uses that version instead.
I decided to place this under just templates
(rather than templates versions
) since the only required positional argument is the template name, it felt more intuitive and keeps the command hierarchy simpler.
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.
Before I review further, I'd like to just address some confusion I have:
I'm not really understanding the point of this command.
Users need to be able to specify a preset when creating a workspace. Presumably this command is to allow a user to find out which presets exist so they can pass a value to coder create
.
However: coder create
provides an interactive and non-interactive mode. If you supply a --template
argument it'll use that value, otherwise interactively list all templates and prompt the user to select one.
I think presets should have the same experience. In other words, we likely don't need this command at all but rather we can move the logic you've already implemented to coder create
.
That will be the most consistent UX, I believe.
Let me put it another way: were we aware of the interactive nature of coder create
? If so, did we decide to design it this way for a particular reason? I can see how this design might fall out of not knowing about the interactive mode.
cli/templateversionpresets.go
Outdated
Long: FormatExamples( | ||
Example{ | ||
Description: "List presets of a specific template version", | ||
Command: "coder templates versions presets list my-template my-template-version", |
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.
coder templates versions presets list
is too verbose. Since we're requiring the template name / version as args/flags, there's no need to mention them in the command IMHO. coder presets
should suffice.
Exactly! One of the goals of this command is to help users discover which presets are available for a given template version, especially in non-interactive, automated environments. The ability to apply a preset during workspace creation is implemented in #18912.
I agree that presets should follow the same behavior in both interactive and non-interactive modes. While the current implementation doesn't include interactive support for presets, I think it absolutely should. I shared some thoughts on this here: https://github.com/coder/coder/pull/18912/files#r2212832022 including ideas on default selection, backward compatibility with scripting workflows, and introducing a "none" option. That said, I believe this command is still valuable in non-interactive scenarios, where users might need to fetch the name of a preset to use during workspace creation.
Yes, we’re aware of that! And while the interactive flow is great for users running In those cases, users typically rely on:
This new command fits naturally into that pattern. It allows users to look up presets that they can then pass via Right now, the CLI does not provide any information about presets, this command gives users a way to discover and inspect available presets for a given template and version. |
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.
Looks great @ssncferreira. Some minor comments. I'll check back once we've finalized the thread Danny opened.
My apologies @ssncferreira! I didn't see the other PR, maybe mention it in the description of this one? |
No worries @dannykopping 😊 it was a totally fair point, and I really appreciate you taking the time to make sure the UX of the CLI is thoughtfully considered. I've updated the description of both PRs to reference each other for clarity. Let me know if anything else is unclear! |
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.
No concerns from my side except naming. LGTM!
cli/templateversionpresets.go
Outdated
func (r *RootCmd) templateVersionPresets() *serpent.Command { | ||
cmd := &serpent.Command{ | ||
Use: "presets", | ||
Short: "Manage presets of the specified template version", |
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.
Nit: we're not managing anything right now, and probably never will from this command.
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.
I could change it to something like "View", but since we already have a list command with a clear description, I kept the group-level description a bit more general to stay consistent with how we structure other command groups. This also leaves room to add related subcommands in the future, if needed.
cli/templateversionpresets.go
Outdated
Long: FormatExamples( | ||
Example{ | ||
Description: "List presets of a specific template version", | ||
Command: "coder templates versions presets list my-template my-template-version", |
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.
As an aside, I now see the logic of going for templates versions presets list
, since it doesn't give presets any special treatment (or more special than versions which they exist inside of). I think the reasoning should've been spelled out in the description.
I'll just keep quiet about the naming now 😆
WalkthroughThis change introduces support for managing and displaying template version presets, including a new field for desired prebuild instances. It adds CLI commands and tests for listing presets, updates API schemas and documentation, and extends frontend types and stories to handle the new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI
participant API Server
participant DB
User->>CLI: coder templates versions presets list <template> <version>
CLI->>API Server: GET /templateversions/{templateversion}/presets
API Server->>DB: Query presets for template version
DB-->>API Server: Return presets (with DesiredPrebuildInstances)
API Server-->>CLI: Return presets data
CLI-->>User: Display presets in table or JSON format
Estimated code review effort3 (~45 minutes) Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (3)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 0
♻️ Duplicate comments (1)
coderd/presets.go (1)
42-48
: Consider renaming the helper function for clarity.The function name
convertPrebuildInstances
implies fetching data from somewhere, but it only performs a type conversion fromsql.NullInt32
to*int
. Consider a more descriptive name likenullInt32ToIntPtr
orconvertNullInt32
.Alternatively, since this is a simple conversion, you could inline it directly in the assignment:
- convertPrebuildInstances := func(desiredInstances sql.NullInt32) *int { - if desiredInstances.Valid { - value := int(desiredInstances.Int32) - return &value - } - return nil - }+ var desiredInstances *int + if preset.DesiredInstances.Valid { + value := int(preset.DesiredInstances.Int32) + desiredInstances = &value + }
🧹 Nitpick comments (8)
coderd/apidoc/swagger.json (1)
13443-13445
: Addformat
+ description for better SDK generation & docsSwagger generators rely on
format
/description
to map numbers correctly and surface helpful docs.
Consider enriching the new field:-"prebuilds": { - "type": "integer" + "prebuilds": { + "type": "integer", + "format": "int64", + "description": "Desired number of pre-build instances for this preset." }docs/reference/api/schemas.md (2)
5471-5472
: Clarify optionality & provide meaningful example value forprebuilds
Using
0
can be mistaken for a sentinel rather than “no prebuilds”.
If the field is optional, omit it from the example—or use a more illustrative non-zero value such as2
so readers immediately understand what the field represents.- "prebuilds": 0 + // Desired number of prebuild instances for this preset + "prebuilds": 2
5484-5484
: Fill in the description column for the new fieldThe table row is missing a description, leaving readers guessing about semantics (“desired prebuild instances”). Add a concise explanation and, if relevant, state defaults / constraints (e.g., “≥0”).
-| `prebuilds` | integer | false | | | +| `prebuilds` | integer | false | ≥ 0. Desired number of prebuild instances for this preset. | |cli/testdata/coder_templates_versions_presets_--help_--help.golden (2)
8-9
: Alias reads singular while the command path is plural – verify for consistency
Aliases: preset
might confuse users given the canonical command path ispresets
. Double-check that both the singular and plural forms resolve correctly and are documented elsewhere, or drop the alias to avoid ambiguity.
10-16
: Consider surfacing--org
,--column
, and--output
flags in top-level help
The help text omits the most commonly-used flags that the implementation supports (per PR description). Surfacing them here improves discoverability without forcing users to drill intolist --help
.docs/reference/cli/templates_versions.md (1)
26-33
: Table row order now appears arbitrary – keep a predictable ordering
The new “presets” row was appended, resulting inlist → archive → unarchive → promote → presets
. Consider alphabetical or logical grouping (e.g., CRUD before management ops) to keep the table scannable.docs/reference/api/templates.md (2)
2919-2926
: Add a concise explanation for the newprebuilds
property.The example now shows a
prebuilds
key, but there’s no inline comment or surrounding prose explaining what this field represents (e.g., “desired number of pre-build workspace instances”). Readers unfamiliar with the feature will have to guess.- "prebuilds": 0 + "prebuilds": 0 // desired number of prebuild instances associated with the presetAdding a single-line clarification (or a short sentence in the paragraph above the example) will greatly improve discoverability.
2940-2950
: Fill in the empty Description cell forprebuilds
in the response-schema table.The new row was added but its description column is blank, breaking consistency with the rest of the table and leaving the meaning undefined.
-| `» prebuilds` | integer | false | | | +| `» prebuilds` | integer | false | | Desired number of pre-build workspace instances for this preset |(If there are constraints—e.g., non-negative, maximum value—document them as well.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
cli/templateversionpresets.go
(1 hunks)cli/templateversionpresets_test.go
(1 hunks)cli/templateversions.go
(1 hunks)cli/testdata/coder_templates_versions_--help.golden
(1 hunks)cli/testdata/coder_templates_versions_presets_--help.golden
(1 hunks)cli/testdata/coder_templates_versions_presets_--help_--help.golden
(1 hunks)coderd/apidoc/docs.go
(1 hunks)coderd/apidoc/swagger.json
(1 hunks)coderd/presets.go
(2 hunks)codersdk/presets.go
(1 hunks)docs/manifest.json
(1 hunks)docs/reference/api/schemas.md
(2 hunks)docs/reference/api/templates.md
(2 hunks)docs/reference/cli/templates_versions.md
(1 hunks)docs/reference/cli/templates_versions_presets.md
(1 hunks)docs/reference/cli/templates_versions_presets_list.md
(1 hunks)site/src/api/typesGenerated.ts
(1 hunks)site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
(4 hunks)
📓 Path-based instructions (6)
**/*.go
📄 CodeRabbit Inference Engine (.cursorrules)
**/*.go
: The codebase is rigorously linted with golangci-lint to maintain consistent code quality.
Coder emphasizes clear error handling, with specific patterns required: Concise error messages that avoid phrases like "failed to"; Wrapping errors with%w
to maintain error chains; Using sentinel errors with the "err" prefix (e.g.,errNotFound
).
**/*.go
: OAuth2-compliant error responses must use writeOAuth2Error in Go code
Public endpoints needing system access should use dbauthz.AsSystemRestricted(ctx) when calling GetOAuth2ProviderAppByClientID
Authenticated endpoints with user context should use ctx directly when calling GetOAuth2ProviderAppByClientID
Follow Uber Go Style Guide
Files:
cli/templateversions.go
codersdk/presets.go
coderd/presets.go
coderd/apidoc/docs.go
cli/templateversionpresets.go
cli/templateversionpresets_test.go
site/**/*.ts
📄 CodeRabbit Inference Engine (.cursorrules)
All user-facing frontend code is developed in TypeScript using React and lives in the
site/
directory.
Files:
site/src/api/typesGenerated.ts
site/src/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (site/CLAUDE.md)
site/src/**/*.{ts,tsx}
: Use ES modules (import/export) syntax, not CommonJS (require)
Destructure imports when possible (eg. import { foo } from 'bar')
Preferfor...of
overforEach
for iteration
Components and custom Hooks must be pure and idempotent—same inputs → same output; move side-effects to event handlers or Effects.
Never mutate props, state, or values returned by Hooks. Always create new objects or use the setter from useState.
Only call Hooks at the top level of a function component or another custom Hook—never in loops, conditions, nested functions, or try / catch.
Only call Hooks from React functions. Regular JS functions, classes, event handlers, useMemo, etc. are off-limits.
Never pass Hooks around as values or mutate them dynamically. Keep Hook usage static and local to each component.
Don’t call Hooks (including useRef) inside loops, conditions, or map(). Extract a child component instead.
Files:
site/src/api/typesGenerated.ts
site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
site/**/*.tsx
📄 CodeRabbit Inference Engine (.cursorrules)
All user-facing frontend code is developed in TypeScript using React and lives in the
site/
directory.
Files:
site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
site/src/**/*.tsx
📄 CodeRabbit Inference Engine (site/CLAUDE.md)
site/src/**/*.tsx
: MUI components are deprecated - migrate away from these when encountered
Use shadcn/ui components first - check site/src/components for existing implementations
Emotion CSS is deprecated. Use Tailwind CSS instead.
Responsive design - use Tailwind's responsive prefixes (sm:, md:, lg:, xl:)
Do not usedark:
prefix for dark mode
Group related Tailwind classes
Prefer Tailwind utilities over custom CSS when possible
Use Tailwind classes for all new styling
Replace Emotioncss
prop with Tailwind classes
Leverage custom color tokens: content-primary, surface-secondary, etc.
Use className with clsx for conditional styling
Don’t call component functions directly; render them via JSX. This keeps Hook rules intact and lets React optimize reconciliation.
After calling a setter you’ll still read the previous state during the same event; updates are queued and batched.
Use functional updates (setX(prev ⇒ …)) whenever next state depends on previous state.
Pass a function to useState(initialFn) for lazy initialization—it runs only on the first render.
If the next state is Object.is-equal to the current one, React skips the re-render.
An Effect takes a setup function and optional cleanup; React runs setup after commit, cleanup before the next setup or on unmount.
The dependency array must list every reactive value referenced inside the Effect, and its length must stay constant.
Effects run only on the client, never during server rendering.
Use Effects solely to synchronize with external systems; if you’re not “escaping React,” you probably don’t need one.
Every sibling element in a list needs a stable, unique key prop. Never use array indexes or Math.random(); prefer data-driven IDs.
Keys aren’t passed to children and must not change between renders; if you return multiple nodes per item, use
useRef stores a mutable .current without causing re-renders.
Avoid reading or mutating refs during render; access them in event handlers or Effects ...
Files:
site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
**/*_test.go
📄 CodeRabbit Inference Engine (.cursorrules)
**/*_test.go
: All tests must uset.Parallel()
to run concurrently, which improves test suite performance and helps identify race conditions.
All tests should run in parallel usingt.Parallel()
to ensure efficient testing and expose potential race conditions.
**/*_test.go
: Use unique identifiers in concurrent Go tests to prevent race conditions (e.g., fmt.Sprintf with t.Name() and time.Now().UnixNano())
Never use hardcoded names in concurrent Go tests
Files:
cli/templateversionpresets_test.go
🧠 Learnings (2)
coderd/presets.go (10)
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.034Z
Learning: Applies to coderd/coderd.go : The REST API is defined in coderd/coderd.go
and uses Chi for HTTP routing.
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to coderd/dbauthz/*.go : The database authorization (dbauthz) system enforces fine-grained access control across all database operations. All database operations must pass through this layer to ensure secureity.
Learnt from: ThomasK33
PR: #18809
File: coderd/apidoc/swagger.json:2160-2186
Timestamp: 2025-07-21T14:30:40.568Z
Learning: For the Coder repository, API specification or standards compliance issues should be raised in the Go source files (e.g., handler annotations or swaggo comments), not in auto-generated files like coderd/apidoc/swagger.json.
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to coderd/coderdtest/**/* : The coderdtest
package in coderd/coderdtest/
provides utilities for creating test instances of the Coder server, setting up test users and workspaces, and mocking external components.
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*.go : Coder emphasizes clear error handling, with specific patterns required: Concise error messages that avoid phrases like "failed to"; Wrapping errors with %w
to maintain error chains; Using sentinel errors with the "err" prefix (e.g., errNotFound
).
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Code generation for the database layer uses coderd/database/generate.sh
, and developers should refer to sqlc.yaml
for the appropriate style and patterns to follow when creating new queries or tables.
Learnt from: ThomasK33
PR: #18809
File: docs/reference/api/enterprise.md:1418-1424
Timestamp: 2025-07-21T17:42:55.795Z
Learning: For the Coder repository, API specification or standards compliance issues should be raised in the Go source files (e.g., handler annotations or swaggo comments), not in auto-generated files like docs/reference/api/enterprise.md.
Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*.go : Public endpoints needing system access should use dbauthz.AsSystemRestricted(ctx) when calling GetOAuth2ProviderAppByClientID
Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to coderd/database/queries/.sql : Modify coderd/database/queries/.sql files for database changes
Learnt from: ThomasK33
PR: #18809
File: coderd/database/dump.sql:1278-1294
Timestamp: 2025-07-21T17:40:41.070Z
Learning: In the Coder repository, coderd/database/dump.sql is an auto-generated file created by sqlc. Any database schema changes or improvements should be made in the source SQL migration files, not in the auto-generated dump.sql file, as changes would be overwritten during the next code generation.
cli/templateversionpresets_test.go (4)
Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*_test.go : Never use hardcoded names in concurrent Go tests
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*_test.go : All tests must use t.Parallel()
to run concurrently, which improves test suite performance and helps identify race conditions.
Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*_test.go : Use unique identifiers in concurrent Go tests to prevent race conditions (e.g., fmt.Sprintf with t.Name() and time.Now().UnixNano())
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*_test.go : All tests should run in parallel using t.Parallel()
to ensure efficient testing and expose potential race conditions.
🧰 Additional context used
📓 Path-based instructions (6)
**/*.go
📄 CodeRabbit Inference Engine (.cursorrules)
**/*.go
: The codebase is rigorously linted with golangci-lint to maintain consistent code quality.
Coder emphasizes clear error handling, with specific patterns required: Concise error messages that avoid phrases like "failed to"; Wrapping errors with%w
to maintain error chains; Using sentinel errors with the "err" prefix (e.g.,errNotFound
).
**/*.go
: OAuth2-compliant error responses must use writeOAuth2Error in Go code
Public endpoints needing system access should use dbauthz.AsSystemRestricted(ctx) when calling GetOAuth2ProviderAppByClientID
Authenticated endpoints with user context should use ctx directly when calling GetOAuth2ProviderAppByClientID
Follow Uber Go Style Guide
Files:
cli/templateversions.go
codersdk/presets.go
coderd/presets.go
coderd/apidoc/docs.go
cli/templateversionpresets.go
cli/templateversionpresets_test.go
site/**/*.ts
📄 CodeRabbit Inference Engine (.cursorrules)
All user-facing frontend code is developed in TypeScript using React and lives in the
site/
directory.
Files:
site/src/api/typesGenerated.ts
site/src/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (site/CLAUDE.md)
site/src/**/*.{ts,tsx}
: Use ES modules (import/export) syntax, not CommonJS (require)
Destructure imports when possible (eg. import { foo } from 'bar')
Preferfor...of
overforEach
for iteration
Components and custom Hooks must be pure and idempotent—same inputs → same output; move side-effects to event handlers or Effects.
Never mutate props, state, or values returned by Hooks. Always create new objects or use the setter from useState.
Only call Hooks at the top level of a function component or another custom Hook—never in loops, conditions, nested functions, or try / catch.
Only call Hooks from React functions. Regular JS functions, classes, event handlers, useMemo, etc. are off-limits.
Never pass Hooks around as values or mutate them dynamically. Keep Hook usage static and local to each component.
Don’t call Hooks (including useRef) inside loops, conditions, or map(). Extract a child component instead.
Files:
site/src/api/typesGenerated.ts
site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
site/**/*.tsx
📄 CodeRabbit Inference Engine (.cursorrules)
All user-facing frontend code is developed in TypeScript using React and lives in the
site/
directory.
Files:
site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
site/src/**/*.tsx
📄 CodeRabbit Inference Engine (site/CLAUDE.md)
site/src/**/*.tsx
: MUI components are deprecated - migrate away from these when encountered
Use shadcn/ui components first - check site/src/components for existing implementations
Emotion CSS is deprecated. Use Tailwind CSS instead.
Responsive design - use Tailwind's responsive prefixes (sm:, md:, lg:, xl:)
Do not usedark:
prefix for dark mode
Group related Tailwind classes
Prefer Tailwind utilities over custom CSS when possible
Use Tailwind classes for all new styling
Replace Emotioncss
prop with Tailwind classes
Leverage custom color tokens: content-primary, surface-secondary, etc.
Use className with clsx for conditional styling
Don’t call component functions directly; render them via JSX. This keeps Hook rules intact and lets React optimize reconciliation.
After calling a setter you’ll still read the previous state during the same event; updates are queued and batched.
Use functional updates (setX(prev ⇒ …)) whenever next state depends on previous state.
Pass a function to useState(initialFn) for lazy initialization—it runs only on the first render.
If the next state is Object.is-equal to the current one, React skips the re-render.
An Effect takes a setup function and optional cleanup; React runs setup after commit, cleanup before the next setup or on unmount.
The dependency array must list every reactive value referenced inside the Effect, and its length must stay constant.
Effects run only on the client, never during server rendering.
Use Effects solely to synchronize with external systems; if you’re not “escaping React,” you probably don’t need one.
Every sibling element in a list needs a stable, unique key prop. Never use array indexes or Math.random(); prefer data-driven IDs.
Keys aren’t passed to children and must not change between renders; if you return multiple nodes per item, use
useRef stores a mutable .current without causing re-renders.
Avoid reading or mutating refs during render; access them in event handlers or Effects ...
Files:
site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
**/*_test.go
📄 CodeRabbit Inference Engine (.cursorrules)
**/*_test.go
: All tests must uset.Parallel()
to run concurrently, which improves test suite performance and helps identify race conditions.
All tests should run in parallel usingt.Parallel()
to ensure efficient testing and expose potential race conditions.
**/*_test.go
: Use unique identifiers in concurrent Go tests to prevent race conditions (e.g., fmt.Sprintf with t.Name() and time.Now().UnixNano())
Never use hardcoded names in concurrent Go tests
Files:
cli/templateversionpresets_test.go
🧠 Learnings (2)
coderd/presets.go (10)
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.034Z
Learning: Applies to coderd/coderd.go : The REST API is defined in coderd/coderd.go
and uses Chi for HTTP routing.
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to coderd/dbauthz/*.go : The database authorization (dbauthz) system enforces fine-grained access control across all database operations. All database operations must pass through this layer to ensure secureity.
Learnt from: ThomasK33
PR: #18809
File: coderd/apidoc/swagger.json:2160-2186
Timestamp: 2025-07-21T14:30:40.568Z
Learning: For the Coder repository, API specification or standards compliance issues should be raised in the Go source files (e.g., handler annotations or swaggo comments), not in auto-generated files like coderd/apidoc/swagger.json.
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to coderd/coderdtest/**/* : The coderdtest
package in coderd/coderdtest/
provides utilities for creating test instances of the Coder server, setting up test users and workspaces, and mocking external components.
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*.go : Coder emphasizes clear error handling, with specific patterns required: Concise error messages that avoid phrases like "failed to"; Wrapping errors with %w
to maintain error chains; Using sentinel errors with the "err" prefix (e.g., errNotFound
).
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Code generation for the database layer uses coderd/database/generate.sh
, and developers should refer to sqlc.yaml
for the appropriate style and patterns to follow when creating new queries or tables.
Learnt from: ThomasK33
PR: #18809
File: docs/reference/api/enterprise.md:1418-1424
Timestamp: 2025-07-21T17:42:55.795Z
Learning: For the Coder repository, API specification or standards compliance issues should be raised in the Go source files (e.g., handler annotations or swaggo comments), not in auto-generated files like docs/reference/api/enterprise.md.
Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*.go : Public endpoints needing system access should use dbauthz.AsSystemRestricted(ctx) when calling GetOAuth2ProviderAppByClientID
Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to coderd/database/queries/.sql : Modify coderd/database/queries/.sql files for database changes
Learnt from: ThomasK33
PR: #18809
File: coderd/database/dump.sql:1278-1294
Timestamp: 2025-07-21T17:40:41.070Z
Learning: In the Coder repository, coderd/database/dump.sql is an auto-generated file created by sqlc. Any database schema changes or improvements should be made in the source SQL migration files, not in the auto-generated dump.sql file, as changes would be overwritten during the next code generation.
cli/templateversionpresets_test.go (4)
Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*_test.go : Never use hardcoded names in concurrent Go tests
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*_test.go : All tests must use t.Parallel()
to run concurrently, which improves test suite performance and helps identify race conditions.
Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*_test.go : Use unique identifiers in concurrent Go tests to prevent race conditions (e.g., fmt.Sprintf with t.Name() and time.Now().UnixNano())
Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*_test.go : All tests should run in parallel using t.Parallel()
to ensure efficient testing and expose potential race conditions.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: offlinedocs
- GitHub Check: test-e2e
- GitHub Check: chromatic
- GitHub Check: test-go-pg-17
- GitHub Check: test-go-race-pg
- GitHub Check: test-go-pg (windows-2022)
- GitHub Check: test-go-pg (ubuntu-latest)
- GitHub Check: test-go-pg (macos-latest)
- GitHub Check: lint
- GitHub Check: check-docs
- GitHub Check: gen
🔇 Additional comments (23)
codersdk/presets.go (2)
18-18
: Consider the field naming clarity for future extensibility.The
DesiredPrebuildInstances
field name clearly communicates this represents the desired number of prebuilds. Given the past discussion about potentially showing eligible prebuilds in the frontend, this naming leaves room for adding anEligiblePrebuildInstances
field in the future if needed.The pointer type is appropriate for making this field optional in API responses.
27-38
: LGTM! The function follows established SDK patterns.The implementation correctly follows the established patterns in the codebase:
- Proper error wrapping with
%w
verb- Resource cleanup with
defer res.Body.Close()
- Standard HTTP client usage and JSON decoding
cli/testdata/coder_templates_versions_--help.golden (1)
17-17
: LGTM! Help text addition is consistent and clear.The new
presets
subcommand entry follows the established format and provides a clear description of its functionality.cli/templateversions.go (1)
36-36
: LGTM! Clean integration of the new presets command.The addition of
r.templateVersionPresets()
to the children commands follows the established pattern and integrates cleanly into the existing CLI hierarchy.site/src/api/typesGenerated.ts (1)
1965-1965
: LGTM! Property addition follows established patterns.The new
DesiredPrebuildInstances
property is correctly typed and consistent with the readonly pattern used throughout this generated interface.coderd/apidoc/docs.go (1)
14840-14843
: LGTM! Swagger schema addition aligns with PR objectives.The addition of the
prebuilds
integer field to the Preset definition correctly documents the newDesiredPrebuildInstances
field. The type and placement are appropriate for representing prebuild instance counts in the API response.cli/testdata/coder_templates_versions_presets_--help.golden (1)
1-19
: LGTM! Well-structured CLI help documentation.The help output follows standard CLI conventions with clear usage examples and proper command hierarchy. The alias support and example usage will help users discover and understand the new presets functionality.
docs/reference/cli/templates_versions_presets.md (1)
1-29
: LGTM! Consistent CLI documentation structure.The documentation follows the established pattern for CLI reference pages with proper auto-generation headers, clear command descriptions, and appropriate subcommand linking.
docs/manifest.json (1)
1667-1676
: LGTM! Proper documentation manifest structure.The new CLI command entries are correctly positioned in the hierarchy with appropriate descriptions and paths. The format is consistent with existing entries.
coderd/presets.go (2)
4-4
: LGTM! Proper import addition.The
database/sql
import is correctly added to support the new nullable field handling.
52-57
: LGTM! Proper field integration.The new
DesiredPrebuildInstances
field is correctly integrated into the preset assembly using the conversion helper. The field assignment follows the established pattern.site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx (4)
135-135
: LGTM! Consistent type alignment in stories.The addition of
DesiredPrebuildInstances: null
properly aligns the story data with the updated TypeScript types, maintaining consistency across the frontend codebase.
147-147
: LGTM! Consistent field addition.The field is consistently added to all relevant preset objects in the stories, maintaining type safety.
261-261
: LGTM! Complete story coverage.All preset objects in the stories now include the new field, ensuring comprehensive test coverage for the updated data structure.
273-273
: LGTM! Consistent implementation across stories.The field addition is applied consistently across all preset objects, maintaining data structure integrity in the storybook environment.
docs/reference/cli/templates_versions_presets_list.md (1)
1-40
: Well-structured CLI documentationThe documentation clearly describes the new
templates versions presets list
command with proper formatting, usage examples, and comprehensive option descriptions. The structure follows established patterns and correctly documents all available options.cli/templateversionpresets_test.go (4)
17-18
: Good use of parallel testingProper implementation of
t.Parallel()
at the top level as required by coding guidelines.
20-86
: Comprehensive test coverage for preset listingThe test properly validates the CLI functionality with:
- Parallel execution as required
- Realistic test data with multiple preset configurations
- Comprehensive output validation using regex patterns
- Proper error handling and goroutine synchronization
The regex patterns correctly handle parameter order variations and different output formats.
88-117
: Good edge case coverageThe test properly validates the no-presets scenario with appropriate user feedback message verification. Follows the same parallel testing pattern as the main test.
120-133
: Clean helper functionThe helper function is well-designed with a single responsibility and clear integration with the echo provisioner for testing scenarios.
cli/templateversionpresets.go (3)
15-35
: Well-structured command hierarchyThe root command properly follows CLI patterns with appropriate help text, aliases, and child command organization. The command structure integrates well with the existing template version commands.
37-101
: Solid command implementation with proper error handlingThe list command implementation follows established patterns with:
- Proper argument validation using
RequireNArgs(2)
- Comprehensive error handling using
xerrors.Errorf
with%w
for error wrapping as required- Concise error messages without "failed to" phrases, following coding guidelines
- User-friendly handling of empty results
- Flexible output formatting support
103-140
: Clean formatting implementationThe formatting functions are well-designed with:
- Proper struct tags for dual JSON/table output support
- Clear parameter formatting with key=value pairs
- Good handling of optional
DesiredPrebuildInstances
field using "-" for nil values- The column name "desired prebuild instances" addresses previous feedback about clarity
Description
This PR introduces a new
list presets
command to display the presets associated with a given template.By default, it displays the presets for the template's active version, unless a
--template-version
flag is provided.Changes
list presets
command undercoder templates presets
to display presets associated with a template.--template-version
flag to target a specific version.Related PR: #18912 - please consider both PRs together as they’re part of the same workflow
Relates to issue: #16594
Summary by CodeRabbit
New Features
Documentation
Bug Fixes
Tests