forked from lunny/changelog
Updates and priority changes (#62)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/62 Reviewed-by: 6543 <6543@obermui.de> Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: John Olheiser <john+gitea@jolheiser.com> Co-committed-by: John Olheiser <john+gitea@jolheiser.com>
This commit is contained in:
parent
f3ee0e5726
commit
57e620da5b
10
.drone.yml
10
.drone.yml
@ -13,18 +13,18 @@ trigger:
|
||||
steps:
|
||||
- name: build
|
||||
pull: always
|
||||
image: golang:1.17
|
||||
image: golang:1.18
|
||||
environment:
|
||||
GOPROXY: https://goproxy.cn,direct
|
||||
GOPROXY: https://goproxy.io,direct
|
||||
commands:
|
||||
- go test -race ./...
|
||||
- go build
|
||||
|
||||
- name: check
|
||||
pull: always
|
||||
image: golang:1.17
|
||||
image: golang:1.18
|
||||
environment:
|
||||
GOPROXY: https://goproxy.cn,direct
|
||||
GOPROXY: https://goproxy.io,direct
|
||||
commands:
|
||||
- make lint
|
||||
|
||||
@ -70,7 +70,7 @@ steps:
|
||||
pull: always
|
||||
image: techknowlogick/xgo:latest
|
||||
environment:
|
||||
GOPROXY: https://goproxy.cn,direct
|
||||
GOPROXY: https://goproxy.io,direct
|
||||
commands:
|
||||
- export PATH=$PATH:$GOPATH/bin
|
||||
- make release
|
||||
|
@ -10,12 +10,11 @@ linters:
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- golint
|
||||
- gosimple
|
||||
- govet
|
||||
- maligned
|
||||
- misspell
|
||||
- prealloc
|
||||
- revive
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
|
18
Makefile
18
Makefile
@ -15,27 +15,23 @@ else
|
||||
LONG_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')
|
||||
endif
|
||||
|
||||
LDFLAGS := $(LDFLAGS) -X "main.Version=$(LONG_VERSION)"
|
||||
LDFLAGS := $(LDFLAGS) -X "code.gitea.io/changelog/cmd.Version=$(LONG_VERSION)"
|
||||
|
||||
.PHONY: build
|
||||
build: generate
|
||||
build:
|
||||
$(GO) build -ldflags '-s -w $(LDFLAGS)'
|
||||
|
||||
.PHONY: generate
|
||||
generate:
|
||||
$(GO) generate ./...
|
||||
.PHONY: test
|
||||
test:
|
||||
$(GO) test -race -v ./...
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
@hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
export BINARY="golangci-lint"; \
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.37.0; \
|
||||
fi
|
||||
golangci-lint run --timeout 5m
|
||||
$(GO) run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.46.2 run --timeout 5m
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
go fmt ./...
|
||||
$(GO) fmt ./...
|
||||
|
||||
.PHONY: release
|
||||
release: release-dirs check-xgo release-windows release-linux release-darwin release-copy release-compress release-check
|
||||
|
@ -15,7 +15,7 @@ Download a pre-built binary from our [downloads page](https://dl.gitea.io/change
|
||||
|
||||
## Configuration
|
||||
|
||||
See the [changelog.example.yml](changelog.example.yml) example file.
|
||||
See the [changelog.example.yml](config/changelog.example.yml) example file.
|
||||
|
||||
## Usage
|
||||
|
||||
@ -31,7 +31,6 @@ changelog -m=1.11.0 -c=/path/to/my_config_file contributors
|
||||
|
||||
## Building
|
||||
```
|
||||
go generate ./...
|
||||
go build
|
||||
```
|
||||
|
||||
|
@ -1,44 +0,0 @@
|
||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
exampleFile = "changelog.example.yml"
|
||||
writeFile = "config/config_default.go"
|
||||
tmpl = `// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package config
|
||||
|
||||
func init() {
|
||||
DefaultConfig = []byte(` + "`" + `%s` + "`" + `)
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
func main() {
|
||||
bytes, err := ioutil.ReadFile(exampleFile)
|
||||
if err != nil {
|
||||
fmt.Printf("Could not read from %s. Are you in the root directory of the project?", exampleFile)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
data := fmt.Sprintf(tmpl, string(bytes))
|
||||
|
||||
if err := ioutil.WriteFile(writeFile, []byte(data), os.ModePerm); err != nil {
|
||||
fmt.Printf("Could not write to %s.", writeFile)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
80
cmd/cmd.go
80
cmd/cmd.go
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@ -7,18 +7,82 @@ package cmd
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
MilestoneFlag string
|
||||
TagFlag string
|
||||
ConfigPathFlag string
|
||||
TokenFlag string
|
||||
DetailsFlag bool
|
||||
AfterFlag int64
|
||||
IssuesFlag bool
|
||||
// Version of changelog
|
||||
Version = "development"
|
||||
milestoneFlag string
|
||||
tagFlag string
|
||||
configPathFlag string
|
||||
tokenFlag string
|
||||
detailsFlag bool
|
||||
afterFlag int64
|
||||
issuesFlag bool
|
||||
)
|
||||
|
||||
// New returns a new changelog App
|
||||
func New() *cli.App {
|
||||
app := &cli.App{
|
||||
Name: "changelog",
|
||||
Usage: "Changelog tools for Gitea",
|
||||
Version: Version,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "milestone",
|
||||
Aliases: []string{"m"},
|
||||
Usage: "Targeted milestone",
|
||||
Destination: &milestoneFlag,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tag",
|
||||
Aliases: []string{"T"},
|
||||
Usage: "Git tag for milestone url, if not set milestone is used",
|
||||
Destination: &tagFlag,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "config",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "Specify a config file",
|
||||
Value: getDefaultConfigFile(),
|
||||
Destination: &configPathFlag,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "token",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "Access token for private repositories/instances",
|
||||
Destination: &tokenFlag,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "details",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "Generate detail lists instead of long lists",
|
||||
Destination: &detailsFlag,
|
||||
},
|
||||
&cli.Int64Flag{
|
||||
Name: "after",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Only select PRs after a given index (continuing a previous changelog)",
|
||||
Destination: &afterFlag,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "issues",
|
||||
Aliases: []string{"i"},
|
||||
Usage: "Generate changelog from issues (otherwise from pulls)",
|
||||
Destination: &issuesFlag,
|
||||
},
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
Generate,
|
||||
Contributors,
|
||||
Init,
|
||||
},
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
func getDefaultConfigFile() string {
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
|
@ -20,17 +20,13 @@ var Contributors = &cli.Command{
|
||||
Action: runContributors,
|
||||
}
|
||||
|
||||
func runContributors(cmd *cli.Context) error {
|
||||
if ConfigPathFlag == "" {
|
||||
ConfigPathFlag = getDefaultConfigFile()
|
||||
}
|
||||
|
||||
cfg, err := config.New(ConfigPathFlag)
|
||||
func runContributors(_ *cli.Context) error {
|
||||
cfg, err := config.New(configPathFlag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, MilestoneFlag, TagFlag, TokenFlag, IssuesFlag)
|
||||
s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, milestoneFlag, tagFlag, tokenFlag, issuesFlag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/changelog/config"
|
||||
"code.gitea.io/changelog/service"
|
||||
@ -14,30 +15,19 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
Generate = &cli.Command{
|
||||
Name: "generate",
|
||||
Usage: "Generates a changelog for a special milestone",
|
||||
Action: runGenerate,
|
||||
}
|
||||
labels = make(map[string]string)
|
||||
entries = make(map[string][]service.Entry)
|
||||
defaultGroup string
|
||||
)
|
||||
var Generate = &cli.Command{
|
||||
Name: "generate",
|
||||
Usage: "Generates a changelog for a special milestone",
|
||||
Action: runGenerate,
|
||||
}
|
||||
|
||||
func runGenerate(cmd *cli.Context) error {
|
||||
if ConfigPathFlag == "" {
|
||||
ConfigPathFlag = getDefaultConfigFile()
|
||||
}
|
||||
|
||||
cfg, err := config.New(ConfigPathFlag)
|
||||
func runGenerate(_ *cli.Context) error {
|
||||
cfg, err := config.New(configPathFlag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
processGroups(cfg.Groups)
|
||||
|
||||
s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, MilestoneFlag, TagFlag, TokenFlag, IssuesFlag)
|
||||
s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, milestoneFlag, tagFlag, tokenFlag, issuesFlag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -47,7 +37,17 @@ func runGenerate(cmd *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
processPRs(prs, cfg.SkipRegex)
|
||||
var defaultGroup string
|
||||
for _, g := range cfg.Groups {
|
||||
if g.Default {
|
||||
defaultGroup = g.Name
|
||||
}
|
||||
}
|
||||
if defaultGroup == "" {
|
||||
defaultGroup = cfg.Groups[len(cfg.Groups)-1].Name
|
||||
}
|
||||
|
||||
entries := processPRs(prs, cfg.NameLabels(), defaultGroup, cfg.SkipRegex)
|
||||
|
||||
fmt.Println(title)
|
||||
fmt.Println()
|
||||
@ -56,7 +56,7 @@ func runGenerate(cmd *cli.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if DetailsFlag {
|
||||
if detailsFlag {
|
||||
fmt.Println("<details><summary>" + g.Name + "</summary>")
|
||||
fmt.Println()
|
||||
for _, entry := range entries[g.Name] {
|
||||
@ -74,44 +74,32 @@ func runGenerate(cmd *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func processGroups(groups []config.Group) {
|
||||
for _, g := range groups {
|
||||
entries[g.Name] = []service.Entry{}
|
||||
for _, l := range g.Labels {
|
||||
labels[l] = g.Name
|
||||
}
|
||||
if g.Default {
|
||||
defaultGroup = g.Name
|
||||
}
|
||||
}
|
||||
|
||||
if defaultGroup == "" {
|
||||
defaultGroup = groups[len(groups)-1].Name
|
||||
}
|
||||
}
|
||||
|
||||
func processPRs(prs []service.Entry, skip *regexp.Regexp) {
|
||||
func processPRs(prs []service.Entry, order []config.NameLabel, defaultGroup string, skip *regexp.Regexp) map[string][]service.Entry {
|
||||
entries := make(map[string][]service.Entry)
|
||||
PRLoop: // labels in Go, let's get old school
|
||||
for _, pr := range prs {
|
||||
if pr.Index < AfterFlag {
|
||||
if pr.Index < afterFlag {
|
||||
continue
|
||||
}
|
||||
|
||||
var label string
|
||||
for _, lb := range pr.Labels {
|
||||
if skip != nil && skip.MatchString(lb.Name) {
|
||||
continue PRLoop
|
||||
}
|
||||
}
|
||||
section := processSection(pr, order, defaultGroup)
|
||||
entries[section] = append(entries[section], pr)
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
if g, ok := labels[lb.Name]; ok && len(label) == 0 {
|
||||
label = g
|
||||
func processSection(pr service.Entry, order []config.NameLabel, defaultGroup string) string {
|
||||
for _, o := range order {
|
||||
for _, lb := range pr.Labels {
|
||||
if strings.EqualFold(o.Label, lb.Name) {
|
||||
return o.Name
|
||||
}
|
||||
}
|
||||
|
||||
if len(label) > 0 {
|
||||
entries[label] = append(entries[label], pr)
|
||||
} else {
|
||||
entries[defaultGroup] = append(entries[defaultGroup], pr)
|
||||
}
|
||||
}
|
||||
return defaultGroup
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ var (
|
||||
nameFlag string
|
||||
)
|
||||
|
||||
func runInit(cmd *cli.Context) error {
|
||||
func runInit(_ *cli.Context) error {
|
||||
if _, err := os.Stat(nameFlag); err == nil {
|
||||
return fmt.Errorf("file '%s' already exists", nameFlag)
|
||||
}
|
||||
|
@ -5,12 +5,14 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
//go:embed changelog.example.yml
|
||||
var DefaultConfig []byte
|
||||
|
||||
// Group is a grouping of PRs
|
||||
@ -20,6 +22,24 @@ type Group struct {
|
||||
Default bool `yaml:"default"`
|
||||
}
|
||||
|
||||
// NameLabel is a Group mapping for a Label to a Name
|
||||
type NameLabel struct {
|
||||
Name string
|
||||
Label string
|
||||
}
|
||||
|
||||
// NameLabels returns a slice of NameLabel
|
||||
func (g Group) NameLabels() []NameLabel {
|
||||
nl := make([]NameLabel, 0)
|
||||
for _, l := range g.Labels {
|
||||
nl = append(nl, NameLabel{
|
||||
Name: g.Name,
|
||||
Label: l,
|
||||
})
|
||||
}
|
||||
return nl
|
||||
}
|
||||
|
||||
// Config is the changelog settings
|
||||
type Config struct {
|
||||
Repo string `yaml:"repo"`
|
||||
@ -30,13 +50,20 @@ type Config struct {
|
||||
SkipRegex *regexp.Regexp `yaml:"-"`
|
||||
}
|
||||
|
||||
// NameLabels returns a slice of NameLabel for each Group, keeping them in order (priority)
|
||||
func (c Config) NameLabels() []NameLabel {
|
||||
nl := make([]NameLabel, 0)
|
||||
for _, g := range c.Groups {
|
||||
nl = append(nl, g.NameLabels()...)
|
||||
}
|
||||
return nl
|
||||
}
|
||||
|
||||
// New Load a config from a path, defaulting to changelog.example.yml
|
||||
func New(configPath string) (*Config, error) {
|
||||
var err error
|
||||
var configContent []byte
|
||||
if len(configPath) == 0 {
|
||||
configContent = DefaultConfig
|
||||
} else {
|
||||
configContent := DefaultConfig
|
||||
if len(configPath) != 0 {
|
||||
configContent, err = ioutil.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1,65 +0,0 @@
|
||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package config
|
||||
|
||||
func init() {
|
||||
DefaultConfig = []byte(`# The full repository name
|
||||
repo: go-gitea/gitea
|
||||
|
||||
# Service type (gitea or github)
|
||||
service: github
|
||||
|
||||
# Base URL for Gitea instance if using gitea service type (optional)
|
||||
# Default: https://gitea.com
|
||||
base-url:
|
||||
|
||||
# Changelog groups and which labeled PRs to add to each group
|
||||
groups:
|
||||
-
|
||||
name: BREAKING
|
||||
labels:
|
||||
- kind/breaking
|
||||
-
|
||||
name: FEATURES
|
||||
labels:
|
||||
- kind/feature
|
||||
-
|
||||
name: BUGFIXES
|
||||
labels:
|
||||
- kind/bug
|
||||
-
|
||||
name: ENHANCEMENTS
|
||||
labels:
|
||||
- kind/enhancement
|
||||
- kind/refactor
|
||||
- kind/ui
|
||||
-
|
||||
name: SECURITY
|
||||
labels:
|
||||
- kind/security
|
||||
-
|
||||
name: TESTING
|
||||
labels:
|
||||
- kind/testing
|
||||
-
|
||||
name: TRANSLATION
|
||||
labels:
|
||||
- kind/translation
|
||||
-
|
||||
name: BUILD
|
||||
labels:
|
||||
- kind/build
|
||||
- kind/lint
|
||||
-
|
||||
name: DOCS
|
||||
labels:
|
||||
- kind/docs
|
||||
-
|
||||
name: MISC
|
||||
default: true
|
||||
|
||||
# regex indicating which labels to skip for the changelog
|
||||
skip-labels: skip-changelog|backport\/.+`)
|
||||
}
|
13
go.mod
13
go.mod
@ -1,12 +1,19 @@
|
||||
module code.gitea.io/changelog
|
||||
|
||||
go 1.13
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
code.gitea.io/sdk/gitea v0.14.0
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/google/go-github/v32 v32.1.0
|
||||
github.com/urfave/cli/v2 v2.2.0
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de // indirect
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
github.com/hashicorp/go-version v1.2.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de // indirect
|
||||
)
|
||||
|
66
main.go
66
main.go
@ -4,79 +4,15 @@
|
||||
|
||||
package main
|
||||
|
||||
//go:generate go run changelog.example.go
|
||||
//go:generate go fmt ./...
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"code.gitea.io/changelog/cmd"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
// Version of changelog
|
||||
Version = "development"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := &cli.App{
|
||||
Name: "changelog",
|
||||
Usage: "Changelog tools for Gitea",
|
||||
Version: Version,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "milestone",
|
||||
Aliases: []string{"m"},
|
||||
Usage: "Targeted milestone",
|
||||
Destination: &cmd.MilestoneFlag,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tag",
|
||||
Aliases: []string{"T"},
|
||||
Usage: "Git tag for milestone url, if not set milestone is used",
|
||||
Destination: &cmd.TagFlag,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "config",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "Specify a config file",
|
||||
Destination: &cmd.ConfigPathFlag,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "token",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "Access token for private repositories/instances",
|
||||
Destination: &cmd.TokenFlag,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "details",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "Generate detail lists instead of long lists",
|
||||
Destination: &cmd.DetailsFlag,
|
||||
},
|
||||
&cli.Int64Flag{
|
||||
Name: "after",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Only select PRs after a given index (continuing a previous changelog)",
|
||||
Destination: &cmd.AfterFlag,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "issues",
|
||||
Aliases: []string{"i"},
|
||||
Usage: "Generate changelog from issues (otherwise from pulls)",
|
||||
Destination: &cmd.IssuesFlag,
|
||||
},
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
cmd.Generate,
|
||||
cmd.Contributors,
|
||||
cmd.Init,
|
||||
},
|
||||
}
|
||||
|
||||
app := cmd.New()
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
fmt.Printf("Failed to run app with %s: %v\n", os.Args[1:], err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user