2014-03-15 15:01:50 +04:00
|
|
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
2020-01-10 00:34:25 +03:00
|
|
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
2022-11-27 21:20:29 +03:00
|
|
|
// SPDX-License-Identifier: MIT
|
2014-03-15 15:01:50 +04:00
|
|
|
|
2016-03-11 19:56:52 +03:00
|
|
|
package context
|
2014-03-15 15:01:50 +04:00
|
|
|
|
|
|
|
import (
|
2021-01-26 18:36:53 +03:00
|
|
|
"context"
|
2016-11-30 00:49:06 +03:00
|
|
|
"html"
|
2014-03-22 21:44:02 +04:00
|
|
|
"html/template"
|
2014-04-15 20:27:29 +04:00
|
|
|
"io"
|
2014-03-15 15:01:50 +04:00
|
|
|
"net/http"
|
2018-03-16 00:13:34 +03:00
|
|
|
"net/url"
|
2014-03-23 00:40:09 +04:00
|
|
|
"strings"
|
2014-03-19 17:57:55 +04:00
|
|
|
"time"
|
2014-03-15 15:01:50 +04:00
|
|
|
|
2021-11-09 22:57:58 +03:00
|
|
|
"code.gitea.io/gitea/models/unit"
|
2021-11-24 12:49:20 +03:00
|
|
|
user_model "code.gitea.io/gitea/models/user"
|
2021-01-27 17:56:54 +03:00
|
|
|
mc "code.gitea.io/gitea/modules/cache"
|
2022-01-20 02:26:57 +03:00
|
|
|
"code.gitea.io/gitea/modules/git"
|
2022-07-23 09:38:03 +03:00
|
|
|
"code.gitea.io/gitea/modules/httpcache"
|
2016-11-10 19:24:48 +03:00
|
|
|
"code.gitea.io/gitea/modules/setting"
|
2021-01-26 18:36:53 +03:00
|
|
|
"code.gitea.io/gitea/modules/templates"
|
|
|
|
"code.gitea.io/gitea/modules/translation"
|
2021-01-30 11:55:53 +03:00
|
|
|
"code.gitea.io/gitea/modules/web/middleware"
|
2019-08-23 19:40:30 +03:00
|
|
|
|
2021-01-26 18:36:53 +03:00
|
|
|
"gitea.com/go-chi/cache"
|
|
|
|
"gitea.com/go-chi/session"
|
2014-03-15 15:01:50 +04:00
|
|
|
)
|
|
|
|
|
2021-01-26 18:36:53 +03:00
|
|
|
// Render represents a template render
|
|
|
|
type Render interface {
|
Make HTML template functions support context (#24056)
# Background
Golang template is not friendly for large projects, and Golang template
team is quite slow, related:
* `https://github.com/golang/go/issues/54450`
Without upstream support, we can also have our solution to make HTML
template functions support context.
It helps a lot, the above Golang template issue `#54450` explains a lot:
1. It makes `{{Locale.Tr}}` could be used in any template, without
passing unclear `(dict "root" . )` anymore.
2. More and more functions need `context`, like `avatar`, etc, we do not
need to do `(dict "Context" $.Context)` anymore.
3. Many request-related functions could be shared by parent&children
templates, like "user setting" / "system setting"
See the test `TestScopedTemplateSetFuncMap`, one template set, two
`Execute` calls with different `CtxFunc`.
# The Solution
Instead of waiting for upstream, this PR re-uses the escaped HTML
template trees, use `AddParseTree` to add related templates/trees to a
new template instance, then the new template instance can have its own
FuncMap , the function calls in the template trees will always use the
new template's FuncMap.
`template.New` / `template.AddParseTree` / `adding-FuncMap` are all
quite fast, so the performance is not affected.
The details:
1. Make a new `html/template/Template` for `all` templates
2. Add template code to the `all` template
3. Freeze the `all` template, reset its exec func map, it shouldn't
execute any template.
4. When a router wants to render a template by its `name`
1. Find the `name` in `all`
2. Find all its related sub templates
3. Escape all related templates (just like what the html template
package does)
4. Add the escaped parse-trees of related templates into a new (scoped)
`text/template/Template`
5. Add context-related func map into the new (scoped) text template
6. Execute the new (scoped) text template
7. To improve performance, the escaped templates are cached to `template
sets`
# FAQ
## There is a `unsafe` call, is this PR unsafe?
This PR is safe. Golang has strict language definition, it's safe to do
so: https://pkg.go.dev/unsafe#Pointer (1) Conversion of a *T1 to Pointer
to *T2
## What if Golang template supports such feature in the future?
The public structs/interfaces/functions introduced by this PR is quite
simple, the code of `HTMLRender` is not changed too much. It's very easy
to switch to the official mechanism if there would be one.
## Does this PR change the template execution behavior?
No, see the tests (welcome to design more tests if it's necessary)
---------
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2023-04-20 11:08:58 +03:00
|
|
|
TemplateLookup(tmpl string) (templates.TemplateExecutor, error)
|
2023-04-08 09:21:50 +03:00
|
|
|
HTML(w io.Writer, status int, name string, data interface{}) error
|
2021-01-26 18:36:53 +03:00
|
|
|
}
|
|
|
|
|
2014-03-15 17:17:16 +04:00
|
|
|
// Context represents context of a request.
|
2014-03-15 15:01:50 +04:00
|
|
|
type Context struct {
|
2021-10-12 21:11:35 +03:00
|
|
|
Resp ResponseWriter
|
|
|
|
Req *http.Request
|
2023-05-04 09:36:34 +03:00
|
|
|
Data middleware.ContextData // data used by MVC templates
|
2023-05-08 12:36:54 +03:00
|
|
|
PageData map[string]any // data used by JavaScript modules in one page, it's `window.config.pageData`
|
2021-10-12 21:11:35 +03:00
|
|
|
Render Render
|
2023-05-08 12:36:54 +03:00
|
|
|
Locale translation.Locale
|
|
|
|
Cache cache.Cache
|
|
|
|
Csrf CSRFProtector
|
|
|
|
Flash *middleware.Flash
|
|
|
|
Session session.Store
|
2014-07-26 08:24:27 +04:00
|
|
|
|
2017-06-26 04:06:40 +03:00
|
|
|
Link string // current request URL
|
2017-11-28 12:43:51 +03:00
|
|
|
EscapedLink string
|
2022-03-22 10:03:22 +03:00
|
|
|
Doer *user_model.User
|
2014-11-18 19:07:16 +03:00
|
|
|
IsSigned bool
|
|
|
|
IsBasicAuth bool
|
2014-03-15 20:03:23 +04:00
|
|
|
|
2022-03-26 12:04:22 +03:00
|
|
|
ContextUser *user_model.User
|
|
|
|
Repo *Repository
|
|
|
|
Org *Organization
|
2022-03-30 11:42:47 +03:00
|
|
|
Package *Package
|
2014-03-15 15:01:50 +04:00
|
|
|
}
|
|
|
|
|
2022-05-05 17:13:23 +03:00
|
|
|
// Close frees all resources hold by Context
|
|
|
|
func (ctx *Context) Close() error {
|
|
|
|
var err error
|
|
|
|
if ctx.Req != nil && ctx.Req.MultipartForm != nil {
|
|
|
|
err = ctx.Req.MultipartForm.RemoveAll() // remove the temp files buffered to tmp directory
|
|
|
|
}
|
|
|
|
// TODO: close opened repo, and more
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-05-08 12:36:54 +03:00
|
|
|
// TrHTMLEscapeArgs runs ".Locale.Tr()" but pre-escapes all arguments with html.EscapeString.
|
2021-11-16 21:18:25 +03:00
|
|
|
// This is useful if the locale message is intended to only produce HTML content.
|
|
|
|
func (ctx *Context) TrHTMLEscapeArgs(msg string, args ...string) string {
|
|
|
|
trArgs := make([]interface{}, len(args))
|
|
|
|
for i, arg := range args {
|
|
|
|
trArgs[i] = html.EscapeString(arg)
|
|
|
|
}
|
2023-05-08 12:36:54 +03:00
|
|
|
return ctx.Locale.Tr(msg, trArgs...)
|
2021-01-24 18:23:05 +03:00
|
|
|
}
|
|
|
|
|
2023-05-08 12:36:54 +03:00
|
|
|
func (ctx *Context) Tr(msg string, args ...any) string {
|
|
|
|
return ctx.Locale.Tr(msg, args...)
|
2018-03-16 00:13:34 +03:00
|
|
|
}
|
|
|
|
|
2023-05-08 12:36:54 +03:00
|
|
|
func (ctx *Context) TrN(cnt any, key1, keyN string, args ...any) string {
|
|
|
|
return ctx.Locale.TrN(cnt, key1, keyN, args...)
|
2021-01-26 18:36:53 +03:00
|
|
|
}
|
|
|
|
|
2021-05-31 09:18:11 +03:00
|
|
|
// Deadline is part of the interface for context.Context and we pass this to the request context
|
|
|
|
func (ctx *Context) Deadline() (deadline time.Time, ok bool) {
|
|
|
|
return ctx.Req.Context().Deadline()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Done is part of the interface for context.Context and we pass this to the request context
|
|
|
|
func (ctx *Context) Done() <-chan struct{} {
|
|
|
|
return ctx.Req.Context().Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Err is part of the interface for context.Context and we pass this to the request context
|
|
|
|
func (ctx *Context) Err() error {
|
|
|
|
return ctx.Req.Context().Err()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Value is part of the interface for context.Context and we pass this to the request context
|
|
|
|
func (ctx *Context) Value(key interface{}) interface{} {
|
2022-01-20 02:26:57 +03:00
|
|
|
if key == git.RepositoryContextKey && ctx.Repo != nil {
|
|
|
|
return ctx.Repo.GitRepo
|
|
|
|
}
|
Append `(comment)` when a link points at a comment rather than the whole issue (#23734)
Close #23671
For the feature mentioned above, this PR append ' (comment)' to the
rendered html if it is a hashcomment.
After the PR, type in the following
```
pull request from other repo:
http://localhost:3000/testOrg/testOrgRepo/pulls/2
pull request from this repo:
http://localhost:3000/aaa/testA/pulls/2
issue comment from this repo:
http://localhost:3000/aaa/testA/issues/1#issuecomment-18
http://localhost:3000/aaa/testA/pulls/2#issue-9
issue comment from other repo:
http://localhost:3000/testOrg/testOrgRepo/pulls/2#issuecomment-24
http://localhost:3000/testOrg/testOrgRepo/pulls/2#issue
```
Gives:
<img width="687" alt="截屏2023-03-27 13 53 06"
src="https://user-images.githubusercontent.com/17645053/227852387-2b218e0d-3468-4d90-ad81-d702ddd17fd2.png">
Other than the above feature, this PR also includes two other changes:
1 Right now, the render of links from file changed tab in pull request
might not be very proper, for example, if type in the following. (not
sure if this is an issue or design, if not an issue, I will revert the
changes). example on
[try.gitea.io](https://try.gitea.io/HesterG/testrepo/pulls/1)
```
https://try.gitea.io/HesterG/testrepo/pulls/1/files#issuecomment-162725
https://try.gitea.io/HesterG/testrepo/pulls/1/files
```
it will render the following
<img width="899" alt="截屏2023-03-24 15 41 37"
src="https://user-images.githubusercontent.com/17645053/227456117-5eccedb7-9118-4540-929d-aee9a76de852.png">
In this PR, skip processing the link into a ref issue if it is a link
from files changed tab in pull request
After:
type in following
```
hash comment on files changed tab:
http://localhost:3000/testOrg/testOrgRepo/pulls/2/files#issuecomment-24
files changed link:
http://localhost:3000/testOrg/testOrgRepo/pulls/2/files
```
Gives
<img width="708" alt="截屏2023-03-27 22 09 02"
src="https://user-images.githubusercontent.com/17645053/227964273-5dc06c50-3713-489c-b05d-d95367d0ab0f.png">
2 Right now, after editing the comment area, there will not be tippys
attached to `ref-issue`; and no tippy attached on preview as well.
example:
https://user-images.githubusercontent.com/17645053/227850540-5ae34e2d-b1d7-4d0d-9726-7701bf825d1f.mov
In this PR, in frontend, make sure tippy is added after editing the
comment, and to the comment on preview tab
After:
https://user-images.githubusercontent.com/17645053/227853777-06f56b4c-1148-467c-b6f7-f79418e67504.mov
2023-04-03 11:02:57 +03:00
|
|
|
if key == translation.ContextKey && ctx.Locale != nil {
|
|
|
|
return ctx.Locale
|
|
|
|
}
|
2021-05-31 09:18:11 +03:00
|
|
|
return ctx.Req.Context().Value(key)
|
|
|
|
}
|
|
|
|
|
2021-12-15 09:59:57 +03:00
|
|
|
type contextKeyType struct{}
|
|
|
|
|
|
|
|
var contextKey interface{} = contextKeyType{}
|
2021-01-26 18:36:53 +03:00
|
|
|
|
|
|
|
// WithContext set up install context in request
|
|
|
|
func WithContext(req *http.Request, ctx *Context) *http.Request {
|
|
|
|
return req.WithContext(context.WithValue(req.Context(), contextKey, ctx))
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetContext retrieves install context from request
|
|
|
|
func GetContext(req *http.Request) *Context {
|
2023-04-13 22:45:33 +03:00
|
|
|
if ctx, ok := req.Context().Value(contextKey).(*Context); ok {
|
|
|
|
return ctx
|
|
|
|
}
|
|
|
|
return nil
|
2021-01-26 18:36:53 +03:00
|
|
|
}
|
|
|
|
|
2023-05-08 12:36:54 +03:00
|
|
|
// Contexter initializes a classic context for a request.
|
|
|
|
func Contexter() func(next http.Handler) http.Handler {
|
|
|
|
rnd := templates.HTMLRenderer()
|
|
|
|
csrfOpts := CsrfOptions{
|
2021-01-26 18:36:53 +03:00
|
|
|
Secret: setting.SecretKey,
|
|
|
|
Cookie: setting.CSRFCookieName,
|
|
|
|
SetCookie: true,
|
|
|
|
Secure: setting.SessionConfig.Secure,
|
|
|
|
CookieHTTPOnly: setting.CSRFCookieHTTPOnly,
|
|
|
|
Header: "X-Csrf-Token",
|
|
|
|
CookieDomain: setting.SessionConfig.Domain,
|
|
|
|
CookiePath: setting.SessionConfig.CookiePath,
|
2021-03-07 11:12:43 +03:00
|
|
|
SameSite: setting.SessionConfig.SameSite,
|
2021-01-26 18:36:53 +03:00
|
|
|
}
|
2022-04-08 08:21:05 +03:00
|
|
|
if !setting.IsProd {
|
|
|
|
CsrfTokenRegenerationInterval = 5 * time.Second // in dev, re-generate the tokens more aggressively for debug purpose
|
|
|
|
}
|
2021-01-26 18:36:53 +03:00
|
|
|
return func(next http.Handler) http.Handler {
|
|
|
|
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
2022-01-20 20:46:10 +03:00
|
|
|
ctx := Context{
|
2021-01-26 18:36:53 +03:00
|
|
|
Resp: NewResponse(resp),
|
2021-01-27 17:56:54 +03:00
|
|
|
Cache: mc.GetCache(),
|
2023-05-04 09:36:34 +03:00
|
|
|
Locale: middleware.Locale(resp, req),
|
|
|
|
Link: setting.AppSubURL + strings.TrimSuffix(req.URL.EscapedPath(), "/"),
|
2021-01-26 18:36:53 +03:00
|
|
|
Render: rnd,
|
|
|
|
Session: session.GetSession(req),
|
|
|
|
Repo: &Repository{
|
|
|
|
PullRequest: &PullRequest{},
|
|
|
|
},
|
2023-05-04 09:36:34 +03:00
|
|
|
Org: &Organization{},
|
|
|
|
Data: middleware.GetContextData(req.Context()),
|
2021-01-26 18:36:53 +03:00
|
|
|
}
|
2022-05-05 17:13:23 +03:00
|
|
|
defer ctx.Close()
|
|
|
|
|
2023-05-04 09:36:34 +03:00
|
|
|
ctx.Data.MergeFrom(middleware.CommonTemplateContextData())
|
|
|
|
ctx.Data["Context"] = &ctx
|
|
|
|
ctx.Data["CurrentURL"] = setting.AppSubURL + req.URL.RequestURI()
|
|
|
|
ctx.Data["Link"] = ctx.Link
|
|
|
|
ctx.Data["locale"] = ctx.Locale
|
|
|
|
|
2021-10-15 05:35:26 +03:00
|
|
|
// PageData is passed by reference, and it will be rendered to `window.config.pageData` in `head.tmpl` for JavaScript modules
|
2023-05-04 09:36:34 +03:00
|
|
|
ctx.PageData = map[string]any{}
|
2021-10-12 21:11:35 +03:00
|
|
|
ctx.Data["PageData"] = ctx.PageData
|
2021-01-26 18:36:53 +03:00
|
|
|
|
|
|
|
ctx.Req = WithContext(req, &ctx)
|
2023-04-13 22:45:33 +03:00
|
|
|
ctx.Csrf = PrepareCSRFProtector(csrfOpts, &ctx)
|
2021-01-26 18:36:53 +03:00
|
|
|
|
2023-04-13 22:45:33 +03:00
|
|
|
// Get the last flash message from cookie
|
|
|
|
lastFlashCookie := middleware.GetSiteCookie(ctx.Req, CookieNameFlash)
|
|
|
|
if vals, _ := url.ParseQuery(lastFlashCookie); len(vals) > 0 {
|
|
|
|
// store last Flash message into the template data, to render it
|
|
|
|
ctx.Data["Flash"] = &middleware.Flash{
|
2021-01-26 18:36:53 +03:00
|
|
|
DataStore: &ctx,
|
|
|
|
Values: vals,
|
|
|
|
ErrorMsg: vals.Get("error"),
|
|
|
|
SuccessMsg: vals.Get("success"),
|
|
|
|
InfoMsg: vals.Get("info"),
|
|
|
|
WarningMsg: vals.Get("warning"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-13 22:45:33 +03:00
|
|
|
// prepare an empty Flash message for current request
|
|
|
|
ctx.Flash = &middleware.Flash{DataStore: &ctx, Values: url.Values{}}
|
2021-01-26 18:36:53 +03:00
|
|
|
ctx.Resp.Before(func(resp ResponseWriter) {
|
2023-04-13 22:45:33 +03:00
|
|
|
if val := ctx.Flash.Encode(); val != "" {
|
|
|
|
middleware.SetSiteCookie(ctx.Resp, CookieNameFlash, val, 0)
|
|
|
|
} else if lastFlashCookie != "" {
|
|
|
|
middleware.SetSiteCookie(ctx.Resp, CookieNameFlash, "", -1)
|
2021-01-26 18:36:53 +03:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid.
|
|
|
|
if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") {
|
|
|
|
if err := ctx.Req.ParseMultipartForm(setting.Attachment.MaxSize << 20); err != nil && !strings.Contains(err.Error(), "EOF") { // 32MB max size
|
|
|
|
ctx.ServerError("ParseMultipartForm", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2018-08-27 05:23:27 +03:00
|
|
|
|
2023-03-08 23:40:04 +03:00
|
|
|
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), 0, "no-transform")
|
2021-08-06 23:47:10 +03:00
|
|
|
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
2021-01-26 18:36:53 +03:00
|
|
|
|
2023-04-13 22:45:33 +03:00
|
|
|
ctx.Data["CsrfToken"] = ctx.Csrf.GetToken()
|
2021-01-26 18:36:53 +03:00
|
|
|
ctx.Data["CsrfTokenHtml"] = template.HTML(`<input type="hidden" name="_csrf" value="` + ctx.Data["CsrfToken"].(string) + `">`)
|
|
|
|
|
2021-05-05 00:48:31 +03:00
|
|
|
// FIXME: do we really always need these setting? There should be someway to have to avoid having to always set these
|
2021-01-26 18:36:53 +03:00
|
|
|
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations
|
2021-04-15 19:53:57 +03:00
|
|
|
ctx.Data["DisableStars"] = setting.Repository.DisableStars
|
Implement actions (#21937)
Close #13539.
Co-authored by: @lunny @appleboy @fuxiaohei and others.
Related projects:
- https://gitea.com/gitea/actions-proto-def
- https://gitea.com/gitea/actions-proto-go
- https://gitea.com/gitea/act
- https://gitea.com/gitea/act_runner
### Summary
The target of this PR is to bring a basic implementation of "Actions",
an internal CI/CD system of Gitea. That means even though it has been
merged, the state of the feature is **EXPERIMENTAL**, and please note
that:
- It is disabled by default;
- It shouldn't be used in a production environment currently;
- It shouldn't be used in a public Gitea instance currently;
- Breaking changes may be made before it's stable.
**Please comment on #13539 if you have any different product design
ideas**, all decisions reached there will be adopted here. But in this
PR, we don't talk about **naming, feature-creep or alternatives**.
### ⚠️ Breaking
`gitea-actions` will become a reserved user name. If a user with the
name already exists in the database, it is recommended to rename it.
### Some important reviews
- What is `DEFAULT_ACTIONS_URL` in `app.ini` for?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1055954954
- Why the api for runners is not under the normal `/api/v1` prefix?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1061173592
- Why DBFS?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1061301178
- Why ignore events triggered by `gitea-actions` bot?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1063254103
- Why there's no permission control for actions?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1090229868
### What it looks like
<details>
#### Manage runners
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205870657-c72f590e-2e08-4cd4-be7f-2e0abb299bbf.png">
#### List runs
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205872794-50fde990-2b45-48c1-a178-908e4ec5b627.png">
#### View logs
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205872501-9b7b9000-9542-4991-8f55-18ccdada77c3.png">
</details>
### How to try it
<details>
#### 1. Start Gitea
Clone this branch and [install from
source](https://docs.gitea.io/en-us/install-from-source).
Add additional configurations in `app.ini` to enable Actions:
```ini
[actions]
ENABLED = true
```
Start it.
If all is well, you'll see the management page of runners:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205877365-8e30a780-9b10-4154-b3e8-ee6c3cb35a59.png">
#### 2. Start runner
Clone the [act_runner](https://gitea.com/gitea/act_runner), and follow
the
[README](https://gitea.com/gitea/act_runner/src/branch/main/README.md)
to start it.
If all is well, you'll see a new runner has been added:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205878000-216f5937-e696-470d-b66c-8473987d91c3.png">
#### 3. Enable actions for a repo
Create a new repo or open an existing one, check the `Actions` checkbox
in settings and submit.
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205879705-53e09208-73c0-4b3e-a123-2dcf9aba4b9c.png">
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205879383-23f3d08f-1a85-41dd-a8b3-54e2ee6453e8.png">
If all is well, you'll see a new tab "Actions":
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205881648-a8072d8c-5803-4d76-b8a8-9b2fb49516c1.png">
#### 4. Upload workflow files
Upload some workflow files to `.gitea/workflows/xxx.yaml`, you can
follow the [quickstart](https://docs.github.com/en/actions/quickstart)
of GitHub Actions. Yes, Gitea Actions is compatible with GitHub Actions
in most cases, you can use the same demo:
```yaml
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
```
If all is well, you'll see a new run in `Actions` tab:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205884473-79a874bc-171b-4aaf-acd5-0241a45c3b53.png">
#### 5. Check the logs of jobs
Click a run and you'll see the logs:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205884800-994b0374-67f7-48ff-be9a-4c53f3141547.png">
#### 6. Go on
You can try more examples in [the
documents](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions)
of GitHub Actions, then you might find a lot of bugs.
Come on, PRs are welcome.
</details>
See also: [Feature Preview: Gitea
Actions](https://blog.gitea.io/2022/12/feature-preview-gitea-actions/)
---------
Co-authored-by: a1012112796 <1012112796@qq.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: ChristopherHX <christopher.homberger@web.de>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-01-31 04:45:19 +03:00
|
|
|
ctx.Data["EnableActions"] = setting.Actions.Enabled
|
2021-01-26 18:36:53 +03:00
|
|
|
|
|
|
|
ctx.Data["ManifestData"] = setting.ManifestData
|
|
|
|
|
2021-11-09 22:57:58 +03:00
|
|
|
ctx.Data["UnitWikiGlobalDisabled"] = unit.TypeWiki.UnitGlobalDisabled()
|
|
|
|
ctx.Data["UnitIssuesGlobalDisabled"] = unit.TypeIssues.UnitGlobalDisabled()
|
|
|
|
ctx.Data["UnitPullsGlobalDisabled"] = unit.TypePullRequests.UnitGlobalDisabled()
|
|
|
|
ctx.Data["UnitProjectsGlobalDisabled"] = unit.TypeProjects.UnitGlobalDisabled()
|
Implement actions (#21937)
Close #13539.
Co-authored by: @lunny @appleboy @fuxiaohei and others.
Related projects:
- https://gitea.com/gitea/actions-proto-def
- https://gitea.com/gitea/actions-proto-go
- https://gitea.com/gitea/act
- https://gitea.com/gitea/act_runner
### Summary
The target of this PR is to bring a basic implementation of "Actions",
an internal CI/CD system of Gitea. That means even though it has been
merged, the state of the feature is **EXPERIMENTAL**, and please note
that:
- It is disabled by default;
- It shouldn't be used in a production environment currently;
- It shouldn't be used in a public Gitea instance currently;
- Breaking changes may be made before it's stable.
**Please comment on #13539 if you have any different product design
ideas**, all decisions reached there will be adopted here. But in this
PR, we don't talk about **naming, feature-creep or alternatives**.
### ⚠️ Breaking
`gitea-actions` will become a reserved user name. If a user with the
name already exists in the database, it is recommended to rename it.
### Some important reviews
- What is `DEFAULT_ACTIONS_URL` in `app.ini` for?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1055954954
- Why the api for runners is not under the normal `/api/v1` prefix?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1061173592
- Why DBFS?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1061301178
- Why ignore events triggered by `gitea-actions` bot?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1063254103
- Why there's no permission control for actions?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1090229868
### What it looks like
<details>
#### Manage runners
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205870657-c72f590e-2e08-4cd4-be7f-2e0abb299bbf.png">
#### List runs
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205872794-50fde990-2b45-48c1-a178-908e4ec5b627.png">
#### View logs
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205872501-9b7b9000-9542-4991-8f55-18ccdada77c3.png">
</details>
### How to try it
<details>
#### 1. Start Gitea
Clone this branch and [install from
source](https://docs.gitea.io/en-us/install-from-source).
Add additional configurations in `app.ini` to enable Actions:
```ini
[actions]
ENABLED = true
```
Start it.
If all is well, you'll see the management page of runners:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205877365-8e30a780-9b10-4154-b3e8-ee6c3cb35a59.png">
#### 2. Start runner
Clone the [act_runner](https://gitea.com/gitea/act_runner), and follow
the
[README](https://gitea.com/gitea/act_runner/src/branch/main/README.md)
to start it.
If all is well, you'll see a new runner has been added:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205878000-216f5937-e696-470d-b66c-8473987d91c3.png">
#### 3. Enable actions for a repo
Create a new repo or open an existing one, check the `Actions` checkbox
in settings and submit.
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205879705-53e09208-73c0-4b3e-a123-2dcf9aba4b9c.png">
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205879383-23f3d08f-1a85-41dd-a8b3-54e2ee6453e8.png">
If all is well, you'll see a new tab "Actions":
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205881648-a8072d8c-5803-4d76-b8a8-9b2fb49516c1.png">
#### 4. Upload workflow files
Upload some workflow files to `.gitea/workflows/xxx.yaml`, you can
follow the [quickstart](https://docs.github.com/en/actions/quickstart)
of GitHub Actions. Yes, Gitea Actions is compatible with GitHub Actions
in most cases, you can use the same demo:
```yaml
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
```
If all is well, you'll see a new run in `Actions` tab:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205884473-79a874bc-171b-4aaf-acd5-0241a45c3b53.png">
#### 5. Check the logs of jobs
Click a run and you'll see the logs:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205884800-994b0374-67f7-48ff-be9a-4c53f3141547.png">
#### 6. Go on
You can try more examples in [the
documents](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions)
of GitHub Actions, then you might find a lot of bugs.
Come on, PRs are welcome.
</details>
See also: [Feature Preview: Gitea
Actions](https://blog.gitea.io/2022/12/feature-preview-gitea-actions/)
---------
Co-authored-by: a1012112796 <1012112796@qq.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: ChristopherHX <christopher.homberger@web.de>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-01-31 04:45:19 +03:00
|
|
|
ctx.Data["UnitActionsGlobalDisabled"] = unit.TypeActions.UnitGlobalDisabled()
|
2021-05-05 00:48:31 +03:00
|
|
|
|
2021-01-26 18:36:53 +03:00
|
|
|
ctx.Data["AllLangs"] = translation.AllLangs()
|
2020-12-22 14:13:50 +03:00
|
|
|
|
2021-01-26 18:36:53 +03:00
|
|
|
next.ServeHTTP(ctx.Resp, ctx.Req)
|
|
|
|
})
|
2014-03-15 15:01:50 +04:00
|
|
|
}
|
|
|
|
}
|