From 254fc8aada26acfe588fd7727d6cf11e3ef1341b Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 10 May 2023 13:35:31 +0200 Subject: [PATCH 01/11] Backend changes --- coderd/templateversions.go | 105 ++++++++++++++++++++++++++++++--- codersdk/templateversions.go | 8 +++ site/src/api/typesGenerated.ts | 5 ++ 3 files changed, 110 insertions(+), 8 deletions(-) diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 8b31c6ad177f1..15b037bd62988 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -62,7 +62,19 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) { return } - httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user)) + schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ + Message: "Internal error listing parameter schemas.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas)) } // @Summary Patch template version by ID @@ -156,7 +168,19 @@ func (api *API) patchTemplateVersion(rw http.ResponseWriter, r *http.Request) { return } - httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(updatedTemplateVersion, convertProvisionerJob(job), user)) + schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ + Message: "Internal error listing parameter schemas.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(updatedTemplateVersion, convertProvisionerJob(job), user, schemas)) } // @Summary Cancel template version by ID @@ -887,7 +911,18 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque }) return err } - apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), user)) + schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ + Message: "Internal error listing parameter schemas.", + Detail: err.Error(), + }) + return err + } + apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), user, schemas)) } return nil @@ -951,7 +986,19 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) { return } - httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user)) + schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ + Message: "Internal error listing parameter schemas.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas)) } // @Summary Get template version by organization, template, and name @@ -1025,7 +1072,19 @@ func (api *API) templateVersionByOrganizationTemplateAndName(rw http.ResponseWri return } - httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user)) + schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ + Message: "Internal error listing parameter schemas.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas)) } // @Summary Get previous template version by organization, template, and name @@ -1120,7 +1179,19 @@ func (api *API) previousTemplateVersionByOrganizationTemplateAndName(rw http.Res return } - httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(previousTemplateVersion, convertProvisionerJob(job), user)) + schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ + Message: "Internal error listing parameter schemas.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(previousTemplateVersion, convertProvisionerJob(job), user, schemas)) } // @Summary Update active template version by template ID @@ -1494,7 +1565,19 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht return } - httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user)) + schemas, err := api.Database.GetParameterSchemasByJobID(ctx, provisionerJob.ID) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ + Message: "Internal error listing parameter schemas.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user, schemas)) } // templateVersionResources returns the workspace agent resources associated @@ -1561,7 +1644,7 @@ func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) { api.provisionerJobLogs(rw, r, job) } -func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, user database.User) codersdk.TemplateVersion { +func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, user database.User, schemas []database.ParameterSchema) codersdk.TemplateVersion { createdBy := codersdk.User{ ID: user.ID, Username: user.Username, @@ -1572,6 +1655,11 @@ func convertTemplateVersion(version database.TemplateVersion, job codersdk.Provi AvatarURL: user.AvatarURL.String, } + var warnings []codersdk.TemplateVersionWarning + if len(schemas) > 0 { + warnings = append(warnings, codersdk.TemplateVersionWarningDeprecatedParameters) + } + return codersdk.TemplateVersion{ ID: version.ID, TemplateID: &version.TemplateID.UUID, @@ -1582,6 +1670,7 @@ func convertTemplateVersion(version database.TemplateVersion, job codersdk.Provi Job: job, Readme: version.Readme, CreatedBy: createdBy, + Warnings: warnings, } } diff --git a/codersdk/templateversions.go b/codersdk/templateversions.go index b1608643084ec..bc80ea0d04766 100644 --- a/codersdk/templateversions.go +++ b/codersdk/templateversions.go @@ -11,6 +11,12 @@ import ( "github.com/google/uuid" ) +type TemplateVersionWarning string + +const ( + TemplateVersionWarningDeprecatedParameters = "DEPRECATED_PARAMETERS" +) + // TemplateVersion represents a single version of a template. type TemplateVersion struct { ID uuid.UUID `json:"id" format:"uuid"` @@ -22,6 +28,8 @@ type TemplateVersion struct { Job ProvisionerJob `json:"job"` Readme string `json:"readme"` CreatedBy User `json:"created_by"` + + Warnings []TemplateVersionWarning `json:"warnings,omitempty" enums:"DEPRECATED_PARAMETERS"` } type TemplateVersionGitAuth struct { diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 49618413b5ece..dbdb3470999e4 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -899,6 +899,7 @@ export interface TemplateVersion { readonly job: ProvisionerJob readonly readme: string readonly created_by: User + readonly warnings?: TemplateVersionWarning[] } // From codersdk/templateversions.go @@ -1590,6 +1591,10 @@ export const ServerSentEventTypes: ServerSentEventType[] = [ export type TemplateRole = "" | "admin" | "use" export const TemplateRoles: TemplateRole[] = ["", "admin", "use"] +// From codersdk/templateversions.go +export type TemplateVersionWarning = never +export const TemplateVersionWarnings: TemplateVersionWarning[] = [] + // From codersdk/users.go export type UserStatus = "active" | "suspended" export const UserStatuses: UserStatus[] = ["active", "suspended"] From 912a604a5acffba90abc5ee152cf725627e6da00 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 10 May 2023 14:05:15 +0200 Subject: [PATCH 02/11] site: get template version --- .../xServices/workspace/workspaceXService.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/site/src/xServices/workspace/workspaceXService.ts b/site/src/xServices/workspace/workspaceXService.ts index e4bc7461301c1..ee161d87153d9 100644 --- a/site/src/xServices/workspace/workspaceXService.ts +++ b/site/src/xServices/workspace/workspaceXService.ts @@ -59,6 +59,7 @@ export interface WorkspaceContext { eventSource?: EventSource workspace?: TypesGen.Workspace template?: TypesGen.Template + templateVersion?: TypesGen.TemplateVersion build?: TypesGen.WorkspaceBuild getWorkspaceError?: AxiosError getTemplateWarning: Error | unknown @@ -157,6 +158,9 @@ export const workspaceMachine = createMachine( getTemplate: { data: TypesGen.Template } + getTemplateVersion: { + data: TypesGen.TemplateVersion + } getTemplateParameters: { data: TypesGen.TemplateVersionParameter[] } @@ -221,6 +225,28 @@ export const workspaceMachine = createMachine( onDone: [ { actions: ["assignTemplate", "clearGetTemplateWarning"], + target: "gettingTemplateVersion", + }, + ], + onError: [ + { + actions: [ + "assignGetTemplateWarning", + "displayGetTemplateWarning", + ], + target: "error", + }, + ], + }, + tags: "loading", + }, + gettingTemplateVersion: { + invoke: { + src: "getTemplateVersion", + id: "getTemplateVersion", + onDone: [ + { + actions: ["assignTemplateVersion", "clearGetTemplateWarning"], target: "gettingPermissions", }, ], @@ -557,6 +583,9 @@ export const workspaceMachine = createMachine( assignTemplate: assign({ template: (_, event) => event.data, }), + assignTemplateVersion: assign({ + templateVersion: (_, event) => event.data, + }), assignPermissions: assign({ // Setting event.data as Permissions to be more stricted. So we know // what permissions we asked for. @@ -689,6 +718,13 @@ export const workspaceMachine = createMachine( throw Error("Cannot get template without workspace") } }, + getTemplateVersion: async (context) => { + if (context.template) { + return await API.getTemplateVersion(context.template.active_version_id) + } else { + throw Error("Cannot get template version without template") + } + }, updateWorkspace: ({ workspace }, { buildParameters }) => async (send) => { From e2eab2bdb813e0bfed19677d3ad2adc01e051428 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 10 May 2023 14:55:47 +0200 Subject: [PATCH 03/11] MVP --- codersdk/templateversions.go | 2 +- site/src/api/typesGenerated.ts | 6 +++-- site/src/components/Workspace/Workspace.tsx | 23 +++++++++++++++++++ .../TemplateSummaryPageView.tsx | 21 +++++++++++++++++ .../WorkspacePage/WorkspaceReadyPage.tsx | 2 ++ .../xServices/workspace/workspaceXService.ts | 4 +++- 6 files changed, 54 insertions(+), 4 deletions(-) diff --git a/codersdk/templateversions.go b/codersdk/templateversions.go index bc80ea0d04766..cfc9af54443ae 100644 --- a/codersdk/templateversions.go +++ b/codersdk/templateversions.go @@ -14,7 +14,7 @@ import ( type TemplateVersionWarning string const ( - TemplateVersionWarningDeprecatedParameters = "DEPRECATED_PARAMETERS" + TemplateVersionWarningDeprecatedParameters TemplateVersionWarning = "DEPRECATED_PARAMETERS" ) // TemplateVersion represents a single version of a template. diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index dbdb3470999e4..c8cd218ce22f4 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1592,8 +1592,10 @@ export type TemplateRole = "" | "admin" | "use" export const TemplateRoles: TemplateRole[] = ["", "admin", "use"] // From codersdk/templateversions.go -export type TemplateVersionWarning = never -export const TemplateVersionWarnings: TemplateVersionWarning[] = [] +export type TemplateVersionWarning = "DEPRECATED_PARAMETERS" +export const TemplateVersionWarnings: TemplateVersionWarning[] = [ + "DEPRECATED_PARAMETERS", +] // From codersdk/users.go export type UserStatus = "active" | "suspended" diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index 8a1db80814baf..fd275e8014053 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -26,6 +26,8 @@ import { PageHeaderTitle, PageHeaderSubtitle, } from "components/PageHeader/FullWidthPageHeader" +import { Maybe } from "components/Conditionals/Maybe" +import { Link } from "@material-ui/core" export enum WorkspaceErrors { GET_BUILDS_ERROR = "getBuildsError", @@ -52,6 +54,7 @@ export interface WorkspaceProps { workspace: TypesGen.Workspace resources?: TypesGen.WorkspaceResource[] builds?: TypesGen.WorkspaceBuild[] + templateWarnings?: TypesGen.TemplateVersionWarning[] canUpdateWorkspace: boolean canUpdateTemplate: boolean canChangeVersions: boolean @@ -96,6 +99,7 @@ export const Workspace: FC> = ({ quota_budget, failedBuildLogs, handleBuildRetry, + templateWarnings, }) => { const styles = useStyles() const navigate = useNavigate() @@ -186,6 +190,25 @@ export const Workspace: FC> = ({ handleClick={() => navigate(`/templates`)} /> + {templateWarnings && ( + + +
+ This template uses legacy parameters which will be deprecated + in the next Coder release. Learn how to migrate in{" "} + + our documentation + + . +
+
+
+ )} + {failedBuildLogs && ( diff --git a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx index 4c46a84369cb1..28681dbfb67d0 100644 --- a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx +++ b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx @@ -11,6 +11,9 @@ import { FC, useEffect } from "react" import { DAUChart } from "../../../components/DAUChart/DAUChart" import { TemplateSummaryData } from "./data" import { useLocation, useNavigate } from "react-router-dom" +import { Maybe } from "components/Conditionals/Maybe" +import { AlertBanner } from "components/AlertBanner/AlertBanner" +import Link from "@material-ui/core/Link" export interface TemplateSummaryPageViewProps { data?: TemplateSummaryData @@ -48,6 +51,24 @@ export const TemplateSummaryPageView: FC = ({ return ( + {activeVersion.warnings && ( + + +
+ This template uses legacy parameters which will be deprecated in + the next Coder release. Learn how to migrate in{" "} + + our documentation + + . +
+
+
+ )} {daus && } diff --git a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx index f25ca22927a4b..de80d7314e925 100644 --- a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx +++ b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx @@ -54,6 +54,7 @@ export const WorkspaceReadyPage = ({ const { workspace, template, + templateVersion, builds, getBuildsError, buildError, @@ -157,6 +158,7 @@ export const WorkspaceReadyPage = ({ sshPrefix={sshPrefix} template={template} quota_budget={quotaState.context.quota?.budget} + templateWarnings={templateVersion?.warnings} /> { if (context.template) { - return await API.getTemplateVersion(context.template.active_version_id) + return await API.getTemplateVersion( + context.template.active_version_id, + ) } else { throw Error("Cannot get template version without template") } From 2f71ed5f25f71c3ebb18e9dd55f08b00402ca646 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 10 May 2023 15:37:19 +0200 Subject: [PATCH 04/11] fix --- .../TemplateVersionWarnings.tsx | 32 +++++++++++++++++++ site/src/components/Workspace/Workspace.tsx | 22 ++----------- .../TemplateSummaryPageView.tsx | 23 ++----------- 3 files changed, 36 insertions(+), 41 deletions(-) create mode 100644 site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx diff --git a/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx new file mode 100644 index 0000000000000..645c0fc7a1a53 --- /dev/null +++ b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx @@ -0,0 +1,32 @@ +import { FC } from "react" +import * as TypesGen from "api/typesGenerated" +import { AlertBanner } from "components/AlertBanner/AlertBanner" +import { Maybe } from "components/Conditionals/Maybe" +import Link from "@material-ui/core/Link" + +export interface TemplateVersionWarnings { + warnings?: TypesGen.TemplateVersionWarning[] +} + +export const TemplateVersionWarnings: FC< + React.PropsWithChildren +> = ({ warnings }) => { + if (!warnings) { + return <> + } + + return ( + + +
+ This template uses legacy parameters which will be deprecated in the + next Coder release. Learn how to migrate in{" "} + + our documentation + + . +
+
+
+ ) +} diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index fd275e8014053..570d58d2d5b26 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -26,8 +26,7 @@ import { PageHeaderTitle, PageHeaderSubtitle, } from "components/PageHeader/FullWidthPageHeader" -import { Maybe } from "components/Conditionals/Maybe" -import { Link } from "@material-ui/core" +import { TemplateVersionWarnings } from "components/TemplateVersionWarnings/TemplateVersionWarnings" export enum WorkspaceErrors { GET_BUILDS_ERROR = "getBuildsError", @@ -190,24 +189,7 @@ export const Workspace: FC> = ({ handleClick={() => navigate(`/templates`)} /> - {templateWarnings && ( - - -
- This template uses legacy parameters which will be deprecated - in the next Coder release. Learn how to migrate in{" "} - - our documentation - - . -
-
-
- )} + {failedBuildLogs && ( diff --git a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx index 28681dbfb67d0..462b9db37e69a 100644 --- a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx +++ b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.tsx @@ -11,9 +11,7 @@ import { FC, useEffect } from "react" import { DAUChart } from "../../../components/DAUChart/DAUChart" import { TemplateSummaryData } from "./data" import { useLocation, useNavigate } from "react-router-dom" -import { Maybe } from "components/Conditionals/Maybe" -import { AlertBanner } from "components/AlertBanner/AlertBanner" -import Link from "@material-ui/core/Link" +import { TemplateVersionWarnings } from "components/TemplateVersionWarnings/TemplateVersionWarnings" export interface TemplateSummaryPageViewProps { data?: TemplateSummaryData @@ -51,24 +49,7 @@ export const TemplateSummaryPageView: FC = ({ return ( - {activeVersion.warnings && ( - - -
- This template uses legacy parameters which will be deprecated in - the next Coder release. Learn how to migrate in{" "} - - our documentation - - . -
-
-
- )} + {daus && } From 9b3fa89ce18ef048c967dbd50a399853a67f83ca Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 10 May 2023 15:43:27 +0200 Subject: [PATCH 05/11] gen --- coderd/apidoc/docs.go | 18 +++++++++++++++++ coderd/apidoc/swagger.json | 12 ++++++++++++ docs/api/schemas.md | 40 ++++++++++++++++++++++++++------------ docs/api/templates.md | 23 +++++++++++++++------- 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 58788629a1038..5c8382e9f6670 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -9012,6 +9012,15 @@ const docTemplate = `{ "updated_at": { "type": "string", "format": "date-time" + }, + "warnings": { + "type": "array", + "items": { + "enum": [ + "DEPRECATED_PARAMETERS" + ], + "$ref": "#/definitions/codersdk.TemplateVersionWarning" + } } } }, @@ -9150,6 +9159,15 @@ const docTemplate = `{ } } }, + "codersdk.TemplateVersionWarning": { + "type": "string", + "enum": [ + "DEPRECATED_PARAMETERS" + ], + "x-enum-varnames": [ + "TemplateVersionWarningDeprecatedParameters" + ] + }, "codersdk.TokenConfig": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 96c9c7261f527..ea6be761af9ae 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -8098,6 +8098,13 @@ "updated_at": { "type": "string", "format": "date-time" + }, + "warnings": { + "type": "array", + "items": { + "enum": ["DEPRECATED_PARAMETERS"], + "$ref": "#/definitions/codersdk.TemplateVersionWarning" + } } } }, @@ -8224,6 +8231,11 @@ } } }, + "codersdk.TemplateVersionWarning": { + "type": "string", + "enum": ["DEPRECATED_PARAMETERS"], + "x-enum-varnames": ["TemplateVersionWarningDeprecatedParameters"] + }, "codersdk.TokenConfig": { "type": "object", "properties": { diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 977e467c5b2ba..85c5f7ea9e0e3 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -4106,23 +4106,25 @@ Parameter represents a set value for the scope. "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "readme": "string", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "updated_at": "2019-08-24T14:15:22Z" + "updated_at": "2019-08-24T14:15:22Z", + "warnings": ["DEPRECATED_PARAMETERS"] } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| ----------------- | -------------------------------------------------- | -------- | ------------ | ----------- | -| `created_at` | string | false | | | -| `created_by` | [codersdk.User](#codersdkuser) | false | | | -| `id` | string | false | | | -| `job` | [codersdk.ProvisionerJob](#codersdkprovisionerjob) | false | | | -| `name` | string | false | | | -| `organization_id` | string | false | | | -| `readme` | string | false | | | -| `template_id` | string | false | | | -| `updated_at` | string | false | | | +| Name | Type | Required | Restrictions | Description | +| ----------------- | --------------------------------------------------------------------------- | -------- | ------------ | ----------- | +| `created_at` | string | false | | | +| `created_by` | [codersdk.User](#codersdkuser) | false | | | +| `id` | string | false | | | +| `job` | [codersdk.ProvisionerJob](#codersdkprovisionerjob) | false | | | +| `name` | string | false | | | +| `organization_id` | string | false | | | +| `readme` | string | false | | | +| `template_id` | string | false | | | +| `updated_at` | string | false | | | +| `warnings` | array of [codersdk.TemplateVersionWarning](#codersdktemplateversionwarning) | false | | | ## codersdk.TemplateVersionGitAuth @@ -4260,6 +4262,20 @@ Parameter represents a set value for the scope. | `type` | `number` | | `type` | `bool` | +## codersdk.TemplateVersionWarning + +```json +"DEPRECATED_PARAMETERS" +``` + +### Properties + +#### Enumerated Values + +| Value | +| ----------------------- | +| `DEPRECATED_PARAMETERS` | + ## codersdk.TokenConfig ```json diff --git a/docs/api/templates.md b/docs/api/templates.md index 7df57183b54e3..6364e4b8e0279 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -394,7 +394,8 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "readme": "string", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "updated_at": "2019-08-24T14:15:22Z" + "updated_at": "2019-08-24T14:15:22Z", + "warnings": ["DEPRECATED_PARAMETERS"] } ``` @@ -471,7 +472,8 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "readme": "string", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "updated_at": "2019-08-24T14:15:22Z" + "updated_at": "2019-08-24T14:15:22Z", + "warnings": ["DEPRECATED_PARAMETERS"] } ``` @@ -580,7 +582,8 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "readme": "string", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "updated_at": "2019-08-24T14:15:22Z" + "updated_at": "2019-08-24T14:15:22Z", + "warnings": ["DEPRECATED_PARAMETERS"] } ``` @@ -877,7 +880,8 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions \ "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "readme": "string", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "updated_at": "2019-08-24T14:15:22Z" + "updated_at": "2019-08-24T14:15:22Z", + "warnings": ["DEPRECATED_PARAMETERS"] } ] ``` @@ -927,6 +931,7 @@ Status Code **200** | `» readme` | string | false | | | | `» template_id` | string(uuid) | false | | | | `» updated_at` | string(date-time) | false | | | +| `» warnings` | array | false | | | #### Enumerated Values @@ -1064,7 +1069,8 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions/{templ "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "readme": "string", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "updated_at": "2019-08-24T14:15:22Z" + "updated_at": "2019-08-24T14:15:22Z", + "warnings": ["DEPRECATED_PARAMETERS"] } ] ``` @@ -1114,6 +1120,7 @@ Status Code **200** | `» readme` | string | false | | | | `» template_id` | string(uuid) | false | | | | `» updated_at` | string(date-time) | false | | | +| `» warnings` | array | false | | | #### Enumerated Values @@ -1195,7 +1202,8 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion} \ "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "readme": "string", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "updated_at": "2019-08-24T14:15:22Z" + "updated_at": "2019-08-24T14:15:22Z", + "warnings": ["DEPRECATED_PARAMETERS"] } ``` @@ -1280,7 +1288,8 @@ curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion} "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "readme": "string", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "updated_at": "2019-08-24T14:15:22Z" + "updated_at": "2019-08-24T14:15:22Z", + "warnings": ["DEPRECATED_PARAMETERS"] } ``` From c0ae875fa2e9992d280bf5e067b3e71820c14191 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 11 May 2023 10:58:23 +0200 Subject: [PATCH 06/11] unit tests --- coderd/templateversions_test.go | 43 +++++++++++++++++++ .../TemplateVersionWarnings.tsx | 2 +- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index 12880449d57f2..4b192673a5de2 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -138,6 +138,7 @@ func TestPostTemplateVersionsByOrganization(t *testing.T) { require.Len(t, auditor.AuditLogs(), 2) assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs()[1].Action) }) + t.Run("Example", func(t *testing.T) { t.Parallel() client := coderdtest.New(t, nil) @@ -1453,3 +1454,45 @@ func TestTemplateVersionPatch(t *testing.T) { require.Error(t, err) }) } + +func TestTemplateVersionWarnings(t *testing.T) { + t.Parallel() + + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + user := coderdtest.CreateFirstUser(t, client) + + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() + + templateVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: []*proto.Parse_Response{{ + Type: &proto.Parse_Response_Complete{ + Complete: &proto.Parse_Complete{ + ParameterSchemas: []*proto.ParameterSchema{ + { + AllowOverrideSource: true, + Name: "example", + Description: "description 1", + DefaultSource: &proto.ParameterSource{ + Scheme: proto.ParameterSource_DATA, + Value: "tomato", + }, + DefaultDestination: &proto.ParameterDestination{ + Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE, + }, + }, + }, + }, + }, + }}, + ProvisionApply: echo.ProvisionComplete, + ProvisionPlan: echo.ProvisionComplete, + }) + coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID) + template := coderdtest.CreateTemplate(t, client, user.OrganizationID, templateVersion.ID) + + templateVersion, err := client.TemplateVersion(ctx, template.ActiveVersionID) + require.NoError(t, err) + + require.Contains(t, templateVersion.Warnings, codersdk.TemplateVersionWarningDeprecatedParameters) +} diff --git a/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx index 645c0fc7a1a53..d06c37f5f2585 100644 --- a/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx +++ b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx @@ -2,7 +2,7 @@ import { FC } from "react" import * as TypesGen from "api/typesGenerated" import { AlertBanner } from "components/AlertBanner/AlertBanner" import { Maybe } from "components/Conditionals/Maybe" -import Link from "@material-ui/core/Link" +import Link from "@mui/material/Link" export interface TemplateVersionWarnings { warnings?: TypesGen.TemplateVersionWarning[] From 44297c601716df94b3c95e040b824b721d7e0f14 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 11 May 2023 11:11:38 +0200 Subject: [PATCH 07/11] Storybook --- .../TemplateVersionWarnings.stories.tsx | 19 +++++++++++++++++++ .../TemplateVersionWarnings.tsx | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.stories.tsx diff --git a/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.stories.tsx b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.stories.tsx new file mode 100644 index 0000000000000..7c3e0ebb4da46 --- /dev/null +++ b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.stories.tsx @@ -0,0 +1,19 @@ +import { Story } from "@storybook/react" +import { + TemplateVersionWarnings, + TemplateVersionWarningsProps, +} from "./TemplateVersionWarnings" + +export default { + title: "components/TemplateVersionWarnings", + component: TemplateVersionWarnings, +} + +const Template: Story = (args) => ( + +) + +export const DeprecatedParameters = Template.bind({}) +DeprecatedParameters.args = { + warnings: ["DEPRECATED_PARAMETERS"], +} diff --git a/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx index d06c37f5f2585..c6e7a609c1cf9 100644 --- a/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx +++ b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx @@ -4,12 +4,12 @@ import { AlertBanner } from "components/AlertBanner/AlertBanner" import { Maybe } from "components/Conditionals/Maybe" import Link from "@mui/material/Link" -export interface TemplateVersionWarnings { +export interface TemplateVersionWarningsProps { warnings?: TypesGen.TemplateVersionWarning[] } export const TemplateVersionWarnings: FC< - React.PropsWithChildren + React.PropsWithChildren > = ({ warnings }) => { if (!warnings) { return <> From 9cd4e73b7ac466d33124f20688371006336e1b59 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 11 May 2023 11:48:25 +0200 Subject: [PATCH 08/11] more tests --- .../TemplateVersionWarnings.tsx | 22 ++++++++++--------- .../TemplateSummaryPage.test.tsx | 14 ++++++++++++ site/src/testHelpers/entities.ts | 12 ++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx index c6e7a609c1cf9..6f25efb925470 100644 --- a/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx +++ b/site/src/components/TemplateVersionWarnings/TemplateVersionWarnings.tsx @@ -17,16 +17,18 @@ export const TemplateVersionWarnings: FC< return ( - -
- This template uses legacy parameters which will be deprecated in the - next Coder release. Learn how to migrate in{" "} - - our documentation - - . -
-
+
+ +
+ This template uses legacy parameters which will be deprecated in the + next Coder release. Learn how to migrate in{" "} + + our documentation + + . +
+
+
) } diff --git a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx index de2e2c9747768..538090510bf6d 100644 --- a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx +++ b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx @@ -6,6 +6,7 @@ import { MockTemplate, MockTemplateVersion, MockMemberPermissions, + MockTemplateVersion3, } from "testHelpers/entities" import { renderWithAuth } from "testHelpers/renderHelpers" import { server } from "testHelpers/server" @@ -50,4 +51,17 @@ describe("TemplateSummaryPage", () => { const dropdownButton = screen.queryByLabelText("open-dropdown") expect(dropdownButton).toBe(null) }) + it("shows the template version warning", async () => { + server.use( + rest.get( + "/api/v2/templateversions/:templateVersionId", + async (req, res, ctx) => { + return res(ctx.status(200), ctx.json(MockTemplateVersion3)) + }, + ), + ) + renderPage() + await screen.findByText(MockTemplate.display_name) + await screen.findByTestId("warning-deprecated-parameters") + }) }) diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index c9458a79af61c..dd63741299ae3 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -312,6 +312,18 @@ You can add instructions here created_by: MockUser, } +export const MockTemplateVersion3: TypesGen.TemplateVersion = { + id: "test-template-version-3", + created_at: "2022-05-17T17:39:01.382927298Z", + updated_at: "2022-05-17T17:39:01.382927298Z", + template_id: "test-template", + job: MockProvisionerJob, + name: "test-version-3", + readme: "README", + created_by: MockUser, + warnings: ["DEPRECATED_PARAMETERS"], +} + export const MockTemplate: TypesGen.Template = { id: "test-template", created_at: "2022-05-17T17:39:01.382927298Z", From 716c2057de8240de4540fdf16fa38f5d9310d846 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 11 May 2023 12:17:49 +0200 Subject: [PATCH 09/11] more unit tests --- .../pages/WorkspacePage/WorkspacePage.test.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/site/src/pages/WorkspacePage/WorkspacePage.test.tsx b/site/src/pages/WorkspacePage/WorkspacePage.test.tsx index 4ca8a3910749b..aad09d1c17a90 100644 --- a/site/src/pages/WorkspacePage/WorkspacePage.test.tsx +++ b/site/src/pages/WorkspacePage/WorkspacePage.test.tsx @@ -19,6 +19,7 @@ import { MockDeletingWorkspace, MockDeletedWorkspace, MockBuilds, + MockTemplateVersion3, } from "testHelpers/entities" import * as api from "../../api/api" import { Workspace } from "../../api/typesGenerated" @@ -351,4 +352,18 @@ describe("WorkspacePage", () => { expect(rows).toHaveLength(MockBuilds.length + 1) }) }) + + it("shows the template warnings", async () => { + server.use( + rest.get( + "/api/v2/templateversions/:templateVersionId", + async (req, res, ctx) => { + return res(ctx.status(200), ctx.json(MockTemplateVersion3)) + }, + ), + ) + + await renderWorkspacePage() + await screen.findByTestId("warning-deprecated-parameters") + }) }) From 3eafd7063f12bbc82c27df9a3f3f662000767157 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 11 May 2023 17:20:39 +0200 Subject: [PATCH 10/11] storybook tests --- .../src/components/Workspace/Workspace.stories.tsx | 6 ++++++ .../TemplateSummaryPage.test.tsx | 14 -------------- .../TemplateSummaryPageView.stories.tsx | 11 +++++++++++ 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/site/src/components/Workspace/Workspace.stories.tsx b/site/src/components/Workspace/Workspace.stories.tsx index dd93520ba6a15..f78142175f2e3 100644 --- a/site/src/components/Workspace/Workspace.stories.tsx +++ b/site/src/components/Workspace/Workspace.stories.tsx @@ -658,3 +658,9 @@ function makeFailedBuildLogs(): ProvisionerJobLog[] { }, ] } + +export const WithDeprecatedParameters = Template.bind({}) +WithDeprecatedParameters.args = { + ...Running.args, + templateWarnings: ["DEPRECATED_PARAMETERS"], +} diff --git a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx index 538090510bf6d..de2e2c9747768 100644 --- a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx +++ b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx @@ -6,7 +6,6 @@ import { MockTemplate, MockTemplateVersion, MockMemberPermissions, - MockTemplateVersion3, } from "testHelpers/entities" import { renderWithAuth } from "testHelpers/renderHelpers" import { server } from "testHelpers/server" @@ -51,17 +50,4 @@ describe("TemplateSummaryPage", () => { const dropdownButton = screen.queryByLabelText("open-dropdown") expect(dropdownButton).toBe(null) }) - it("shows the template version warning", async () => { - server.use( - rest.get( - "/api/v2/templateversions/:templateVersionId", - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(MockTemplateVersion3)) - }, - ), - ) - renderPage() - await screen.findByText(MockTemplate.display_name) - await screen.findByTestId("warning-deprecated-parameters") - }) }) diff --git a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.stories.tsx b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.stories.tsx index a6869b189672c..58f47a8c5a1de 100644 --- a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.stories.tsx +++ b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.stories.tsx @@ -3,6 +3,7 @@ import { MockTemplate, MockTemplateDAUResponse, MockTemplateVersion, + MockTemplateVersion3, MockWorkspaceResource, MockWorkspaceResource2, } from "testHelpers/entities" @@ -65,3 +66,13 @@ SmallViewport.args = { SmallViewport.parameters = { chromatic: { viewports: [600] }, } + +export const WithDeprecatedParameters = Template.bind({}) +WithDeprecatedParameters.args = { + template: MockTemplate, + activeVersion: MockTemplateVersion3, + data: { + resources: [MockWorkspaceResource, MockWorkspaceResource2], + daus: MockTemplateDAUResponse, + }, +} From 7f3f4c5280b16408ea1e905e3578a5b076e7f349 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Fri, 12 May 2023 11:09:39 +0200 Subject: [PATCH 11/11] fix: store --- coderd/templateversions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 15b037bd62988..39d803049ba3d 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -911,7 +911,7 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque }) return err } - schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) + schemas, err := store.GetParameterSchemasByJobID(ctx, job.ID) if errors.Is(err, sql.ErrNoRows) { err = nil }