mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-15 00:01:25 -04:00
Compare commits
19 Commits
4011821c94
...
7fd5d38860
Author | SHA1 | Date | |
---|---|---|---|
|
7fd5d38860 | ||
|
faa96553d1 | ||
|
b6145bfaa3 | ||
|
707ecec715 | ||
|
fd29071e57 | ||
|
1947409ef0 | ||
|
cc910014ab | ||
|
f1f0430f9f | ||
|
519939fa8c | ||
|
f518b42d4c | ||
|
66877aed54 | ||
|
706f4686b8 | ||
|
be93e48ccb | ||
|
85016af1fe | ||
|
b80538f37d | ||
|
c14d3e80e8 | ||
|
36dc11869d | ||
|
f47ea60c07 | ||
|
03f37d82fe |
@ -267,26 +267,10 @@ with the rest of the summary matching the original PR. Similarly for frontports
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
The below is a script that may be helpful in creating backports. YMMV.
|
A command to help create backports can be found in `contrib/backport` and can be installed (from inside the gitea repo root directory) using:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/sh
|
go install contrib/backport/backport.go
|
||||||
PR="$1"
|
|
||||||
SHA="$2"
|
|
||||||
VERSION="$3"
|
|
||||||
|
|
||||||
if [ -z "$SHA" ]; then
|
|
||||||
SHA=$(gh api /repos/go-gitea/gitea/pulls/$PR -q '.merge_commit_sha')
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$VERSION" ]; then
|
|
||||||
VERSION="v1.16"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo git checkout origin/release/"$VERSION" -b backport-$PR-$VERSION
|
|
||||||
git checkout origin/release/"$VERSION" -b backport-$PR-$VERSION
|
|
||||||
git cherry-pick $SHA && git commit --amend && git push zeripath backport-$PR-$VERSION && xdg-open https://github.com/go-gitea/gitea/compare/release/"$VERSION"...zeripath:backport-$PR-$VERSION
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Developer Certificate of Origin (DCO)
|
## Developer Certificate of Origin (DCO)
|
||||||
|
41
contrib/backport/README
Normal file
41
contrib/backport/README
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
`backport`
|
||||||
|
==========
|
||||||
|
|
||||||
|
`backport` is a command to help create backports of PRs. It backports a
|
||||||
|
provided PR from main on to a released version.
|
||||||
|
|
||||||
|
It will create a backport branch, cherry-pick the PR's merge commit, adjust
|
||||||
|
the commit message and then push this back up to your fork's remote.
|
||||||
|
|
||||||
|
The default version will read from `docs/config.yml`. You can override this
|
||||||
|
using the option `--version`.
|
||||||
|
|
||||||
|
The upstream branches will be fetched, using the remote `origin`. This can
|
||||||
|
be overrided using `--upstream`, and fetching can be avoided using
|
||||||
|
`--no-fetch`.
|
||||||
|
|
||||||
|
By default the branch created will be called `backport-$PR-$VERSION`. You
|
||||||
|
can override this using the option `--backport-branch`. This branch will
|
||||||
|
be created from `--release-branch` which is `release/$(VERSION)`
|
||||||
|
by default and will be pulled from `$(UPSTREAM)`.
|
||||||
|
|
||||||
|
The merge-commit as determined by the github API will be used as the SHA to
|
||||||
|
cherry-pick. You can override this using `--cherry-pick`.
|
||||||
|
|
||||||
|
The commit message will be amended to add the `Backport` header.
|
||||||
|
`--no-amend-message` can be set to stop this from happening.
|
||||||
|
|
||||||
|
If cherry-pick is successful the backported branch will be pushed up to your
|
||||||
|
fork using your remote. These will be determined using `git remote -v`. You
|
||||||
|
can set your fork name using `--fork-user` and your remote name using
|
||||||
|
`--remote`. You can avoid pushing using `--no-push`.
|
||||||
|
|
||||||
|
If the push is successful, `xdg-open` will be called to open a backport url.
|
||||||
|
You can stop this using `--no-xdg-open`.
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go install contrib/backport/backport.go
|
||||||
|
```
|
438
contrib/backport/backport.go
Normal file
438
contrib/backport/backport.go
Normal file
@ -0,0 +1,438 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"os/signal"
|
||||||
|
"path"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/google/go-github/v45/github"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultVersion = "v1.18" // to backport to
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := cli.NewApp()
|
||||||
|
app.Name = "backport"
|
||||||
|
app.Usage = "Backport provided PR-number on to the current or previous released version"
|
||||||
|
app.Description = `Backport will look-up the PR in Gitea's git log and attempt to cherry-pick it on the current version`
|
||||||
|
app.ArgsUsage = "<PR-to-backport>"
|
||||||
|
|
||||||
|
app.Flags = []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "version",
|
||||||
|
Usage: "Version branch to backport on to",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "upstream",
|
||||||
|
Value: "origin",
|
||||||
|
Usage: "Upstream remote for the Gitea upstream",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "release-branch",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Release branch to backport on. Will default to release/<version>",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "cherry-pick",
|
||||||
|
Usage: "SHA to cherry-pick as backport",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "backport-branch",
|
||||||
|
Usage: "Backport branch to backport on to (default: backport-<pr>-<version>",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "remote",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Remote for your fork of the Gitea upstream",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "fork-user",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Forked user name on Github",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "no-fetch",
|
||||||
|
Usage: "Set this flag to prevent fetch of remote branches",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "no-amend-message",
|
||||||
|
Usage: "Set this flag to prevent automatic amendment of the commit message",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "no-push",
|
||||||
|
Usage: "Set this flag to prevent pushing the backport up to your fork",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "no-xdg-open",
|
||||||
|
Usage: "Set this flag to not use xdg-open to open the PR URL",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cli.AppHelpTemplate = `NAME:
|
||||||
|
{{.Name}} - {{.Usage}}
|
||||||
|
USAGE:
|
||||||
|
{{.HelpName}} {{if .VisibleFlags}}[options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
|
||||||
|
{{if len .Authors}}
|
||||||
|
AUTHOR:
|
||||||
|
{{range .Authors}}{{ . }}{{end}}
|
||||||
|
{{end}}{{if .Commands}}
|
||||||
|
OPTIONS:
|
||||||
|
{{range .VisibleFlags}}{{.}}
|
||||||
|
{{end}}{{end}}
|
||||||
|
`
|
||||||
|
|
||||||
|
app.Action = runBackport
|
||||||
|
|
||||||
|
if err := app.Run(os.Args); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Unable to backport: %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runBackport(c *cli.Context) error {
|
||||||
|
ctx, cancel := installSignals()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
version := c.String("version")
|
||||||
|
if version == "" {
|
||||||
|
version = readVersion()
|
||||||
|
}
|
||||||
|
if version == "" {
|
||||||
|
version = defaultVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream := c.String("upstream")
|
||||||
|
if upstream == "" {
|
||||||
|
upstream = "origin"
|
||||||
|
}
|
||||||
|
|
||||||
|
forkUser := c.String("fork-user")
|
||||||
|
remote := c.String("remote")
|
||||||
|
if remote == "" && !c.Bool("--no-push") {
|
||||||
|
var err error
|
||||||
|
remote, forkUser, err = determineRemote(ctx, forkUser)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
upstreamReleaseBranch := c.String("release-branch")
|
||||||
|
if upstreamReleaseBranch == "" {
|
||||||
|
upstreamReleaseBranch = path.Join("release", version)
|
||||||
|
}
|
||||||
|
|
||||||
|
localReleaseBranch := path.Join(upstream, upstreamReleaseBranch)
|
||||||
|
|
||||||
|
args := c.Args()
|
||||||
|
if len(args) == 0 {
|
||||||
|
return fmt.Errorf("no PR number provided\nProvide a PR number to backport")
|
||||||
|
} else if len(args) != 1 {
|
||||||
|
return fmt.Errorf("multiple PRs provided %v\nOnly a single PR can be backported at a time", args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pr := args[0]
|
||||||
|
|
||||||
|
backportBranch := c.String("backport-branch")
|
||||||
|
if backportBranch == "" {
|
||||||
|
backportBranch = "backport-" + pr + "-" + version
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("* Backporting %s to %s as %s\n", pr, localReleaseBranch, backportBranch)
|
||||||
|
|
||||||
|
sha := c.String("cherry-pick")
|
||||||
|
if sha == "" {
|
||||||
|
var err error
|
||||||
|
sha, err = determineSHAforPR(ctx, pr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sha == "" {
|
||||||
|
return fmt.Errorf("unable to determine sha for cherry-pick of %s", pr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.Bool("no-fetch") {
|
||||||
|
if err := fetchRemoteAndMain(ctx, upstream, upstreamReleaseBranch); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := checkoutBackportBranch(ctx, backportBranch, localReleaseBranch); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cherrypick(ctx, sha); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.Bool("no-amend-message") {
|
||||||
|
if err := amendCommit(ctx, pr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.Bool("no-push") {
|
||||||
|
url := "https://github.com/go-gitea/gitea/compare/" + upstreamReleaseBranch + "..." + forkUser + ":" + backportBranch
|
||||||
|
|
||||||
|
if err := gitPushUp(ctx, remote, backportBranch); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.Bool("no-xdg-open") {
|
||||||
|
if err := xdgOpen(ctx, url); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("* Navigate to %s to open PR\n", url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func xdgOpen(ctx context.Context, url string) error {
|
||||||
|
fmt.Printf("* `xdg-open %s`\n", url)
|
||||||
|
out, err := exec.CommandContext(ctx, "xdg-open", url).Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s", string(out))
|
||||||
|
return fmt.Errorf("unable to xdg-open to %s: %w", url, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func gitPushUp(ctx context.Context, remote, backportBranch string) error {
|
||||||
|
fmt.Printf("* `git push -u %s %s`\n", remote, backportBranch)
|
||||||
|
out, err := exec.CommandContext(ctx, "git", "push", "-u", remote, backportBranch).Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s", string(out))
|
||||||
|
return fmt.Errorf("unable to push up to %s: %w", remote, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func amendCommit(ctx context.Context, pr string) error {
|
||||||
|
fmt.Printf("* Amending commit to prepend `Backport #%s` to body\n", pr)
|
||||||
|
out, err := exec.CommandContext(ctx, "git", "log", "-1", "--pretty=format:%B").Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s", string(out))
|
||||||
|
return fmt.Errorf("unable to get last log message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.SplitN(string(out), "\n", 2)
|
||||||
|
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return fmt.Errorf("unable to interpret log message:\n%s", string(out))
|
||||||
|
}
|
||||||
|
subject, body := parts[0], parts[1]
|
||||||
|
if !strings.HasSuffix(subject, " (#"+pr+")") {
|
||||||
|
subject = subject + " (#" + pr + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err = exec.CommandContext(ctx, "git", "commit", "--amend", "-m", subject+"\n\nBackport #"+pr+"\n"+body).Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s", string(out))
|
||||||
|
return fmt.Errorf("unable to amend last log message: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cherrypick(ctx context.Context, sha string) error {
|
||||||
|
// Check if a CHERRY_PICK_HEAD exists
|
||||||
|
if _, err := os.Stat(".git/CHERRY_PICK_HEAD"); err == nil {
|
||||||
|
// Assume that we are in the middle of cherry-pick - continue it
|
||||||
|
fmt.Println("* Attempting git cherry-pick --continue")
|
||||||
|
out, err := exec.CommandContext(ctx, "git", "cherry-pick", "--continue").Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "git cherry-pick --continue failed:\n%s\n", string(out))
|
||||||
|
return fmt.Errorf("unable to continue cherry-pick: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("* Attempting git cherry-pick %s\n", sha)
|
||||||
|
out, err := exec.CommandContext(ctx, "git", "cherry-pick", sha).Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "git cherry-pick %s failed:\n%s\n", sha, string(out))
|
||||||
|
return fmt.Errorf("git cherry-pick %s failed: %w", sha, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkoutBackportBranch(ctx context.Context, backportBranch, releaseBranch string) error {
|
||||||
|
out, err := exec.CommandContext(ctx, "git", "branch", "--show-current").Output()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to check current branch %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentBranch := strings.TrimSpace(string(out))
|
||||||
|
fmt.Printf("* Current branch is %s\n", currentBranch)
|
||||||
|
if currentBranch == backportBranch {
|
||||||
|
fmt.Printf("* Current branch is %s - not checking out\n", currentBranch)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := exec.CommandContext(ctx, "git", "rev-list", "-1", backportBranch).Output(); err == nil {
|
||||||
|
fmt.Printf("* Branch %s already exists. Checking it out...\n", backportBranch)
|
||||||
|
return exec.CommandContext(ctx, "git", "checkout", "-f", backportBranch).Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("* `git checkout -b %s %s`\n", backportBranch, releaseBranch)
|
||||||
|
return exec.CommandContext(ctx, "git", "checkout", "-b", backportBranch, releaseBranch).Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchRemoteAndMain(ctx context.Context, remote, releaseBranch string) error {
|
||||||
|
fmt.Printf("* `git fetch %s main`\n", remote)
|
||||||
|
out, err := exec.CommandContext(ctx, "git", "fetch", remote, "main").Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(string(out))
|
||||||
|
return fmt.Errorf("unable to fetch %s from %s: %w", "main", remote, err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(out))
|
||||||
|
|
||||||
|
fmt.Printf("* `git fetch %s %s`\n", remote, releaseBranch)
|
||||||
|
out, err = exec.CommandContext(ctx, "git", "fetch", remote, releaseBranch).Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(string(out))
|
||||||
|
return fmt.Errorf("unable to fetch %s from %s: %w", releaseBranch, remote, err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(out))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func determineRemote(ctx context.Context, forkUser string) (string, string, error) {
|
||||||
|
out, err := exec.CommandContext(ctx, "git", "remote", "-v").Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Unable to list git remotes:\n%s\n", string(out))
|
||||||
|
return "", "", fmt.Errorf("unable to determine forked remote: %w", err)
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(out), "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
fields := strings.Split(line, "\t")
|
||||||
|
name, remote := fields[0], fields[1]
|
||||||
|
// only look at pushers
|
||||||
|
if !strings.HasSuffix(remote, " (push)") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// only look at github.com pushes
|
||||||
|
if !strings.Contains(remote, "github.com") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// ignore go-gitea/gitea
|
||||||
|
if strings.Contains(remote, "go-gitea/gitea") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !strings.Contains(remote, forkUser) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(remote, "git@github.com:") {
|
||||||
|
forkUser = strings.TrimPrefix(remote, "git@github.com:")
|
||||||
|
} else if strings.HasPrefix(remote, "https://github.com/") {
|
||||||
|
forkUser = strings.TrimPrefix(remote, "https://github.com/")
|
||||||
|
} else if strings.HasPrefix(remote, "https://www.github.com/") {
|
||||||
|
forkUser = strings.TrimPrefix(remote, "https://www.github.com/")
|
||||||
|
} else if forkUser == "" {
|
||||||
|
return "", "", fmt.Errorf("unable to extract forkUser from remote %s: %s", name, remote)
|
||||||
|
}
|
||||||
|
idx := strings.Index(forkUser, "/")
|
||||||
|
if idx >= 0 {
|
||||||
|
forkUser = forkUser[:idx]
|
||||||
|
}
|
||||||
|
return name, forkUser, nil
|
||||||
|
}
|
||||||
|
return "", "", fmt.Errorf("unable to find appropriate remote in:\n%s", string(out))
|
||||||
|
}
|
||||||
|
|
||||||
|
func readVersion() string {
|
||||||
|
bs, err := os.ReadFile("docs/config.yaml")
|
||||||
|
if err != nil {
|
||||||
|
if err == os.ErrNotExist {
|
||||||
|
log.Println("`docs/config.yaml` not present")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
fmt.Fprintf(os.Stderr, "Unable to read `docs/config.yaml`: %v\n", err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type params struct {
|
||||||
|
Version string
|
||||||
|
}
|
||||||
|
type docConfig struct {
|
||||||
|
Params params
|
||||||
|
}
|
||||||
|
dc := &docConfig{}
|
||||||
|
if err := yaml.Unmarshal(bs, dc); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Unable to read `docs/config.yaml`: %v\n", err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if dc.Params.Version == "" {
|
||||||
|
fmt.Fprintf(os.Stderr, "No version in `docs/config.yaml`")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
version := dc.Params.Version
|
||||||
|
if version[0] != 'v' {
|
||||||
|
version = "v" + version
|
||||||
|
}
|
||||||
|
|
||||||
|
split := strings.SplitN(version, ".", 3)
|
||||||
|
|
||||||
|
return strings.Join(split[:2], ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
func determineSHAforPR(ctx context.Context, prStr string) (string, error) {
|
||||||
|
prNum, err := strconv.Atoi(prStr)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := github.NewClient(http.DefaultClient)
|
||||||
|
|
||||||
|
pr, _, err := client.PullRequests.Get(ctx, "go-gitea", "gitea", prNum)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.Merged == nil || !*pr.Merged {
|
||||||
|
return "", fmt.Errorf("PR #%d is not yet merged - cannot determine sha to backport", prNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.MergeCommitSHA != nil {
|
||||||
|
return *pr.MergeCommitSHA, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func installSignals() (context.Context, context.CancelFunc) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
go func() {
|
||||||
|
// install notify
|
||||||
|
signalChannel := make(chan os.Signal, 1)
|
||||||
|
|
||||||
|
signal.Notify(
|
||||||
|
signalChannel,
|
||||||
|
syscall.SIGINT,
|
||||||
|
syscall.SIGTERM,
|
||||||
|
)
|
||||||
|
select {
|
||||||
|
case <-signalChannel:
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
cancel()
|
||||||
|
signal.Reset()
|
||||||
|
}()
|
||||||
|
|
||||||
|
return ctx, cancel
|
||||||
|
}
|
@ -37,7 +37,7 @@ PROVIDER_CONFIG = $GITEA_WORK_DIR/data/sessions
|
|||||||
|
|
||||||
[picture]
|
[picture]
|
||||||
AVATAR_UPLOAD_PATH = $GITEA_WORK_DIR/data/avatars
|
AVATAR_UPLOAD_PATH = $GITEA_WORK_DIR/data/avatars
|
||||||
REPOSITORY_AVATAR_UPLOAD_PATH = $GITEA_WORK_DIR/data/gitea/repo-avatars
|
REPOSITORY_AVATAR_UPLOAD_PATH = $GITEA_WORK_DIR/data/repo-avatars
|
||||||
|
|
||||||
[attachment]
|
[attachment]
|
||||||
PATH = $GITEA_WORK_DIR/data/attachments
|
PATH = $GITEA_WORK_DIR/data/attachments
|
||||||
|
@ -54,7 +54,7 @@ To maintain understandable code and avoid circular dependencies it is important
|
|||||||
|
|
||||||
### Package Dependencies
|
### Package Dependencies
|
||||||
|
|
||||||
Since Golang don't support import cycles, we have to decide the package dependencies carefully. There are some levels between those packages. Below is the ideal package dependencies direction.
|
Since Golang doesn't support import cycles, we have to decide the package dependencies carefully. There are some levels between those packages. Below is the ideal package dependencies direction.
|
||||||
|
|
||||||
`cmd` -> `routers` -> `services` -> `models` -> `modules`
|
`cmd` -> `routers` -> `services` -> `models` -> `modules`
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ The patterns are case-insensitive which matches the behaviour of the package reg
|
|||||||
|
|
||||||
### How the cleanup rules work
|
### How the cleanup rules work
|
||||||
|
|
||||||
The cleanup rules are part of the [clean up job]({{< relref "doc/advanced/config-cheat-sheet.en-us.md#cron---cleanup-expired-packages-croncleanup_packages" >}}) and run periodicly.
|
The cleanup rules are part of the [clean up job]({{< relref "doc/advanced/config-cheat-sheet.en-us.md#cron---cleanup-expired-packages-croncleanup_packages" >}}) and run periodically.
|
||||||
|
|
||||||
The cleanup rule:
|
The cleanup rule:
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ Currently there are a check list below:
|
|||||||
Sometimes if you moved or renamed your Gitea binary when upgrade and you haven't run `Update the '.ssh/authorized_keys' file with Gitea SSH keys. (Not needed for the built-in SSH server.)` on your Admin Panel. Then all pull/push via SSH will not be work.
|
Sometimes if you moved or renamed your Gitea binary when upgrade and you haven't run `Update the '.ssh/authorized_keys' file with Gitea SSH keys. (Not needed for the built-in SSH server.)` on your Admin Panel. Then all pull/push via SSH will not be work.
|
||||||
This check will help you to check if it works well.
|
This check will help you to check if it works well.
|
||||||
|
|
||||||
For contributors, if you want to add more checks, you can wrie ad new function like `func(ctx *cli.Context) ([]string, error)` and
|
For contributors, if you want to add more checks, you can write a new function like `func(ctx *cli.Context) ([]string, error)` and
|
||||||
append it to `doctor.go`.
|
append it to `doctor.go`.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
@ -24,7 +24,7 @@ in search for references. These references will be shown as links in the Issue V
|
|||||||
and, in some cases, produce certain _actions_.
|
and, in some cases, produce certain _actions_.
|
||||||
|
|
||||||
Likewise, commit messages are parsed when they are listed, and _actions_
|
Likewise, commit messages are parsed when they are listed, and _actions_
|
||||||
are can be triggered when they are pushed to the main branch.
|
can be triggered when they are pushed to the main branch.
|
||||||
|
|
||||||
To prevent the creation of unintended references, there are certain rules
|
To prevent the creation of unintended references, there are certain rules
|
||||||
for them to be recognized. For example, they should not be included inside code
|
for them to be recognized. For example, they should not be included inside code
|
||||||
|
@ -6,11 +6,13 @@ package actions
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
@ -63,6 +65,24 @@ func (run *ActionRun) Link() string {
|
|||||||
return fmt.Sprintf("%s/actions/runs/%d", run.Repo.Link(), run.Index)
|
return fmt.Sprintf("%s/actions/runs/%d", run.Repo.Link(), run.Index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RefLink return the url of run's ref
|
||||||
|
func (run *ActionRun) RefLink() string {
|
||||||
|
refName := git.RefName(run.Ref)
|
||||||
|
if refName.RefGroup() == "pull" {
|
||||||
|
return run.Repo.Link() + "/pulls/" + refName.ShortName()
|
||||||
|
}
|
||||||
|
return git.RefURL(run.Repo.Link(), run.Ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrettyRef return #id for pull ref or ShortName for others
|
||||||
|
func (run *ActionRun) PrettyRef() string {
|
||||||
|
refName := git.RefName(run.Ref)
|
||||||
|
if refName.RefGroup() == "pull" {
|
||||||
|
return "#" + strings.TrimSuffix(strings.TrimPrefix(run.Ref, git.PullPrefix), "/head")
|
||||||
|
}
|
||||||
|
return refName.ShortName()
|
||||||
|
}
|
||||||
|
|
||||||
// LoadAttributes load Repo TriggerUser if not loaded
|
// LoadAttributes load Repo TriggerUser if not loaded
|
||||||
func (run *ActionRun) LoadAttributes(ctx context.Context) error {
|
func (run *ActionRun) LoadAttributes(ctx context.Context) error {
|
||||||
if run == nil {
|
if run == nil {
|
||||||
|
@ -358,12 +358,19 @@ func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output
|
|||||||
}
|
}
|
||||||
|
|
||||||
func visitNode(ctx *RenderContext, procs, textProcs []processor, node *html.Node) {
|
func visitNode(ctx *RenderContext, procs, textProcs []processor, node *html.Node) {
|
||||||
// Add user-content- to IDs if they don't already have them
|
// Add user-content- to IDs and "#" links if they don't already have them
|
||||||
for idx, attr := range node.Attr {
|
for idx, attr := range node.Attr {
|
||||||
if attr.Key == "id" && !(strings.HasPrefix(attr.Val, "user-content-") || blackfridayExtRegex.MatchString(attr.Val)) {
|
val := strings.TrimPrefix(attr.Val, "#")
|
||||||
|
notHasPrefix := !(strings.HasPrefix(val, "user-content-") || blackfridayExtRegex.MatchString(val))
|
||||||
|
|
||||||
|
if attr.Key == "id" && notHasPrefix {
|
||||||
node.Attr[idx].Val = "user-content-" + attr.Val
|
node.Attr[idx].Val = "user-content-" + attr.Val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if attr.Key == "href" && strings.HasPrefix(attr.Val, "#") && notHasPrefix {
|
||||||
|
node.Attr[idx].Val = "#user-content-" + val
|
||||||
|
}
|
||||||
|
|
||||||
if attr.Key == "class" && attr.Val == "emoji" {
|
if attr.Key == "class" && attr.Val == "emoji" {
|
||||||
textProcs = nil
|
textProcs = nil
|
||||||
}
|
}
|
||||||
|
@ -35,12 +35,12 @@ var (
|
|||||||
// issueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234
|
// issueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234
|
||||||
issueAlphanumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([A-Z]{1,10}-[1-9][0-9]*)(?:\s|$|\)|\]|:|\.(\s|$))`)
|
issueAlphanumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([A-Z]{1,10}-[1-9][0-9]*)(?:\s|$|\)|\]|:|\.(\s|$))`)
|
||||||
// crossReferenceIssueNumericPattern matches string that references a numeric issue in a different repository
|
// crossReferenceIssueNumericPattern matches string that references a numeric issue in a different repository
|
||||||
// e.g. gogits/gogs#12345
|
// e.g. org/repo#12345
|
||||||
crossReferenceIssueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+[#!][0-9]+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
crossReferenceIssueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+[#!][0-9]+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
||||||
// crossReferenceCommitPattern matches a string that references a commit in a different repository
|
// crossReferenceCommitPattern matches a string that references a commit in a different repository
|
||||||
// e.g. go-gitea/gitea@d8a994ef, go-gitea/gitea@d8a994ef243349f321568f9e36d5c3f444b99cae (7-40 characters)
|
// e.g. go-gitea/gitea@d8a994ef, go-gitea/gitea@d8a994ef243349f321568f9e36d5c3f444b99cae (7-40 characters)
|
||||||
crossReferenceCommitPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+)/([0-9a-zA-Z-_\.]+)@([0-9a-f]{7,40})(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
crossReferenceCommitPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+)/([0-9a-zA-Z-_\.]+)@([0-9a-f]{7,40})(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
||||||
// spaceTrimmedPattern let's us find the trailing space
|
// spaceTrimmedPattern let's find the trailing space
|
||||||
spaceTrimmedPattern = regexp.MustCompile(`(?:.*[0-9a-zA-Z-_])\s`)
|
spaceTrimmedPattern = regexp.MustCompile(`(?:.*[0-9a-zA-Z-_])\s`)
|
||||||
// timeLogPattern matches string for time tracking
|
// timeLogPattern matches string for time tracking
|
||||||
timeLogPattern = regexp.MustCompile(`(?:\s|^|\(|\[)(@([0-9]+([\.,][0-9]+)?(w|d|m|h))+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
timeLogPattern = regexp.MustCompile(`(?:\s|^|\(|\[)(@([0-9]+([\.,][0-9]+)?(w|d|m|h))+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
||||||
@ -365,7 +365,7 @@ func FindRenderizableCommitCrossReference(content string) (bool, *RenderizableRe
|
|||||||
Owner: content[m[2]:m[3]],
|
Owner: content[m[2]:m[3]],
|
||||||
Name: content[m[4]:m[5]],
|
Name: content[m[4]:m[5]],
|
||||||
CommitSha: content[m[6]:m[7]],
|
CommitSha: content[m[6]:m[7]],
|
||||||
RefLocation: &RefSpan{Start: m[0], End: m[1]},
|
RefLocation: &RefSpan{Start: m[2], End: m[7]},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ func TestFindRenderizableCommitCrossReference(t *testing.T) {
|
|||||||
Owner: "go-gitea",
|
Owner: "go-gitea",
|
||||||
Name: "gitea",
|
Name: "gitea",
|
||||||
CommitSha: "abcd1234",
|
CommitSha: "abcd1234",
|
||||||
RefLocation: &RefSpan{Start: 4, End: 29},
|
RefLocation: &RefSpan{Start: 5, End: 28},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1131,6 +1131,7 @@ editor.commit_directly_to_this_branch = Commit directly to the <strong class="br
|
|||||||
editor.create_new_branch = Create a <strong>new branch</strong> for this commit and start a pull request.
|
editor.create_new_branch = Create a <strong>new branch</strong> for this commit and start a pull request.
|
||||||
editor.create_new_branch_np = Create a <strong>new branch</strong> for this commit.
|
editor.create_new_branch_np = Create a <strong>new branch</strong> for this commit.
|
||||||
editor.propose_file_change = Propose file change
|
editor.propose_file_change = Propose file change
|
||||||
|
editor.new_branch_name = Name the new branch for this commit
|
||||||
editor.new_branch_name_desc = New branch name…
|
editor.new_branch_name_desc = New branch name…
|
||||||
editor.cancel = Cancel
|
editor.cancel = Cancel
|
||||||
editor.filename_cannot_be_empty = The filename cannot be empty.
|
editor.filename_cannot_be_empty = The filename cannot be empty.
|
||||||
@ -1336,6 +1337,8 @@ issues.action_milestone = Milestone
|
|||||||
issues.action_milestone_no_select = No milestone
|
issues.action_milestone_no_select = No milestone
|
||||||
issues.action_assignee = Assignee
|
issues.action_assignee = Assignee
|
||||||
issues.action_assignee_no_select = No assignee
|
issues.action_assignee_no_select = No assignee
|
||||||
|
issues.action_check = Check/Uncheck
|
||||||
|
issues.action_check_all = Check/Uncheck all items
|
||||||
issues.opened_by = opened %[1]s by <a href="%[2]s">%[3]s</a>
|
issues.opened_by = opened %[1]s by <a href="%[2]s">%[3]s</a>
|
||||||
pulls.merged_by = by <a href="%[2]s">%[3]s</a> was merged %[1]s
|
pulls.merged_by = by <a href="%[2]s">%[3]s</a> was merged %[1]s
|
||||||
pulls.merged_by_fake = by %[2]s was merged %[1]s
|
pulls.merged_by_fake = by %[2]s was merged %[1]s
|
||||||
@ -1870,6 +1873,7 @@ settings.pulls.allow_manual_merge = Enable Mark PR as manually merged
|
|||||||
settings.pulls.enable_autodetect_manual_merge = Enable autodetect manual merge (Note: In some special cases, misjudgments can occur)
|
settings.pulls.enable_autodetect_manual_merge = Enable autodetect manual merge (Note: In some special cases, misjudgments can occur)
|
||||||
settings.pulls.allow_rebase_update = Enable updating pull request branch by rebase
|
settings.pulls.allow_rebase_update = Enable updating pull request branch by rebase
|
||||||
settings.pulls.default_delete_branch_after_merge = Delete pull request branch after merge by default
|
settings.pulls.default_delete_branch_after_merge = Delete pull request branch after merge by default
|
||||||
|
settings.releases_desc = Enable Repository Releases
|
||||||
settings.packages_desc = Enable Repository Packages Registry
|
settings.packages_desc = Enable Repository Packages Registry
|
||||||
settings.projects_desc = Enable Repository Projects
|
settings.projects_desc = Enable Repository Projects
|
||||||
settings.actions_desc = Enable Repository Actions
|
settings.actions_desc = Enable Repository Actions
|
||||||
|
@ -49,7 +49,7 @@ type ViewRequest struct {
|
|||||||
type ViewResponse struct {
|
type ViewResponse struct {
|
||||||
State struct {
|
State struct {
|
||||||
Run struct {
|
Run struct {
|
||||||
HTMLURL string `json:"htmlurl"`
|
Link string `json:"link"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
CanCancel bool `json:"canCancel"`
|
CanCancel bool `json:"canCancel"`
|
||||||
Done bool `json:"done"`
|
Done bool `json:"done"`
|
||||||
@ -105,7 +105,7 @@ func ViewPost(ctx *context_module.Context) {
|
|||||||
resp := &ViewResponse{}
|
resp := &ViewResponse{}
|
||||||
|
|
||||||
resp.State.Run.Title = run.Title
|
resp.State.Run.Title = run.Title
|
||||||
resp.State.Run.HTMLURL = run.HTMLURL()
|
resp.State.Run.Link = run.Link()
|
||||||
resp.State.Run.CanCancel = !run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions)
|
resp.State.Run.CanCancel = !run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions)
|
||||||
resp.State.Run.Done = run.Status.IsDone()
|
resp.State.Run.Done = run.Status.IsDone()
|
||||||
resp.State.Run.Jobs = make([]*ViewJob, 0, len(jobs)) // marshal to '[]' instead fo 'null' in json
|
resp.State.Run.Jobs = make([]*ViewJob, 0, len(jobs)) // marshal to '[]' instead fo 'null' in json
|
||||||
|
@ -1395,7 +1395,7 @@ func CleanUpPullRequest(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func deleteBranch(ctx *context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository) {
|
func deleteBranch(ctx *context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository) {
|
||||||
fullBranchName := pr.HeadRepo.Owner.Name + "/" + pr.HeadBranch
|
fullBranchName := pr.HeadRepo.FullName() + ":" + pr.HeadBranch
|
||||||
if err := repo_service.DeleteBranch(ctx.Doer, pr.HeadRepo, gitRepo, pr.HeadBranch); err != nil {
|
if err := repo_service.DeleteBranch(ctx.Doer, pr.HeadRepo, gitRepo, pr.HeadBranch); err != nil {
|
||||||
switch {
|
switch {
|
||||||
case git.IsErrBranchNotExist(err):
|
case git.IsErrBranchNotExist(err):
|
||||||
|
@ -488,6 +488,15 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeProjects)
|
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeProjects)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if form.EnableReleases && !unit_model.TypeReleases.UnitGlobalDisabled() {
|
||||||
|
units = append(units, repo_model.RepoUnit{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Type: unit_model.TypeReleases,
|
||||||
|
})
|
||||||
|
} else if !unit_model.TypeReleases.UnitGlobalDisabled() {
|
||||||
|
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeReleases)
|
||||||
|
}
|
||||||
|
|
||||||
if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() {
|
if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() {
|
||||||
units = append(units, repo_model.RepoUnit{
|
units = append(units, repo_model.RepoUnit{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
|
@ -67,7 +67,6 @@ type notifyInput struct {
|
|||||||
func newNotifyInput(repo *repo_model.Repository, doer *user_model.User, event webhook_module.HookEventType) *notifyInput {
|
func newNotifyInput(repo *repo_model.Repository, doer *user_model.User, event webhook_module.HookEventType) *notifyInput {
|
||||||
return ¬ifyInput{
|
return ¬ifyInput{
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
Ref: repo.DefaultBranch,
|
|
||||||
Doer: doer,
|
Doer: doer,
|
||||||
Event: event,
|
Event: event,
|
||||||
}
|
}
|
||||||
@ -90,6 +89,9 @@ func (input *notifyInput) WithPayload(payload api.Payloader) *notifyInput {
|
|||||||
|
|
||||||
func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyInput {
|
func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyInput {
|
||||||
input.PullRequest = pr
|
input.PullRequest = pr
|
||||||
|
if input.Ref == "" {
|
||||||
|
input.Ref = pr.GetGitRefName()
|
||||||
|
}
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,8 +126,13 @@ func notify(ctx context.Context, input *notifyInput) error {
|
|||||||
}
|
}
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
ref := input.Ref
|
||||||
|
if ref == "" {
|
||||||
|
ref = input.Repo.DefaultBranch
|
||||||
|
}
|
||||||
|
|
||||||
// Get the commit object for the ref
|
// Get the commit object for the ref
|
||||||
commit, err := gitRepo.GetCommit(input.Ref)
|
commit, err := gitRepo.GetCommit(ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("gitRepo.GetCommit: %w", err)
|
return fmt.Errorf("gitRepo.GetCommit: %w", err)
|
||||||
}
|
}
|
||||||
@ -152,7 +159,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
|||||||
OwnerID: input.Repo.OwnerID,
|
OwnerID: input.Repo.OwnerID,
|
||||||
WorkflowID: id,
|
WorkflowID: id,
|
||||||
TriggerUserID: input.Doer.ID,
|
TriggerUserID: input.Doer.ID,
|
||||||
Ref: input.Ref,
|
Ref: ref,
|
||||||
CommitSHA: commit.ID.String(),
|
CommitSHA: commit.ID.String(),
|
||||||
IsForkPullRequest: input.PullRequest != nil && input.PullRequest.IsFromFork(),
|
IsForkPullRequest: input.PullRequest != nil && input.PullRequest.IsFromFork(),
|
||||||
Event: input.Event,
|
Event: input.Event,
|
||||||
|
@ -146,6 +146,7 @@ type RepoSettingForm struct {
|
|||||||
ExternalTrackerRegexpPattern string
|
ExternalTrackerRegexpPattern string
|
||||||
EnableCloseIssuesViaCommitInAnyBranch bool
|
EnableCloseIssuesViaCommitInAnyBranch bool
|
||||||
EnableProjects bool
|
EnableProjects bool
|
||||||
|
EnableReleases bool
|
||||||
EnablePackages bool
|
EnablePackages bool
|
||||||
EnablePulls bool
|
EnablePulls bool
|
||||||
EnableActions bool
|
EnableActions bool
|
||||||
|
@ -303,14 +303,14 @@
|
|||||||
<dt>{{.locale.Tr "admin.config.disable_gravatar"}}</dt>
|
<dt>{{.locale.Tr "admin.config.disable_gravatar"}}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<div class="ui toggle checkbox">
|
<div class="ui toggle checkbox">
|
||||||
<input type="checkbox" name="picture.disable_gravatar" version="{{.SystemSettings.GetVersion "picture.disable_gravatar"}}"{{if .SystemSettings.GetBool "picture.disable_gravatar"}} checked{{end}}>
|
<input type="checkbox" name="picture.disable_gravatar" version="{{.SystemSettings.GetVersion "picture.disable_gravatar"}}"{{if .SystemSettings.GetBool "picture.disable_gravatar"}} checked{{end}} title="{{.locale.Tr "admin.config.disable_gravatar"}}">
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
<dt>{{.locale.Tr "admin.config.enable_federated_avatar"}}</dt>
|
<dt>{{.locale.Tr "admin.config.enable_federated_avatar"}}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<div class="ui toggle checkbox">
|
<div class="ui toggle checkbox">
|
||||||
<input type="checkbox" name="picture.enable_federated_avatar" version="{{.SystemSettings.GetVersion "picture.enable_federated_avatar"}}"{{if .SystemSettings.GetBool "picture.enable_federated_avatar"}} checked{{end}}>
|
<input type="checkbox" name="picture.enable_federated_avatar" version="{{.SystemSettings.GetVersion "picture.enable_federated_avatar"}}"{{if .SystemSettings.GetBool "picture.enable_federated_avatar"}} checked{{end}} title="{{.locale.Tr "admin.config.enable_federated_avatar"}}">
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>{{.locale.Tr "units.unit"}}</th>
|
<th>{{.locale.Tr "units.unit"}}</th>
|
||||||
<th class="center aligned">{{.locale.Tr "org.teams.none_access"}}
|
<th class="center aligned">{{.locale.Tr "org.teams.none_access"}}
|
||||||
<span class="tooltip vm" data-content="{{.locale.Tr "org.teams.none_access_helper"}}">{{svg "octicon-question" 16 "ml-2"}}</th>
|
<span class="tooltip vm" data-content="{{.locale.Tr "org.teams.none_access_helper"}}">{{svg "octicon-question" 16 "ml-2"}}</span></th>
|
||||||
<th class="center aligned">{{.locale.Tr "org.teams.read_access"}}
|
<th class="center aligned">{{.locale.Tr "org.teams.read_access"}}
|
||||||
<span class="tooltip vm" data-content="{{.locale.Tr "org.teams.read_access_helper"}}">{{svg "octicon-question" 16 "ml-2"}}</span></th>
|
<span class="tooltip vm" data-content="{{.locale.Tr "org.teams.read_access_helper"}}">{{svg "octicon-question" 16 "ml-2"}}</span></th>
|
||||||
<th class="center aligned">{{.locale.Tr "org.teams.write_access"}}
|
<th class="center aligned">{{.locale.Tr "org.teams.write_access"}}
|
||||||
@ -99,17 +99,17 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="center aligned">
|
<td class="center aligned">
|
||||||
<div class="ui radio checkbox">
|
<div class="ui radio checkbox">
|
||||||
<input type="radio" class="hidden" name="unit_{{$unit.Type.Value}}" value="0"{{if or ($unit.Type.UnitGlobalDisabled) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 0)}} checked{{end}}>
|
<input type="radio" class="hidden" name="unit_{{$unit.Type.Value}}" value="0"{{if or ($unit.Type.UnitGlobalDisabled) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 0)}} checked{{end}} title="{{$.locale.Tr "org.teams.none_access"}}">
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="center aligned">
|
<td class="center aligned">
|
||||||
<div class="ui radio checkbox">
|
<div class="ui radio checkbox">
|
||||||
<input type="radio" class="hidden" name="unit_{{$unit.Type.Value}}" value="1"{{if or (eq $.Team.ID 0) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 1)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}}>
|
<input type="radio" class="hidden" name="unit_{{$unit.Type.Value}}" value="1"{{if or (eq $.Team.ID 0) (eq ($.Team.UnitAccessMode $.Context $unit.Type) 1)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}} title="{{$.locale.Tr "org.teams.read_access"}}">
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="center aligned">
|
<td class="center aligned">
|
||||||
<div class="ui radio checkbox">
|
<div class="ui radio checkbox">
|
||||||
<input type="radio" class="hidden" name="unit_{{$unit.Type.Value}}" value="2"{{if (eq ($.Team.UnitAccessMode $.Context $unit.Type) 2)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}}>
|
<input type="radio" class="hidden" name="unit_{{$unit.Type.Value}}" value="2"{{if (eq ($.Team.UnitAccessMode $.Context $unit.Type) 2)}} checked{{end}} {{if $unit.Type.UnitGlobalDisabled}}disabled{{end}} title="{{$.locale.Tr "org.teams.write_access"}}">
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -7,8 +7,15 @@
|
|||||||
<div class="issue-item-main f1 fc df">
|
<div class="issue-item-main f1 fc df">
|
||||||
<div class="issue-item-top-row">
|
<div class="issue-item-top-row">
|
||||||
<a class="index ml-0 mr-2" href="{{if .HTMLURL}}{{.HTMLURL}}{{else}}{{$.Link}}/{{.Index}}{{end}}">
|
<a class="index ml-0 mr-2" href="{{if .HTMLURL}}{{.HTMLURL}}{{else}}{{$.Link}}/{{.Index}}{{end}}">
|
||||||
{{.Title}} <span class="ui label">{{RefShortName .Ref}}</span>
|
{{.Title}}
|
||||||
</a>
|
</a>
|
||||||
|
<span class="ui label">
|
||||||
|
{{if .RefLink}}
|
||||||
|
<a href="{{.RefLink}}">{{.PrettyRef}}</a>
|
||||||
|
{{else}}
|
||||||
|
{{.PrettyRef}}
|
||||||
|
{{end}}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="desc issue-item-bottom-row df ac fw my-1">
|
<div class="desc issue-item-bottom-row df ac fw my-1">
|
||||||
<b>{{if not $.CurWorkflow}}{{.WorkflowID}} {{end}}#{{.Index}}</b>: {{$.locale.Tr "actions.runs.commit"}}
|
<b>{{if not $.CurWorkflow}}{{.WorkflowID}} {{end}}#{{.Index}}</b>: {{$.locale.Tr "actions.runs.commit"}}
|
||||||
|
@ -79,6 +79,7 @@
|
|||||||
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}} mt-3" id="diff-{{$file.NameHash}}" data-old-filename="{{$file.OldName}}" data-new-filename="{{$file.Name}}" {{if $file.ShouldBeHidden}}data-folded="true"{{end}}>
|
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}} mt-3" id="diff-{{$file.NameHash}}" data-old-filename="{{$file.OldName}}" data-new-filename="{{$file.Name}}" {{if $file.ShouldBeHidden}}data-folded="true"{{end}}>
|
||||||
<h4 class="diff-file-header sticky-2nd-row ui top attached normal header df ac sb">
|
<h4 class="diff-file-header sticky-2nd-row ui top attached normal header df ac sb">
|
||||||
<div class="df ac">
|
<div class="df ac">
|
||||||
|
{{if or (gt $file.Addition 0) (gt $file.Deletion 0) $file.IsBin}}
|
||||||
<a role="button" class="fold-file muted mr-2">
|
<a role="button" class="fold-file muted mr-2">
|
||||||
{{if $file.ShouldBeHidden}}
|
{{if $file.ShouldBeHidden}}
|
||||||
{{svg "octicon-chevron-right" 18}}
|
{{svg "octicon-chevron-right" 18}}
|
||||||
@ -86,6 +87,7 @@
|
|||||||
{{svg "octicon-chevron-down" 18}}
|
{{svg "octicon-chevron-down" 18}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</a>
|
</a>
|
||||||
|
{{end}}
|
||||||
<div class="bold df ac">
|
<div class="bold df ac">
|
||||||
{{if $file.IsBin}}
|
{{if $file.IsBin}}
|
||||||
<span class="ml-1 mr-3">
|
<span class="ml-1 mr-3">
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
<div class="quick-pull-branch-name {{if not (eq .commit_choice "commit-to-new-branch")}}hide{{end}}">
|
<div class="quick-pull-branch-name {{if not (eq .commit_choice "commit-to-new-branch")}}hide{{end}}">
|
||||||
<div class="new-branch-name-input field {{if .Err_NewBranchName}}error{{end}}">
|
<div class="new-branch-name-input field {{if .Err_NewBranchName}}error{{end}}">
|
||||||
{{svg "octicon-git-branch"}}
|
{{svg "octicon-git-branch"}}
|
||||||
<input type="text" name="new_branch_name" value="{{.new_branch_name}}" class="input-contrast mr-2 js-quick-pull-new-branch-name" placeholder="{{.locale.Tr "repo.editor.new_branch_name_desc"}}" {{if eq .commit_choice "commit-to-new-branch"}}required{{end}}>
|
<input type="text" name="new_branch_name" value="{{.new_branch_name}}" class="input-contrast mr-2 js-quick-pull-new-branch-name" placeholder="{{.locale.Tr "repo.editor.new_branch_name_desc"}}" {{if eq .commit_choice "commit-to-new-branch"}}required{{end}} title="{{.locale.Tr "repo.editor.new_branch_name"}}">
|
||||||
<span class="text-muted js-quick-pull-normalization-info"></span>
|
<span class="text-muted js-quick-pull-normalization-info"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
<form method="post" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}">
|
<form method="post" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}">
|
||||||
{{$.CsrfTokenHtml}}
|
{{$.CsrfTokenHtml}}
|
||||||
<div class="ui labeled button{{if not $.IsSigned}} tooltip{{end}}" tabindex="0"{{if not $.IsSigned}} data-content="{{$.locale.Tr "repo.watch_guest_user"}}" data-position="top center"{{end}}>
|
<div class="ui labeled button{{if not $.IsSigned}} tooltip{{end}}"{{if not $.IsSigned}} data-content="{{$.locale.Tr "repo.watch_guest_user"}}" data-position="top center"{{end}}>
|
||||||
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}}>
|
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}}>
|
||||||
{{if $.IsWatchingRepo}}{{svg "octicon-eye-closed" 16}}{{$.locale.Tr "repo.unwatch"}}{{else}}{{svg "octicon-eye"}}{{$.locale.Tr "repo.watch"}}{{end}}
|
{{if $.IsWatchingRepo}}{{svg "octicon-eye-closed" 16}}{{$.locale.Tr "repo.unwatch"}}{{else}}{{svg "octicon-eye"}}{{$.locale.Tr "repo.watch"}}{{end}}
|
||||||
</button>
|
</button>
|
||||||
@ -80,7 +80,7 @@
|
|||||||
{{if not $.DisableStars}}
|
{{if not $.DisableStars}}
|
||||||
<form method="post" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}">
|
<form method="post" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}">
|
||||||
{{$.CsrfTokenHtml}}
|
{{$.CsrfTokenHtml}}
|
||||||
<div class="ui labeled button{{if not $.IsSigned}} tooltip{{end}}" tabindex="0"{{if not $.IsSigned}} data-content="{{$.locale.Tr "repo.star_guest_user"}}" data-position="top center"{{end}}>
|
<div class="ui labeled button{{if not $.IsSigned}} tooltip{{end}}"{{if not $.IsSigned}} data-content="{{$.locale.Tr "repo.star_guest_user"}}" data-position="top center"{{end}}>
|
||||||
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}}>
|
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}}>
|
||||||
{{if $.IsStaringRepo}}{{svg "octicon-star-fill"}}{{$.locale.Tr "repo.unstar"}}{{else}}{{svg "octicon-star"}}{{$.locale.Tr "repo.star"}}{{end}}
|
{{if $.IsStaringRepo}}{{svg "octicon-star-fill"}}{{$.locale.Tr "repo.unstar"}}{{else}}{{svg "octicon-star"}}{{$.locale.Tr "repo.star"}}{{end}}
|
||||||
</button>
|
</button>
|
||||||
@ -100,7 +100,7 @@
|
|||||||
{{else if and (not $.CanSignedUserFork) (eq (len $.UserAndOrgForks) 0)}}
|
{{else if and (not $.CanSignedUserFork) (eq (len $.UserAndOrgForks) 0)}}
|
||||||
data-content="{{$.locale.Tr "repo.fork_from_self"}}"
|
data-content="{{$.locale.Tr "repo.fork_from_self"}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
data-position="top center" tabindex="0">
|
data-position="top center">
|
||||||
<a class="ui compact{{if $.ShowForkModal}} show-modal{{end}} small basic button"
|
<a class="ui compact{{if $.ShowForkModal}} show-modal{{end}} small basic button"
|
||||||
{{if not $.CanSignedUserFork}}
|
{{if not $.CanSignedUserFork}}
|
||||||
{{if gt (len $.UserAndOrgForks) 1}}
|
{{if gt (len $.UserAndOrgForks) 1}}
|
||||||
|
@ -30,8 +30,7 @@
|
|||||||
<div class="six wide column">
|
<div class="six wide column">
|
||||||
{{if $.CanWriteIssuesOrPulls}}
|
{{if $.CanWriteIssuesOrPulls}}
|
||||||
<div class="ui checkbox issue-checkbox-all vm">
|
<div class="ui checkbox issue-checkbox-all vm">
|
||||||
<input type="checkbox"></input>
|
<input type="checkbox" title="{{.locale.Tr "repo.issues.action_check_all"}}">
|
||||||
<label></label>
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{template "repo/issue/openclose" .}}
|
{{template "repo/issue/openclose" .}}
|
||||||
|
@ -212,6 +212,13 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</a>
|
</a>
|
||||||
<div class="menu" data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/projects">
|
<div class="menu" data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/projects">
|
||||||
|
<div class="header" style="text-transform: none;font-size:16px;">{{.locale.Tr "repo.issues.new.add_project_title"}}</div>
|
||||||
|
{{if or .OpenProjects .ClosedProjects}}
|
||||||
|
<div class="ui icon search input">
|
||||||
|
<i class="icon df ac jc">{{svg "octicon-search" 16}}</i>
|
||||||
|
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_projects"}}">
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
<div class="no-select item">{{.locale.Tr "repo.issues.new.clear_projects"}}</div>
|
<div class="no-select item">{{.locale.Tr "repo.issues.new.clear_projects"}}</div>
|
||||||
{{if .OpenProjects}}
|
{{if .OpenProjects}}
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
|
@ -420,6 +420,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{$isReleasesEnabled := .Repository.UnitEnabled $.Context $.UnitTypeReleases}}
|
||||||
|
<div class="inline field">
|
||||||
|
<label>{{.locale.Tr "repo.releases"}}</label>
|
||||||
|
{{if .UnitTypeReleases.UnitGlobalDisabled}}
|
||||||
|
<div class="ui checkbox tooltip disabled" data-content="{{.locale.Tr "repo.unit_disabled"}}">
|
||||||
|
{{else}}
|
||||||
|
<div class="ui checkbox">
|
||||||
|
{{end}}
|
||||||
|
<input class="enable-system" name="enable_releases" type="checkbox" {{if $isReleasesEnabled}}checked{{end}}>
|
||||||
|
<label>{{.locale.Tr "repo.settings.releases_desc"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{$isPackagesEnabled := .Repository.UnitEnabled $.Context $.UnitTypePackages}}
|
{{$isPackagesEnabled := .Repository.UnitEnabled $.Context $.UnitTypePackages}}
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label>{{.locale.Tr "repo.packages"}}</label>
|
<label>{{.locale.Tr "repo.packages"}}</label>
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
<div class="issue-item-left df">
|
<div class="issue-item-left df">
|
||||||
{{if $.CanWriteIssuesOrPulls}}
|
{{if $.CanWriteIssuesOrPulls}}
|
||||||
<div class="ui checkbox issue-checkbox">
|
<div class="ui checkbox issue-checkbox">
|
||||||
<input type="checkbox" data-issue-id={{.ID}}></input>
|
<input type="checkbox" data-issue-id={{.ID}} title="{{$.locale.Tr "repo.issues.action_check"}} «{{.Title}}»">
|
||||||
<label></label>
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="issue-item-icon">
|
<div class="issue-item-icon">
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
<a class="{{if not $.RepoIDs}}ui basic primary button{{end}} repo name item" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&q={{$.Keyword}}">
|
<a class="{{if not $.RepoIDs}}ui basic primary button{{end}} repo name item" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&q={{$.Keyword}}">
|
||||||
<span class="text truncate">All</span>
|
<span class="text truncate">All</span>
|
||||||
<div class="ui {{if $.IsShowClosed}}red{{else}}green{{end}} label">{{CountFmt .TotalIssueCount}}</div>
|
<span class="ui">{{CountFmt .TotalIssueCount}}</span>
|
||||||
</a>
|
</a>
|
||||||
{{range .Repos}}
|
{{range .Repos}}
|
||||||
{{with $Repo := .}}
|
{{with $Repo := .}}
|
||||||
@ -49,7 +49,7 @@
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
]&sort={{$.SortType}}&state={{$.State}}&q={{$.Keyword}}" title="{{.FullName}}">
|
]&sort={{$.SortType}}&state={{$.State}}&q={{$.Keyword}}" title="{{.FullName}}">
|
||||||
<span class="text truncate">{{$Repo.FullName}}</span>
|
<span class="text truncate">{{$Repo.FullName}}</span>
|
||||||
<div class="ui {{if $.IsShowClosed}}red{{else}}green{{end}} label">{{CountFmt (index $.Counts $Repo.ID)}}</div>
|
<span class="ui">{{CountFmt (index $.Counts $Repo.ID)}}</span>
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
{{avatar . 100}}
|
{{avatar . 100}}
|
||||||
<span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
|
<span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
|
||||||
<span class="org-visibility">
|
<span class="org-visibility">
|
||||||
{{if .Visibility.IsLimited}}<div class="ui medium orange horizontal label">{{$.locale.Tr "org.settings.visibility.limited_shortname"}}</div>{{end}}
|
{{if .Visibility.IsLimited}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.limited_shortname"}}</div>{{end}}
|
||||||
{{if .Visibility.IsPrivate}}<div class="ui medium red horizontal label">{{$.locale.Tr "org.settings.visibility.private_shortname"}}</div>{{end}}
|
{{if .Visibility.IsPrivate}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.private_shortname"}}</div>{{end}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -187,7 +187,7 @@ func TestPullCleanUpAfterMerge(t *testing.T) {
|
|||||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
resultMsg := htmlDoc.doc.Find(".ui.message>p").Text()
|
resultMsg := htmlDoc.doc.Find(".ui.message>p").Text()
|
||||||
|
|
||||||
assert.EqualValues(t, "Branch 'user1/feature/test' has been deleted.", resultMsg)
|
assert.EqualValues(t, "Branch 'user1/repo1:feature/test' has been deleted.", resultMsg)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTU1NTE2MTh9.h
|
|||||||
ENABLED = true
|
ENABLED = true
|
||||||
|
|
||||||
[email.incoming]
|
[email.incoming]
|
||||||
ENABLED = true
|
ENABLED = false
|
||||||
HOST = smtpimap
|
HOST = smtpimap
|
||||||
PORT = 993
|
PORT = 993
|
||||||
USERNAME = debug@localdomain.test
|
USERNAME = debug@localdomain.test
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<div class="action-view-left">
|
<div class="action-view-left">
|
||||||
<div class="job-group-section">
|
<div class="job-group-section">
|
||||||
<div class="job-brief-list">
|
<div class="job-brief-list">
|
||||||
<a class="job-brief-item" v-for="(job, index) in run.jobs" :key="job.id" :href="run.htmlurl+'/jobs/'+index">
|
<a class="job-brief-item" v-for="(job, index) in run.jobs" :key="job.id" :href="run.link+'/jobs/'+index">
|
||||||
<SvgIcon name="octicon-check-circle-fill" class="green" v-if="job.status === 'success'"/>
|
<SvgIcon name="octicon-check-circle-fill" class="green" v-if="job.status === 'success'"/>
|
||||||
<SvgIcon name="octicon-skip" class="ui text grey" v-else-if="job.status === 'skipped'"/>
|
<SvgIcon name="octicon-skip" class="ui text grey" v-else-if="job.status === 'skipped'"/>
|
||||||
<SvgIcon name="octicon-clock" class="ui text yellow" v-else-if="job.status === 'waiting'"/>
|
<SvgIcon name="octicon-clock" class="ui text yellow" v-else-if="job.status === 'waiting'"/>
|
||||||
@ -92,7 +92,7 @@ const sfc = {
|
|||||||
|
|
||||||
// provided by backend
|
// provided by backend
|
||||||
run: {
|
run: {
|
||||||
htmlurl: '',
|
link: '',
|
||||||
title: '',
|
title: '',
|
||||||
canCancel: false,
|
canCancel: false,
|
||||||
done: false,
|
done: false,
|
||||||
@ -163,11 +163,11 @@ const sfc = {
|
|||||||
},
|
},
|
||||||
// rerun a job
|
// rerun a job
|
||||||
rerunJob(idx) {
|
rerunJob(idx) {
|
||||||
this.fetch(`${this.run.htmlurl}/jobs/${idx}/rerun`);
|
this.fetch(`${this.run.link}/jobs/${idx}/rerun`);
|
||||||
},
|
},
|
||||||
// cancel a run
|
// cancel a run
|
||||||
cancelRun() {
|
cancelRun() {
|
||||||
this.fetch(`${this.run.htmlurl}/cancel`);
|
this.fetch(`${this.run.link}/cancel`);
|
||||||
},
|
},
|
||||||
|
|
||||||
createLogLine(line) {
|
createLogLine(line) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user