Skip to content

Commit 1656249

Browse files
authored
feat: add all safe experiments to the deployment page (#10276)
* added new option table type for experiments * added tests * fixed go tests * added go test for new param * removing query change * clearing ExperimentsAll * dont mutate ExperimentsAll * added new route for safe experiments * added new route for safe experiments * added test for new route * PR feedback * altered design * alias children
1 parent 35f9e2e commit 1656249

File tree

17 files changed

+360
-39
lines changed

17 files changed

+360
-39
lines changed

coderd/apidoc/docs.go

Lines changed: 30 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 26 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ func New(options *Options) *API {
597597
})
598598
r.Route("/experiments", func(r chi.Router) {
599599
r.Use(apiKeyMiddleware)
600+
r.Get("/available", handleExperimentsSafe)
600601
r.Get("/", api.handleExperimentsGet)
601602
})
602603
r.Get("/updatecheck", api.updateCheck)

coderd/experiments.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import (
44
"net/http"
55

66
"github.com/coder/coder/v2/coderd/httpapi"
7+
"github.com/coder/coder/v2/codersdk"
78
)
89

9-
// @Summary Get experiments
10-
// @ID get-experiments
10+
// @Summary Get enabled experiments
11+
// @ID get-enabled-experiments
1112
// @Security CoderSessionToken
1213
// @Produce json
1314
// @Tags General
@@ -17,3 +18,17 @@ func (api *API) handleExperimentsGet(rw http.ResponseWriter, r *http.Request) {
1718
ctx := r.Context()
1819
httpapi.Write(ctx, rw, http.StatusOK, api.Experiments)
1920
}
21+
22+
// @Summary Get safe experiments
23+
// @ID get-safe-experiments
24+
// @Security CoderSessionToken
25+
// @Produce json
26+
// @Tags General
27+
// @Success 200 {array} codersdk.Experiment
28+
// @Router /experiments/available [get]
29+
func handleExperimentsSafe(rw http.ResponseWriter, r *http.Request) {
30+
ctx := r.Context()
31+
httpapi.Write(ctx, rw, http.StatusOK, codersdk.AvailableExperiments{
32+
Safe: codersdk.ExperimentsAll,
33+
})
34+
}

coderd/experiments_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,21 @@ func Test_Experiments(t *testing.T) {
116116
require.Error(t, err)
117117
require.ErrorContains(t, err, httpmw.SignedOutErrorMessage)
118118
})
119+
120+
t.Run("available experiments", func(t *testing.T) {
121+
t.Parallel()
122+
cfg := coderdtest.DeploymentValues(t)
123+
client := coderdtest.New(t, &coderdtest.Options{
124+
DeploymentValues: cfg,
125+
})
126+
_ = coderdtest.CreateFirstUser(t, client)
127+
128+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
129+
defer cancel()
130+
131+
experiments, err := client.SafeExperiments(ctx)
132+
require.NoError(t, err)
133+
require.NotNil(t, experiments)
134+
require.ElementsMatch(t, codersdk.ExperimentsAll, experiments.Safe)
135+
})
119136
}

codersdk/deployment.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2013,12 +2013,13 @@ var ExperimentsAll = Experiments{
20132013
ExperimentSingleTailnet,
20142014
}
20152015

2016-
// Experiments is a list of experiments that are enabled for the deployment.
2016+
// Experiments is a list of experiments.
20172017
// Multiple experiments may be enabled at the same time.
20182018
// Experiments are not safe for production use, and are not guaranteed to
20192019
// be backwards compatible. They may be removed or renamed at any time.
20202020
type Experiments []Experiment
20212021

2022+
// Returns a list of experiments that are enabled for the deployment.
20222023
func (e Experiments) Enabled(ex Experiment) bool {
20232024
for _, v := range e {
20242025
if v == ex {
@@ -2041,6 +2042,25 @@ func (c *Client) Experiments(ctx context.Context) (Experiments, error) {
20412042
return exp, json.NewDecoder(res.Body).Decode(&exp)
20422043
}
20432044

2045+
// AvailableExperiments is an expandable type that returns all safe experiments
2046+
// available to be used with a deployment.
2047+
type AvailableExperiments struct {
2048+
Safe []Experiment `json:"safe"`
2049+
}
2050+
2051+
func (c *Client) SafeExperiments(ctx context.Context) (AvailableExperiments, error) {
2052+
res, err := c.Request(ctx, http.MethodGet, "/api/v2/experiments/available", nil)
2053+
if err != nil {
2054+
return AvailableExperiments{}, err
2055+
}
2056+
defer res.Body.Close()
2057+
if res.StatusCode != http.StatusOK {
2058+
return AvailableExperiments{}, ReadBodyAsError(res)
2059+
}
2060+
var exp AvailableExperiments
2061+
return exp, json.NewDecoder(res.Body).Decode(&exp)
2062+
}
2063+
20442064
type DAUsResponse struct {
20452065
Entries []DAUEntry `json:"entries"`
20462066
TZHourOffset int `json:"tz_hour_offset"`

docs/api/general.md

Lines changed: 39 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/src/api/api.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,19 @@ export const getExperiments = async (): Promise<TypesGen.Experiment[]> => {
864864
}
865865
};
866866

867+
export const getAvailableExperiments =
868+
async (): Promise<TypesGen.AvailableExperiments> => {
869+
try {
870+
const response = await axios.get("/api/v2/experiments/available");
871+
return response.data;
872+
} catch (error) {
873+
if (axios.isAxiosError(error) && error.response?.status === 404) {
874+
return { safe: [] };
875+
}
876+
throw error;
877+
}
878+
};
879+
867880
export const getExternalAuthProvider = async (
868881
provider: string,
869882
): Promise<TypesGen.ExternalAuth> => {

site/src/api/queries/experiments.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,10 @@ export const experiments = (queryClient: QueryClient) => {
1919
},
2020
} satisfies UseQueryOptions<Experiments>;
2121
};
22+
23+
export const availableExperiments = () => {
24+
return {
25+
queryKey: ["availableExperiments"],
26+
queryFn: async () => API.getAvailableExperiments(),
27+
};
28+
};

site/src/api/typesGenerated.ts

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)