Skip to content

Commit d04ba2c

Browse files
authored
feat: add template version creator (#3001)
1 parent d26b3b7 commit d04ba2c

14 files changed

+114
-16
lines changed

coderd/audit/diff_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,14 @@ func TestDiff(t *testing.T) {
114114
UpdatedAt: time.Now(),
115115
OrganizationID: uuid.UUID{3},
116116
Name: "rust",
117+
CreatedBy: uuid.NullUUID{UUID: uuid.UUID{4}, Valid: true},
117118
},
118119
exp: audit.Map{
119120
"id": uuid.UUID{1}.String(),
120121
"template_id": uuid.UUID{2}.String(),
121122
"organization_id": uuid.UUID{3}.String(),
122123
"name": "rust",
124+
"created_by": uuid.UUID{4}.String(),
123125
},
124126
},
125127
{
@@ -132,11 +134,13 @@ func TestDiff(t *testing.T) {
132134
UpdatedAt: time.Now(),
133135
OrganizationID: uuid.UUID{3},
134136
Name: "rust",
137+
CreatedBy: uuid.NullUUID{UUID: uuid.UUID{4}, Valid: true},
135138
},
136139
exp: audit.Map{
137140
"id": uuid.UUID{1}.String(),
138141
"organization_id": uuid.UUID{3}.String(),
139142
"name": "rust",
143+
"created_by": uuid.UUID{4}.String(),
140144
},
141145
},
142146
})

coderd/audit/table.go

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ var AuditableResources = auditMap(map[any]map[string]Action{
8383
"name": ActionTrack,
8484
"readme": ActionTrack,
8585
"job_id": ActionIgnore, // Not helpful in a diff because jobs aren't tracked in audit logs.
86+
"created_by": ActionTrack,
8687
},
8788
&database.User{}: {
8889
"id": ActionTrack,

coderd/database/databasefake/databasefake.go

+1
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,7 @@ func (q *fakeQuerier) InsertTemplateVersion(_ context.Context, arg database.Inse
15111511
Name: arg.Name,
15121512
Readme: arg.Readme,
15131513
JobID: arg.JobID,
1514+
CreatedBy: arg.CreatedBy,
15141515
}
15151516
q.templateVersions = append(q.templateVersions, version)
15161517
return version, nil

coderd/database/dump.sql

+5-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE ONLY template_versions DROP COLUMN IF EXISTS created_by;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
BEGIN;
2+
3+
ALTER TABLE ONLY template_versions ADD COLUMN IF NOT EXISTS created_by uuid REFERENCES users (id) ON DELETE RESTRICT;
4+
5+
UPDATE
6+
template_versions
7+
SET
8+
created_by = (
9+
SELECT created_by FROM templates
10+
WHERE template_versions.template_id = templates.id
11+
LIMIT 1
12+
)
13+
WHERE
14+
created_by IS NULL;
15+
16+
COMMIT;

coderd/database/models.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

+16-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/templateversions.sql

+3-2
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ INSERT INTO
7070
updated_at,
7171
"name",
7272
readme,
73-
job_id
73+
job_id,
74+
created_by
7475
)
7576
VALUES
76-
($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *;
77+
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING *;
7778

7879
-- name: UpdateTemplateVersionByID :exec
7980
UPDATE

coderd/templates.go

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
209209
UUID: dbTemplate.ID,
210210
Valid: true,
211211
},
212+
UpdatedAt: database.Now(),
212213
})
213214
if err != nil {
214215
return xerrors.Errorf("insert template version: %s", err)

coderd/templateversions.go

+58-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package coderd
22

33
import (
4+
"context"
45
"database/sql"
56
"encoding/json"
67
"errors"
@@ -36,7 +37,16 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) {
3637
return
3738
}
3839

39-
httpapi.Write(rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job)))
40+
createdByName, err := getUsernameByUserID(r.Context(), api.Database, templateVersion.CreatedBy)
41+
if err != nil {
42+
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
43+
Message: "Internal error fetching creator name.",
44+
Detail: err.Error(),
45+
})
46+
return
47+
}
48+
49+
httpapi.Write(rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), createdByName))
4050
}
4151

4252
func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Request) {
@@ -476,7 +486,15 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque
476486
})
477487
return err
478488
}
479-
apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job)))
489+
createdByName, err := getUsernameByUserID(r.Context(), store, version.CreatedBy)
490+
if err != nil {
491+
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
492+
Message: "Internal error fetching creator name.",
493+
Detail: err.Error(),
494+
})
495+
return err
496+
}
497+
apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), createdByName))
480498
}
481499

482500
return nil
@@ -525,7 +543,16 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) {
525543
return
526544
}
527545

528-
httpapi.Write(rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job)))
546+
createdByName, err := getUsernameByUserID(r.Context(), api.Database, templateVersion.CreatedBy)
547+
if err != nil {
548+
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
549+
Message: "Internal error fetching creator name.",
550+
Detail: err.Error(),
551+
})
552+
return
553+
}
554+
555+
httpapi.Write(rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), createdByName))
529556
}
530557

531558
func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Request) {
@@ -735,6 +762,10 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
735762
Name: namesgenerator.GetRandomName(1),
736763
Readme: "",
737764
JobID: provisionerJob.ID,
765+
CreatedBy: uuid.NullUUID{
766+
UUID: apiKey.UserID,
767+
Valid: true,
768+
},
738769
})
739770
if err != nil {
740771
return xerrors.Errorf("insert template version: %w", err)
@@ -748,7 +779,16 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
748779
return
749780
}
750781

751-
httpapi.Write(rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob)))
782+
createdByName, err := getUsernameByUserID(r.Context(), api.Database, templateVersion.CreatedBy)
783+
if err != nil {
784+
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
785+
Message: "Internal error fetching creator name.",
786+
Detail: err.Error(),
787+
})
788+
return
789+
}
790+
791+
httpapi.Write(rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), createdByName))
752792
}
753793

754794
// templateVersionResources returns the workspace agent resources associated
@@ -796,7 +836,18 @@ func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) {
796836
api.provisionerJobLogs(rw, r, job)
797837
}
798838

799-
func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob) codersdk.TemplateVersion {
839+
func getUsernameByUserID(ctx context.Context, db database.Store, userID uuid.NullUUID) (string, error) {
840+
if !userID.Valid {
841+
return "", nil
842+
}
843+
user, err := db.GetUserByID(ctx, userID.UUID)
844+
if err != nil {
845+
return "", err
846+
}
847+
return user.Username, nil
848+
}
849+
850+
func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, createdByName string) codersdk.TemplateVersion {
800851
return codersdk.TemplateVersion{
801852
ID: version.ID,
802853
TemplateID: &version.TemplateID.UUID,
@@ -806,5 +857,7 @@ func convertTemplateVersion(version database.TemplateVersion, job codersdk.Provi
806857
Name: version.Name,
807858
Job: job,
808859
Readme: version.Readme,
860+
CreatedByID: version.CreatedBy.UUID,
861+
CreatedByName: createdByName,
809862
}
810863
}

codersdk/templateversions.go

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type TemplateVersion struct {
2020
Name string `json:"name"`
2121
Job ProvisionerJob `json:"job"`
2222
Readme string `json:"readme"`
23+
CreatedByID uuid.UUID `json:"created_by_id"`
24+
CreatedByName string `json:"created_by_name"`
2325
}
2426

2527
// TemplateVersion returns a template version by ID.

site/src/api/typesGenerated.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export interface CreateTemplateRequest {
8787
readonly min_autostart_interval_ms?: number
8888
}
8989

90-
// From codersdk/templateversions.go:106:6
90+
// From codersdk/templateversions.go:108:6
9191
export interface CreateTemplateVersionDryRunRequest {
9292
readonly WorkspaceName: string
9393
readonly ParameterValues: CreateParameterRequest[]
@@ -290,6 +290,8 @@ export interface TemplateVersion {
290290
readonly name: string
291291
readonly job: ProvisionerJob
292292
readonly readme: string
293+
readonly created_by_id: string
294+
readonly created_by_name: string
293295
}
294296

295297
// From codersdk/templates.go:100:6

site/src/testHelpers/entities.ts

+2
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ name:Template test
112112
You can add instructions here
113113
114114
[Some link info](https://coder.com)`,
115+
created_by_id: "test-creator-id",
116+
created_by_name: "test_creator",
115117
}
116118

117119
export const MockTemplate: TypesGen.Template = {

0 commit comments

Comments
 (0)