code.gitea.io/gitea@v1.22.3/routers/api/v1/repo/status.go (about)

     1  // Copyright 2017 Gitea. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package repo
     5  
     6  import (
     7  	"fmt"
     8  	"net/http"
     9  
    10  	"code.gitea.io/gitea/models/db"
    11  	git_model "code.gitea.io/gitea/models/git"
    12  	api "code.gitea.io/gitea/modules/structs"
    13  	"code.gitea.io/gitea/modules/web"
    14  	"code.gitea.io/gitea/routers/api/v1/utils"
    15  	"code.gitea.io/gitea/services/context"
    16  	"code.gitea.io/gitea/services/convert"
    17  	commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
    18  )
    19  
    20  // NewCommitStatus creates a new CommitStatus
    21  func NewCommitStatus(ctx *context.APIContext) {
    22  	// swagger:operation POST /repos/{owner}/{repo}/statuses/{sha} repository repoCreateStatus
    23  	// ---
    24  	// summary: Create a commit status
    25  	// produces:
    26  	// - application/json
    27  	// parameters:
    28  	// - name: owner
    29  	//   in: path
    30  	//   description: owner of the repo
    31  	//   type: string
    32  	//   required: true
    33  	// - name: repo
    34  	//   in: path
    35  	//   description: name of the repo
    36  	//   type: string
    37  	//   required: true
    38  	// - name: sha
    39  	//   in: path
    40  	//   description: sha of the commit
    41  	//   type: string
    42  	//   required: true
    43  	// - name: body
    44  	//   in: body
    45  	//   schema:
    46  	//     "$ref": "#/definitions/CreateStatusOption"
    47  	// responses:
    48  	//   "201":
    49  	//     "$ref": "#/responses/CommitStatus"
    50  	//   "400":
    51  	//     "$ref": "#/responses/error"
    52  	//   "404":
    53  	//     "$ref": "#/responses/notFound"
    54  
    55  	form := web.GetForm(ctx).(*api.CreateStatusOption)
    56  	sha := ctx.Params("sha")
    57  	if len(sha) == 0 {
    58  		ctx.Error(http.StatusBadRequest, "sha not given", nil)
    59  		return
    60  	}
    61  	status := &git_model.CommitStatus{
    62  		State:       form.State,
    63  		TargetURL:   form.TargetURL,
    64  		Description: form.Description,
    65  		Context:     form.Context,
    66  	}
    67  	if err := commitstatus_service.CreateCommitStatus(ctx, ctx.Repo.Repository, ctx.Doer, sha, status); err != nil {
    68  		ctx.Error(http.StatusInternalServerError, "CreateCommitStatus", err)
    69  		return
    70  	}
    71  
    72  	ctx.JSON(http.StatusCreated, convert.ToCommitStatus(ctx, status))
    73  }
    74  
    75  // GetCommitStatuses returns all statuses for any given commit hash
    76  func GetCommitStatuses(ctx *context.APIContext) {
    77  	// swagger:operation GET /repos/{owner}/{repo}/statuses/{sha} repository repoListStatuses
    78  	// ---
    79  	// summary: Get a commit's statuses
    80  	// produces:
    81  	// - application/json
    82  	// parameters:
    83  	// - name: owner
    84  	//   in: path
    85  	//   description: owner of the repo
    86  	//   type: string
    87  	//   required: true
    88  	// - name: repo
    89  	//   in: path
    90  	//   description: name of the repo
    91  	//   type: string
    92  	//   required: true
    93  	// - name: sha
    94  	//   in: path
    95  	//   description: sha of the commit
    96  	//   type: string
    97  	//   required: true
    98  	// - name: sort
    99  	//   in: query
   100  	//   description: type of sort
   101  	//   type: string
   102  	//   enum: [oldest, recentupdate, leastupdate, leastindex, highestindex]
   103  	//   required: false
   104  	// - name: state
   105  	//   in: query
   106  	//   description: type of state
   107  	//   type: string
   108  	//   enum: [pending, success, error, failure, warning]
   109  	//   required: false
   110  	// - name: page
   111  	//   in: query
   112  	//   description: page number of results to return (1-based)
   113  	//   type: integer
   114  	// - name: limit
   115  	//   in: query
   116  	//   description: page size of results
   117  	//   type: integer
   118  	// responses:
   119  	//   "200":
   120  	//     "$ref": "#/responses/CommitStatusList"
   121  	//   "400":
   122  	//     "$ref": "#/responses/error"
   123  	//   "404":
   124  	//     "$ref": "#/responses/notFound"
   125  
   126  	getCommitStatuses(ctx, ctx.Params("sha"))
   127  }
   128  
   129  // GetCommitStatusesByRef returns all statuses for any given commit ref
   130  func GetCommitStatusesByRef(ctx *context.APIContext) {
   131  	// swagger:operation GET /repos/{owner}/{repo}/commits/{ref}/statuses repository repoListStatusesByRef
   132  	// ---
   133  	// summary: Get a commit's statuses, by branch/tag/commit reference
   134  	// produces:
   135  	// - application/json
   136  	// parameters:
   137  	// - name: owner
   138  	//   in: path
   139  	//   description: owner of the repo
   140  	//   type: string
   141  	//   required: true
   142  	// - name: repo
   143  	//   in: path
   144  	//   description: name of the repo
   145  	//   type: string
   146  	//   required: true
   147  	// - name: ref
   148  	//   in: path
   149  	//   description: name of branch/tag/commit
   150  	//   type: string
   151  	//   required: true
   152  	// - name: sort
   153  	//   in: query
   154  	//   description: type of sort
   155  	//   type: string
   156  	//   enum: [oldest, recentupdate, leastupdate, leastindex, highestindex]
   157  	//   required: false
   158  	// - name: state
   159  	//   in: query
   160  	//   description: type of state
   161  	//   type: string
   162  	//   enum: [pending, success, error, failure, warning]
   163  	//   required: false
   164  	// - name: page
   165  	//   in: query
   166  	//   description: page number of results to return (1-based)
   167  	//   type: integer
   168  	// - name: limit
   169  	//   in: query
   170  	//   description: page size of results
   171  	//   type: integer
   172  	// responses:
   173  	//   "200":
   174  	//     "$ref": "#/responses/CommitStatusList"
   175  	//   "400":
   176  	//     "$ref": "#/responses/error"
   177  	//   "404":
   178  	//     "$ref": "#/responses/notFound"
   179  
   180  	filter := utils.ResolveRefOrSha(ctx, ctx.Params("ref"))
   181  	if ctx.Written() {
   182  		return
   183  	}
   184  
   185  	getCommitStatuses(ctx, filter) // By default filter is maybe the raw SHA
   186  }
   187  
   188  func getCommitStatuses(ctx *context.APIContext, sha string) {
   189  	if len(sha) == 0 {
   190  		ctx.Error(http.StatusBadRequest, "ref/sha not given", nil)
   191  		return
   192  	}
   193  	sha = utils.MustConvertToSHA1(ctx.Base, ctx.Repo, sha)
   194  	repo := ctx.Repo.Repository
   195  
   196  	listOptions := utils.GetListOptions(ctx)
   197  
   198  	statuses, maxResults, err := db.FindAndCount[git_model.CommitStatus](ctx, &git_model.CommitStatusOptions{
   199  		ListOptions: listOptions,
   200  		RepoID:      repo.ID,
   201  		SHA:         sha,
   202  		SortType:    ctx.FormTrim("sort"),
   203  		State:       ctx.FormTrim("state"),
   204  	})
   205  	if err != nil {
   206  		ctx.Error(http.StatusInternalServerError, "GetCommitStatuses", fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %w", repo.FullName(), sha, ctx.FormInt("page"), err))
   207  		return
   208  	}
   209  
   210  	apiStatuses := make([]*api.CommitStatus, 0, len(statuses))
   211  	for _, status := range statuses {
   212  		apiStatuses = append(apiStatuses, convert.ToCommitStatus(ctx, status))
   213  	}
   214  
   215  	ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
   216  	ctx.SetTotalCountHeader(maxResults)
   217  
   218  	ctx.JSON(http.StatusOK, apiStatuses)
   219  }
   220  
   221  // GetCombinedCommitStatusByRef returns the combined status for any given commit hash
   222  func GetCombinedCommitStatusByRef(ctx *context.APIContext) {
   223  	// swagger:operation GET /repos/{owner}/{repo}/commits/{ref}/status repository repoGetCombinedStatusByRef
   224  	// ---
   225  	// summary: Get a commit's combined status, by branch/tag/commit reference
   226  	// produces:
   227  	// - application/json
   228  	// parameters:
   229  	// - name: owner
   230  	//   in: path
   231  	//   description: owner of the repo
   232  	//   type: string
   233  	//   required: true
   234  	// - name: repo
   235  	//   in: path
   236  	//   description: name of the repo
   237  	//   type: string
   238  	//   required: true
   239  	// - name: ref
   240  	//   in: path
   241  	//   description: name of branch/tag/commit
   242  	//   type: string
   243  	//   required: true
   244  	// - name: page
   245  	//   in: query
   246  	//   description: page number of results to return (1-based)
   247  	//   type: integer
   248  	// - name: limit
   249  	//   in: query
   250  	//   description: page size of results
   251  	//   type: integer
   252  	// responses:
   253  	//   "200":
   254  	//     "$ref": "#/responses/CombinedStatus"
   255  	//   "400":
   256  	//     "$ref": "#/responses/error"
   257  	//   "404":
   258  	//     "$ref": "#/responses/notFound"
   259  
   260  	sha := utils.ResolveRefOrSha(ctx, ctx.Params("ref"))
   261  	if ctx.Written() {
   262  		return
   263  	}
   264  
   265  	repo := ctx.Repo.Repository
   266  
   267  	statuses, count, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, utils.GetListOptions(ctx))
   268  	if err != nil {
   269  		ctx.Error(http.StatusInternalServerError, "GetLatestCommitStatus", fmt.Errorf("GetLatestCommitStatus[%s, %s]: %w", repo.FullName(), sha, err))
   270  		return
   271  	}
   272  
   273  	if len(statuses) == 0 {
   274  		ctx.JSON(http.StatusOK, &api.CombinedStatus{})
   275  		return
   276  	}
   277  
   278  	combiStatus := convert.ToCombinedStatus(ctx, statuses, convert.ToRepo(ctx, repo, ctx.Repo.Permission))
   279  
   280  	ctx.SetTotalCountHeader(count)
   281  	ctx.JSON(http.StatusOK, combiStatus)
   282  }