Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
silverwind | 9d720a45a2 | |
Denys Konovalov | 91a081912c | |
techknowlogick | 769323fbd7 | |
jolheiser | 3d93c3a0cd | |
6543 | 482c085290 |
|
@ -2,8 +2,6 @@
|
|||
|
||||
A changelog generator for Gitea
|
||||
|
||||
[![Build Status](https://drone.gitea.com/api/badges/gitea/changelog/status.svg)](https://drone.gitea.com/gitea/changelog)
|
||||
|
||||
## Purpose
|
||||
|
||||
This repo is currently part of Gitea. The purpose of it is to generate a changelog when writing release notes.
|
||||
|
@ -12,7 +10,7 @@ This tool generates a changelog from PRs based on their milestone and labels.
|
|||
|
||||
## Installation
|
||||
|
||||
Download a pre-built binary from our [downloads page](https://dl.gitea.io/changelog-tool/) or clone the source and follow the [building instructions](#building).
|
||||
Download a pre-built binary from our [downloads page](https://dl.gitea.com/changelog-tool/) or clone the source and follow the [building instructions](#building).
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@ -45,7 +43,7 @@ Fork -> Patch -> Push -> Pull Request
|
|||
## Authors
|
||||
|
||||
* [Maintainers](https://gitea.com/org/gitea/members)
|
||||
* [Contributors](https://gitea.com/gitea/changelog/commits/branch/master)<!-- FIXME when contributors page works -->
|
||||
* [Contributors](https://gitea.com/gitea/changelog/commits/branch/main)<!-- FIXME when contributors page works -->
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
@ -10,46 +10,53 @@ base-url:
|
|||
|
||||
# Changelog groups and which labeled PRs to add to each group
|
||||
groups:
|
||||
-
|
||||
-
|
||||
name: BREAKING
|
||||
labels:
|
||||
- kind/breaking
|
||||
-
|
||||
- pr/breaking
|
||||
-
|
||||
name: FEATURES
|
||||
labels:
|
||||
- kind/feature
|
||||
- type/feature
|
||||
-
|
||||
name: API
|
||||
labels:
|
||||
- modifies/api
|
||||
-
|
||||
name: BUGFIXES
|
||||
labels:
|
||||
- kind/bug
|
||||
-
|
||||
- type/bug
|
||||
-
|
||||
name: ENHANCEMENTS
|
||||
labels:
|
||||
- kind/enhancement
|
||||
- kind/refactor
|
||||
- kind/ui
|
||||
- type/enhancement
|
||||
- type/refactoring
|
||||
- topic/ui
|
||||
- topic/ui-interaction
|
||||
- performance/speed
|
||||
-
|
||||
name: SECURITY
|
||||
labels:
|
||||
- kind/security
|
||||
-
|
||||
- topic/security
|
||||
-
|
||||
name: TESTING
|
||||
labels:
|
||||
- kind/testing
|
||||
-
|
||||
- type/testing
|
||||
-
|
||||
name: TRANSLATION
|
||||
labels:
|
||||
- kind/translation
|
||||
-
|
||||
- modifies/translation
|
||||
-
|
||||
name: BUILD
|
||||
labels:
|
||||
- kind/build
|
||||
- kind/lint
|
||||
-
|
||||
- topic/build
|
||||
- topic/code-linting
|
||||
-
|
||||
name: DOCS
|
||||
labels:
|
||||
- kind/docs
|
||||
-
|
||||
- type/docs
|
||||
- modifies/docs
|
||||
-
|
||||
name: MISC
|
||||
default: true
|
||||
|
||||
|
|
|
@ -6,9 +6,12 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-github/v50/github"
|
||||
|
@ -22,27 +25,39 @@ type GitHub struct {
|
|||
Token string
|
||||
Repo string
|
||||
Issues bool
|
||||
client *github.Client
|
||||
}
|
||||
|
||||
// OwnerRepo splits owner/repo
|
||||
func (gh *GitHub) OwnerRepo() (string, string) {
|
||||
parts := strings.Split(gh.Repo, "/")
|
||||
if len(parts) < 2 {
|
||||
return parts[0], ""
|
||||
}
|
||||
return parts[0], parts[1]
|
||||
}
|
||||
|
||||
// Generate returns a GitHub changelog
|
||||
func (gh *GitHub) Generate() (string, []Entry, error) {
|
||||
tagURL := fmt.Sprintf("## [%s](https://github.com/%s/releases/tag/%s) - %s", gh.Milestone, gh.Repo, gh.GitTag, time.Now().Format("2006-01-02"))
|
||||
|
||||
client := github.NewClient(httpClient())
|
||||
owner, repo := gh.OwnerRepo()
|
||||
ctx := context.Background()
|
||||
gh.initClient(ctx)
|
||||
|
||||
tagURL := fmt.Sprintf("## [%s](https://github.com/%s/releases/tag/%s) - %s", gh.Milestone, gh.Repo, gh.GitTag, time.Now().Format("2006-01-02"))
|
||||
|
||||
prs := make([]Entry, 0)
|
||||
|
||||
state := "merged"
|
||||
if gh.Issues {
|
||||
state = "closed"
|
||||
milestoneNum, err := gh.milestoneNum(ctx)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
query := fmt.Sprintf(`repo:%s is:%s milestone:"%s"`, gh.Repo, state, gh.Milestone)
|
||||
p := 1
|
||||
perPage := 100
|
||||
for {
|
||||
result, _, err := client.Search.Issues(ctx, query, &github.SearchOptions{
|
||||
result, _, err := gh.client.Issues.ListByRepo(ctx, owner, repo, &github.IssueListByRepoOptions{
|
||||
Milestone: strconv.Itoa(milestoneNum),
|
||||
State: "closed",
|
||||
ListOptions: github.ListOptions{
|
||||
Page: p,
|
||||
PerPage: perPage,
|
||||
|
@ -55,7 +70,7 @@ func (gh *GitHub) Generate() (string, []Entry, error) {
|
|||
|
||||
isPull := !(gh.Issues)
|
||||
|
||||
for _, pr := range result.Issues {
|
||||
for _, pr := range result {
|
||||
if pr.IsPullRequest() == isPull {
|
||||
p := Entry{
|
||||
Title: CleanTitle(pr.GetTitle()),
|
||||
|
@ -74,7 +89,7 @@ func (gh *GitHub) Generate() (string, []Entry, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if len(result.Issues) != perPage {
|
||||
if len(result) != perPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -84,15 +99,21 @@ func (gh *GitHub) Generate() (string, []Entry, error) {
|
|||
|
||||
// Contributors returns a list of contributors from GitHub
|
||||
func (gh *GitHub) Contributors() (ContributorList, error) {
|
||||
client := github.NewClient(httpClient())
|
||||
ctx := context.Background()
|
||||
owner, repo := gh.OwnerRepo()
|
||||
gh.initClient(ctx)
|
||||
|
||||
contributorsMap := make(map[string]bool)
|
||||
query := fmt.Sprintf(`repo:%s is:merged milestone:"%s"`, gh.Repo, gh.Milestone)
|
||||
milestoneNum, err := gh.milestoneNum(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p := 1
|
||||
perPage := 100
|
||||
for {
|
||||
result, _, err := client.Search.Issues(ctx, query, &github.SearchOptions{
|
||||
result, _, err := gh.client.Issues.ListByRepo(ctx, owner, repo, &github.IssueListByRepoOptions{
|
||||
Milestone: strconv.Itoa(milestoneNum),
|
||||
State: "closed",
|
||||
ListOptions: github.ListOptions{
|
||||
Page: p,
|
||||
PerPage: perPage,
|
||||
|
@ -103,11 +124,11 @@ func (gh *GitHub) Contributors() (ContributorList, error) {
|
|||
}
|
||||
p++
|
||||
|
||||
for _, pr := range result.Issues {
|
||||
for _, pr := range result {
|
||||
contributorsMap[pr.GetUser().GetLogin()] = true
|
||||
}
|
||||
|
||||
if len(result.Issues) != perPage {
|
||||
if len(result) != perPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -123,14 +144,51 @@ func (gh *GitHub) Contributors() (ContributorList, error) {
|
|||
return contributors, nil
|
||||
}
|
||||
|
||||
func httpClient() *http.Client {
|
||||
func (gh *GitHub) initClient(ctx context.Context) {
|
||||
token := gh.Token
|
||||
if envToken, ok := os.LookupEnv("CHANGELOG_GITHUB_TOKEN"); ok && token == "" {
|
||||
token = envToken
|
||||
}
|
||||
cl := http.DefaultClient
|
||||
if token, ok := os.LookupEnv("CHANGELOG_GITHUB_TOKEN"); ok {
|
||||
ctx := context.Background()
|
||||
if token != "" {
|
||||
ts := oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: token},
|
||||
)
|
||||
cl = oauth2.NewClient(ctx, ts)
|
||||
}
|
||||
return cl
|
||||
|
||||
gh.client = github.NewClient(cl)
|
||||
}
|
||||
|
||||
func (gh *GitHub) milestoneNum(ctx context.Context) (int, error) {
|
||||
owner, repo := gh.OwnerRepo()
|
||||
p := 1
|
||||
perPage := 100
|
||||
for {
|
||||
milestones, _, err := gh.client.Issues.ListMilestones(ctx, owner, repo, &github.MilestoneListOptions{
|
||||
State: "all",
|
||||
ListOptions: github.ListOptions{
|
||||
Page: p,
|
||||
PerPage: perPage,
|
||||
},
|
||||
Sort: "due_on",
|
||||
Direction: "desc",
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
p++
|
||||
|
||||
for _, milestone := range milestones {
|
||||
if strings.EqualFold(milestone.GetTitle(), gh.Milestone) {
|
||||
return milestone.GetNumber(), nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(milestones) != perPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return 0, errors.New("no milestone found")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue