Compare commits

...

5 Commits
v1.0.0 ... main

Author SHA1 Message Date
silverwind 9d720a45a2 Remove `type/dependency-update` (#84)
This only removes the `type/dependency-update` label which I recently deleted on GitHub. The file was CRLF and the web editor converted it to LF. I'd say LF is preferred anyways.

Reviewed-on: https://gitea.com/gitea/changelog/pulls/84
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: Denys Konovalov <denyskon@noreply.gitea.com>
2024-03-27 20:08:27 +00:00
Denys Konovalov 91a081912c Switch to new label style (#83)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/83
Reviewed-by: John Olheiser <john+gitea@jolheiser.com>
Reviewed-by: delvh <dev.lh@web.de>
Co-authored-by: Denys Konovalov <denyskon@noreply.gitea.com>
Co-committed-by: Denys Konovalov <denyskon@noreply.gitea.com>
2023-11-14 02:08:19 +00:00
techknowlogick 769323fbd7 minor updates to readme 2023-09-05 14:35:42 +00:00
jolheiser 3d93c3a0cd Use issue list API instead of search (#78)
This PR changes to using the GH issue list API rather than search, as for some reason the search results started missing several PRs...

Reviewed-on: https://gitea.com/gitea/changelog/pulls/78
Co-authored-by: jolheiser <john.olheiser@gmail.com>
Co-committed-by: jolheiser <john.olheiser@gmail.com>
2023-07-20 10:08:48 +00:00
6543 482c085290 Respect --token argument on github too (#79)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/79
Reviewed-by: John Olheiser <john+gitea@jolheiser.com>
Reviewed-by: delvh <dev.lh@web.de>
2023-06-23 17:20:48 +00:00
3 changed files with 106 additions and 43 deletions

View File

@ -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

View File

@ -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

View File

@ -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")
}