package integrations
import (
+ "fmt"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
)
-func TestAPIReposGetTags(t *testing.T) {
+func TestAPIRepoTags(t *testing.T) {
defer prepareTestEnv(t)()
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
- req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/tags?token="+token, user.Name)
+ repoName := "repo1"
+
+ req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/tags?token=%s", user.Name, repoName, token)
resp := session.MakeRequest(t, req, http.StatusOK)
var tags []*api.Tag
assert.Len(t, tags, 1)
assert.Equal(t, "v1.1", tags[0].Name)
+ assert.Equal(t, "Initial commit", tags[0].Message)
assert.Equal(t, "65f1bf27bc3bf70f64657658635e66094edbcb4d", tags[0].Commit.SHA)
assert.Equal(t, setting.AppURL+"api/v1/repos/user2/repo1/git/commits/65f1bf27bc3bf70f64657658635e66094edbcb4d", tags[0].Commit.URL)
assert.Equal(t, setting.AppURL+"user2/repo1/archive/v1.1.zip", tags[0].ZipballURL)
assert.Equal(t, setting.AppURL+"user2/repo1/archive/v1.1.tar.gz", tags[0].TarballURL)
+
+ newTag := createNewTagUsingAPI(t, session, token, user.Name, repoName, "awesome-tag", "", "nice!\nand some text")
+ resp = session.MakeRequest(t, req, http.StatusOK)
+ DecodeJSON(t, resp, &tags)
+ assert.Len(t, tags, 2)
+ for _, tag := range tags {
+ if tag.Name != "v1.1" {
+ assert.EqualValues(t, newTag.Name, tag.Name)
+ assert.EqualValues(t, newTag.Message, tag.Message)
+ assert.EqualValues(t, "nice!\nand some text", tag.Message)
+ assert.EqualValues(t, newTag.Commit.SHA, tag.Commit.SHA)
+ }
+ }
+}
+
+func createNewTagUsingAPI(t *testing.T, session *TestSession, token string, ownerName, repoName, name, target, msg string) *api.Tag {
+ urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/tags?token=%s", ownerName, repoName, token)
+ req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateTagOption{
+ TagName: name,
+ Message: msg,
+ Target: target,
+ })
+ resp := session.MakeRequest(t, req, http.StatusCreated)
+
+ var respObj api.Tag
+ DecodeJSON(t, resp, &respObj)
+ return &respObj
}
import (
"fmt"
"strconv"
+ "strings"
"time"
"code.gitea.io/gitea/models"
func ToTag(repo *models.Repository, t *git.Tag) *api.Tag {
return &api.Tag{
Name: t.Name,
+ Message: strings.TrimSpace(t.Message),
ID: t.ID.String(),
Commit: ToCommitMeta(repo, t),
ZipballURL: util.URLJoin(repo.HTMLURL(), "archive", t.Name+".zip"),
// Tag represents a repository tag
type Tag struct {
Name string `json:"name"`
+ Message string `json:"message"`
ID string `json:"id"`
Commit *CommitMeta `json:"commit"`
ZipballURL string `json:"zipball_url"`
URL string `json:"url"`
SHA string `json:"sha"`
}
+
+// CreateTagOption options when creating a tag
+type CreateTagOption struct {
+ // required: true
+ TagName string `json:"tag_name" binding:"Required"`
+ Message string `json:"message"`
+ Target string `json:"target"`
+}
}, reqToken(), reqAdmin())
m.Group("/tags", func() {
m.Get("", repo.ListTags)
+ m.Post("", reqRepoWriter(models.UnitTypeCode), bind(api.CreateTagOption{}), repo.CreateTag)
m.Delete("/{tag}", repo.DeleteTag)
}, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(true))
m.Group("/keys", func() {
import (
"errors"
+ "fmt"
"net/http"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert"
api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
releaseservice "code.gitea.io/gitea/services/release"
)
ctx.Status(http.StatusNoContent)
}
+
+// CreateTag create a new git tag in a repository
+func CreateTag(ctx *context.APIContext) {
+ // swagger:operation POST /repos/{owner}/{repo}/tags repository repoCreateTag
+ // ---
+ // summary: Create a new git tag in a repository
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: body
+ // in: body
+ // schema:
+ // "$ref": "#/definitions/CreateTagOption"
+ // responses:
+ // "200":
+ // "$ref": "#/responses/AnnotatedTag"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "409":
+ // "$ref": "#/responses/conflict"
+ form := web.GetForm(ctx).(*api.CreateTagOption)
+
+ // If target is not provided use default branch
+ if len(form.Target) == 0 {
+ form.Target = ctx.Repo.Repository.DefaultBranch
+ }
+
+ commit, err := ctx.Repo.GitRepo.GetCommit(form.Target)
+ if err != nil {
+ ctx.Error(http.StatusNotFound, "target not found", fmt.Errorf("target not found: %v", err))
+ return
+ }
+
+ if err := releaseservice.CreateNewTag(ctx.User, ctx.Repo.Repository, commit.ID.String(), form.TagName, form.Message); err != nil {
+ if models.IsErrTagAlreadyExists(err) {
+ ctx.Error(http.StatusConflict, "tag exist", err)
+ return
+ }
+ ctx.InternalServerError(err)
+ return
+ }
+
+ tag, err := ctx.Repo.GitRepo.GetTag(form.TagName)
+ if err != nil {
+ ctx.InternalServerError(err)
+ return
+ }
+ ctx.JSON(http.StatusCreated, convert.ToTag(ctx.Repo.Repository, tag))
+}
// in:body
PullReviewRequestOptions api.PullReviewRequestOptions
+
+ // in:body
+ CreateTagOption api.CreateTagOption
}
"$ref": "#/responses/TagList"
}
}
+ },
+ "post": {
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "repository"
+ ],
+ "summary": "Create a new git tag in a repository",
+ "operationId": "repoCreateTag",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "owner of the repo",
+ "name": "owner",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "name of the repo",
+ "name": "repo",
+ "in": "path",
+ "required": true
+ },
+ {
+ "name": "body",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/CreateTagOption"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/AnnotatedTag"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ },
+ "409": {
+ "$ref": "#/responses/conflict"
+ }
+ }
}
},
"/repos/{owner}/{repo}/tags/{tag}": {
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
+ "CreateTagOption": {
+ "description": "CreateTagOption options when creating a tag",
+ "type": "object",
+ "required": [
+ "tag_name"
+ ],
+ "properties": {
+ "message": {
+ "type": "string",
+ "x-go-name": "Message"
+ },
+ "tag_name": {
+ "type": "string",
+ "x-go-name": "TagName"
+ },
+ "target": {
+ "type": "string",
+ "x-go-name": "Target"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
"CreateTeamOption": {
"description": "CreateTeamOption options for creating a team",
"type": "object",
"type": "string",
"x-go-name": "ID"
},
+ "message": {
+ "type": "string",
+ "x-go-name": "Message"
+ },
"name": {
"type": "string",
"x-go-name": "Name"
"parameterBodies": {
"description": "parameterBodies",
"schema": {
- "$ref": "#/definitions/PullReviewRequestOptions"
+ "$ref": "#/definitions/CreateTagOption"
}
},
"redirect": {