Repository: fsouza/fake-gcs-server
Pull request #1537 (2024-03-14 18:10:28)

build(deps): bump docker/setup-buildx-action from 3.1.0 to 3.2.0
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.1.0 to 3.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/docker/setup-buildx-action/releases">docker/setup-buildx-action's releases</a>.</em></p>
<blockquote>
<h2>v3.2.0</h2>
<ul>
<li>Rename and align config inputs by <a href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a href="https://redirect.github.com/docker/setup-buildx-action/pull/303">docker/setup-buildx-action#303</a>
<ul>
<li><code>config</code> to <code>buildkitd-config</code></li>
<li><code>config-inline</code> to <code>buildkitd-config-inline</code></li>
</ul>
</li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.17.0 to 0.19.0 in <a href="https://redirect.github.com/docker/setup-buildx-action/pull/302">docker/setup-buildx-action#302</a> <a href="https://redirect.github.com/docker/setup-buildx-action/pull/306">docker/setup-buildx-action#306</a></li>
</ul>
<blockquote>
<p>[!NOTE]
<code>config</code> and <code>config-inline</code> input names are deprecated and will be removed in next major release.</p>
</blockquote>
<p><strong>Full Changelog</strong>: <a href="https://github.com/docker/setup-buildx-action/compare/v3.1.0...v3.2.0">https://github.com/docker/setup-buildx-action/compare/v3.1.0...v3.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/docker/setup-buildx-action/commit/2b51285047da1547ffb1b2203d8be4c0af6b1f20"><code>2b51285</code></a> Merge pull request <a href="https://redirect.github.com/docker/setup-buildx-action/issues/306">#306</a> from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a href="https://github.com/docker/setup-buildx-action/commit/0f00370563710ebfbdf4287b76a0a5d88864e7f9"><code>0f00370</code></a> chore: update generated content</li>
<li><a href="https://github.com/docker/setup-buildx-action/commit/11c9683db9ea73b2090280c1cfa7d725bd8a60fa"><code>11c9683</code></a> build(deps): bump <code>@​docker/actions-toolkit</code> from 0.18.0 to 0.19.0</li>
<li><a href="https://github.com/docker/setup-buildx-action/commit/56a16b8f2aa74bcbd3ab9ec13027cd3ac8e3f94f"><code>56a16b8</code></a> Merge pull request <a href="https://redirect.github.com/docker/setup-buildx-action/issues/303">#303</a> from crazy-max/fix-inputs</li>
<li><a href="https://github.com/docker/setup-buildx-action/commit/c23f46eb919af18b86ac6f0f4646a63a7a452b4d"><code>c23f46e</code></a> chore: update generated content</li>
<li><a href="https://github.com/docker/setup-buildx-action/commit/f876da6242168c5bb185ad517fb42f0b59fba456"><code>f876da6</code></a> rename and align config inputs</li>
<li><a href="https://github.com/docker/setup-buildx-action/commit/b7cf918227e7a90a94eea8534a6b0cc1965a0ccd"><code>b7cf918</code></a> Merge pull request <a href="https://redirect.github.com/docker/setup-buildx-action/issues/304">#304</a> from crazy-max/rm-docs-dir</li>
<li><a href="https://github.com/docker/setup-buildx-action/commit/0150f0ed7a2bf35ffea40dcc932b2241d1989c90"><code>0150f0e</code></a> chore: remove docs dir</li>
<li><a href="https://github.com/docker/setup-buildx-action/commit/d89f1f91164c405e0d6c9fb1787dd217e90bdfab"><code>d89f1f9</code></a> Merge pull request <a href="https://redirect.github.com/docker/setup-buildx-action/issues/302">#302</a> from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a href="https://github.com/docker/setup-buildx-action/commit/12d65f6595845ebd24708c24c4e620cafcea8440"><code>12d65f6</code></a> chore: update generated content</li>
<li>Additional commits viewable in <a href="https://github.com/docker/setup-buildx-action/compare/v3.1.0...v3.2.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=docker/setup-buildx-action&package-manager=github_actions&previous-version=3.1.0&new-version=3.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/.github/workflows/docker-push.yml b/.github/workflows/docker-push.yml
index a5fee7f..e539e13 100644
--- a/.github/workflows/docker-push.yml
+++ b/.github/workflows/docker-push.yml
@@ -29,7 +29,7 @@ jobs:
 
       - name: setup buildx
         id: buildx
-        uses: docker/setup-buildx-action@v3.1.0
+        uses: docker/setup-buildx-action@v3.2.0
 
       - name: login to docker hub
         uses: docker/login-action@v3.1.0
