Add Attachment API (#3478)

* Add Attachment API
* repos/:owner/:repo/releases (add attachments)
* repos/:owner/:repo/releases/:id (add attachments)
* repos/:owner/:repo/releases/:id/attachments
* repos/:owner/:repo/releases/:id/attachments/:attachment_id

Signed-off-by: Jonas Franz <info@jonasfranz.de>

* Add unit tests for new attachment functions
Fix comments

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* fix lint

* Update vendor.json

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* remove version of sdk

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Fix unit tests
Add missing license header

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Add CreateReleaseAttachment
Add EditReleaseAttachment
Add DeleteReleaseAttachment

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Add filename query parameter for choosing another name for an attachment

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Fix order of imports

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Restricting updatable attachment columns

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* gofmt

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Update go-sdk
Replace Attachments with Assets

Signed-off-by: Jonas Franz <info@jonasfranz.de>

* Update go-sdk

Signed-off-by: Jonas Franz <info@jonasfranz.de>

* Updating go-sdk and regenerating swagger

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Add missing file of go-sdk

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Change origin of code.gitea.io/sdk to code.gitea.io/sdk
Update code.gitea.io/sdk

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Update swagger

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Update updateAttachment
This commit is contained in:
Jonas Franz 2018-03-06 02:22:16 +01:00 committed by Bo-Yi Wu
parent 69ea5e4385
commit 9a5e628a7e
30 changed files with 1043 additions and 122 deletions

View file

@ -12,7 +12,7 @@ import (
// CreateUserOption create user options
type CreateUserOption struct {
SourceID int64 `json:"source_id"`
SourceID int64 `json:"source_id"`
LoginName string `json:"login_name"`
// required: true
Username string `json:"username" binding:"Required;AlphaDashDot;MaxSize(35)"`
@ -21,8 +21,8 @@ type CreateUserOption struct {
// swagger:strfmt email
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
// required: true
Password string `json:"password" binding:"Required;MaxSize(255)"`
SendNotify bool `json:"send_notify"`
Password string `json:"password" binding:"Required;MaxSize(255)"`
SendNotify bool `json:"send_notify"`
}
// AdminCreateUser create a user
@ -37,20 +37,20 @@ func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, error) {
// EditUserOption edit user options
type EditUserOption struct {
SourceID int64 `json:"source_id"`
SourceID int64 `json:"source_id"`
LoginName string `json:"login_name"`
FullName string `json:"full_name" binding:"MaxSize(100)"`
FullName string `json:"full_name" binding:"MaxSize(100)"`
// required: true
// swagger:strfmt email
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
Password string `json:"password" binding:"MaxSize(255)"`
Website string `json:"website" binding:"MaxSize(50)"`
Location string `json:"location" binding:"MaxSize(50)"`
Active *bool `json:"active"`
Admin *bool `json:"admin"`
AllowGitHook *bool `json:"allow_git_hook"`
AllowImportLocal *bool `json:"allow_import_local"`
MaxRepoCreation *int `json:"max_repo_creation"`
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
Password string `json:"password" binding:"MaxSize(255)"`
Website string `json:"website" binding:"MaxSize(50)"`
Location string `json:"location" binding:"MaxSize(50)"`
Active *bool `json:"active"`
Admin *bool `json:"admin"`
AllowGitHook *bool `json:"allow_git_hook"`
AllowImportLocal *bool `json:"allow_import_local"`
MaxRepoCreation *int `json:"max_repo_creation"`
}
// AdminEditUser modify user informations

View file

@ -3,15 +3,90 @@
// license that can be found in the LICENSE file.
package gitea // import "code.gitea.io/sdk/gitea"
import "time"
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"time"
)
// Attachment a generic attachment
// swagger:model
type Attachment struct {
ID int64 `json:"id"`
Name string `json:"name"`
Size int64 `json:"size"`
DownloadCount int64 `json:"download_count"`
Created time.Time `json:"created_at"`
UUID string `json:"uuid"`
DownloadURL string `json:"browser_download_url"`
ID int64 `json:"id"`
Name string `json:"name"`
Size int64 `json:"size"`
DownloadCount int64 `json:"download_count"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
UUID string `json:"uuid"`
DownloadURL string `json:"browser_download_url"`
}
// ListReleaseAttachments list release's attachments
func (c *Client) ListReleaseAttachments(user, repo string, release int64) ([]*Attachment, error) {
attachments := make([]*Attachment, 0, 10)
err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases/%d/assets", user, repo, release),
nil, nil, &attachments)
return attachments, err
}
// ListReleaseAttachments list release's attachments
func (c *Client) GetReleaseAttachment(user, repo string, release int64, id int64) (*Attachment, error) {
a := new(Attachment)
err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id),
nil, nil, &a)
return a, err
}
// CreateReleaseAttachment creates an attachment for the given release
func (c *Client) CreateReleaseAttachment(user, repo string, release int64, file io.Reader, filename string) (*Attachment, error) {
// Write file to body
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("attachment", filename)
if err != nil {
return nil, err
}
if _, err = io.Copy(part, file); err != nil {
return nil, err
}
if err = writer.Close(); err != nil {
return nil, err
}
// Send request
attachment := new(Attachment)
err = c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/releases/%d/assets", user, repo, release),
http.Header{"Content-Type": {writer.FormDataContentType()}}, body, &attachment)
return attachment, err
}
// EditReleaseAttachment updates the given attachment with the given options
func (c *Client) EditReleaseAttachment(user, repo string, release int64, attachment int64, form EditAttachmentOptions) (*Attachment, error) {
body, err := json.Marshal(&form)
if err != nil {
return nil, err
}
attach := new(Attachment)
return attach, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, attachment), jsonHeader, bytes.NewReader(body), attach)
}
// DeleteReleaseAttachment deletes the given attachment including the uploaded file
func (c *Client) DeleteReleaseAttachment(user, repo string, release int64, id int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id), nil, nil)
return err
}
// EditAttachmentOptions options for editing attachments
// swagger:model
type EditAttachmentOptions struct {
Name string `json:"name"`
}

View file

@ -7,6 +7,7 @@ package gitea
import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
@ -69,6 +70,8 @@ func (c *Client) getResponse(method, path string, header http.Header, body io.Re
return nil, errors.New("403 Forbidden")
case 404:
return nil, errors.New("404 Not Found")
case 422:
return nil, fmt.Errorf("422 Unprocessable Entity: %s", string(data))
}
if resp.StatusCode/100 != 2 {

View file

@ -21,16 +21,16 @@ var (
// Hook a hook is a web hook when one repository changed
type Hook struct {
ID int64 `json:"id"`
Type string `json:"type"`
URL string `json:"-"`
Config map[string]string `json:"config"`
Events []string `json:"events"`
Active bool `json:"active"`
ID int64 `json:"id"`
Type string `json:"type"`
URL string `json:"-"`
Config map[string]string `json:"config"`
Events []string `json:"events"`
Active bool `json:"active"`
// swagger:strfmt date-time
Updated time.Time `json:"updated_at"`
Updated time.Time `json:"updated_at"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
Created time.Time `json:"created_at"`
}
// HookList represents a list of API hook.
@ -67,7 +67,7 @@ type CreateHookOption struct {
Type string `json:"type" binding:"Required"`
// required: true
Config map[string]string `json:"config" binding:"Required"`
Events []string `json:"events"`
Events []string `json:"events"`
// default: false
Active bool `json:"active"`
}
@ -95,8 +95,8 @@ func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook,
// EditHookOption options when modify one hook
type EditHookOption struct {
Config map[string]string `json:"config"`
Events []string `json:"events"`
Active *bool `json:"active"`
Events []string `json:"events"`
Active *bool `json:"active"`
}
// EditOrgHook modify one hook of an organization, with hook id and options
@ -140,7 +140,7 @@ type Payloader interface {
// PayloadUser represents the author or committer of a commit
type PayloadUser struct {
// Full name of the commit author
Name string `json:"name"`
Name string `json:"name"`
// swagger:strfmt email
Email string `json:"email"`
UserName string `json:"username"`
@ -159,7 +159,7 @@ type PayloadCommit struct {
Committer *PayloadUser `json:"committer"`
Verification *PayloadCommitVerification `json:"verification"`
// swagger:strfmt date-time
Timestamp time.Time `json:"timestamp"`
Timestamp time.Time `json:"timestamp"`
}
// PayloadCommitVerification represents the GPG verification of a commit

View file

@ -43,12 +43,12 @@ type Issue struct {
//
// type: string
// enum: open,closed
State StateType `json:"state"`
Comments int `json:"comments"`
State StateType `json:"state"`
Comments int `json:"comments"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
Created time.Time `json:"created_at"`
// swagger:strfmt date-time
Updated time.Time `json:"updated_at"`
Updated time.Time `json:"updated_at"`
PullRequest *PullRequestMeta `json:"pull_request"`
}
@ -86,15 +86,15 @@ func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, error) {
// CreateIssueOption options to create one issue
type CreateIssueOption struct {
// required:true
Title string `json:"title" binding:"Required"`
Body string `json:"body"`
Title string `json:"title" binding:"Required"`
Body string `json:"body"`
// username of assignee
Assignee string `json:"assignee"`
Assignee string `json:"assignee"`
// milestone id
Milestone int64 `json:"milestone"`
Milestone int64 `json:"milestone"`
// list of label ids
Labels []int64 `json:"labels"`
Closed bool `json:"closed"`
Labels []int64 `json:"labels"`
Closed bool `json:"closed"`
}
// CreateIssue create a new issue for a given repository

View file

@ -13,16 +13,16 @@ import (
// Comment represents a comment on a commit or issue
type Comment struct {
ID int64 `json:"id"`
HTMLURL string `json:"html_url"`
PRURL string `json:"pull_request_url"`
IssueURL string `json:"issue_url"`
Poster *User `json:"user"`
Body string `json:"body"`
ID int64 `json:"id"`
HTMLURL string `json:"html_url"`
PRURL string `json:"pull_request_url"`
IssueURL string `json:"issue_url"`
Poster *User `json:"user"`
Body string `json:"body"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
Created time.Time `json:"created_at"`
// swagger:strfmt date-time
Updated time.Time `json:"updated_at"`
Updated time.Time `json:"updated_at"`
}
// ListIssueComments list comments on an issue.

View file

@ -13,8 +13,8 @@ import (
// Label a label to an issue or a pr
// swagger:model
type Label struct {
ID int64 `json:"id"`
Name string `json:"name"`
ID int64 `json:"id"`
Name string `json:"name"`
// example: 00aabb
Color string `json:"color"`
URL string `json:"url"`
@ -36,7 +36,7 @@ func (c *Client) GetRepoLabel(owner, repo string, id int64) (*Label, error) {
// CreateLabelOption options for creating a label
type CreateLabelOption struct {
// required:true
Name string `json:"name" binding:"Required"`
Name string `json:"name" binding:"Required"`
// required:true
// example: #00aabb
Color string `json:"color" binding:"Required;Size(7)"`

View file

@ -13,16 +13,16 @@ import (
// Milestone milestone is a collection of issues on one repository
type Milestone struct {
ID int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
State StateType `json:"state"`
OpenIssues int `json:"open_issues"`
ClosedIssues int `json:"closed_issues"`
ID int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
State StateType `json:"state"`
OpenIssues int `json:"open_issues"`
ClosedIssues int `json:"closed_issues"`
// swagger:strfmt date-time
Closed *time.Time `json:"closed_at"`
Closed *time.Time `json:"closed_at"`
// swagger:strfmt date-time
Deadline *time.Time `json:"due_on"`
Deadline *time.Time `json:"due_on"`
}
// ListRepoMilestones list all the milestones of one repository
@ -39,10 +39,10 @@ func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, error)
// CreateMilestoneOption options for creating a milestone
type CreateMilestoneOption struct {
Title string `json:"title"`
Description string `json:"description"`
Title string `json:"title"`
Description string `json:"description"`
// swagger:strfmt date-time
Deadline *time.Time `json:"due_on"`
Deadline *time.Time `json:"due_on"`
}
// CreateMilestone create one milestone with options

View file

@ -13,7 +13,7 @@ import (
// TrackedTime worked time for an issue / pr
type TrackedTime struct {
ID int64 `json:"id"`
ID int64 `json:"id"`
// swagger:strfmt date-time
Created time.Time `json:"created"`
// Time in seconds

View file

@ -42,11 +42,11 @@ func (c *Client) GetOrg(orgname string) (*Organization, error) {
// CreateOrgOption options for creating an organization
type CreateOrgOption struct {
// required: true
UserName string `json:"username" binding:"Required"`
FullName string `json:"full_name"`
UserName string `json:"username" binding:"Required"`
FullName string `json:"full_name"`
Description string `json:"description"`
Website string `json:"website"`
Location string `json:"location"`
Website string `json:"website"`
Location string `json:"location"`
}
// EditOrgOption options for editing an organization

View file

@ -10,7 +10,7 @@ type Team struct {
Name string `json:"name"`
Description string `json:"description"`
// enum: none,read,write,admin,owner
Permission string `json:"permission"`
Permission string `json:"permission"`
}
// CreateTeamOption options for creating a team
@ -19,7 +19,7 @@ type CreateTeamOption struct {
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `json:"description" binding:"MaxSize(255)"`
// enum: read,write,admin
Permission string `json:"permission"`
Permission string `json:"permission"`
}
// EditTeamOption options for editing a team
@ -28,5 +28,5 @@ type EditTeamOption struct {
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `json:"description" binding:"MaxSize(255)"`
// enum: read,write,admin
Permission string `json:"permission"`
Permission string `json:"permission"`
}

View file

@ -29,8 +29,8 @@ type PullRequest struct {
DiffURL string `json:"diff_url"`
PatchURL string `json:"patch_url"`
Mergeable bool `json:"mergeable"`
HasMerged bool `json:"merged"`
Mergeable bool `json:"mergeable"`
HasMerged bool `json:"merged"`
// swagger:strfmt date-time
Merged *time.Time `json:"merged_at"`
MergedCommitID *string `json:"merge_commit_sha"`

View file

@ -13,21 +13,22 @@ import (
// Release represents a repository release
type Release struct {
ID int64 `json:"id"`
TagName string `json:"tag_name"`
Target string `json:"target_commitish"`
Title string `json:"name"`
Note string `json:"body"`
URL string `json:"url"`
TarURL string `json:"tarball_url"`
ZipURL string `json:"zipball_url"`
IsDraft bool `json:"draft"`
IsPrerelease bool `json:"prerelease"`
ID int64 `json:"id"`
TagName string `json:"tag_name"`
Target string `json:"target_commitish"`
Title string `json:"name"`
Note string `json:"body"`
URL string `json:"url"`
TarURL string `json:"tarball_url"`
ZipURL string `json:"zipball_url"`
IsDraft bool `json:"draft"`
IsPrerelease bool `json:"prerelease"`
// swagger:strfmt date-time
CreatedAt time.Time `json:"created_at"`
CreatedAt time.Time `json:"created_at"`
// swagger:strfmt date-time
PublishedAt time.Time `json:"published_at"`
Publisher *User `json:"author"`
PublishedAt time.Time `json:"published_at"`
Publisher *User `json:"author"`
Attachments []*Attachment `json:"assets"`
}
// ListReleases list releases of a repository

View file

@ -41,10 +41,10 @@ type Repository struct {
OpenIssues int `json:"open_issues_count"`
DefaultBranch string `json:"default_branch"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
Created time.Time `json:"created_at"`
// swagger:strfmt date-time
Updated time.Time `json:"updated_at"`
Permissions *Permission `json:"permissions,omitempty"`
Updated time.Time `json:"updated_at"`
Permissions *Permission `json:"permissions,omitempty"`
}
// ListMyRepos lists all repositories for the authenticated user that has access to.
@ -122,15 +122,15 @@ func (c *Client) DeleteRepo(owner, repo string) error {
// MigrateRepoOption options for migrating a repository from an external service
type MigrateRepoOption struct {
// required: true
CloneAddr string `json:"clone_addr" binding:"Required"`
CloneAddr string `json:"clone_addr" binding:"Required"`
AuthUsername string `json:"auth_username"`
AuthPassword string `json:"auth_password"`
// required: true
UID int `json:"uid" binding:"Required"`
// required: true
RepoName string `json:"repo_name" binding:"Required"`
Mirror bool `json:"mirror"`
Private bool `json:"private"`
RepoName string `json:"repo_name" binding:"Required"`
Mirror bool `json:"mirror"`
Private bool `json:"private"`
Description string `json:"description"`
}

View file

@ -13,10 +13,10 @@ import (
// DeployKey a deploy key
type DeployKey struct {
ID int64 `json:"id"`
Key string `json:"key"`
URL string `json:"url"`
Title string `json:"title"`
ID int64 `json:"id"`
Key string `json:"key"`
URL string `json:"url"`
Title string `json:"title"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
ReadOnly bool `json:"read_only"`

View file

@ -38,9 +38,9 @@ type Status struct {
Context string `json:"context"`
Creator *User `json:"creator"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
Created time.Time `json:"created_at"`
// swagger:strfmt date-time
Updated time.Time `json:"updated_at"`
Updated time.Time `json:"updated_at"`
}
// CombinedStatus holds the combined state of several statuses for a single commit

View file

@ -13,13 +13,13 @@ import (
// swagger:model
type User struct {
// the user's id
ID int64 `json:"id"`
ID int64 `json:"id"`
// the user's username
UserName string `json:"login"`
UserName string `json:"login"`
// the user's full name
FullName string `json:"full_name"`
FullName string `json:"full_name"`
// swagger:strfmt email
Email string `json:"email"`
Email string `json:"email"`
// URL to the user's avatar
AvatarURL string `json:"avatar_url"`
}

View file

@ -24,9 +24,9 @@ type GPGKey struct {
CanEncryptStorage bool `json:"can_encrypt_storage"`
CanCertify bool `json:"can_certify"`
// swagger:strfmt date-time
Created time.Time `json:"created_at,omitempty"`
Created time.Time `json:"created_at,omitempty"`
// swagger:strfmt date-time
Expires time.Time `json:"expires_at,omitempty"`
Expires time.Time `json:"expires_at,omitempty"`
}
// GPGKeyEmail an email attached to a GPGKey

14
vendor/code.gitea.io/sdk/gitea/user_search.go generated vendored Normal file
View file

@ -0,0 +1,14 @@
package gitea
import "fmt"
type searchUsersResponse struct {
Users []*User `json:"data"`
}
// SearchUsers finds users by query
func (c *Client) SearchUsers(query string, limit int) ([]*User, error) {
resp := new(searchUsersResponse)
err := c.getParsedResponse("GET", fmt.Sprintf("/users/search?q=%s&limit=%d", query, limit), nil, nil, &resp)
return resp.Users, err
}

6
vendor/vendor.json vendored
View file

@ -9,10 +9,10 @@
"revisionTime": "2018-02-10T03:05:43Z"
},
{
"checksumSHA1": "Qtq0kW+BnpYMOriaoCjMa86WGG8=",
"checksumSHA1": "PWaIU7g1YSkETxka2DIS1EYsPK0=",
"path": "code.gitea.io/sdk/gitea",
"revision": "79eee8f12c7fc1cc5b802c5cdc5b494ef3733866",
"revisionTime": "2017-12-20T06:57:50Z"
"revision": "cdbef997666132599cc92dc22aa94de3db04adeb",
"revisionTime": "2018-03-02T14:48:43Z"
},
{
"checksumSHA1": "bOODD4Gbw3GfcuQPU2dI40crxxk=",