Repository: cloudflare/cloudflare-go
Pull request #1177 (2023-01-12 16:55:50)

Add support for compatibility date and flags
## Description

This PR adds support for the compatibility_date and compatibility_flags options when uploading a worker script.
https://developers.cloudflare.com/workers/platform/compatibility-dates/

## Has your change been tested?

* test included

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [x] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [x] This change is using publicly documented (api.cloudflare.com or developers.cloudflare.com) and stable APIs.

/fyi @GustavoCaso - attempting to get https://github.com/Shopify/cloudflare-go/pull/13 upstreamed


Patch:
diff --git a/.changelog/1177.txt b/.changelog/1177.txt
new file mode 100644
index 000000000..bb9f8d81e
--- /dev/null
+++ b/.changelog/1177.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+workers: Add support for compatibility_date and compatibility_flags when upoading a worker script
+```
diff --git a/workers.go b/workers.go
index b834c58b1..0a983bdc3 100644
--- a/workers.go
+++ b/workers.go
@@ -35,6 +35,16 @@ type CreateWorkerParams struct {
 	// Bindings should be a map where the keys are the binding name, and the
 	// values are the binding content
 	Bindings map[string]WorkerBinding
+
+	// CompatibilityDate is a date in the form yyyy-mm-dd,
+	// which will be used to determine which version of the Workers runtime is used.
+	//  https://developers.cloudflare.com/workers/platform/compatibility-dates/
+	CompatibilityDate string
+
+	// CompatibilityFlags are the names of features of the Workers runtime to be enabled or disabled,
+	// usually used together with CompatibilityDate.
+	//  https://developers.cloudflare.com/workers/platform/compatibility-dates/#compatibility-flags
+	CompatibilityFlags []string
 }
 
 // WorkerScriptParams provides a worker script and the associated bindings.
@@ -224,7 +234,7 @@ func (api *API) UploadWorker(ctx context.Context, rc *ResourceContainer, params
 		err         error
 	)
 
-	if params.Module || params.Logpush != nil || len(params.Bindings) > 0 {
+	if params.Module || params.Logpush != nil || len(params.Bindings) > 0 || params.CompatibilityDate != "" || len(params.CompatibilityFlags) > 0 {
 		contentType, body, err = formatMultipartBody(params)
 		if err != nil {
 			return WorkerScriptResponse{}, err
@@ -258,13 +268,17 @@ func formatMultipartBody(params CreateWorkerParams) (string, []byte, error) {
 	// Write metadata part
 	var scriptPartName string
 	meta := struct {
-		BodyPart   string              `json:"body_part,omitempty"`
-		MainModule string              `json:"main_module,omitempty"`
-		Bindings   []workerBindingMeta `json:"bindings"`
-		Logpush    *bool               `json:"logpush,omitempty"`
+		BodyPart           string              `json:"body_part,omitempty"`
+		MainModule         string              `json:"main_module,omitempty"`
+		Bindings           []workerBindingMeta `json:"bindings"`
+		Logpush            *bool               `json:"logpush,omitempty"`
+		CompatibilityDate  string              `json:"compatibility_date,omitempty"`
+		CompatibilityFlags []string            `json:"compatibility_flags,omitempty"`
 	}{
-		Bindings: make([]workerBindingMeta, 0, len(params.Bindings)),
-		Logpush:  params.Logpush,
+		Bindings:           make([]workerBindingMeta, 0, len(params.Bindings)),
+		Logpush:            params.Logpush,
+		CompatibilityDate:  params.CompatibilityDate,
+		CompatibilityFlags: params.CompatibilityFlags,
 	}
 
 	if params.Module {


Test patch:
diff --git a/workers_test.go b/workers_test.go
index c76b7d053..b9b7fc2d6 100644
--- a/workers_test.go
+++ b/workers_test.go
@@ -275,9 +275,11 @@ func getFileDetails(r *http.Request, key string) (*multipart.FileHeader, error)
 }
 
 type multipartUpload struct {
-	Script      string
-	BindingMeta map[string]workerBindingMeta
-	Logpush     *bool
+	Script             string
+	BindingMeta        map[string]workerBindingMeta
+	Logpush            *bool
+	CompatibilityDate  string
+	CompatibilityFlags []string
 }
 
 func parseMultipartUpload(r *http.Request) (multipartUpload, error) {
@@ -288,10 +290,12 @@ func parseMultipartUpload(r *http.Request) (multipartUpload, error) {
 	}
 
 	var metadata struct {
-		BodyPart   string              `json:"body_part,omitempty"`
-		MainModule string              `json:"main_module,omitempty"`
-		Bindings   []workerBindingMeta `json:"bindings"`
-		Logpush    *bool               `json:"logpush,omitempty"`
+		BodyPart           string              `json:"body_part,omitempty"`
+		MainModule         string              `json:"main_module,omitempty"`
+		Bindings           []workerBindingMeta `json:"bindings"`
+		Logpush            *bool               `json:"logpush,omitempty"`
+		CompatibilityDate  string              `json:"compatibility_date,omitempty"`
+		CompatibilityFlags []string            `json:"compatibility_flags,omitempty"`
 	}
 	err = json.Unmarshal(mdBytes, &metadata)
 	if err != nil {
@@ -318,9 +322,11 @@ func parseMultipartUpload(r *http.Request) (multipartUpload, error) {
 	}
 
 	return multipartUpload{
-		Script:      string(script),
-		BindingMeta: bindingMeta,
-		Logpush:     metadata.Logpush,
+		Script:             string(script),
+		BindingMeta:        bindingMeta,
+		Logpush:            metadata.Logpush,
+		CompatibilityDate:  metadata.CompatibilityDate,
+		CompatibilityFlags: metadata.CompatibilityFlags,
 	}, nil
 }
 
@@ -859,3 +865,34 @@ func TestUploadWorker_WithLogpush(t *testing.T) {
 		assert.Equal(t, want, res)
 	}
 }
+
+func TestUploadWorker_WithCompatibilityFlags(t *testing.T) {
+	setup()
+	defer teardown()
+
+	compatibilityDate := time.Now().Format("2006-01-02")
+	compatibilityFlags := []string{"formdata_parser_supports_files"}
+
+	handler := func(w http.ResponseWriter, r *http.Request) {
+		assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method)
+
+		mpUpload, err := parseMultipartUpload(r)
+		assert.NoError(t, err)
+
+		assert.Equal(t, workerScript, mpUpload.Script)
+		assert.Equal(t, compatibilityDate, mpUpload.CompatibilityDate)
+		assert.Equal(t, compatibilityFlags, mpUpload.CompatibilityFlags)
+
+		w.Header().Set("content-type", "application/json")
+		fmt.Fprint(w, uploadWorkerResponseData)
+	}
+	mux.HandleFunc("/accounts/"+testAccountID+"/workers/scripts/bar", handler)
+
+	_, err := client.UploadWorker(context.Background(), AccountIdentifier(testAccountID), CreateWorkerParams{
+		ScriptName:         "bar",
+		Script:             workerScript,
+		CompatibilityDate:  compatibilityDate,
+		CompatibilityFlags: compatibilityFlags,
+	})
+	assert.NoError(t, err)
+}