mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-11-01 06:51:18 +00:00
[GITEA] Add Upload URL to release API
- Resolves https://codeberg.org/forgejo/forgejo/issues/580 - Return a `upload_field` to any release API response, which points to the API URL for uploading new assets. - Adds unit test. - Adds integration testing to verify URL is returned correctly and that upload endpoint actually works (cherry picked from commit074413a2dc) (cherry picked from commit33feed4723) (cherry picked from commit1ca21b95ff) (cherry picked from commit874f07cec2) (cherry picked from commita78c538d8e) (cherry picked from commitbef38ce382)
This commit is contained in:
parent
46e31009a8
commit
c8eb345354
6 changed files with 79 additions and 0 deletions
|
|
@ -133,6 +133,11 @@ func (r *Release) HTMLURL() string {
|
|||
return r.Repo.HTMLURL() + "/releases/tag/" + util.PathEscapeSegments(r.TagName)
|
||||
}
|
||||
|
||||
// APIUploadURL the api url to upload assets to a release. release must have attributes loaded
|
||||
func (r *Release) APIUploadURL() string {
|
||||
return r.APIURL() + "/assets"
|
||||
}
|
||||
|
||||
// Link the relative url for a release on the web UI. release must have attributes loaded
|
||||
func (r *Release) Link() string {
|
||||
return r.Repo.Link() + "/releases/tag/" + util.PathEscapeSegments(r.TagName)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ type Release struct {
|
|||
HTMLURL string `json:"html_url"`
|
||||
TarURL string `json:"tarball_url"`
|
||||
ZipURL string `json:"zipball_url"`
|
||||
UploadURL string `json:"upload_url"`
|
||||
IsDraft bool `json:"draft"`
|
||||
IsPrerelease bool `json:"prerelease"`
|
||||
// swagger:strfmt date-time
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ func ToAPIRelease(ctx context.Context, repo *repo_model.Repository, r *repo_mode
|
|||
HTMLURL: r.HTMLURL(),
|
||||
TarURL: r.TarURL(),
|
||||
ZipURL: r.ZipURL(),
|
||||
UploadURL: r.APIUploadURL(),
|
||||
IsDraft: r.IsDraft,
|
||||
IsPrerelease: r.IsPrerelease,
|
||||
CreatedAt: r.CreatedUnix.AsTime(),
|
||||
|
|
|
|||
28
services/convert/release_test.go
Normal file
28
services/convert/release_test.go
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2023 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package convert
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRelease_ToRelease(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
release1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ID: 1})
|
||||
release1.LoadAttributes(db.DefaultContext)
|
||||
|
||||
apiRelease := ToAPIRelease(db.DefaultContext, repo1, release1)
|
||||
assert.NotNil(t, apiRelease)
|
||||
assert.EqualValues(t, 1, apiRelease.ID)
|
||||
assert.EqualValues(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1", apiRelease.URL)
|
||||
assert.EqualValues(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1/assets", apiRelease.UploadURL)
|
||||
}
|
||||
4
templates/swagger/v1_json.tmpl
generated
4
templates/swagger/v1_json.tmpl
generated
|
|
@ -20886,6 +20886,10 @@
|
|||
"type": "string",
|
||||
"x-go-name": "Target"
|
||||
},
|
||||
"upload_url": {
|
||||
"type": "string",
|
||||
"x-go-name": "UploadURL"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"x-go-name": "URL"
|
||||
|
|
|
|||
|
|
@ -4,9 +4,13 @@
|
|||
package integration
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
|
|
@ -38,12 +42,15 @@ func TestAPIListReleases(t *testing.T) {
|
|||
case 1:
|
||||
assert.False(t, release.IsDraft)
|
||||
assert.False(t, release.IsPrerelease)
|
||||
assert.True(t, strings.HasSuffix(release.UploadURL, "/api/v1/repos/user2/repo1/releases/1/assets"), release.UploadURL)
|
||||
case 4:
|
||||
assert.True(t, release.IsDraft)
|
||||
assert.False(t, release.IsPrerelease)
|
||||
assert.True(t, strings.HasSuffix(release.UploadURL, "/api/v1/repos/user2/repo1/releases/4/assets"), release.UploadURL)
|
||||
case 5:
|
||||
assert.False(t, release.IsDraft)
|
||||
assert.True(t, release.IsPrerelease)
|
||||
assert.True(t, strings.HasSuffix(release.UploadURL, "/api/v1/repos/user2/repo1/releases/5/assets"), release.UploadURL)
|
||||
default:
|
||||
assert.NoError(t, fmt.Errorf("unexpected release: %v", release))
|
||||
}
|
||||
|
|
@ -248,3 +255,36 @@ func TestAPIDeleteReleaseByTagName(t *testing.T) {
|
|||
req = NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/tags/release-tag?token=%s", owner.Name, repo.Name, token))
|
||||
_ = MakeRequest(t, req, http.StatusNoContent)
|
||||
}
|
||||
|
||||
func TestAPIUploadAssetRelease(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||
session := loginUser(t, owner.LowerName)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
|
||||
r := createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test")
|
||||
|
||||
filename := "image.png"
|
||||
buff := generateImg()
|
||||
body := &bytes.Buffer{}
|
||||
|
||||
writer := multipart.NewWriter(body)
|
||||
part, err := writer.CreateFormFile("attachment", filename)
|
||||
assert.NoError(t, err)
|
||||
_, err = io.Copy(part, &buff)
|
||||
assert.NoError(t, err)
|
||||
err = writer.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
req := NewRequestWithBody(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets?name=test-asset&token=%s", owner.Name, repo.Name, r.ID, token), body)
|
||||
req.Header.Add("Content-Type", writer.FormDataContentType())
|
||||
resp := MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
var attachment *api.Attachment
|
||||
DecodeJSON(t, resp, &attachment)
|
||||
|
||||
assert.EqualValues(t, "test-asset", attachment.Name)
|
||||
assert.EqualValues(t, 104, attachment.Size)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue