From eea3c74abfa326d54293dc626cf33d19e3180190 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:08:28 -0700 Subject: [PATCH 01/31] Add webhook authorization token option --- internal/planetscale/webhooks.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/internal/planetscale/webhooks.go b/internal/planetscale/webhooks.go index 3e253013..870f12be 100644 --- a/internal/planetscale/webhooks.go +++ b/internal/planetscale/webhooks.go @@ -46,11 +46,12 @@ type ListWebhooksRequest struct { // CreateWebhookRequest is the request for creating a webhook. type CreateWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - URL string `json:"url"` - Enabled *bool `json:"enabled,omitempty"` - Events []string `json:"events,omitempty"` + Organization string `json:"-"` + Database string `json:"-"` + URL string `json:"url"` + AuthorizationToken string `json:"authorization_token,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Events []string `json:"events,omitempty"` } // GetWebhookRequest is the request for getting a webhook. @@ -62,12 +63,13 @@ type GetWebhookRequest struct { // UpdateWebhookRequest is the request for updating a webhook. type UpdateWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` - URL *string `json:"url,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Events []string `json:"events,omitempty"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` + URL *string `json:"url,omitempty"` + AuthorizationToken *string `json:"authorization_token,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Events []string `json:"events,omitempty"` } // DeleteWebhookRequest is the request for deleting a webhook. From 1055c18ff4bb62e28665a542b870223f27a47970 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:08:34 -0700 Subject: [PATCH 02/31] Add webhook authorization token option --- internal/planetscale/webhooks_test.go | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/internal/planetscale/webhooks_test.go b/internal/planetscale/webhooks_test.go index 8b73c5a0..dcefc93a 100644 --- a/internal/planetscale/webhooks_test.go +++ b/internal/planetscale/webhooks_test.go @@ -98,7 +98,7 @@ func TestWebhooks_List_WithPagination(t *testing.T) { func TestWebhooks_Create(t *testing.T) { c := qt.New(t) - wantBody := []byte("{\"url\":\"https://example.com/webhook\",\"enabled\":true,\"events\":[\"branch.ready\"]}\n") + wantBody := []byte("{\"url\":\"https://example.com/webhook\",\"authorization_token\":\"automation-token\",\"enabled\":true,\"events\":[\"branch.ready\"]}\n") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(201) @@ -132,11 +132,12 @@ func TestWebhooks_Create(t *testing.T) { enabled := true webhook, err := client.Webhooks.Create(ctx, &CreateWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - URL: "https://example.com/webhook", - Enabled: &enabled, - Events: []string{"branch.ready"}, + Organization: testOrg, + Database: testDatabase, + URL: "https://example.com/webhook", + AuthorizationToken: "automation-token", + Enabled: &enabled, + Events: []string{"branch.ready"}, }) c.Assert(err, qt.IsNil) @@ -191,7 +192,7 @@ func TestWebhooks_Get(t *testing.T) { func TestWebhooks_Update(t *testing.T) { c := qt.New(t) - wantBody := []byte("{\"url\":\"https://example.com/new-webhook\",\"enabled\":false}\n") + wantBody := []byte("{\"url\":\"https://example.com/new-webhook\",\"authorization_token\":\"automation-token\",\"enabled\":false}\n") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) @@ -224,13 +225,15 @@ func TestWebhooks_Update(t *testing.T) { ctx := context.Background() newURL := "https://example.com/new-webhook" enabled := false + authorizationToken := "automation-token" webhook, err := client.Webhooks.Update(ctx, &UpdateWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", - URL: &newURL, - Enabled: &enabled, + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", + URL: &newURL, + AuthorizationToken: &authorizationToken, + Enabled: &enabled, }) c.Assert(err, qt.IsNil) From 13d9d57d7222a81f941fd2bc324f260881f4bdbf Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:08:41 -0700 Subject: [PATCH 03/31] Add webhook authorization token option --- internal/cmd/webhook/create.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/internal/cmd/webhook/create.go b/internal/cmd/webhook/create.go index e6fa2c5f..d332d905 100644 --- a/internal/cmd/webhook/create.go +++ b/internal/cmd/webhook/create.go @@ -11,9 +11,10 @@ import ( func CreateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { - url string - events []string - enabled bool + url string + authorizationToken string + events []string + enabled bool } cmd := &cobra.Command{ @@ -30,10 +31,11 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } req := &planetscale.CreateWebhookRequest{ - Organization: ch.Config.Organization, - Database: database, - URL: flags.url, - Events: flags.events, + Organization: ch.Config.Organization, + Database: database, + URL: flags.url, + AuthorizationToken: flags.authorizationToken, + Events: flags.events, } if cmd.Flags().Changed("enabled") { @@ -61,6 +63,7 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to (required)") + cmd.Flags().StringVar(&flags.authorizationToken, "authorization-token", "", "Bearer token to include in the Authorization header") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") From eaaa6b9760c4dbebe9058255574cc632611747af Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:08:47 -0700 Subject: [PATCH 04/31] Add webhook authorization token option --- internal/cmd/webhook/create_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/cmd/webhook/create_test.go b/internal/cmd/webhook/create_test.go index 389c903d..1b921642 100644 --- a/internal/cmd/webhook/create_test.go +++ b/internal/cmd/webhook/create_test.go @@ -26,6 +26,7 @@ func TestWebhook_CreateCmd(t *testing.T) { db := "mydb" url := "https://example.com/webhook" events := []string{"branch.created", "branch.deleted"} + authorizationToken := "automation-token" createdAt := time.Date(2025, 1, 15, 10, 30, 0, 0, time.UTC) webhook := &ps.Webhook{ @@ -42,6 +43,7 @@ func TestWebhook_CreateCmd(t *testing.T) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, db) c.Assert(req.URL, qt.Equals, url) + c.Assert(req.AuthorizationToken, qt.Equals, authorizationToken) c.Assert(req.Events, qt.DeepEquals, events) return webhook, nil }, @@ -60,7 +62,7 @@ func TestWebhook_CreateCmd(t *testing.T) { } cmd := CreateCmd(ch) - cmd.SetArgs([]string{db, "--url", url, "--events", "branch.created,branch.deleted"}) + cmd.SetArgs([]string{db, "--url", url, "--authorization-token", authorizationToken, "--events", "branch.created,branch.deleted"}) err := cmd.Execute() c.Assert(err, qt.IsNil) From b9a6defb6080f8508a0a61f937c44241722f5e8e Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:08:53 -0700 Subject: [PATCH 05/31] Add webhook authorization token option --- internal/cmd/webhook/update.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/internal/cmd/webhook/update.go b/internal/cmd/webhook/update.go index a1521f60..3b1b11b5 100644 --- a/internal/cmd/webhook/update.go +++ b/internal/cmd/webhook/update.go @@ -11,9 +11,10 @@ import ( func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { - url string - events []string - enabled bool + url string + authorizationToken string + events []string + enabled bool } cmd := &cobra.Command{ @@ -43,6 +44,11 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { changed = true } + if cmd.Flags().Changed("authorization-token") { + req.AuthorizationToken = &flags.authorizationToken + changed = true + } + if cmd.Flags().Changed("events") { req.Events = flags.events changed = true @@ -54,7 +60,7 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } if !changed { - return fmt.Errorf("at least one of --url, --events, or --enabled must be provided") + return fmt.Errorf("at least one of --url, --authorization-token, --events, or --enabled must be provided") } end := ch.Printer.PrintProgress(fmt.Sprintf("Updating webhook %s for %s", printer.BoldBlue(webhookID), printer.BoldBlue(database))) @@ -78,6 +84,7 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to") + cmd.Flags().StringVar(&flags.authorizationToken, "authorization-token", "", "Bearer token to include in the Authorization header") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") From 118feda6b6906de773482511ba52faca886d16fa Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:08:58 -0700 Subject: [PATCH 06/31] Add webhook authorization token option --- internal/cmd/webhook/update_test.go | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/internal/cmd/webhook/update_test.go b/internal/cmd/webhook/update_test.go index 0293fb46..d606c493 100644 --- a/internal/cmd/webhook/update_test.go +++ b/internal/cmd/webhook/update_test.go @@ -120,6 +120,55 @@ func TestWebhook_UpdateCmd_EnabledFlag(t *testing.T) { c.Assert(svc.UpdateFnInvoked, qt.IsTrue) } +func TestWebhook_UpdateCmd_AuthorizationTokenFlag(t *testing.T) { + c := qt.New(t) + + var buf bytes.Buffer + format := printer.JSON + p := printer.NewPrinter(&format) + p.SetResourceOutput(&buf) + + org := "planetscale" + db := "mydb" + webhookID := "webhook-123" + authorizationToken := "automation-token" + + webhook := &ps.Webhook{ + ID: webhookID, + URL: "https://example.com/webhook", + Enabled: true, + } + + svc := &mock.WebhooksService{ + UpdateFn: func(ctx context.Context, req *ps.UpdateWebhookRequest) (*ps.Webhook, error) { + c.Assert(req.Organization, qt.Equals, org) + c.Assert(req.Database, qt.Equals, db) + c.Assert(req.ID, qt.Equals, webhookID) + c.Assert(*req.AuthorizationToken, qt.Equals, authorizationToken) + return webhook, nil + }, + } + + ch := &cmdutil.Helper{ + Printer: p, + Config: &config.Config{ + Organization: org, + }, + Client: func() (*ps.Client, error) { + return &ps.Client{ + Webhooks: svc, + }, nil + }, + } + + cmd := UpdateCmd(ch) + cmd.SetArgs([]string{db, webhookID, "--authorization-token", authorizationToken}) + err := cmd.Execute() + + c.Assert(err, qt.IsNil) + c.Assert(svc.UpdateFnInvoked, qt.IsTrue) +} + func TestWebhook_UpdateCmd_RequiresAtLeastOneFlag(t *testing.T) { c := qt.New(t) From 6c81ea928193c3b42706f62c430b07726e63af43 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:13:10 -0700 Subject: [PATCH 07/31] Expose webhook authorization token configuration --- internal/planetscale/webhooks.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/internal/planetscale/webhooks.go b/internal/planetscale/webhooks.go index 870f12be..4cbb75b2 100644 --- a/internal/planetscale/webhooks.go +++ b/internal/planetscale/webhooks.go @@ -26,16 +26,17 @@ type webhooksResponse struct { // Webhook represents a PlanetScale webhook. type Webhook struct { - ID string `json:"id"` - URL string `json:"url"` - Secret string `json:"secret"` - Enabled bool `json:"enabled"` - LastSentResult string `json:"last_sent_result"` - LastSentSuccess bool `json:"last_sent_success"` - LastSentAt time.Time `json:"last_sent_at"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Events []string `json:"events"` + ID string `json:"id"` + URL string `json:"url"` + Secret string `json:"secret"` + AuthorizationTokenConfigured bool `json:"authorization_token_configured"` + Enabled bool `json:"enabled"` + LastSentResult string `json:"last_sent_result"` + LastSentSuccess bool `json:"last_sent_success"` + LastSentAt time.Time `json:"last_sent_at"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Events []string `json:"events"` } // ListWebhooksRequest is the request for listing webhooks. From 8a09887871b8e5548c0aa9c7b9af99613cf94433 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:13:15 -0700 Subject: [PATCH 08/31] Expose webhook authorization token configuration --- internal/planetscale/webhooks_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/planetscale/webhooks_test.go b/internal/planetscale/webhooks_test.go index dcefc93a..a88ab475 100644 --- a/internal/planetscale/webhooks_test.go +++ b/internal/planetscale/webhooks_test.go @@ -29,6 +29,7 @@ func TestWebhooks_List(t *testing.T) { "id": "webhook-123", "url": "https://example.com/webhook", "secret": "secret-123", + "authorization_token_configured": true, "enabled": true, "last_sent_result": "success", "last_sent_success": true, @@ -56,6 +57,7 @@ func TestWebhooks_List(t *testing.T) { c.Assert(len(webhooks), qt.Equals, 1) c.Assert(webhooks[0].ID, qt.Equals, "webhook-123") c.Assert(webhooks[0].URL, qt.Equals, "https://example.com/webhook") + c.Assert(webhooks[0].AuthorizationTokenConfigured, qt.IsTrue) c.Assert(webhooks[0].Enabled, qt.IsTrue) c.Assert(webhooks[0].Events, qt.DeepEquals, []string{"branch.ready", "deploy_request.opened"}) } From 2c09c97b68b2850d2d8448bed9367103499cf112 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:13:22 -0700 Subject: [PATCH 09/31] Expose webhook authorization token configuration --- internal/cmd/webhook/webhook.go | 60 ++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/internal/cmd/webhook/webhook.go b/internal/cmd/webhook/webhook.go index 8404dd28..61983237 100644 --- a/internal/cmd/webhook/webhook.go +++ b/internal/cmd/webhook/webhook.go @@ -33,12 +33,13 @@ func WebhookCmd(ch *cmdutil.Helper) *cobra.Command { // Webhook returns a table and json serializable webhook for printing. type Webhook struct { - ID string `header:"id" json:"id"` - URL string `header:"url" json:"url"` - Events string `header:"events" json:"events"` - Enabled bool `header:"enabled" json:"enabled"` - CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` - UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` + ID string `header:"id" json:"id"` + URL string `header:"url" json:"url"` + AuthorizationTokenConfigured bool `header:"authorization token" json:"authorization_token_configured"` + Events string `header:"events" json:"events"` + Enabled bool `header:"enabled" json:"enabled"` + CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` + UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` orig *ps.Webhook } @@ -50,13 +51,14 @@ func (w *Webhook) MarshalJSON() ([]byte, error) { // toWebhook returns a struct that prints out the various fields of a webhook model. func toWebhook(webhook *ps.Webhook) *Webhook { return &Webhook{ - ID: webhook.ID, - URL: webhook.URL, - Events: strings.Join(webhook.Events, ", "), - Enabled: webhook.Enabled, - CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), - UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), - orig: webhook, + ID: webhook.ID, + URL: webhook.URL, + AuthorizationTokenConfigured: webhook.AuthorizationTokenConfigured, + Events: strings.Join(webhook.Events, ", "), + Enabled: webhook.Enabled, + CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), + UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), + orig: webhook, } } @@ -70,13 +72,14 @@ func toWebhooks(webhooks []*ps.Webhook) []*Webhook { // WebhookWithSecret includes the webhook secret for display. type WebhookWithSecret struct { - ID string `header:"id" json:"id"` - URL string `header:"url" json:"url"` - Secret string `header:"secret" json:"secret"` - Events string `header:"events" json:"events"` - Enabled bool `header:"enabled" json:"enabled"` - CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` - UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` + ID string `header:"id" json:"id"` + URL string `header:"url" json:"url"` + Secret string `header:"secret" json:"secret"` + AuthorizationTokenConfigured bool `header:"authorization token" json:"authorization_token_configured"` + Events string `header:"events" json:"events"` + Enabled bool `header:"enabled" json:"enabled"` + CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` + UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` orig *ps.Webhook } @@ -88,13 +91,14 @@ func (w *WebhookWithSecret) MarshalJSON() ([]byte, error) { // toWebhookWithSecret returns a struct that includes the webhook secret. func toWebhookWithSecret(webhook *ps.Webhook) *WebhookWithSecret { return &WebhookWithSecret{ - ID: webhook.ID, - URL: webhook.URL, - Secret: webhook.Secret, - Events: strings.Join(webhook.Events, ", "), - Enabled: webhook.Enabled, - CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), - UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), - orig: webhook, + ID: webhook.ID, + URL: webhook.URL, + Secret: webhook.Secret, + AuthorizationTokenConfigured: webhook.AuthorizationTokenConfigured, + Events: strings.Join(webhook.Events, ", "), + Enabled: webhook.Enabled, + CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), + UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), + orig: webhook, } } From df9c8393a57a225dd69809c4d47e69d53b7cee91 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:22:34 -0700 Subject: [PATCH 10/31] Rename webhook authorization token fields --- internal/planetscale/webhooks_test.go | 60 +++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/internal/planetscale/webhooks_test.go b/internal/planetscale/webhooks_test.go index a88ab475..029aee77 100644 --- a/internal/planetscale/webhooks_test.go +++ b/internal/planetscale/webhooks_test.go @@ -29,7 +29,7 @@ func TestWebhooks_List(t *testing.T) { "id": "webhook-123", "url": "https://example.com/webhook", "secret": "secret-123", - "authorization_token_configured": true, + "webhook_authorization_token_configured": true, "enabled": true, "last_sent_result": "success", "last_sent_success": true, @@ -49,15 +49,15 @@ func TestWebhooks_List(t *testing.T) { ctx := context.Background() webhooks, err := client.Webhooks.List(ctx, &ListWebhooksRequest{ - Organization: testOrg, - Database: testDatabase, + Organization: testOrg, + Database: testDatabase, }) c.Assert(err, qt.IsNil) c.Assert(len(webhooks), qt.Equals, 1) c.Assert(webhooks[0].ID, qt.Equals, "webhook-123") c.Assert(webhooks[0].URL, qt.Equals, "https://example.com/webhook") - c.Assert(webhooks[0].AuthorizationTokenConfigured, qt.IsTrue) + c.Assert(webhooks[0].WebhookAuthorizationTokenConfigured, qt.IsTrue) c.Assert(webhooks[0].Enabled, qt.IsTrue) c.Assert(webhooks[0].Events, qt.DeepEquals, []string{"branch.ready", "deploy_request.opened"}) } @@ -89,8 +89,8 @@ func TestWebhooks_List_WithPagination(t *testing.T) { ctx := context.Background() webhooks, err := client.Webhooks.List(ctx, &ListWebhooksRequest{ - Organization: testOrg, - Database: testDatabase, + Organization: testOrg, + Database: testDatabase, }, WithPage(2), WithPerPage(10)) c.Assert(err, qt.IsNil) @@ -100,7 +100,7 @@ func TestWebhooks_List_WithPagination(t *testing.T) { func TestWebhooks_Create(t *testing.T) { c := qt.New(t) - wantBody := []byte("{\"url\":\"https://example.com/webhook\",\"authorization_token\":\"automation-token\",\"enabled\":true,\"events\":[\"branch.ready\"]}\n") + wantBody := []byte("{\"url\":\"https://example.com/webhook\",\"webhook_authorization_token\":\"automation-token\",\"enabled\":true,\"events\":[\"branch.ready\"]}\n") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(201) @@ -134,12 +134,12 @@ func TestWebhooks_Create(t *testing.T) { enabled := true webhook, err := client.Webhooks.Create(ctx, &CreateWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - URL: "https://example.com/webhook", - AuthorizationToken: "automation-token", - Enabled: &enabled, - Events: []string{"branch.ready"}, + Organization: testOrg, + Database: testDatabase, + URL: "https://example.com/webhook", + WebhookAuthorizationToken: "automation-token", + Enabled: &enabled, + Events: []string{"branch.ready"}, }) c.Assert(err, qt.IsNil) @@ -180,9 +180,9 @@ func TestWebhooks_Get(t *testing.T) { ctx := context.Background() webhook, err := client.Webhooks.Get(ctx, &GetWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", }) c.Assert(err, qt.IsNil) @@ -194,7 +194,7 @@ func TestWebhooks_Get(t *testing.T) { func TestWebhooks_Update(t *testing.T) { c := qt.New(t) - wantBody := []byte("{\"url\":\"https://example.com/new-webhook\",\"authorization_token\":\"automation-token\",\"enabled\":false}\n") + wantBody := []byte("{\"url\":\"https://example.com/new-webhook\",\"webhook_authorization_token\":\"automation-token\",\"enabled\":false}\n") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) @@ -227,15 +227,15 @@ func TestWebhooks_Update(t *testing.T) { ctx := context.Background() newURL := "https://example.com/new-webhook" enabled := false - authorizationToken := "automation-token" + webhookAuthorizationToken := "automation-token" webhook, err := client.Webhooks.Update(ctx, &UpdateWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", - URL: &newURL, - AuthorizationToken: &authorizationToken, - Enabled: &enabled, + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", + URL: &newURL, + WebhookAuthorizationToken: &webhookAuthorizationToken, + Enabled: &enabled, }) c.Assert(err, qt.IsNil) @@ -260,9 +260,9 @@ func TestWebhooks_Delete(t *testing.T) { ctx := context.Background() err = client.Webhooks.Delete(ctx, &DeleteWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", }) c.Assert(err, qt.IsNil) @@ -283,9 +283,9 @@ func TestWebhooks_Test(t *testing.T) { ctx := context.Background() err = client.Webhooks.Test(ctx, &TestWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", }) c.Assert(err, qt.IsNil) From b6c758bcc200b93ef099e01a959e188596a72018 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:22:40 -0700 Subject: [PATCH 11/31] Rename webhook authorization token fields --- internal/cmd/webhook/webhook.go | 74 ++++++++++++++++----------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/internal/cmd/webhook/webhook.go b/internal/cmd/webhook/webhook.go index 61983237..4b8e1329 100644 --- a/internal/cmd/webhook/webhook.go +++ b/internal/cmd/webhook/webhook.go @@ -13,9 +13,9 @@ import ( // WebhookCmd encapsulates the command for managing webhooks. func WebhookCmd(ch *cmdutil.Helper) *cobra.Command { cmd := &cobra.Command{ - Use: "webhook ", - Short: "Create, list, and manage webhooks", - PersistentPreRunE: cmdutil.CheckAuthentication(ch.Config), + Use: "webhook ", + Short: "Create, list, and manage webhooks", + PersistentPreRunE: cmdutil.CheckAuthentication(ch.Config), } cmd.PersistentFlags().StringVar(&ch.Config.Organization, "org", ch.Config.Organization, "The organization for the current user") @@ -33,15 +33,15 @@ func WebhookCmd(ch *cmdutil.Helper) *cobra.Command { // Webhook returns a table and json serializable webhook for printing. type Webhook struct { - ID string `header:"id" json:"id"` - URL string `header:"url" json:"url"` - AuthorizationTokenConfigured bool `header:"authorization token" json:"authorization_token_configured"` - Events string `header:"events" json:"events"` - Enabled bool `header:"enabled" json:"enabled"` - CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` - UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` + ID string `header:"id" json:"id"` + URL string `header:"url" json:"url"` + WebhookAuthorizationTokenConfigured bool `header:"webhook authorization token" json:"webhook_authorization_token_configured"` + Events string `header:"events" json:"events"` + Enabled bool `header:"enabled" json:"enabled"` + CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` + UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` - orig *ps.Webhook + orig *ps.Webhook } func (w *Webhook) MarshalJSON() ([]byte, error) { @@ -51,14 +51,14 @@ func (w *Webhook) MarshalJSON() ([]byte, error) { // toWebhook returns a struct that prints out the various fields of a webhook model. func toWebhook(webhook *ps.Webhook) *Webhook { return &Webhook{ - ID: webhook.ID, - URL: webhook.URL, - AuthorizationTokenConfigured: webhook.AuthorizationTokenConfigured, - Events: strings.Join(webhook.Events, ", "), - Enabled: webhook.Enabled, - CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), - UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), - orig: webhook, + ID: webhook.ID, + URL: webhook.URL, + WebhookAuthorizationTokenConfigured: webhook.WebhookAuthorizationTokenConfigured, + Events: strings.Join(webhook.Events, ", "), + Enabled: webhook.Enabled, + CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), + UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), + orig: webhook, } } @@ -72,16 +72,16 @@ func toWebhooks(webhooks []*ps.Webhook) []*Webhook { // WebhookWithSecret includes the webhook secret for display. type WebhookWithSecret struct { - ID string `header:"id" json:"id"` - URL string `header:"url" json:"url"` - Secret string `header:"secret" json:"secret"` - AuthorizationTokenConfigured bool `header:"authorization token" json:"authorization_token_configured"` - Events string `header:"events" json:"events"` - Enabled bool `header:"enabled" json:"enabled"` - CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` - UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` + ID string `header:"id" json:"id"` + URL string `header:"url" json:"url"` + Secret string `header:"secret" json:"secret"` + WebhookAuthorizationTokenConfigured bool `header:"webhook authorization token" json:"webhook_authorization_token_configured"` + Events string `header:"events" json:"events"` + Enabled bool `header:"enabled" json:"enabled"` + CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` + UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` - orig *ps.Webhook + orig *ps.Webhook } func (w *WebhookWithSecret) MarshalJSON() ([]byte, error) { @@ -91,14 +91,14 @@ func (w *WebhookWithSecret) MarshalJSON() ([]byte, error) { // toWebhookWithSecret returns a struct that includes the webhook secret. func toWebhookWithSecret(webhook *ps.Webhook) *WebhookWithSecret { return &WebhookWithSecret{ - ID: webhook.ID, - URL: webhook.URL, - Secret: webhook.Secret, - AuthorizationTokenConfigured: webhook.AuthorizationTokenConfigured, - Events: strings.Join(webhook.Events, ", "), - Enabled: webhook.Enabled, - CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), - UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), - orig: webhook, + ID: webhook.ID, + URL: webhook.URL, + Secret: webhook.Secret, + WebhookAuthorizationTokenConfigured: webhook.WebhookAuthorizationTokenConfigured, + Events: strings.Join(webhook.Events, ", "), + Enabled: webhook.Enabled, + CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), + UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), + orig: webhook, } } From 0474dde7d76d8a745495c7771594907f5fe7d4bc Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:22:46 -0700 Subject: [PATCH 12/31] Rename webhook authorization token fields --- internal/cmd/webhook/create.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/cmd/webhook/create.go b/internal/cmd/webhook/create.go index d332d905..781ca025 100644 --- a/internal/cmd/webhook/create.go +++ b/internal/cmd/webhook/create.go @@ -12,16 +12,16 @@ import ( func CreateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { url string - authorizationToken string + webhookAuthorizationToken string events []string enabled bool } cmd := &cobra.Command{ - Use: "create ", - Short: "Create a webhook for a database", - Args: cmdutil.RequiredArgs("database"), - RunE: func(cmd *cobra.Command, args []string) error { + Use: "create ", + Short: "Create a webhook for a database", + Args: cmdutil.RequiredArgs("database"), + RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() database := args[0] @@ -31,11 +31,11 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } req := &planetscale.CreateWebhookRequest{ - Organization: ch.Config.Organization, - Database: database, - URL: flags.url, - AuthorizationToken: flags.authorizationToken, - Events: flags.events, + Organization: ch.Config.Organization, + Database: database, + URL: flags.url, + WebhookAuthorizationToken: flags.webhookAuthorizationToken, + Events: flags.events, } if cmd.Flags().Changed("enabled") { @@ -63,7 +63,7 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to (required)") - cmd.Flags().StringVar(&flags.authorizationToken, "authorization-token", "", "Bearer token to include in the Authorization header") + cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Bearer token to include in the Authorization header") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") From 0c333ed7783cabe3e9441359e45bc8e84886bb58 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:22:51 -0700 Subject: [PATCH 13/31] Rename webhook authorization token fields --- internal/cmd/webhook/update.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/cmd/webhook/update.go b/internal/cmd/webhook/update.go index 3b1b11b5..80330a24 100644 --- a/internal/cmd/webhook/update.go +++ b/internal/cmd/webhook/update.go @@ -12,16 +12,16 @@ import ( func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { url string - authorizationToken string + webhookAuthorizationToken string events []string enabled bool } cmd := &cobra.Command{ - Use: "update ", - Short: "Update a webhook for a database", - Args: cmdutil.RequiredArgs("database", "webhook-id"), - RunE: func(cmd *cobra.Command, args []string) error { + Use: "update ", + Short: "Update a webhook for a database", + Args: cmdutil.RequiredArgs("database", "webhook-id"), + RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() database := args[0] webhookID := args[1] @@ -32,9 +32,9 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } req := &planetscale.UpdateWebhookRequest{ - Organization: ch.Config.Organization, - Database: database, - ID: webhookID, + Organization: ch.Config.Organization, + Database: database, + ID: webhookID, } changed := false @@ -44,8 +44,8 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { changed = true } - if cmd.Flags().Changed("authorization-token") { - req.AuthorizationToken = &flags.authorizationToken + if cmd.Flags().Changed("webhook-authorization-token") { + req.WebhookAuthorizationToken = &flags.webhookAuthorizationToken changed = true } @@ -60,7 +60,7 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } if !changed { - return fmt.Errorf("at least one of --url, --authorization-token, --events, or --enabled must be provided") + return fmt.Errorf("at least one of --url, --webhook-authorization-token, --events, or --enabled must be provided") } end := ch.Printer.PrintProgress(fmt.Sprintf("Updating webhook %s for %s", printer.BoldBlue(webhookID), printer.BoldBlue(database))) @@ -84,7 +84,7 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to") - cmd.Flags().StringVar(&flags.authorizationToken, "authorization-token", "", "Bearer token to include in the Authorization header") + cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Bearer token to include in the Authorization header") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") From f77d28a01d4885506d8456afeb43de0b8cc69a9a Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:22:56 -0700 Subject: [PATCH 14/31] Rename webhook authorization token fields --- internal/cmd/webhook/update_test.go | 50 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/internal/cmd/webhook/update_test.go b/internal/cmd/webhook/update_test.go index d606c493..a0822f4c 100644 --- a/internal/cmd/webhook/update_test.go +++ b/internal/cmd/webhook/update_test.go @@ -29,11 +29,11 @@ func TestWebhook_UpdateCmd(t *testing.T) { createdAt := time.Date(2025, 1, 15, 10, 30, 0, 0, time.UTC) webhook := &ps.Webhook{ - ID: webhookID, - URL: newURL, - Enabled: true, - Events: []string{"branch.created"}, - CreatedAt: createdAt, + ID: webhookID, + URL: newURL, + Enabled: true, + Events: []string{"branch.created"}, + CreatedAt: createdAt, } svc := &mock.WebhooksService{ @@ -47,8 +47,8 @@ func TestWebhook_UpdateCmd(t *testing.T) { } ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { @@ -83,11 +83,11 @@ func TestWebhook_UpdateCmd_EnabledFlag(t *testing.T) { createdAt := time.Date(2025, 1, 15, 10, 30, 0, 0, time.UTC) webhook := &ps.Webhook{ - ID: webhookID, - URL: "https://example.com/webhook", - Enabled: false, - Events: []string{"branch.created"}, - CreatedAt: createdAt, + ID: webhookID, + URL: "https://example.com/webhook", + Enabled: false, + Events: []string{"branch.created"}, + CreatedAt: createdAt, } svc := &mock.WebhooksService{ @@ -101,8 +101,8 @@ func TestWebhook_UpdateCmd_EnabledFlag(t *testing.T) { } ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { @@ -120,7 +120,7 @@ func TestWebhook_UpdateCmd_EnabledFlag(t *testing.T) { c.Assert(svc.UpdateFnInvoked, qt.IsTrue) } -func TestWebhook_UpdateCmd_AuthorizationTokenFlag(t *testing.T) { +func TestWebhook_UpdateCmd_WebhookAuthorizationTokenFlag(t *testing.T) { c := qt.New(t) var buf bytes.Buffer @@ -131,12 +131,12 @@ func TestWebhook_UpdateCmd_AuthorizationTokenFlag(t *testing.T) { org := "planetscale" db := "mydb" webhookID := "webhook-123" - authorizationToken := "automation-token" + webhookAuthorizationToken := "automation-token" webhook := &ps.Webhook{ - ID: webhookID, - URL: "https://example.com/webhook", - Enabled: true, + ID: webhookID, + URL: "https://example.com/webhook", + Enabled: true, } svc := &mock.WebhooksService{ @@ -144,14 +144,14 @@ func TestWebhook_UpdateCmd_AuthorizationTokenFlag(t *testing.T) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, db) c.Assert(req.ID, qt.Equals, webhookID) - c.Assert(*req.AuthorizationToken, qt.Equals, authorizationToken) + c.Assert(*req.WebhookAuthorizationToken, qt.Equals, webhookAuthorizationToken) return webhook, nil }, } ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { @@ -162,7 +162,7 @@ func TestWebhook_UpdateCmd_AuthorizationTokenFlag(t *testing.T) { } cmd := UpdateCmd(ch) - cmd.SetArgs([]string{db, webhookID, "--authorization-token", authorizationToken}) + cmd.SetArgs([]string{db, webhookID, "--webhook-authorization-token", webhookAuthorizationToken}) err := cmd.Execute() c.Assert(err, qt.IsNil) @@ -182,8 +182,8 @@ func TestWebhook_UpdateCmd_RequiresAtLeastOneFlag(t *testing.T) { webhookID := "webhook-123" ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { From f9952ba3673181518a88844c47ac21c7aa17c5aa Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:23:02 -0700 Subject: [PATCH 15/31] Rename webhook authorization token fields --- internal/planetscale/webhooks.go | 74 ++++++++++++++++---------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/internal/planetscale/webhooks.go b/internal/planetscale/webhooks.go index 4cbb75b2..da9a42d8 100644 --- a/internal/planetscale/webhooks.go +++ b/internal/planetscale/webhooks.go @@ -21,74 +21,74 @@ type WebhooksService interface { } type webhooksResponse struct { - Webhooks []*Webhook `json:"data"` + Webhooks []*Webhook `json:"data"` } // Webhook represents a PlanetScale webhook. type Webhook struct { - ID string `json:"id"` - URL string `json:"url"` - Secret string `json:"secret"` - AuthorizationTokenConfigured bool `json:"authorization_token_configured"` - Enabled bool `json:"enabled"` - LastSentResult string `json:"last_sent_result"` - LastSentSuccess bool `json:"last_sent_success"` - LastSentAt time.Time `json:"last_sent_at"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Events []string `json:"events"` + ID string `json:"id"` + URL string `json:"url"` + Secret string `json:"secret"` + WebhookAuthorizationTokenConfigured bool `json:"webhook_authorization_token_configured"` + Enabled bool `json:"enabled"` + LastSentResult string `json:"last_sent_result"` + LastSentSuccess bool `json:"last_sent_success"` + LastSentAt time.Time `json:"last_sent_at"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Events []string `json:"events"` } // ListWebhooksRequest is the request for listing webhooks. type ListWebhooksRequest struct { - Organization string `json:"-"` - Database string `json:"-"` + Organization string `json:"-"` + Database string `json:"-"` } // CreateWebhookRequest is the request for creating a webhook. type CreateWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - URL string `json:"url"` - AuthorizationToken string `json:"authorization_token,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Events []string `json:"events,omitempty"` + Organization string `json:"-"` + Database string `json:"-"` + URL string `json:"url"` + WebhookAuthorizationToken string `json:"webhook_authorization_token,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Events []string `json:"events,omitempty"` } // GetWebhookRequest is the request for getting a webhook. type GetWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` } // UpdateWebhookRequest is the request for updating a webhook. type UpdateWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` - URL *string `json:"url,omitempty"` - AuthorizationToken *string `json:"authorization_token,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Events []string `json:"events,omitempty"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` + URL *string `json:"url,omitempty"` + WebhookAuthorizationToken *string `json:"webhook_authorization_token,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Events []string `json:"events,omitempty"` } // DeleteWebhookRequest is the request for deleting a webhook. type DeleteWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` } // TestWebhookRequest is the request for testing a webhook. type TestWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` } type webhooksService struct { - client *Client + client *Client } func (w *webhooksService) List(ctx context.Context, listReq *ListWebhooksRequest, opts ...ListOption) ([]*Webhook, error) { From 7d1c93653000f668ad48151834d835c5f3d3b3e9 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:23:07 -0700 Subject: [PATCH 16/31] Rename webhook authorization token fields --- internal/cmd/webhook/create_test.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/cmd/webhook/create_test.go b/internal/cmd/webhook/create_test.go index 1b921642..096f7388 100644 --- a/internal/cmd/webhook/create_test.go +++ b/internal/cmd/webhook/create_test.go @@ -26,16 +26,16 @@ func TestWebhook_CreateCmd(t *testing.T) { db := "mydb" url := "https://example.com/webhook" events := []string{"branch.created", "branch.deleted"} - authorizationToken := "automation-token" + webhookAuthorizationToken := "automation-token" createdAt := time.Date(2025, 1, 15, 10, 30, 0, 0, time.UTC) webhook := &ps.Webhook{ - ID: "webhook-123", - URL: url, - Secret: "abcdefgh", - Enabled: true, - Events: events, - CreatedAt: createdAt, + ID: "webhook-123", + URL: url, + Secret: "abcdefgh", + Enabled: true, + Events: events, + CreatedAt: createdAt, } svc := &mock.WebhooksService{ @@ -43,15 +43,15 @@ func TestWebhook_CreateCmd(t *testing.T) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, db) c.Assert(req.URL, qt.Equals, url) - c.Assert(req.AuthorizationToken, qt.Equals, authorizationToken) + c.Assert(req.WebhookAuthorizationToken, qt.Equals, webhookAuthorizationToken) c.Assert(req.Events, qt.DeepEquals, events) return webhook, nil }, } ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { @@ -62,7 +62,7 @@ func TestWebhook_CreateCmd(t *testing.T) { } cmd := CreateCmd(ch) - cmd.SetArgs([]string{db, "--url", url, "--authorization-token", authorizationToken, "--events", "branch.created,branch.deleted"}) + cmd.SetArgs([]string{db, "--url", url, "--webhook-authorization-token", webhookAuthorizationToken, "--events", "branch.created,branch.deleted"}) err := cmd.Execute() c.Assert(err, qt.IsNil) @@ -84,8 +84,8 @@ func TestWebhook_CreateCmd_RequiresURL(t *testing.T) { db := "mydb" ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { From 40c5460b25c7d07c37f3e0735b7ad70ced10a610 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:24:24 -0700 Subject: [PATCH 17/31] Format renamed webhook token fields --- internal/cmd/webhook/create.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/cmd/webhook/create.go b/internal/cmd/webhook/create.go index 781ca025..468406e1 100644 --- a/internal/cmd/webhook/create.go +++ b/internal/cmd/webhook/create.go @@ -11,10 +11,10 @@ import ( func CreateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { - url string - webhookAuthorizationToken string - events []string - enabled bool + url string + webhookAuthorizationToken string + events []string + enabled bool } cmd := &cobra.Command{ From 73a4cf95dfe4f6b51b49df63e3b1a00b11ea8293 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:24:30 -0700 Subject: [PATCH 18/31] Format renamed webhook token fields --- internal/cmd/webhook/update.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/cmd/webhook/update.go b/internal/cmd/webhook/update.go index 80330a24..c06b16e6 100644 --- a/internal/cmd/webhook/update.go +++ b/internal/cmd/webhook/update.go @@ -11,10 +11,10 @@ import ( func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { - url string - webhookAuthorizationToken string - events []string - enabled bool + url string + webhookAuthorizationToken string + events []string + enabled bool } cmd := &cobra.Command{ From 688b5c61c24e0c97c595c09fbe19c90b1a305695 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:26:20 -0700 Subject: [PATCH 19/31] Clean up webhook token rename formatting --- internal/planetscale/webhooks.go | 74 ++++++++++++++++---------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/internal/planetscale/webhooks.go b/internal/planetscale/webhooks.go index da9a42d8..899f209e 100644 --- a/internal/planetscale/webhooks.go +++ b/internal/planetscale/webhooks.go @@ -21,74 +21,74 @@ type WebhooksService interface { } type webhooksResponse struct { - Webhooks []*Webhook `json:"data"` + Webhooks []*Webhook `json:"data"` } // Webhook represents a PlanetScale webhook. type Webhook struct { - ID string `json:"id"` - URL string `json:"url"` - Secret string `json:"secret"` - WebhookAuthorizationTokenConfigured bool `json:"webhook_authorization_token_configured"` - Enabled bool `json:"enabled"` - LastSentResult string `json:"last_sent_result"` - LastSentSuccess bool `json:"last_sent_success"` - LastSentAt time.Time `json:"last_sent_at"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Events []string `json:"events"` + ID string `json:"id"` + URL string `json:"url"` + Secret string `json:"secret"` + WebhookAuthorizationTokenConfigured bool `json:"webhook_authorization_token_configured"` + Enabled bool `json:"enabled"` + LastSentResult string `json:"last_sent_result"` + LastSentSuccess bool `json:"last_sent_success"` + LastSentAt time.Time `json:"last_sent_at"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Events []string `json:"events"` } // ListWebhooksRequest is the request for listing webhooks. type ListWebhooksRequest struct { - Organization string `json:"-"` - Database string `json:"-"` + Organization string `json:"-"` + Database string `json:"-"` } // CreateWebhookRequest is the request for creating a webhook. type CreateWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - URL string `json:"url"` - WebhookAuthorizationToken string `json:"webhook_authorization_token,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Events []string `json:"events,omitempty"` + Organization string `json:"-"` + Database string `json:"-"` + URL string `json:"url"` + WebhookAuthorizationToken string `json:"webhook_authorization_token,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Events []string `json:"events,omitempty"` } // GetWebhookRequest is the request for getting a webhook. type GetWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` } // UpdateWebhookRequest is the request for updating a webhook. type UpdateWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` - URL *string `json:"url,omitempty"` - WebhookAuthorizationToken *string `json:"webhook_authorization_token,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Events []string `json:"events,omitempty"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` + URL *string `json:"url,omitempty"` + WebhookAuthorizationToken *string `json:"webhook_authorization_token,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Events []string `json:"events,omitempty"` } // DeleteWebhookRequest is the request for deleting a webhook. type DeleteWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` } // TestWebhookRequest is the request for testing a webhook. type TestWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` } type webhooksService struct { - client *Client + client *Client } func (w *webhooksService) List(ctx context.Context, listReq *ListWebhooksRequest, opts ...ListOption) ([]*Webhook, error) { From cd7e6c875f44e1901bc2f3cdcae069af049f6f69 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:26:25 -0700 Subject: [PATCH 20/31] Clean up webhook token rename formatting --- internal/cmd/webhook/create.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/cmd/webhook/create.go b/internal/cmd/webhook/create.go index 468406e1..0e4467a4 100644 --- a/internal/cmd/webhook/create.go +++ b/internal/cmd/webhook/create.go @@ -11,17 +11,17 @@ import ( func CreateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { - url string - webhookAuthorizationToken string - events []string - enabled bool + url string + webhookAuthorizationToken string + events []string + enabled bool } cmd := &cobra.Command{ - Use: "create ", - Short: "Create a webhook for a database", - Args: cmdutil.RequiredArgs("database"), - RunE: func(cmd *cobra.Command, args []string) error { + Use: "create ", + Short: "Create a webhook for a database", + Args: cmdutil.RequiredArgs("database"), + RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() database := args[0] @@ -31,11 +31,11 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } req := &planetscale.CreateWebhookRequest{ - Organization: ch.Config.Organization, - Database: database, - URL: flags.url, - WebhookAuthorizationToken: flags.webhookAuthorizationToken, - Events: flags.events, + Organization: ch.Config.Organization, + Database: database, + URL: flags.url, + WebhookAuthorizationToken: flags.webhookAuthorizationToken, + Events: flags.events, } if cmd.Flags().Changed("enabled") { From 681a448d80c97bb597818aa61a21d8999d71a977 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:26:30 -0700 Subject: [PATCH 21/31] Clean up webhook token rename formatting --- internal/cmd/webhook/webhook.go | 74 ++++++++++++++++----------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/internal/cmd/webhook/webhook.go b/internal/cmd/webhook/webhook.go index 4b8e1329..0c80a543 100644 --- a/internal/cmd/webhook/webhook.go +++ b/internal/cmd/webhook/webhook.go @@ -13,9 +13,9 @@ import ( // WebhookCmd encapsulates the command for managing webhooks. func WebhookCmd(ch *cmdutil.Helper) *cobra.Command { cmd := &cobra.Command{ - Use: "webhook ", - Short: "Create, list, and manage webhooks", - PersistentPreRunE: cmdutil.CheckAuthentication(ch.Config), + Use: "webhook ", + Short: "Create, list, and manage webhooks", + PersistentPreRunE: cmdutil.CheckAuthentication(ch.Config), } cmd.PersistentFlags().StringVar(&ch.Config.Organization, "org", ch.Config.Organization, "The organization for the current user") @@ -33,15 +33,15 @@ func WebhookCmd(ch *cmdutil.Helper) *cobra.Command { // Webhook returns a table and json serializable webhook for printing. type Webhook struct { - ID string `header:"id" json:"id"` - URL string `header:"url" json:"url"` - WebhookAuthorizationTokenConfigured bool `header:"webhook authorization token" json:"webhook_authorization_token_configured"` - Events string `header:"events" json:"events"` - Enabled bool `header:"enabled" json:"enabled"` - CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` - UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` + ID string `header:"id" json:"id"` + URL string `header:"url" json:"url"` + WebhookAuthorizationTokenConfigured bool `header:"webhook authorization token" json:"webhook_authorization_token_configured"` + Events string `header:"events" json:"events"` + Enabled bool `header:"enabled" json:"enabled"` + CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` + UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` - orig *ps.Webhook + orig *ps.Webhook } func (w *Webhook) MarshalJSON() ([]byte, error) { @@ -51,14 +51,14 @@ func (w *Webhook) MarshalJSON() ([]byte, error) { // toWebhook returns a struct that prints out the various fields of a webhook model. func toWebhook(webhook *ps.Webhook) *Webhook { return &Webhook{ - ID: webhook.ID, - URL: webhook.URL, - WebhookAuthorizationTokenConfigured: webhook.WebhookAuthorizationTokenConfigured, - Events: strings.Join(webhook.Events, ", "), - Enabled: webhook.Enabled, - CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), - UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), - orig: webhook, + ID: webhook.ID, + URL: webhook.URL, + WebhookAuthorizationTokenConfigured: webhook.WebhookAuthorizationTokenConfigured, + Events: strings.Join(webhook.Events, ", "), + Enabled: webhook.Enabled, + CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), + UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), + orig: webhook, } } @@ -72,16 +72,16 @@ func toWebhooks(webhooks []*ps.Webhook) []*Webhook { // WebhookWithSecret includes the webhook secret for display. type WebhookWithSecret struct { - ID string `header:"id" json:"id"` - URL string `header:"url" json:"url"` - Secret string `header:"secret" json:"secret"` - WebhookAuthorizationTokenConfigured bool `header:"webhook authorization token" json:"webhook_authorization_token_configured"` - Events string `header:"events" json:"events"` - Enabled bool `header:"enabled" json:"enabled"` - CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` - UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` + ID string `header:"id" json:"id"` + URL string `header:"url" json:"url"` + Secret string `header:"secret" json:"secret"` + WebhookAuthorizationTokenConfigured bool `header:"webhook authorization token" json:"webhook_authorization_token_configured"` + Events string `header:"events" json:"events"` + Enabled bool `header:"enabled" json:"enabled"` + CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` + UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` - orig *ps.Webhook + orig *ps.Webhook } func (w *WebhookWithSecret) MarshalJSON() ([]byte, error) { @@ -91,14 +91,14 @@ func (w *WebhookWithSecret) MarshalJSON() ([]byte, error) { // toWebhookWithSecret returns a struct that includes the webhook secret. func toWebhookWithSecret(webhook *ps.Webhook) *WebhookWithSecret { return &WebhookWithSecret{ - ID: webhook.ID, - URL: webhook.URL, - Secret: webhook.Secret, - WebhookAuthorizationTokenConfigured: webhook.WebhookAuthorizationTokenConfigured, - Events: strings.Join(webhook.Events, ", "), - Enabled: webhook.Enabled, - CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), - UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), - orig: webhook, + ID: webhook.ID, + URL: webhook.URL, + Secret: webhook.Secret, + WebhookAuthorizationTokenConfigured: webhook.WebhookAuthorizationTokenConfigured, + Events: strings.Join(webhook.Events, ", "), + Enabled: webhook.Enabled, + CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), + UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), + orig: webhook, } } From 8ba8a9fd18c6b922916abf934ed29a45e00af486 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:26:37 -0700 Subject: [PATCH 22/31] Clean up webhook token rename formatting --- internal/planetscale/webhooks_test.go | 50 +++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/internal/planetscale/webhooks_test.go b/internal/planetscale/webhooks_test.go index 029aee77..dbd51373 100644 --- a/internal/planetscale/webhooks_test.go +++ b/internal/planetscale/webhooks_test.go @@ -49,8 +49,8 @@ func TestWebhooks_List(t *testing.T) { ctx := context.Background() webhooks, err := client.Webhooks.List(ctx, &ListWebhooksRequest{ - Organization: testOrg, - Database: testDatabase, + Organization: testOrg, + Database: testDatabase, }) c.Assert(err, qt.IsNil) @@ -89,8 +89,8 @@ func TestWebhooks_List_WithPagination(t *testing.T) { ctx := context.Background() webhooks, err := client.Webhooks.List(ctx, &ListWebhooksRequest{ - Organization: testOrg, - Database: testDatabase, + Organization: testOrg, + Database: testDatabase, }, WithPage(2), WithPerPage(10)) c.Assert(err, qt.IsNil) @@ -134,12 +134,12 @@ func TestWebhooks_Create(t *testing.T) { enabled := true webhook, err := client.Webhooks.Create(ctx, &CreateWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - URL: "https://example.com/webhook", - WebhookAuthorizationToken: "automation-token", - Enabled: &enabled, - Events: []string{"branch.ready"}, + Organization: testOrg, + Database: testDatabase, + URL: "https://example.com/webhook", + WebhookAuthorizationToken: "automation-token", + Enabled: &enabled, + Events: []string{"branch.ready"}, }) c.Assert(err, qt.IsNil) @@ -180,9 +180,9 @@ func TestWebhooks_Get(t *testing.T) { ctx := context.Background() webhook, err := client.Webhooks.Get(ctx, &GetWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", }) c.Assert(err, qt.IsNil) @@ -230,12 +230,12 @@ func TestWebhooks_Update(t *testing.T) { webhookAuthorizationToken := "automation-token" webhook, err := client.Webhooks.Update(ctx, &UpdateWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", - URL: &newURL, - WebhookAuthorizationToken: &webhookAuthorizationToken, - Enabled: &enabled, + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", + URL: &newURL, + WebhookAuthorizationToken: &webhookAuthorizationToken, + Enabled: &enabled, }) c.Assert(err, qt.IsNil) @@ -260,9 +260,9 @@ func TestWebhooks_Delete(t *testing.T) { ctx := context.Background() err = client.Webhooks.Delete(ctx, &DeleteWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", }) c.Assert(err, qt.IsNil) @@ -283,9 +283,9 @@ func TestWebhooks_Test(t *testing.T) { ctx := context.Background() err = client.Webhooks.Test(ctx, &TestWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", }) c.Assert(err, qt.IsNil) From 38bc6a87eef0b988bce8ff341121d920014db818 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:26:43 -0700 Subject: [PATCH 23/31] Clean up webhook token rename formatting --- internal/cmd/webhook/create_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/cmd/webhook/create_test.go b/internal/cmd/webhook/create_test.go index 096f7388..f4f6a34d 100644 --- a/internal/cmd/webhook/create_test.go +++ b/internal/cmd/webhook/create_test.go @@ -30,12 +30,12 @@ func TestWebhook_CreateCmd(t *testing.T) { createdAt := time.Date(2025, 1, 15, 10, 30, 0, 0, time.UTC) webhook := &ps.Webhook{ - ID: "webhook-123", - URL: url, - Secret: "abcdefgh", - Enabled: true, - Events: events, - CreatedAt: createdAt, + ID: "webhook-123", + URL: url, + Secret: "abcdefgh", + Enabled: true, + Events: events, + CreatedAt: createdAt, } svc := &mock.WebhooksService{ @@ -50,8 +50,8 @@ func TestWebhook_CreateCmd(t *testing.T) { } ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { @@ -84,8 +84,8 @@ func TestWebhook_CreateCmd_RequiresURL(t *testing.T) { db := "mydb" ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { From bf83fe0875c0bcbec3b84c6afbd099f632eb5cfa Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:26:47 -0700 Subject: [PATCH 24/31] Clean up webhook token rename formatting --- internal/cmd/webhook/update_test.go | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/internal/cmd/webhook/update_test.go b/internal/cmd/webhook/update_test.go index a0822f4c..62c7142d 100644 --- a/internal/cmd/webhook/update_test.go +++ b/internal/cmd/webhook/update_test.go @@ -29,11 +29,11 @@ func TestWebhook_UpdateCmd(t *testing.T) { createdAt := time.Date(2025, 1, 15, 10, 30, 0, 0, time.UTC) webhook := &ps.Webhook{ - ID: webhookID, - URL: newURL, - Enabled: true, - Events: []string{"branch.created"}, - CreatedAt: createdAt, + ID: webhookID, + URL: newURL, + Enabled: true, + Events: []string{"branch.created"}, + CreatedAt: createdAt, } svc := &mock.WebhooksService{ @@ -47,8 +47,8 @@ func TestWebhook_UpdateCmd(t *testing.T) { } ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { @@ -83,11 +83,11 @@ func TestWebhook_UpdateCmd_EnabledFlag(t *testing.T) { createdAt := time.Date(2025, 1, 15, 10, 30, 0, 0, time.UTC) webhook := &ps.Webhook{ - ID: webhookID, - URL: "https://example.com/webhook", - Enabled: false, - Events: []string{"branch.created"}, - CreatedAt: createdAt, + ID: webhookID, + URL: "https://example.com/webhook", + Enabled: false, + Events: []string{"branch.created"}, + CreatedAt: createdAt, } svc := &mock.WebhooksService{ @@ -101,8 +101,8 @@ func TestWebhook_UpdateCmd_EnabledFlag(t *testing.T) { } ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { @@ -134,9 +134,9 @@ func TestWebhook_UpdateCmd_WebhookAuthorizationTokenFlag(t *testing.T) { webhookAuthorizationToken := "automation-token" webhook := &ps.Webhook{ - ID: webhookID, - URL: "https://example.com/webhook", - Enabled: true, + ID: webhookID, + URL: "https://example.com/webhook", + Enabled: true, } svc := &mock.WebhooksService{ @@ -150,8 +150,8 @@ func TestWebhook_UpdateCmd_WebhookAuthorizationTokenFlag(t *testing.T) { } ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { @@ -182,8 +182,8 @@ func TestWebhook_UpdateCmd_RequiresAtLeastOneFlag(t *testing.T) { webhookID := "webhook-123" ch := &cmdutil.Helper{ - Printer: p, - Config: &config.Config{ + Printer: p, + Config: &config.Config{ Organization: org, }, Client: func() (*ps.Client, error) { From 496950e37ec5086d32cb007452f7d694b7b25cca Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:26:52 -0700 Subject: [PATCH 25/31] Clean up webhook token rename formatting --- internal/cmd/webhook/update.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/cmd/webhook/update.go b/internal/cmd/webhook/update.go index c06b16e6..d5101c5e 100644 --- a/internal/cmd/webhook/update.go +++ b/internal/cmd/webhook/update.go @@ -11,17 +11,17 @@ import ( func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { - url string - webhookAuthorizationToken string - events []string - enabled bool + url string + webhookAuthorizationToken string + events []string + enabled bool } cmd := &cobra.Command{ - Use: "update ", - Short: "Update a webhook for a database", - Args: cmdutil.RequiredArgs("database", "webhook-id"), - RunE: func(cmd *cobra.Command, args []string) error { + Use: "update ", + Short: "Update a webhook for a database", + Args: cmdutil.RequiredArgs("database", "webhook-id"), + RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() database := args[0] webhookID := args[1] @@ -32,9 +32,9 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } req := &planetscale.UpdateWebhookRequest{ - Organization: ch.Config.Organization, - Database: database, - ID: webhookID, + Organization: ch.Config.Organization, + Database: database, + ID: webhookID, } changed := false From dc99d4463ed63de5bb41d328e3f856d2bb77dde7 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Tue, 1 Sep 2026 03:02:22 -0700 Subject: [PATCH 26/31] Add explicit webhook token removal --- internal/cmd/webhook/update.go | 21 ++++++-- internal/cmd/webhook/update_test.go | 73 +++++++++++++++++++++++++++ internal/planetscale/webhooks.go | 15 +++--- internal/planetscale/webhooks_test.go | 33 ++++++++++++ 4 files changed, 130 insertions(+), 12 deletions(-) diff --git a/internal/cmd/webhook/update.go b/internal/cmd/webhook/update.go index d5101c5e..d95603c8 100644 --- a/internal/cmd/webhook/update.go +++ b/internal/cmd/webhook/update.go @@ -11,10 +11,11 @@ import ( func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { - url string - webhookAuthorizationToken string - events []string - enabled bool + url string + webhookAuthorizationToken string + clearWebhookAuthorizationToken bool + events []string + enabled bool } cmd := &cobra.Command{ @@ -45,10 +46,18 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } if cmd.Flags().Changed("webhook-authorization-token") { + if flags.webhookAuthorizationToken == "" { + return fmt.Errorf("--webhook-authorization-token cannot be empty; use --clear-webhook-authorization-token to remove the configured token") + } req.WebhookAuthorizationToken = &flags.webhookAuthorizationToken changed = true } + if flags.clearWebhookAuthorizationToken { + req.ClearWebhookAuthorizationToken = true + changed = true + } + if cmd.Flags().Changed("events") { req.Events = flags.events changed = true @@ -60,7 +69,7 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } if !changed { - return fmt.Errorf("at least one of --url, --webhook-authorization-token, --events, or --enabled must be provided") + return fmt.Errorf("at least one of --url, --webhook-authorization-token, --clear-webhook-authorization-token, --events, or --enabled must be provided") } end := ch.Printer.PrintProgress(fmt.Sprintf("Updating webhook %s for %s", printer.BoldBlue(webhookID), printer.BoldBlue(database))) @@ -85,8 +94,10 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to") cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Bearer token to include in the Authorization header") + cmd.Flags().BoolVar(&flags.clearWebhookAuthorizationToken, "clear-webhook-authorization-token", false, "Remove the configured webhook authorization token") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") + cmd.MarkFlagsMutuallyExclusive("webhook-authorization-token", "clear-webhook-authorization-token") return cmd } diff --git a/internal/cmd/webhook/update_test.go b/internal/cmd/webhook/update_test.go index 62c7142d..8560281a 100644 --- a/internal/cmd/webhook/update_test.go +++ b/internal/cmd/webhook/update_test.go @@ -169,6 +169,79 @@ func TestWebhook_UpdateCmd_WebhookAuthorizationTokenFlag(t *testing.T) { c.Assert(svc.UpdateFnInvoked, qt.IsTrue) } +func TestWebhook_UpdateCmd_ClearWebhookAuthorizationTokenFlag(t *testing.T) { + c := qt.New(t) + + var buf bytes.Buffer + format := printer.JSON + p := printer.NewPrinter(&format) + p.SetResourceOutput(&buf) + + org := "planetscale" + db := "mydb" + webhookID := "webhook-123" + webhook := &ps.Webhook{ID: webhookID, URL: "https://example.com/webhook", Enabled: true} + + svc := &mock.WebhooksService{ + UpdateFn: func(ctx context.Context, req *ps.UpdateWebhookRequest) (*ps.Webhook, error) { + c.Assert(req.ClearWebhookAuthorizationToken, qt.IsTrue) + c.Assert(req.WebhookAuthorizationToken, qt.IsNil) + return webhook, nil + }, + } + + ch := &cmdutil.Helper{ + Printer: p, + Config: &config.Config{Organization: org}, + Client: func() (*ps.Client, error) { + return &ps.Client{Webhooks: svc}, nil + }, + } + + cmd := UpdateCmd(ch) + cmd.SetArgs([]string{db, webhookID, "--clear-webhook-authorization-token"}) + err := cmd.Execute() + + c.Assert(err, qt.IsNil) + c.Assert(svc.UpdateFnInvoked, qt.IsTrue) +} + +func TestWebhook_UpdateCmd_RejectsEmptyWebhookAuthorizationToken(t *testing.T) { + c := qt.New(t) + + ch := &cmdutil.Helper{ + Printer: printer.NewPrinter(nil), + Config: &config.Config{Organization: "planetscale"}, + Client: func() (*ps.Client, error) { + return &ps.Client{}, nil + }, + } + + cmd := UpdateCmd(ch) + cmd.SetArgs([]string{"mydb", "webhook-123", "--webhook-authorization-token", ""}) + err := cmd.Execute() + + c.Assert(err, qt.ErrorMatches, `--webhook-authorization-token cannot be empty; use --clear-webhook-authorization-token to remove the configured token`) +} + +func TestWebhook_UpdateCmd_RejectsSetAndClearWebhookAuthorizationToken(t *testing.T) { + c := qt.New(t) + + ch := &cmdutil.Helper{ + Printer: printer.NewPrinter(nil), + Config: &config.Config{Organization: "planetscale"}, + Client: func() (*ps.Client, error) { + return &ps.Client{}, nil + }, + } + + cmd := UpdateCmd(ch) + cmd.SetArgs([]string{"mydb", "webhook-123", "--webhook-authorization-token", "automation-token", "--clear-webhook-authorization-token"}) + err := cmd.Execute() + + c.Assert(err, qt.ErrorMatches, `if any flags in the group \[webhook-authorization-token clear-webhook-authorization-token\] are set none of the others can be; \[clear-webhook-authorization-token webhook-authorization-token\] were all set`) +} + func TestWebhook_UpdateCmd_RequiresAtLeastOneFlag(t *testing.T) { c := qt.New(t) diff --git a/internal/planetscale/webhooks.go b/internal/planetscale/webhooks.go index 899f209e..a0c2ea50 100644 --- a/internal/planetscale/webhooks.go +++ b/internal/planetscale/webhooks.go @@ -64,13 +64,14 @@ type GetWebhookRequest struct { // UpdateWebhookRequest is the request for updating a webhook. type UpdateWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` - URL *string `json:"url,omitempty"` - WebhookAuthorizationToken *string `json:"webhook_authorization_token,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Events []string `json:"events,omitempty"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` + URL *string `json:"url,omitempty"` + WebhookAuthorizationToken *string `json:"webhook_authorization_token,omitempty"` + ClearWebhookAuthorizationToken bool `json:"clear_webhook_authorization_token,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Events []string `json:"events,omitempty"` } // DeleteWebhookRequest is the request for deleting a webhook. diff --git a/internal/planetscale/webhooks_test.go b/internal/planetscale/webhooks_test.go index dbd51373..61972f36 100644 --- a/internal/planetscale/webhooks_test.go +++ b/internal/planetscale/webhooks_test.go @@ -245,6 +245,39 @@ func TestWebhooks_Update(t *testing.T) { c.Assert(webhook.UpdatedAt, qt.Equals, time.Date(2021, 1, 15, 10, 19, 23, 0, time.UTC)) } +func TestWebhooks_Update_ClearWebhookAuthorizationToken(t *testing.T) { + c := qt.New(t) + + wantBody := []byte("{\"clear_webhook_authorization_token\":true}\n") + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + c.Assert(r.Method, qt.Equals, http.MethodPatch) + c.Assert(r.URL.String(), qt.Equals, "/v1/organizations/my-org/databases/planetscale-go-test-db/webhooks/webhook-123") + + data, err := io.ReadAll(r.Body) + c.Assert(err, qt.IsNil) + c.Assert(data, qt.DeepEquals, wantBody) + + _, err = w.Write([]byte(`{"id":"webhook-123","url":"https://example.com/webhook"}`)) + c.Assert(err, qt.IsNil) + })) + defer ts.Close() + + client, err := NewClient(WithBaseURL(ts.URL)) + c.Assert(err, qt.IsNil) + + webhook, err := client.Webhooks.Update(context.Background(), &UpdateWebhookRequest{ + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", + ClearWebhookAuthorizationToken: true, + }) + + c.Assert(err, qt.IsNil) + c.Assert(webhook.ID, qt.Equals, "webhook-123") +} + func TestWebhooks_Delete(t *testing.T) { c := qt.New(t) From f22154be3cf5d1b8e2e814283c26a312f86d4399 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Tue, 1 Sep 2026 08:52:32 -0700 Subject: [PATCH 27/31] Clarify webhook token status heading --- internal/cmd/webhook/webhook.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cmd/webhook/webhook.go b/internal/cmd/webhook/webhook.go index 0c80a543..4fd17611 100644 --- a/internal/cmd/webhook/webhook.go +++ b/internal/cmd/webhook/webhook.go @@ -35,7 +35,7 @@ func WebhookCmd(ch *cmdutil.Helper) *cobra.Command { type Webhook struct { ID string `header:"id" json:"id"` URL string `header:"url" json:"url"` - WebhookAuthorizationTokenConfigured bool `header:"webhook authorization token" json:"webhook_authorization_token_configured"` + WebhookAuthorizationTokenConfigured bool `header:"authorization token configured" json:"webhook_authorization_token_configured"` Events string `header:"events" json:"events"` Enabled bool `header:"enabled" json:"enabled"` CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` @@ -75,7 +75,7 @@ type WebhookWithSecret struct { ID string `header:"id" json:"id"` URL string `header:"url" json:"url"` Secret string `header:"secret" json:"secret"` - WebhookAuthorizationTokenConfigured bool `header:"webhook authorization token" json:"webhook_authorization_token_configured"` + WebhookAuthorizationTokenConfigured bool `header:"authorization token configured" json:"webhook_authorization_token_configured"` Events string `header:"events" json:"events"` Enabled bool `header:"enabled" json:"enabled"` CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` From 953b736262aa36f3eacd4ad70e87a42b07c9736c Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Tue, 1 Sep 2026 09:06:10 -0700 Subject: [PATCH 28/31] Clarify webhook token flag help --- internal/cmd/webhook/create.go | 2 +- internal/cmd/webhook/update.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cmd/webhook/create.go b/internal/cmd/webhook/create.go index 0e4467a4..2b4d4b21 100644 --- a/internal/cmd/webhook/create.go +++ b/internal/cmd/webhook/create.go @@ -63,7 +63,7 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to (required)") - cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Bearer token to include in the Authorization header") + cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token value only; PlanetScale adds the Bearer prefix automatically") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") diff --git a/internal/cmd/webhook/update.go b/internal/cmd/webhook/update.go index d95603c8..35c22461 100644 --- a/internal/cmd/webhook/update.go +++ b/internal/cmd/webhook/update.go @@ -93,7 +93,7 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to") - cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Bearer token to include in the Authorization header") + cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token value only; PlanetScale adds the Bearer prefix automatically") cmd.Flags().BoolVar(&flags.clearWebhookAuthorizationToken, "clear-webhook-authorization-token", false, "Remove the configured webhook authorization token") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") From 52486b57c8a96696e466d8cb9ad0e3333e5ad140 Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Tue, 1 Sep 2026 09:10:56 -0700 Subject: [PATCH 29/31] Tighten webhook token copy --- internal/cmd/webhook/create.go | 2 +- internal/cmd/webhook/update.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cmd/webhook/create.go b/internal/cmd/webhook/create.go index 2b4d4b21..5eda1a98 100644 --- a/internal/cmd/webhook/create.go +++ b/internal/cmd/webhook/create.go @@ -63,7 +63,7 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to (required)") - cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token value only; PlanetScale adds the Bearer prefix automatically") + cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token prefixed with Bearer") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") diff --git a/internal/cmd/webhook/update.go b/internal/cmd/webhook/update.go index 35c22461..4073ec6f 100644 --- a/internal/cmd/webhook/update.go +++ b/internal/cmd/webhook/update.go @@ -93,7 +93,7 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to") - cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token value only; PlanetScale adds the Bearer prefix automatically") + cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token prefixed with Bearer") cmd.Flags().BoolVar(&flags.clearWebhookAuthorizationToken, "clear-webhook-authorization-token", false, "Remove the configured webhook authorization token") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") From 7cf74cef8ff9600f91180a86c3fa775d42e11fee Mon Sep 17 00:00:00 2001 From: Christian Glassiognon <63924603+heyglassy@users.noreply.github.com> Date: Tue, 1 Sep 2026 09:19:03 -0700 Subject: [PATCH 30/31] Fix webhook token help punctuation --- internal/cmd/webhook/create.go | 2 +- internal/cmd/webhook/update.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cmd/webhook/create.go b/internal/cmd/webhook/create.go index 5eda1a98..0e9724f7 100644 --- a/internal/cmd/webhook/create.go +++ b/internal/cmd/webhook/create.go @@ -63,7 +63,7 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to (required)") - cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token prefixed with Bearer") + cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token prefixed with Bearer.") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") diff --git a/internal/cmd/webhook/update.go b/internal/cmd/webhook/update.go index 4073ec6f..731c38c9 100644 --- a/internal/cmd/webhook/update.go +++ b/internal/cmd/webhook/update.go @@ -93,7 +93,7 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to") - cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token prefixed with Bearer") + cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token prefixed with Bearer.") cmd.Flags().BoolVar(&flags.clearWebhookAuthorizationToken, "clear-webhook-authorization-token", false, "Remove the configured webhook authorization token") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") From 81b2bbf6811f74a45031464407238b4540d96210 Mon Sep 17 00:00:00 2001 From: Mike Coutermarsh Date: Fri, 4 Sep 2026 16:34:06 -0400 Subject: [PATCH 31/31] Align webhook flags with the authorization header API. Send the complete Authorization header value as authorization_header, read only authorization_header_configured, and clear by PATCHing an empty string instead of a dedicated clear field. Co-authored-by: Cursor --- internal/cmd/webhook/create.go | 20 ++++----- internal/cmd/webhook/create_test.go | 6 +-- internal/cmd/webhook/update.go | 31 ++++++------- internal/cmd/webhook/update_test.go | 28 ++++++------ internal/cmd/webhook/webhook.go | 64 +++++++++++++-------------- internal/planetscale/webhooks.go | 49 ++++++++++---------- internal/planetscale/webhooks_test.go | 47 ++++++++++---------- 7 files changed, 123 insertions(+), 122 deletions(-) diff --git a/internal/cmd/webhook/create.go b/internal/cmd/webhook/create.go index 0e9724f7..92a39a51 100644 --- a/internal/cmd/webhook/create.go +++ b/internal/cmd/webhook/create.go @@ -11,10 +11,10 @@ import ( func CreateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { - url string - webhookAuthorizationToken string - events []string - enabled bool + url string + authorizationHeader string + events []string + enabled bool } cmd := &cobra.Command{ @@ -31,11 +31,11 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } req := &planetscale.CreateWebhookRequest{ - Organization: ch.Config.Organization, - Database: database, - URL: flags.url, - WebhookAuthorizationToken: flags.webhookAuthorizationToken, - Events: flags.events, + Organization: ch.Config.Organization, + Database: database, + URL: flags.url, + AuthorizationHeader: flags.authorizationHeader, + Events: flags.events, } if cmd.Flags().Changed("enabled") { @@ -63,7 +63,7 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to (required)") - cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token prefixed with Bearer.") + cmd.Flags().StringVar(&flags.authorizationHeader, "authorization-header", "", "The complete Authorization header value, for example Bearer token") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") diff --git a/internal/cmd/webhook/create_test.go b/internal/cmd/webhook/create_test.go index f4f6a34d..79623da2 100644 --- a/internal/cmd/webhook/create_test.go +++ b/internal/cmd/webhook/create_test.go @@ -26,7 +26,7 @@ func TestWebhook_CreateCmd(t *testing.T) { db := "mydb" url := "https://example.com/webhook" events := []string{"branch.created", "branch.deleted"} - webhookAuthorizationToken := "automation-token" + authorizationHeader := "Bearer automation-token" createdAt := time.Date(2025, 1, 15, 10, 30, 0, 0, time.UTC) webhook := &ps.Webhook{ @@ -43,7 +43,7 @@ func TestWebhook_CreateCmd(t *testing.T) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, db) c.Assert(req.URL, qt.Equals, url) - c.Assert(req.WebhookAuthorizationToken, qt.Equals, webhookAuthorizationToken) + c.Assert(req.AuthorizationHeader, qt.Equals, authorizationHeader) c.Assert(req.Events, qt.DeepEquals, events) return webhook, nil }, @@ -62,7 +62,7 @@ func TestWebhook_CreateCmd(t *testing.T) { } cmd := CreateCmd(ch) - cmd.SetArgs([]string{db, "--url", url, "--webhook-authorization-token", webhookAuthorizationToken, "--events", "branch.created,branch.deleted"}) + cmd.SetArgs([]string{db, "--url", url, "--authorization-header", authorizationHeader, "--events", "branch.created,branch.deleted"}) err := cmd.Execute() c.Assert(err, qt.IsNil) diff --git a/internal/cmd/webhook/update.go b/internal/cmd/webhook/update.go index 731c38c9..05c59540 100644 --- a/internal/cmd/webhook/update.go +++ b/internal/cmd/webhook/update.go @@ -11,11 +11,11 @@ import ( func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { var flags struct { - url string - webhookAuthorizationToken string - clearWebhookAuthorizationToken bool - events []string - enabled bool + url string + authorizationHeader string + clearAuthorizationHeader bool + events []string + enabled bool } cmd := &cobra.Command{ @@ -45,16 +45,17 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { changed = true } - if cmd.Flags().Changed("webhook-authorization-token") { - if flags.webhookAuthorizationToken == "" { - return fmt.Errorf("--webhook-authorization-token cannot be empty; use --clear-webhook-authorization-token to remove the configured token") + if cmd.Flags().Changed("authorization-header") { + if flags.authorizationHeader == "" { + return fmt.Errorf("--authorization-header cannot be empty; use --clear-authorization-header to remove the configured header") } - req.WebhookAuthorizationToken = &flags.webhookAuthorizationToken + req.AuthorizationHeader = &flags.authorizationHeader changed = true } - if flags.clearWebhookAuthorizationToken { - req.ClearWebhookAuthorizationToken = true + if flags.clearAuthorizationHeader { + empty := "" + req.AuthorizationHeader = &empty changed = true } @@ -69,7 +70,7 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } if !changed { - return fmt.Errorf("at least one of --url, --webhook-authorization-token, --clear-webhook-authorization-token, --events, or --enabled must be provided") + return fmt.Errorf("at least one of --url, --authorization-header, --clear-authorization-header, --events, or --enabled must be provided") } end := ch.Printer.PrintProgress(fmt.Sprintf("Updating webhook %s for %s", printer.BoldBlue(webhookID), printer.BoldBlue(database))) @@ -93,11 +94,11 @@ func UpdateCmd(ch *cmdutil.Helper) *cobra.Command { } cmd.Flags().StringVar(&flags.url, "url", "", "The URL to send webhook events to") - cmd.Flags().StringVar(&flags.webhookAuthorizationToken, "webhook-authorization-token", "", "Token prefixed with Bearer.") - cmd.Flags().BoolVar(&flags.clearWebhookAuthorizationToken, "clear-webhook-authorization-token", false, "Remove the configured webhook authorization token") + cmd.Flags().StringVar(&flags.authorizationHeader, "authorization-header", "", "The complete Authorization header value, for example Bearer token") + cmd.Flags().BoolVar(&flags.clearAuthorizationHeader, "clear-authorization-header", false, "Remove the configured Authorization header") cmd.Flags().StringSliceVar(&flags.events, "events", nil, "Comma-separated list of events to subscribe to") cmd.Flags().BoolVar(&flags.enabled, "enabled", true, "Whether the webhook is enabled") - cmd.MarkFlagsMutuallyExclusive("webhook-authorization-token", "clear-webhook-authorization-token") + cmd.MarkFlagsMutuallyExclusive("authorization-header", "clear-authorization-header") return cmd } diff --git a/internal/cmd/webhook/update_test.go b/internal/cmd/webhook/update_test.go index 8560281a..90a11664 100644 --- a/internal/cmd/webhook/update_test.go +++ b/internal/cmd/webhook/update_test.go @@ -120,7 +120,7 @@ func TestWebhook_UpdateCmd_EnabledFlag(t *testing.T) { c.Assert(svc.UpdateFnInvoked, qt.IsTrue) } -func TestWebhook_UpdateCmd_WebhookAuthorizationTokenFlag(t *testing.T) { +func TestWebhook_UpdateCmd_AuthorizationHeaderFlag(t *testing.T) { c := qt.New(t) var buf bytes.Buffer @@ -131,7 +131,7 @@ func TestWebhook_UpdateCmd_WebhookAuthorizationTokenFlag(t *testing.T) { org := "planetscale" db := "mydb" webhookID := "webhook-123" - webhookAuthorizationToken := "automation-token" + authorizationHeader := "Bearer automation-token" webhook := &ps.Webhook{ ID: webhookID, @@ -144,7 +144,7 @@ func TestWebhook_UpdateCmd_WebhookAuthorizationTokenFlag(t *testing.T) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, db) c.Assert(req.ID, qt.Equals, webhookID) - c.Assert(*req.WebhookAuthorizationToken, qt.Equals, webhookAuthorizationToken) + c.Assert(*req.AuthorizationHeader, qt.Equals, authorizationHeader) return webhook, nil }, } @@ -162,14 +162,14 @@ func TestWebhook_UpdateCmd_WebhookAuthorizationTokenFlag(t *testing.T) { } cmd := UpdateCmd(ch) - cmd.SetArgs([]string{db, webhookID, "--webhook-authorization-token", webhookAuthorizationToken}) + cmd.SetArgs([]string{db, webhookID, "--authorization-header", authorizationHeader}) err := cmd.Execute() c.Assert(err, qt.IsNil) c.Assert(svc.UpdateFnInvoked, qt.IsTrue) } -func TestWebhook_UpdateCmd_ClearWebhookAuthorizationTokenFlag(t *testing.T) { +func TestWebhook_UpdateCmd_ClearAuthorizationHeaderFlag(t *testing.T) { c := qt.New(t) var buf bytes.Buffer @@ -184,8 +184,8 @@ func TestWebhook_UpdateCmd_ClearWebhookAuthorizationTokenFlag(t *testing.T) { svc := &mock.WebhooksService{ UpdateFn: func(ctx context.Context, req *ps.UpdateWebhookRequest) (*ps.Webhook, error) { - c.Assert(req.ClearWebhookAuthorizationToken, qt.IsTrue) - c.Assert(req.WebhookAuthorizationToken, qt.IsNil) + c.Assert(req.AuthorizationHeader, qt.IsNotNil) + c.Assert(*req.AuthorizationHeader, qt.Equals, "") return webhook, nil }, } @@ -199,14 +199,14 @@ func TestWebhook_UpdateCmd_ClearWebhookAuthorizationTokenFlag(t *testing.T) { } cmd := UpdateCmd(ch) - cmd.SetArgs([]string{db, webhookID, "--clear-webhook-authorization-token"}) + cmd.SetArgs([]string{db, webhookID, "--clear-authorization-header"}) err := cmd.Execute() c.Assert(err, qt.IsNil) c.Assert(svc.UpdateFnInvoked, qt.IsTrue) } -func TestWebhook_UpdateCmd_RejectsEmptyWebhookAuthorizationToken(t *testing.T) { +func TestWebhook_UpdateCmd_RejectsEmptyAuthorizationHeader(t *testing.T) { c := qt.New(t) ch := &cmdutil.Helper{ @@ -218,13 +218,13 @@ func TestWebhook_UpdateCmd_RejectsEmptyWebhookAuthorizationToken(t *testing.T) { } cmd := UpdateCmd(ch) - cmd.SetArgs([]string{"mydb", "webhook-123", "--webhook-authorization-token", ""}) + cmd.SetArgs([]string{"mydb", "webhook-123", "--authorization-header", ""}) err := cmd.Execute() - c.Assert(err, qt.ErrorMatches, `--webhook-authorization-token cannot be empty; use --clear-webhook-authorization-token to remove the configured token`) + c.Assert(err, qt.ErrorMatches, `--authorization-header cannot be empty; use --clear-authorization-header to remove the configured header`) } -func TestWebhook_UpdateCmd_RejectsSetAndClearWebhookAuthorizationToken(t *testing.T) { +func TestWebhook_UpdateCmd_RejectsSetAndClearAuthorizationHeader(t *testing.T) { c := qt.New(t) ch := &cmdutil.Helper{ @@ -236,10 +236,10 @@ func TestWebhook_UpdateCmd_RejectsSetAndClearWebhookAuthorizationToken(t *testin } cmd := UpdateCmd(ch) - cmd.SetArgs([]string{"mydb", "webhook-123", "--webhook-authorization-token", "automation-token", "--clear-webhook-authorization-token"}) + cmd.SetArgs([]string{"mydb", "webhook-123", "--authorization-header", "Bearer automation-token", "--clear-authorization-header"}) err := cmd.Execute() - c.Assert(err, qt.ErrorMatches, `if any flags in the group \[webhook-authorization-token clear-webhook-authorization-token\] are set none of the others can be; \[clear-webhook-authorization-token webhook-authorization-token\] were all set`) + c.Assert(err, qt.ErrorMatches, `if any flags in the group \[authorization-header clear-authorization-header\] are set none of the others can be; \[authorization-header clear-authorization-header\] were all set`) } func TestWebhook_UpdateCmd_RequiresAtLeastOneFlag(t *testing.T) { diff --git a/internal/cmd/webhook/webhook.go b/internal/cmd/webhook/webhook.go index 4fd17611..d0a1b300 100644 --- a/internal/cmd/webhook/webhook.go +++ b/internal/cmd/webhook/webhook.go @@ -33,13 +33,13 @@ func WebhookCmd(ch *cmdutil.Helper) *cobra.Command { // Webhook returns a table and json serializable webhook for printing. type Webhook struct { - ID string `header:"id" json:"id"` - URL string `header:"url" json:"url"` - WebhookAuthorizationTokenConfigured bool `header:"authorization token configured" json:"webhook_authorization_token_configured"` - Events string `header:"events" json:"events"` - Enabled bool `header:"enabled" json:"enabled"` - CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` - UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` + ID string `header:"id" json:"id"` + URL string `header:"url" json:"url"` + AuthorizationHeaderConfigured bool `header:"authorization header configured" json:"authorization_header_configured"` + Events string `header:"events" json:"events"` + Enabled bool `header:"enabled" json:"enabled"` + CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` + UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` orig *ps.Webhook } @@ -51,14 +51,14 @@ func (w *Webhook) MarshalJSON() ([]byte, error) { // toWebhook returns a struct that prints out the various fields of a webhook model. func toWebhook(webhook *ps.Webhook) *Webhook { return &Webhook{ - ID: webhook.ID, - URL: webhook.URL, - WebhookAuthorizationTokenConfigured: webhook.WebhookAuthorizationTokenConfigured, - Events: strings.Join(webhook.Events, ", "), - Enabled: webhook.Enabled, - CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), - UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), - orig: webhook, + ID: webhook.ID, + URL: webhook.URL, + AuthorizationHeaderConfigured: webhook.AuthorizationHeaderConfigured, + Events: strings.Join(webhook.Events, ", "), + Enabled: webhook.Enabled, + CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), + UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), + orig: webhook, } } @@ -72,14 +72,14 @@ func toWebhooks(webhooks []*ps.Webhook) []*Webhook { // WebhookWithSecret includes the webhook secret for display. type WebhookWithSecret struct { - ID string `header:"id" json:"id"` - URL string `header:"url" json:"url"` - Secret string `header:"secret" json:"secret"` - WebhookAuthorizationTokenConfigured bool `header:"authorization token configured" json:"webhook_authorization_token_configured"` - Events string `header:"events" json:"events"` - Enabled bool `header:"enabled" json:"enabled"` - CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` - UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` + ID string `header:"id" json:"id"` + URL string `header:"url" json:"url"` + Secret string `header:"secret" json:"secret"` + AuthorizationHeaderConfigured bool `header:"authorization header configured" json:"authorization_header_configured"` + Events string `header:"events" json:"events"` + Enabled bool `header:"enabled" json:"enabled"` + CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` + UpdatedAt int64 `header:"updated_at,timestamp(ms|utc|human)" json:"updated_at"` orig *ps.Webhook } @@ -91,14 +91,14 @@ func (w *WebhookWithSecret) MarshalJSON() ([]byte, error) { // toWebhookWithSecret returns a struct that includes the webhook secret. func toWebhookWithSecret(webhook *ps.Webhook) *WebhookWithSecret { return &WebhookWithSecret{ - ID: webhook.ID, - URL: webhook.URL, - Secret: webhook.Secret, - WebhookAuthorizationTokenConfigured: webhook.WebhookAuthorizationTokenConfigured, - Events: strings.Join(webhook.Events, ", "), - Enabled: webhook.Enabled, - CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), - UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), - orig: webhook, + ID: webhook.ID, + URL: webhook.URL, + Secret: webhook.Secret, + AuthorizationHeaderConfigured: webhook.AuthorizationHeaderConfigured, + Events: strings.Join(webhook.Events, ", "), + Enabled: webhook.Enabled, + CreatedAt: printer.GetMilliseconds(webhook.CreatedAt), + UpdatedAt: printer.GetMilliseconds(webhook.UpdatedAt), + orig: webhook, } } diff --git a/internal/planetscale/webhooks.go b/internal/planetscale/webhooks.go index a0c2ea50..af1c7678 100644 --- a/internal/planetscale/webhooks.go +++ b/internal/planetscale/webhooks.go @@ -26,17 +26,17 @@ type webhooksResponse struct { // Webhook represents a PlanetScale webhook. type Webhook struct { - ID string `json:"id"` - URL string `json:"url"` - Secret string `json:"secret"` - WebhookAuthorizationTokenConfigured bool `json:"webhook_authorization_token_configured"` - Enabled bool `json:"enabled"` - LastSentResult string `json:"last_sent_result"` - LastSentSuccess bool `json:"last_sent_success"` - LastSentAt time.Time `json:"last_sent_at"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Events []string `json:"events"` + ID string `json:"id"` + URL string `json:"url"` + Secret string `json:"secret"` + AuthorizationHeaderConfigured bool `json:"authorization_header_configured"` + Enabled bool `json:"enabled"` + LastSentResult string `json:"last_sent_result"` + LastSentSuccess bool `json:"last_sent_success"` + LastSentAt time.Time `json:"last_sent_at"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Events []string `json:"events"` } // ListWebhooksRequest is the request for listing webhooks. @@ -47,12 +47,12 @@ type ListWebhooksRequest struct { // CreateWebhookRequest is the request for creating a webhook. type CreateWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - URL string `json:"url"` - WebhookAuthorizationToken string `json:"webhook_authorization_token,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Events []string `json:"events,omitempty"` + Organization string `json:"-"` + Database string `json:"-"` + URL string `json:"url"` + AuthorizationHeader string `json:"authorization_header,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Events []string `json:"events,omitempty"` } // GetWebhookRequest is the request for getting a webhook. @@ -64,14 +64,13 @@ type GetWebhookRequest struct { // UpdateWebhookRequest is the request for updating a webhook. type UpdateWebhookRequest struct { - Organization string `json:"-"` - Database string `json:"-"` - ID string `json:"-"` - URL *string `json:"url,omitempty"` - WebhookAuthorizationToken *string `json:"webhook_authorization_token,omitempty"` - ClearWebhookAuthorizationToken bool `json:"clear_webhook_authorization_token,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Events []string `json:"events,omitempty"` + Organization string `json:"-"` + Database string `json:"-"` + ID string `json:"-"` + URL *string `json:"url,omitempty"` + AuthorizationHeader *string `json:"authorization_header,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Events []string `json:"events,omitempty"` } // DeleteWebhookRequest is the request for deleting a webhook. diff --git a/internal/planetscale/webhooks_test.go b/internal/planetscale/webhooks_test.go index 61972f36..0a208e51 100644 --- a/internal/planetscale/webhooks_test.go +++ b/internal/planetscale/webhooks_test.go @@ -29,7 +29,7 @@ func TestWebhooks_List(t *testing.T) { "id": "webhook-123", "url": "https://example.com/webhook", "secret": "secret-123", - "webhook_authorization_token_configured": true, + "authorization_header_configured": true, "enabled": true, "last_sent_result": "success", "last_sent_success": true, @@ -57,7 +57,7 @@ func TestWebhooks_List(t *testing.T) { c.Assert(len(webhooks), qt.Equals, 1) c.Assert(webhooks[0].ID, qt.Equals, "webhook-123") c.Assert(webhooks[0].URL, qt.Equals, "https://example.com/webhook") - c.Assert(webhooks[0].WebhookAuthorizationTokenConfigured, qt.IsTrue) + c.Assert(webhooks[0].AuthorizationHeaderConfigured, qt.IsTrue) c.Assert(webhooks[0].Enabled, qt.IsTrue) c.Assert(webhooks[0].Events, qt.DeepEquals, []string{"branch.ready", "deploy_request.opened"}) } @@ -100,7 +100,7 @@ func TestWebhooks_List_WithPagination(t *testing.T) { func TestWebhooks_Create(t *testing.T) { c := qt.New(t) - wantBody := []byte("{\"url\":\"https://example.com/webhook\",\"webhook_authorization_token\":\"automation-token\",\"enabled\":true,\"events\":[\"branch.ready\"]}\n") + wantBody := []byte("{\"url\":\"https://example.com/webhook\",\"authorization_header\":\"Bearer automation-token\",\"enabled\":true,\"events\":[\"branch.ready\"]}\n") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(201) @@ -134,12 +134,12 @@ func TestWebhooks_Create(t *testing.T) { enabled := true webhook, err := client.Webhooks.Create(ctx, &CreateWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - URL: "https://example.com/webhook", - WebhookAuthorizationToken: "automation-token", - Enabled: &enabled, - Events: []string{"branch.ready"}, + Organization: testOrg, + Database: testDatabase, + URL: "https://example.com/webhook", + AuthorizationHeader: "Bearer automation-token", + Enabled: &enabled, + Events: []string{"branch.ready"}, }) c.Assert(err, qt.IsNil) @@ -194,7 +194,7 @@ func TestWebhooks_Get(t *testing.T) { func TestWebhooks_Update(t *testing.T) { c := qt.New(t) - wantBody := []byte("{\"url\":\"https://example.com/new-webhook\",\"webhook_authorization_token\":\"automation-token\",\"enabled\":false}\n") + wantBody := []byte("{\"url\":\"https://example.com/new-webhook\",\"authorization_header\":\"Bearer automation-token\",\"enabled\":false}\n") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) @@ -227,15 +227,15 @@ func TestWebhooks_Update(t *testing.T) { ctx := context.Background() newURL := "https://example.com/new-webhook" enabled := false - webhookAuthorizationToken := "automation-token" + authorizationHeader := "Bearer automation-token" webhook, err := client.Webhooks.Update(ctx, &UpdateWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", - URL: &newURL, - WebhookAuthorizationToken: &webhookAuthorizationToken, - Enabled: &enabled, + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", + URL: &newURL, + AuthorizationHeader: &authorizationHeader, + Enabled: &enabled, }) c.Assert(err, qt.IsNil) @@ -245,10 +245,10 @@ func TestWebhooks_Update(t *testing.T) { c.Assert(webhook.UpdatedAt, qt.Equals, time.Date(2021, 1, 15, 10, 19, 23, 0, time.UTC)) } -func TestWebhooks_Update_ClearWebhookAuthorizationToken(t *testing.T) { +func TestWebhooks_Update_ClearAuthorizationHeader(t *testing.T) { c := qt.New(t) - wantBody := []byte("{\"clear_webhook_authorization_token\":true}\n") + wantBody := []byte("{\"authorization_header\":\"\"}\n") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) @@ -267,11 +267,12 @@ func TestWebhooks_Update_ClearWebhookAuthorizationToken(t *testing.T) { client, err := NewClient(WithBaseURL(ts.URL)) c.Assert(err, qt.IsNil) + empty := "" webhook, err := client.Webhooks.Update(context.Background(), &UpdateWebhookRequest{ - Organization: testOrg, - Database: testDatabase, - ID: "webhook-123", - ClearWebhookAuthorizationToken: true, + Organization: testOrg, + Database: testDatabase, + ID: "webhook-123", + AuthorizationHeader: &empty, }) c.Assert(err, qt.IsNil)