diff --git a/fakestorage/object.go b/fakestorage/object.go
index c7b4095..04f86ae 100644
--- a/fakestorage/object.go
+++ b/fakestorage/object.go
@@ -556,7 +556,7 @@ func (s *Server) listObjects(r *http.Request) jsonResponse {
 	if err != nil {
 		return jsonResponse{status: http.StatusNotFound}
 	}
-	return jsonResponse{data: newListObjectsResponse(objs, prefixes)}
+	return jsonResponse{data: newListObjectsResponse(objs, prefixes, s.externalURL)}
 }
 
 func (s *Server) xmlListObjects(r *http.Request) xmlResponse {
@@ -642,7 +642,7 @@ func (s *Server) getObject(w http.ResponseWriter, r *http.Request) {
 		header.Set("Accept-Ranges", "bytes")
 		return jsonResponse{
 			header: header,
-			data:   newObjectResponse(obj.ObjectAttrs),
+			data:   newObjectResponse(obj.ObjectAttrs, s.externalURL),
 		}
 	})
 
@@ -774,9 +774,9 @@ func (s *Server) rewriteObject(r *http.Request) jsonResponse {
 	defer created.Close()
 
 	if vars["copyType"] == "copyTo" {
-		return jsonResponse{data: newObjectResponse(created.ObjectAttrs)}
+		return jsonResponse{data: newObjectResponse(created.ObjectAttrs, s.externalURL)}
 	}
-	return jsonResponse{data: newObjectRewriteResponse(created.ObjectAttrs)}
+	return jsonResponse{data: newObjectRewriteResponse(created.ObjectAttrs, s.externalURL)}
 }
 
 func (s *Server) downloadObject(w http.ResponseWriter, r *http.Request) {
@@ -1139,5 +1139,5 @@ func (s *Server) composeObject(r *http.Request) jsonResponse {
 
 	s.eventManager.Trigger(&backendObj, notification.EventFinalize, nil)
 
-	return jsonResponse{data: newObjectResponse(obj.ObjectAttrs)}
+	return jsonResponse{data: newObjectResponse(obj.ObjectAttrs, s.externalURL)}
 }
diff --git a/fakestorage/response.go b/fakestorage/response.go
index e28b84e..aff80a2 100644
--- a/fakestorage/response.go
+++ b/fakestorage/response.go
@@ -5,6 +5,8 @@
 package fakestorage
 
 import (
+	"fmt"
+	"net/url"
 	"time"
 
 	"github.com/fsouza/fake-gcs-server/internal/backend"
@@ -66,14 +68,14 @@ func newBucketResponse(bucket backend.Bucket, location string) bucketResponse {
 	}
 }
 
-func newListObjectsResponse(objs []ObjectAttrs, prefixes []string) listResponse {
+func newListObjectsResponse(objs []ObjectAttrs, prefixes []string, externalURL string) listResponse {
 	resp := listResponse{
 		Kind:     "storage#objects",
 		Items:    make([]any, len(objs)),
 		Prefixes: prefixes,
 	}
 	for i, obj := range objs {
-		resp.Items[i] = newObjectResponse(obj)
+		resp.Items[i] = newObjectResponse(obj, externalURL)
 	}
 	return resp
 }
@@ -117,9 +119,12 @@ type objectResponse struct {
 	Generation      int64                  `json:"generation,string"`
 	CustomTime      string                 `json:"customTime,omitempty"`
 	Metadata        map[string]string      `json:"metadata,omitempty"`
+	SelfLink        string                 `json:"selfLink,omitempty"`
+	MediaLink       string                 `json:"mediaLink,omitempty"`
+	Metageneration  string                 `json:"metageneration,omitempty"`
 }
 
-func newObjectResponse(obj ObjectAttrs) objectResponse {
+func newObjectResponse(obj ObjectAttrs, externalURL string) objectResponse {
 	acl := getAccessControlsListFromObject(obj)
 
 	return objectResponse{
@@ -140,6 +145,9 @@ func newObjectResponse(obj ObjectAttrs) objectResponse {
 		Updated:         formatTime(obj.Updated),
 		CustomTime:      formatTime(obj.CustomTime),
 		Generation:      obj.Generation,
+		SelfLink:        fmt.Sprintf("%s/storage/v1/b/%s/o/%s", externalURL, url.PathEscape(obj.BucketName), url.PathEscape(obj.Name)),
+		MediaLink:       fmt.Sprintf("%s/download/storage/v1/b/%s/o/%s?alt=media", externalURL, url.PathEscape(obj.BucketName), url.PathEscape(obj.Name)),
+		Metageneration:  "1",
 	}
 }
 
@@ -176,14 +184,14 @@ type rewriteResponse struct {
 	Resource            objectResponse `json:"resource"`
 }
 
-func newObjectRewriteResponse(obj ObjectAttrs) rewriteResponse {
+func newObjectRewriteResponse(obj ObjectAttrs, externalURL string) rewriteResponse {
 	return rewriteResponse{
 		Kind:                "storage#rewriteResponse",
 		TotalBytesRewritten: obj.Size,
 		ObjectSize:          obj.Size,
 		Done:                true,
 		RewriteToken:        "",
-		Resource:            newObjectResponse(obj),
+		Resource:            newObjectResponse(obj, externalURL),
 	}
 }
 
diff --git a/fakestorage/upload.go b/fakestorage/upload.go
index c85de72..7b53d2b 100644
--- a/fakestorage/upload.go
+++ b/fakestorage/upload.go
@@ -249,7 +249,7 @@ func (s *Server) simpleUpload(bucketName string, r *http.Request) jsonResponse {
 		return errToJsonResponse(err)
 	}
 	obj.Close()
-	return jsonResponse{data: newObjectResponse(obj.ObjectAttrs)}
+	return jsonResponse{data: newObjectResponse(obj.ObjectAttrs, s.externalURL)}
 }
 
 type notImplementedSeeker struct {
@@ -297,7 +297,7 @@ func (s *Server) signedUpload(bucketName string, r *http.Request) jsonResponse {
 		return errToJsonResponse(err)
 	}
 	obj.Close()
-	return jsonResponse{data: newObjectResponse(obj.ObjectAttrs)}
+	return jsonResponse{data: newObjectResponse(obj.ObjectAttrs, s.externalURL)}
 }
 
 func getObjectACL(predefinedACL string) []storage.ACLRule {
@@ -386,7 +386,7 @@ func (s *Server) multipartUpload(bucketName string, r *http.Request) jsonRespons
 		return errToJsonResponse(err)
 	}
 	defer obj.Close()
-	return jsonResponse{data: newObjectResponse(obj.ObjectAttrs)}
+	return jsonResponse{data: newObjectResponse(obj.ObjectAttrs, s.externalURL)}
 }
 
 func parseContentTypeParams(requestContentType string) (map[string]string, error) {
@@ -446,7 +446,7 @@ func (s *Server) resumableUpload(bucketName string, r *http.Request) jsonRespons
 		header.Set("X-Goog-Upload-Status", "active")
 	}
 	return jsonResponse{
-		data:   newObjectResponse(obj.ObjectAttrs),
+		data:   newObjectResponse(obj.ObjectAttrs, s.externalURL),
 		header: header,
 	}
 }
@@ -553,7 +553,7 @@ func (s *Server) uploadFileContent(r *http.Request) jsonResponse {
 	}
 	return jsonResponse{
 		status: status,
-		data:   newObjectResponse(obj.ObjectAttrs),
+		data:   newObjectResponse(obj.ObjectAttrs, s.externalURL),
 		header: responseHeader,
 	}
 }


Test patch:
diff --git a/.github/workflows/docker-tests.yml b/.github/workflows/docker-tests.yml
index 6d8818a..4c19f04 100644
--- a/.github/workflows/docker-tests.yml
+++ b/.github/workflows/docker-tests.yml
@@ -16,7 +16,7 @@ jobs:
 
       - name: setup buildx
         id: buildx
-        uses: docker/setup-buildx-action@v3.1.0
+        uses: docker/setup-buildx-action@v3.2.0
 
       - name: build
         uses: docker/build-push-action@v5.2.0
diff --git a/fakestorage/object_test.go b/fakestorage/object_test.go
index a943bf0..e89a664 100644
--- a/fakestorage/object_test.go
+++ b/fakestorage/object_test.go
@@ -15,6 +15,7 @@ import (
 	"hash/crc32"
 	"io"
 	"net/http"
+	"net/url"
 	"reflect"
 	"testing"
 	"time"
@@ -186,6 +187,14 @@ func checkObjectAttrs(testObj Object, attrs *storage.ObjectAttrs, t *testing.T)
 			t.Errorf("wrong MetaHeader returned\nwant %s\ngot %v", testObj.Metadata["MetaHeader"], val)
 		}
 	}
+	externalURL := "" // We don't set any `externalURL` value during tests.
+	expectedMediaLink := fmt.Sprintf("%s/download/storage/v1/b/%s/o/%s?alt=media", externalURL, url.PathEscape(testObj.BucketName), url.PathEscape(testObj.Name))
+	if attrs.MediaLink != expectedMediaLink {
+		t.Errorf("wrong MediaLink returned\nwant %s\ngot  %s", expectedMediaLink, attrs.MediaLink)
+	}
+	if attrs.Metageneration != 1 {
+		t.Errorf("wrong metageneration\nwant 1\ngot  %d", attrs.Metageneration)
+	}
 }
 
 func TestServerClientObjectAttrs(t *testing.T) {