109 lines
2.6 KiB
Go
109 lines
2.6 KiB
Go
|
package blog
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
_ "embed"
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"net/http"
|
||
|
"text/template"
|
||
|
"time"
|
||
|
|
||
|
"github.com/skratchdot/open-golang/open"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
mergedURLFmt = "https://api.github.com/search/issues?q=repo:go-gitea/gitea+is:pr+is:merged+milestone:%s"
|
||
|
changelogURLFmt = "https://api.github.com/search/issues?q=repo:go-gitea/gitea+is:pr+is:merged+Changelog+%s"
|
||
|
|
||
|
//go:embed release.md
|
||
|
tmplContent string
|
||
|
tmpl = template.Must(template.New("").Parse(tmplContent))
|
||
|
)
|
||
|
|
||
|
// Merged is the API response for getting count of merged PRs in a milestone
|
||
|
type Merged struct {
|
||
|
TotalCount int `json:"total_count"`
|
||
|
}
|
||
|
|
||
|
// FormatRelease formats a release template and injects author, milestone, changelog, and merged PR counts
|
||
|
func FormatRelease(author, milestone, changelog string) ([]byte, error) {
|
||
|
resp, err := http.Get(fmt.Sprintf(mergedURLFmt, milestone))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
body, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
var merged Merged
|
||
|
if err := json.Unmarshal(body, &merged); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
date := time.Now()
|
||
|
m := map[string]interface{}{
|
||
|
"Author": author,
|
||
|
"Milestone": milestone,
|
||
|
"Changelog": changelog,
|
||
|
"Merged": merged.TotalCount,
|
||
|
"DateLong": date.Format("2006-01-02T15:04:05+07:00"),
|
||
|
"DateShort": date.Format("2006-01-02"),
|
||
|
}
|
||
|
|
||
|
var buf bytes.Buffer
|
||
|
if err := tmpl.Execute(&buf, m); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return buf.Bytes(), nil
|
||
|
}
|
||
|
|
||
|
// Release is the API response for a release
|
||
|
type Release struct {
|
||
|
Name string `json:"name"`
|
||
|
PublishedAt time.Time `json:"published_at"`
|
||
|
}
|
||
|
|
||
|
// LatestRelease gets the latest release, used as a default for the generator
|
||
|
func LatestRelease() (Release, error) {
|
||
|
var rel Release
|
||
|
resp, err := http.Get("https://api.github.com/repos/go-gitea/gitea/releases/latest")
|
||
|
if err != nil {
|
||
|
return rel, err
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
return rel, json.NewDecoder(resp.Body).Decode(&rel)
|
||
|
}
|
||
|
|
||
|
// ChangelogPR is the API response when searching for the milestone changelog PR
|
||
|
type ChangelogPR struct {
|
||
|
Items []struct {
|
||
|
HTMLURL string `json:"html_url"`
|
||
|
} `json:"items"`
|
||
|
}
|
||
|
|
||
|
// OpenChangelogPullRequest attempts to open a browser to the changelog PR of a given milestone
|
||
|
func OpenChangelogPullRequest(milestone string) error {
|
||
|
resp, err := http.Get(fmt.Sprintf(changelogURLFmt, milestone))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
var pr ChangelogPR
|
||
|
if err := json.NewDecoder(resp.Body).Decode(&pr); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if len(pr.Items) == 0 {
|
||
|
return errors.New("could not find changelog PR")
|
||
|
}
|
||
|
|
||
|
return open.Start(pr.Items[0].HTMLURL + "/files")
|
||
|
}
|