Skip to content

Commit 7011f83

Browse files
committed
fix: account for changed verify jwt config
1 parent 3612d71 commit 7011f83

File tree

2 files changed

+98
-67
lines changed

2 files changed

+98
-67
lines changed

pkg/function/batch.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/docker/go-units"
1717
"github.com/go-errors/errors"
1818
"github.com/supabase/cli/pkg/api"
19-
"github.com/supabase/cli/pkg/cast"
2019
"github.com/supabase/cli/pkg/config"
2120
)
2221

@@ -44,9 +43,9 @@ func (s *EdgeRuntimeAPI) UpsertFunctions(ctx context.Context, functionConfig con
4443
return err
4544
}
4645
policy.Reset()
47-
checksum := make(map[string]string, len(result))
48-
for _, f := range result {
49-
checksum[f.Slug] = cast.Val(f.EzbrSha256, "")
46+
slugToIndex := make(map[string]int, len(result))
47+
for i, f := range result {
48+
slugToIndex[f.Slug] = i
5049
}
5150
var toUpdate api.BulkUpdateFunctionBody
5251
OUTER:
@@ -69,13 +68,15 @@ OUTER:
6968
bodyHash := sha256.Sum256(body.Bytes())
7069
meta.SHA256 = hex.EncodeToString(bodyHash[:])
7170
// Skip if function has not changed
72-
if checksum[slug] == meta.SHA256 {
71+
if i, exists := slugToIndex[slug]; exists && i >= 0 &&
72+
result[i].EzbrSha256 != nil && *result[i].EzbrSha256 == meta.SHA256 &&
73+
result[i].VerifyJwt != nil && *result[i].VerifyJwt == function.VerifyJWT {
7374
fmt.Fprintln(os.Stderr, "No change found in Function:", slug)
7475
continue
7576
}
7677
// Update if function already exists
7778
upsert := func() (api.BulkUpdateFunctionBody, error) {
78-
if _, ok := checksum[slug]; ok {
79+
if _, exists := slugToIndex[slug]; exists {
7980
return s.updateFunction(ctx, slug, meta, bytes.NewReader(body.Bytes()))
8081
}
8182
return s.createFunction(ctx, slug, meta, bytes.NewReader(body.Bytes()))
@@ -84,7 +85,7 @@ OUTER:
8485
fmt.Fprintf(os.Stderr, "Deploying Function: %s (script size: %s)\n", slug, functionSize)
8586
result, err := backoff.RetryNotifyWithData(upsert, policy, func(err error, d time.Duration) {
8687
if strings.Contains(err.Error(), "Duplicated function slug") {
87-
checksum[slug] = ""
88+
slugToIndex[slug] = -1
8889
}
8990
})
9091
if err != nil {

pkg/function/batch_test.go

Lines changed: 90 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/stretchr/testify/assert"
1212
"github.com/stretchr/testify/require"
1313
"github.com/supabase/cli/pkg/api"
14+
"github.com/supabase/cli/pkg/cast"
1415
"github.com/supabase/cli/pkg/config"
1516
)
1617

@@ -29,19 +30,24 @@ func (b *MockBundler) Bundle(ctx context.Context, slug, entrypoint, importMap st
2930
}, nil
3031
}
3132

33+
func mockClient(t *testing.T) EdgeRuntimeAPI {
34+
apiClient, err := api.NewClientWithResponses(mockApiHost)
35+
require.NoError(t, err)
36+
return NewEdgeRuntimeAPI(mockProject, *apiClient, func(era *EdgeRuntimeAPI) {
37+
era.eszip = &MockBundler{}
38+
})
39+
}
40+
3241
const (
3342
mockApiHost = "https://api.supabase.com"
3443
mockProject = "test-project"
3544
)
3645

3746
func TestUpsertFunctions(t *testing.T) {
38-
apiClient, err := api.NewClientWithResponses(mockApiHost)
39-
require.NoError(t, err)
40-
client := NewEdgeRuntimeAPI(mockProject, *apiClient, func(era *EdgeRuntimeAPI) {
41-
era.eszip = &MockBundler{}
42-
})
47+
client := mockClient(t)
4348

4449
t.Run("deploys with bulk update", func(t *testing.T) {
50+
// t.Cleanup(mockClock(100 * time.Millisecond))
4551
// Setup mock api
4652
defer gock.OffAll()
4753
gock.New(mockApiHost).
@@ -53,8 +59,8 @@ func TestUpsertFunctions(t *testing.T) {
5359
Reply(http.StatusOK).
5460
JSON(api.FunctionResponse{Slug: "test-a"})
5561
gock.New(mockApiHost).
56-
Post("/v1/projects/" + mockProject + "/functions/test-b").
57-
Reply(http.StatusOK).
62+
Post("/v1/projects/" + mockProject + "/functions").
63+
Reply(http.StatusCreated).
5864
JSON(api.FunctionResponse{Slug: "test-b"})
5965
gock.New(mockApiHost).
6066
Put("/v1/projects/" + mockProject + "/functions").
@@ -68,8 +74,30 @@ func TestUpsertFunctions(t *testing.T) {
6874
JSON(api.V1BulkUpdateFunctionsResponse{})
6975
// Run test
7076
err := client.UpsertFunctions(context.Background(), config.FunctionConfig{
71-
"test-a": {},
72-
"test-b": {},
77+
"test-a": {Enabled: true},
78+
"test-b": {Enabled: true},
79+
})
80+
// Check error
81+
assert.NoError(t, err)
82+
assert.Empty(t, gock.Pending())
83+
assert.Empty(t, gock.GetUnmatchedRequests())
84+
})
85+
86+
t.Run("skips disabled and unchanged", func(t *testing.T) {
87+
// Setup mock api
88+
defer gock.OffAll()
89+
gock.New(mockApiHost).
90+
Get("/v1/projects/" + mockProject + "/functions").
91+
Reply(http.StatusOK).
92+
JSON([]api.FunctionResponse{{
93+
Slug: "test-a",
94+
VerifyJwt: cast.Ptr(true),
95+
EzbrSha256: cast.Ptr("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
96+
}})
97+
// Run test
98+
err := client.UpsertFunctions(context.Background(), config.FunctionConfig{
99+
"test-a": {Enabled: true, VerifyJWT: true},
100+
"test-b": {Enabled: false},
73101
})
74102
// Check error
75103
assert.NoError(t, err)
@@ -94,7 +122,7 @@ func TestUpsertFunctions(t *testing.T) {
94122
JSON(api.FunctionResponse{Slug: "test"})
95123
// Run test
96124
err := client.UpsertFunctions(context.Background(), config.FunctionConfig{
97-
"test": {},
125+
"test": {Enabled: true},
98126
})
99127
// Check error
100128
assert.NoError(t, err)
@@ -121,58 +149,60 @@ func TestUpsertFunctions(t *testing.T) {
121149
assert.Empty(t, gock.Pending())
122150
assert.Empty(t, gock.GetUnmatchedRequests())
123151
})
152+
}
124153

125-
t.Run("retries on create failure", func(t *testing.T) {
126-
// Setup mock api
127-
defer gock.OffAll()
128-
gock.New(mockApiHost).
129-
Get("/v1/projects/" + mockProject + "/functions").
130-
Reply(http.StatusOK).
131-
JSON([]api.FunctionResponse{})
132-
gock.New(mockApiHost).
133-
Post("/v1/projects/" + mockProject + "/functions").
134-
ReplyError(errors.New("network error"))
135-
gock.New(mockApiHost).
136-
Post("/v1/projects/" + mockProject + "/functions").
137-
Reply(http.StatusServiceUnavailable)
138-
gock.New(mockApiHost).
139-
Post("/v1/projects/" + mockProject + "/functions").
140-
Reply(http.StatusCreated).
141-
JSON(api.FunctionResponse{Slug: "test"})
142-
// Run test
143-
err := client.UpsertFunctions(context.Background(), config.FunctionConfig{
144-
"test": {},
145-
})
146-
// Check error
147-
assert.NoError(t, err)
148-
assert.Empty(t, gock.Pending())
149-
assert.Empty(t, gock.GetUnmatchedRequests())
154+
func TestCreateFunction(t *testing.T) {
155+
client := mockClient(t)
156+
// Setup mock api
157+
defer gock.OffAll()
158+
gock.New(mockApiHost).
159+
Get("/v1/projects/" + mockProject + "/functions").
160+
Reply(http.StatusOK).
161+
JSON([]api.FunctionResponse{})
162+
gock.New(mockApiHost).
163+
Post("/v1/projects/" + mockProject + "/functions").
164+
ReplyError(errors.New("network error"))
165+
gock.New(mockApiHost).
166+
Post("/v1/projects/" + mockProject + "/functions").
167+
Reply(http.StatusServiceUnavailable)
168+
gock.New(mockApiHost).
169+
Post("/v1/projects/" + mockProject + "/functions").
170+
Reply(http.StatusCreated).
171+
JSON(api.FunctionResponse{Slug: "test"})
172+
// Run test
173+
err := client.UpsertFunctions(context.Background(), config.FunctionConfig{
174+
"test": {Enabled: true},
150175
})
176+
// Check error
177+
assert.NoError(t, err)
178+
assert.Empty(t, gock.Pending())
179+
assert.Empty(t, gock.GetUnmatchedRequests())
180+
}
151181

152-
t.Run("retries on update failure", func(t *testing.T) {
153-
// Setup mock api
154-
defer gock.OffAll()
155-
gock.New(mockApiHost).
156-
Get("/v1/projects/" + mockProject + "/functions").
157-
Reply(http.StatusOK).
158-
JSON([]api.FunctionResponse{{Slug: "test"}})
159-
gock.New(mockApiHost).
160-
Patch("/v1/projects/" + mockProject + "/functions/test").
161-
ReplyError(errors.New("network error"))
162-
gock.New(mockApiHost).
163-
Patch("/v1/projects/" + mockProject + "/functions/test").
164-
Reply(http.StatusServiceUnavailable)
165-
gock.New(mockApiHost).
166-
Patch("/v1/projects/" + mockProject + "/functions/test").
167-
Reply(http.StatusOK).
168-
JSON(api.FunctionResponse{Slug: "test"})
169-
// Run test
170-
err := client.UpsertFunctions(context.Background(), config.FunctionConfig{
171-
"test": {},
172-
})
173-
// Check error
174-
assert.NoError(t, err)
175-
assert.Empty(t, gock.Pending())
176-
assert.Empty(t, gock.GetUnmatchedRequests())
182+
func TestUpdateFunction(t *testing.T) {
183+
client := mockClient(t)
184+
// Setup mock api
185+
defer gock.OffAll()
186+
gock.New(mockApiHost).
187+
Get("/v1/projects/" + mockProject + "/functions").
188+
Reply(http.StatusOK).
189+
JSON([]api.FunctionResponse{{Slug: "test"}})
190+
gock.New(mockApiHost).
191+
Patch("/v1/projects/" + mockProject + "/functions/test").
192+
ReplyError(errors.New("network error"))
193+
gock.New(mockApiHost).
194+
Patch("/v1/projects/" + mockProject + "/functions/test").
195+
Reply(http.StatusServiceUnavailable)
196+
gock.New(mockApiHost).
197+
Patch("/v1/projects/" + mockProject + "/functions/test").
198+
Reply(http.StatusOK).
199+
JSON(api.FunctionResponse{Slug: "test"})
200+
// Run test
201+
err := client.UpsertFunctions(context.Background(), config.FunctionConfig{
202+
"test": {Enabled: true},
177203
})
204+
// Check error
205+
assert.NoError(t, err)
206+
assert.Empty(t, gock.Pending())
207+
assert.Empty(t, gock.GetUnmatchedRequests())
178208
}

0 commit comments

Comments
 (0)