Compare commits

...

47 Commits
v0.1.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
techknowlogick 07c0fc1414 release tag pipeline 2023-04-14 15:17:23 -04:00
jolheiser 8156d742f5 Update to urfave/cli/v3 (#77)
This allows for persistent flags, such that `changelog -m v0.4.0 generate` and `changelog generate -m v0.4.0` are equivalent.

Reviewed-on: https://gitea.com/gitea/changelog/pulls/77
Reviewed-by: 6543 <6543@obermui.de>
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: jolheiser <john.olheiser@gmail.com>
Co-committed-by: jolheiser <john.olheiser@gmail.com>
2023-04-03 11:51:25 +08:00
jolheiser 70c955ae17 Title-case PR title (#76)
Resolves #60

Extracts the previous trim into a new func as well to keep any title munging consistent.

Reviewed-on: https://gitea.com/gitea/changelog/pulls/76
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: techknowlogick <techknowlogick@noreply.gitea.io>
Co-authored-by: jolheiser <john.olheiser@gmail.com>
Co-committed-by: jolheiser <john.olheiser@gmail.com>
2023-03-22 04:35:58 +08:00
jolheiser cbd80881bc Trim space on title (#75)
Resolves #74

Reviewed-on: https://gitea.com/gitea/changelog/pulls/75
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: silverwind <silverwind@noreply.gitea.io>
Co-authored-by: jolheiser <john.olheiser@gmail.com>
Co-committed-by: jolheiser <john.olheiser@gmail.com>
2023-03-21 09:54:34 +08:00
techknowlogick 374ea1ab46 checksum compressed files too 2023-03-18 01:58:55 -04:00
techknowlogick d17e881692 properly format checksum file 2023-03-18 01:49:03 -04:00
techknowlogick 66f3e382a1 upload custom files 2023-03-18 01:32:19 -04:00
techknowlogick 0650d7c623 generate full checksum 2023-03-18 01:27:14 -04:00
techknowlogick bda1f380e2 execute with shell 2023-03-18 01:20:34 -04:00
techknowlogick b3eaafbefe add executable bit 2023-03-18 01:16:18 -04:00
techknowlogick 88538267db individual checksums 2023-03-18 01:09:05 -04:00
techknowlogick d55f6646fb simplify hooks 2023-03-18 00:59:17 -04:00
techknowlogick f2b3d8d60f run post build 2023-03-18 00:53:02 -04:00
techknowlogick 583ac7def2 xz binaries 2023-03-18 00:45:40 -04:00
techknowlogick a632296831 actions: test pull requests (#72)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/72
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-committed-by: techknowlogick <techknowlogick@gitea.io>
2023-03-17 04:50:35 +08:00
techknowlogick f18b011032 build and release nightly (#71)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/71
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-committed-by: techknowlogick <techknowlogick@gitea.io>
2023-03-17 04:36:25 +08:00
John Olheiser 8fc84c6a2d Allow for GH token (#70)
After running a few times this morning I started hitting rate limits, so this was a quick way to set an optional GH token.

Co-authored-by: jolheiser <john.olheiser@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/70
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: techknowlogick <techknowlogick@gitea.io>
Reviewed-by: appleboy <appleboy.tw@gmail.com>
Co-authored-by: John Olheiser <john+gitea@jolheiser.com>
Co-committed-by: John Olheiser <john+gitea@jolheiser.com>
2023-02-28 06:21:21 +08:00
techknowlogick e05ef3c254 use go 1.20 (#68)
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/68
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: 6543 <6543@obermui.de>
Reviewed-by: appleboy <appleboy.tw@gmail.com>
2023-02-28 05:59:03 +08:00
techknowlogick 5f171f4c5e use drone secrets for s3 info (#69)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/69
2023-02-08 06:05:57 +08:00
Andrew Thornton 3b83ddcefb Pass global flags down to subcommands (#54)
Fix #51

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/54
Reviewed-by: 6543 <6543@obermui.de>
Reviewed-by: Norwin <noerw@noreply.gitea.io>
Co-authored-by: Andrew Thornton <art27@cantab.net>
Co-committed-by: Andrew Thornton <art27@cantab.net>
2022-09-16 17:31:37 +08:00
techknowlogick 37ed264d72 rename primary branch (#67)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/67
2022-08-22 23:53:51 +08:00
John Olheiser e8f6cebd8b New install method for gxz (#65)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/65
Reviewed-by: Norwin <noerw@noreply.gitea.io>
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>
2022-06-23 20:23:37 +08:00
John Olheiser 05a5366d7f Skip un-grouped PRs if no default is set (#64)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/64
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: 6543 <6543@obermui.de>
Co-authored-by: John Olheiser <john+gitea@jolheiser.com>
Co-committed-by: John Olheiser <john+gitea@jolheiser.com>
2022-06-22 17:16:56 +08:00
John Olheiser 57e620da5b 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>
2022-06-22 09:27:24 +08:00
6543 f3ee0e5726 Add flag to specify git tag (#58)
close #57

Reviewed-on: https://gitea.com/gitea/changelog/pulls/58
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: Norwin <noerw@noreply.gitea.io>
2022-03-13 10:33:03 +08:00
techknowlogick 0ec4342863 use direct s3 endpoint (#59)
Reviewed-on: https://gitea.com/gitea/changelog/pulls/59
2022-03-11 05:02:27 +08:00
techknowlogick ea56b8af5a build with go1.17 & use supported s3 plugin (#56)
this will build with arm64 for darwin because it has been added to xgo plugin

Co-authored-by: Matti R <matti@mdranta.net>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/56
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: Alexey 〒erentyev <axifive@noreply.gitea.io>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-committed-by: techknowlogick <techknowlogick@gitea.io>
2021-10-09 02:57:05 +08:00
Lunny Xiao c38cabc3dc Upgrade gitea sdk to v0.14.0 (#53)
As title.

Reviewed-on: https://gitea.com/gitea/changelog/pulls/53
Reviewed-by: 6543 <6543@obermui.de>
Reviewed-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-committed-by: Lunny Xiao <xiaolunwen@gmail.com>
2021-05-17 18:39:53 +08:00
6543 18ff9e6a0d Update Gitea SDK to v0.13.0 (#49)
adapt new functions

update sdk to v0.13.0

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/49
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: jaqra <jaqra@noreply.gitea.io>
2020-09-22 21:38:11 +00:00
6543 c48910002d Changelog v0.2.0 (#48)
use new release page links

Changelog v0.2.0

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/48
Reviewed-by: jaqra <jaqra@noreply.gitea.io>
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
2020-08-07 13:57:07 +00:00
6543 ec4e62ff9d Update Vendors (#46)
Update Vendors:
* code.gitea.io/sdk/gitea v0.12.1
* github.com/urfave/cli/v2 v2.2.0
* gopkg.in/yaml.v2 v2.3.0

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/46
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
2020-08-07 13:48:37 +00:00
6543 b3574b331b Gitea Service: Use single release page (>= 1.12) (#47)
code format: "...happy path at the end..."

try to fix lint

gitea >= 1.12 has single release page

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/47
Reviewed-by: jaqra <jaqra@noreply.gitea.io>
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
2020-08-07 13:41:58 +00:00
6543 cc58d758be Update google/go-github to v32.1.0 (#45)
Update google/go-github to v32.1.0

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/45
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
2020-08-07 11:55:11 +00:00
jaqra e532c4d5cd Add generate from issues argument (#44)
Fix posible nil problem

Process only merged PRs

Rename variable

Fix github query for issues

Fix typo

Split function & fix lint

Rename variable name

Fix lint error

Add generate from issues argument

Co-authored-by: jaqra <jaqra@hotmail.com>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/44
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
2020-08-04 13:30:19 +00:00
6543 f3a2d35420 Update code.gitea.io/sdk/gitea to v0.12.0 (#43)
update code.gitea.io/sdk/gitea to v0.12.0

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/43
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: mrsdizzie <info@mrsdizzie.com>
2020-05-27 13:51:02 +00:00
Lunny Xiao b8fcd83de4 Fix bug only list first page when get prs from gitea (#41)
Fix bug only list first page when get prs from gitea

Reviewed-on: https://gitea.com/gitea/changelog/pulls/41
Reviewed-by: techknowlogick <techknowlogick@gitea.io>
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-03-29 01:56:21 +00:00
Lunny Xiao cbd79ff6d9 Set default service as github when service type empty (#40)
Set default service as github

Reviewed-on: https://gitea.com/gitea/changelog/pulls/40
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-03-06 11:54:25 +00:00
Andrew Thornton fe3041f2f9 Add newline after title (#39)
Add newline after title

Reviewed-on: https://gitea.com/gitea/changelog/pulls/39
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
Reviewed-by: techknowlogick <techknowlogick@gitea.io>
2020-02-16 00:32:36 +00:00
6543 068df6d865 Changelog 0.1.1 (#38)
spell impruvements

changelog 0.1.1

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/38
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
2020-02-03 00:14:22 +00:00
6543 a9ba232835 use .changelog.yml config if in working dir (#37)
use .changelog.yml config if in working dir

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/37
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
Reviewed-by: Andrew Thornton <art27@cantab.net>
2020-02-02 22:45:12 +00:00
6543 cb765dc996 Fix closed milestone issue (#35)
update go-sdk to fix closed milestone issue

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/35
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
2020-01-31 15:48:37 +00:00
techknowlogick ad405d67fe Update '.drone.yml' (#34)
Update '.drone.yml'

Reviewed-on: https://gitea.com/gitea/changelog/pulls/34
2020-01-27 02:52:04 +00:00
26 changed files with 769 additions and 509 deletions

View File

@ -1,129 +0,0 @@
---
kind: pipeline
name: compliance
platform:
os: linux
arch: arm64
trigger:
event:
- pull_request
steps:
- name: build
pull: always
image: golang:1.13
environment:
GOPROXY: https://goproxy.cn,direct
commands:
- go test -race ./...
- go build
- name: check
pull: always
image: golang:1.13
environment:
GOPROXY: https://goproxy.cn,direct
commands:
- make lint
- name: discord
pull: always
image: appleboy/drone-discord:1
environment:
DISCORD_WEBHOOK_ID:
from_secret: discord_webhook_id
DISCORD_WEBHOOK_TOKEN:
from_secret: discord_webhook_token
when:
event:
- push
- tag
status:
- changed
- failure
---
kind: pipeline
name: release
platform:
os: linux
arch: amd64
trigger:
branch:
- master
event:
- push
- tag
steps:
- name: fetch-tags
pull: always
image: docker:git
commands:
- git fetch --tags --force
- name: release
pull: always
image: techknowlogick/xgo:latest
environment:
GOPROXY: https://goproxy.cn,direct
commands:
- export PATH=$PATH:$GOPATH/bin
- make release
- name: bucket-master
pull: always
image: plugins/s3:1
settings:
acl: public-read
bucket: releases
endpoint: https://storage.gitea.io
path_style: true
source: "dist/release/*"
strip_prefix: dist/release/
target: /changelog-tool/master
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
when:
event:
- push
- name: bucket-tag
pull: always
image: plugins/s3:1
settings:
acl: public-read
bucket: releases
endpoint: https://storage.gitea.io
path_style: true
source: "dist/release/*"
strip_prefix: dist/release/
target: "/changelog-tool/${DRONE_TAG##v}"
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
when:
event:
- tag
- name: gitea
pull: always
image: plugins/gitea-release:1
settings:
api_key:
from_secret: gitea_token
base_url: https://gitea.com
files:
- "dist/*"
when:
event:
- tag

View File

@ -0,0 +1,30 @@
name: goreleaser
on:
push:
branches: [ main ]
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v3
with:
go-version: '>=1.20.1'
- name: goreleaser
uses: https://github.com/goreleaser/goreleaser-action@v4
with:
distribution: goreleaser-pro
version: latest
args: release --nightly
env:
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
S3_REGION: ${{ secrets.AWS_REGION }}
S3_BUCKET: ${{ secrets.AWS_BUCKET }}

View File

@ -0,0 +1,41 @@
name: goreleaser
on:
push:
tags:
- '*'
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v3
with:
go-version: '>=1.20.1'
- name: Import GPG key
id: import_gpg
uses: https://github.com/crazy-max/ghaction-import-gpg@v5
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
fingerprint: CC64B1DB67ABBEECAB24B6455FC346329753F4B0
- name: goreleaser
uses: https://github.com/goreleaser/goreleaser-action@v4
with:
distribution: goreleaser-pro
version: latest
args: release
env:
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
S3_REGION: ${{ secrets.AWS_REGION }}
S3_BUCKET: ${{ secrets.AWS_BUCKET }}
GORELEASER_FORCE_TOKEN: 'gitea'
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}

View File

@ -0,0 +1,19 @@
name: check-and-test
on: [pull_request]
jobs:
check-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '>=1.20.1'
- name: check-and-test
run: |
go test -race ./...
go build
make lint
env:
GOPROXY: https://goproxy.io,direct

7
.gitignore vendored
View File

@ -3,4 +3,9 @@
# Binaries
/changelog
/changelog.exe
/changelog.exe
# Go
/vendor/
dist/

View File

@ -10,12 +10,11 @@ linters:
- gocritic
- gocyclo
- gofmt
- golint
- gosimple
- govet
- maligned
- misspell
- prealloc
- revive
- staticcheck
- structcheck
- typecheck

12
.goreleaser.checksum.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
set -e
if [ -z "$1" ]; then
echo "usage: $0 <path>"
exit 1
fi
SUM=$(shasum -a 256 "$1" | cut -d' ' -f1)
BASENAME=$(basename "$1")
echo -n "${SUM} ${BASENAME}" > "$1".sha256

107
.goreleaser.yaml Normal file
View File

@ -0,0 +1,107 @@
before:
hooks:
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- darwin
- linux
- windows
- freebsd
goarch:
- amd64
- arm
- arm64
goarm:
- "5"
- "6"
- "7"
ignore:
- goos: darwin
goarch: arm
- goos: darwin
goarch: ppc64le
- goos: darwin
goarch: s390x
- goos: windows
goarch: ppc64le
- goos: windows
goarch: s390x
- goos: windows
goarch: arm
goarm: "5"
- goos: windows
goarch: arm
goarm: "6"
- goos: windows
goarch: arm
goarm: "7"
- goos: freebsd
goarch: ppc64le
- goos: freebsd
goarch: s390x
- goos: freebsd
goarch: arm
goarm: "5"
- goos: freebsd
goarch: arm
goarm: "6"
- goos: freebsd
goarch: arm
goarm: "7"
flags:
- -trimpath
ldflags:
- -s -w -X code.gitea.io/changelog/cmd.Version={{ .Summary }}
binary: >-
{{ .ProjectName }}-
{{- .Version }}-
{{- .Os }}-
{{- if eq .Arch "amd64" }}amd64
{{- else if eq .Arch "amd64_v1" }}amd64
{{- else if eq .Arch "386" }}386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}-{{ .Arm }}{{ end }}
no_unique_dist_dir: true
hooks:
post:
- cmd: tar -cJf {{ .Path }}.xz {{ .Path }}
env:
- XZ_OPT=-9
- cmd: sh .goreleaser.checksum.sh {{ .Path }}
- cmd: sh .goreleaser.checksum.sh {{ .Path }}.xz
blobs:
-
provider: s3
bucket: "{{ .Env.S3_BUCKET }}"
region: "{{ .Env.S3_REGION }}"
folder: "changelog-tool/{{.Version}}"
extra_files:
- glob: ./**.xz
- glob: ./**.sha256
archives:
- format: binary
name_template: "{{ .Binary }}"
allow_different_binary_count: true
checksum:
name_template: 'checksums.txt'
extra_files:
- glob: ./**.xz
snapshot:
name_template: "{{ .Branch }}-devel"
nightly:
name_template: "{{ .Branch }}"
gitea_urls:
api: https://gitea.com/api/v1
download: https://gitea.com
# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

View File

@ -1,6 +1,24 @@
# Changelog
## [0.1.0](https://gitea.com/gitea/changelog/pulls?q=&type=all&state=closed&milestone=1231) - 2020-01-25
## [v0.2.0](https://gitea.com/gitea/changelog/releases/tag/v0.2.0) - 2020-08-07
* FEATURES
* Add generate from issues argument (#44)
* BUGFIXES
* Fix bug only list first page when get prs from gitea (#41)
* Add newline after title (#39)
* ENHANCEMENTS
* Gitea Service: Use single release page (>= 1.12) (#47)
* Set default service as github when service type empty (#40)
## [v0.1.1](https://gitea.com/gitea/changelog/releases/tag/v0.1.1) - 2020-02-02
* BUGFIXES
* Use .changelog.yml config if in working dir (#37)
* Fix Gitea get closed milestone too (#35)
## [v0.1.0](https://gitea.com/gitea/changelog/releases/tag/v0.1.0) - 2020-01-25
* FEATURES
* Add init command (#33)
* Add subcommand to display contributors of milestone (#10)

View File

@ -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.23.1; \
fi
golangci-lint run --timeout 5m
$(GO) run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.51.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
@ -82,6 +78,6 @@ release-check:
.PHONY: release-compress
release-compress:
@hash gxz > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/ulikunitz/xz/cmd/gxz; \
$(GO) install github.com/ulikunitz/xz/cmd/gxz@latest; \
fi
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && gxz -k -9 $${file}; done;

View File

@ -1,7 +1,6 @@
# Changelog
A changelog generator for Gitea
[![Build Status](https://drone.gitea.com/api/badges/gitea/changelog/status.svg)](https://drone.gitea.com/gitea/changelog)
A changelog generator for Gitea
## Purpose
@ -11,27 +10,29 @@ 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
See the [changelog.example.yml](changelog.example.yml) example file.
See the [changelog.example.yml](config/changelog.example.yml) example file.
## Usage
#### Changelog Entries
```
changelog -m=1.11.0 -c=/path/to/my_config_file generate
### Changelog Entries
```sh
changelog generate -m=1.11.0 -c=/path/to/my_config_file
```
#### Contributors List
```
changelog -m=1.11.0 -c=/path/to/my_config_file contributors
### Contributors List
```sh
changelog contributors -m=1.11.0 -c=/path/to/my_config_file
```
## Building
```
go generate ./...
```sh
go build
```
@ -42,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

@ -1,43 +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.
// +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)
}
}

View File

@ -1,13 +1,106 @@
// 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.
package cmd
var (
MilestoneFlag string
ConfigPathFlag string
TokenFlag string
DetailsFlag bool
AfterFlag int64
import (
"os"
"path/filepath"
"github.com/urfave/cli/v3"
)
var (
// 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
//
//nolint:funlen
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,
Persistent: true,
},
&cli.StringFlag{
Name: "tag",
Aliases: []string{"T"},
Usage: "Git tag for milestone url, if not set milestone is used",
Destination: &tagFlag,
Persistent: true,
},
&cli.StringFlag{
Name: "config",
Aliases: []string{"c"},
Usage: "Specify a config file",
Value: getDefaultConfigFile(),
Destination: &configPathFlag,
Persistent: true,
},
&cli.StringFlag{
Name: "token",
Aliases: []string{"t"},
Usage: "Access token for private repositories/instances",
Destination: &tokenFlag,
Persistent: true,
},
&cli.BoolFlag{
Name: "details",
Aliases: []string{"d"},
Usage: "Generate detail lists instead of long lists",
Destination: &detailsFlag,
Persistent: true,
},
&cli.Int64Flag{
Name: "after",
Aliases: []string{"a"},
Usage: "Only select PRs after a given index (continuing a previous changelog)",
Destination: &afterFlag,
Persistent: true,
},
&cli.BoolFlag{
Name: "issues",
Aliases: []string{"i"},
Usage: "Generate changelog from issues (otherwise from pulls)",
Destination: &issuesFlag,
Persistent: true,
},
},
Commands: []*cli.Command{
Generate,
Contributors,
Init,
},
}
return app
}
func getDefaultConfigFile() string {
pwd, err := os.Getwd()
if err != nil {
return ""
}
config := filepath.Join(pwd, ".changelog.yml")
info, err := os.Stat(config)
if err == nil && !info.IsDir() {
return config
}
return ""
}

View File

@ -11,7 +11,7 @@ import (
"code.gitea.io/changelog/config"
"code.gitea.io/changelog/service"
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v3"
)
var Contributors = &cli.Command{
@ -20,13 +20,13 @@ var Contributors = &cli.Command{
Action: runContributors,
}
func runContributors(cmd *cli.Context) error {
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, TokenFlag)
s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, milestoneFlag, tagFlag, tokenFlag, issuesFlag)
if err != nil {
return err
}

View File

@ -7,33 +7,27 @@ package cmd
import (
"fmt"
"regexp"
"strings"
"code.gitea.io/changelog/config"
"code.gitea.io/changelog/service"
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v3"
)
var (
Generate = &cli.Command{
Name: "generate",
Usage: "Generates a changelog",
Action: runGenerate,
}
labels = make(map[string]string)
entries = make(map[string][]service.PullRequest)
defaultGroup string
)
var Generate = &cli.Command{
Name: "generate",
Usage: "Generates a changelog for a special milestone",
Action: runGenerate,
}
func runGenerate(cmd *cli.Context) error {
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, TokenFlag)
s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, milestoneFlag, tagFlag, tokenFlag, issuesFlag)
if err != nil {
return err
}
@ -43,15 +37,26 @@ 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 == "" {
fmt.Println("<!-- WARNING - no default group found -->")
}
entries := processPRs(prs, cfg.NameLabels(), defaultGroup, cfg.SkipRegex)
fmt.Println(title)
fmt.Println()
for _, g := range cfg.Groups {
if len(entries[g.Name]) == 0 {
continue
}
if DetailsFlag {
if detailsFlag {
fmt.Println("<details><summary>" + g.Name + "</summary>")
fmt.Println()
for _, entry := range entries[g.Name] {
@ -69,44 +74,35 @@ func runGenerate(cmd *cli.Context) error {
return nil
}
func processGroups(groups []config.Group) {
for _, g := range groups {
entries[g.Name] = []service.PullRequest{}
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.PullRequest, 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)
if section == "" {
continue
}
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
}

View File

@ -11,7 +11,7 @@ import (
"code.gitea.io/changelog/config"
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v3"
)
var (
@ -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)
}

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

@ -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:"-"`
}
// Load a config from a path, defaulting to changelog.example.yml
// 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
@ -54,5 +81,9 @@ func New(configPath string) (*Config, error) {
}
}
if cfg.Service == "" {
cfg.Service = "github"
}
return cfg, nil
}

View File

@ -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\/.+`)
}

25
go.mod
View File

@ -1,12 +1,23 @@
module code.gitea.io/changelog
go 1.13
go 1.18
require (
code.gitea.io/sdk/gitea v0.0.0-20200116035226-b24cfd841cda
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-querystring v1.0.0 // indirect
github.com/urfave/cli/v2 v2.1.1
gopkg.in/yaml.v2 v2.2.7
code.gitea.io/sdk/gitea v0.14.0
github.com/google/go-github/v50 v50.0.0
github.com/urfave/cli/v3 v3.0.0-alpha2
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
gopkg.in/yaml.v2 v2.3.0
)
require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/golang/protobuf v1.3.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/go-version v1.2.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
google.golang.org/appengine v1.6.7 // indirect
)

59
go.sum
View File

@ -1,28 +1,51 @@
code.gitea.io/sdk/gitea v0.0.0-20200116035226-b24cfd841cda h1:J+qDCjmjcewNcPNfHIex5z726cgv/URXK0MnXHTIo1U=
code.gitea.io/sdk/gitea v0.0.0-20200116035226-b24cfd841cda/go.mod h1:SXOCD/+QP5txLJQ2bPkgHGSQs1YQ4s1ep1ZpI6ItO4A=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
code.gitea.io/sdk/gitea v0.14.0 h1:m4J352I3p9+bmJUfS+g0odeQzBY/5OXP91Gv6D4fnJ0=
code.gitea.io/sdk/gitea v0.14.0/go.mod h1:89WiyOX1KEcvjP66sRHdu0RafojGo60bT9UqW17VbWs=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-github/v50 v50.0.0 h1:gdO1AeuSZZK4iYWwVbjni7zg8PIQhp7QfmPunr016Jk=
github.com/google/go-github/v50 v50.0.0/go.mod h1:Ev4Tre8QoKiolvbpOSG3FIi4Mlon3S2Nt9W5JYqKiwA=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/urfave/cli/v3 v3.0.0-alpha2 h1:JKkuTewMlS2leTQeAcsPGL7WmBVa2uoBLy89As4Jauc=
github.com/urfave/cli/v3 v3.0.0-alpha2/go.mod h1:gHI/xEYplFhOa3Y90xJleh3kqqsSanBj/19hVFxiVZ4=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

54
main.go
View File

@ -4,67 +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 generator for Gitea",
Version: Version,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "milestone",
Aliases: []string{"m"},
Usage: "Targeted milestone",
Destination: &cmd.MilestoneFlag,
},
&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,
},
},
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)
}

View File

@ -14,91 +14,126 @@ import (
// Gitea defines a Gitea service
type Gitea struct {
Milestone string
GitTag string
Token string
BaseURL string
Owner string
Repo string
Issues bool
}
// Generate returns a Gitea changelog
func (ge *Gitea) Generate() (string, []PullRequest, error) {
client := gitea.NewClient(ge.BaseURL, ge.Token)
prs := make([]PullRequest, 0)
milestoneID, err := ge.milestoneID(client)
func (ge *Gitea) Generate() (string, []Entry, error) {
client, err := gitea.NewClient(ge.BaseURL, gitea.SetToken(ge.Token))
if err != nil {
return "", nil, err
}
tagURL := fmt.Sprintf("## [%s](%s/%s/%s/pulls?q=&type=all&state=closed&milestone=%d) - %s", ge.Milestone, ge.BaseURL, ge.Owner, ge.Repo, milestoneID, time.Now().Format("2006-01-02"))
entries := make([]Entry, 0)
p := 1
// https://github.com/go-gitea/gitea/blob/d92781bf941972761177ac9e07441f8893758fd3/models/repo.go#L63
// https://github.com/go-gitea/gitea/blob/e3c3b33ea7a5a223e22688c3f0eb2d3dab9f991c/models/pull_list.go#L104
// FIXME Gitea has this hard-coded at 40
perPage := 40
for {
results, err := client.ListRepoPullRequests(ge.Owner, ge.Repo, gitea.ListPullRequestsOptions{
Page: p,
State: "closed",
Milestone: milestoneID,
})
milestone, _, err := client.GetMilestoneByName(ge.Owner, ge.Repo, ge.Milestone)
if err != nil {
return "", nil, err
}
from := "pulls"
if ge.Issues {
from = "issues"
}
tagURL := getGiteaTagURL(client, ge.BaseURL, ge.Owner, ge.Repo, ge.Milestone, ge.GitTag, from, milestone.ID)
perPage := ge.perPage(client)
for p := 1; ; p++ {
options := gitea.ListIssueOption{
ListOptions: gitea.ListOptions{
Page: p,
PageSize: perPage,
},
Milestones: []string{ge.Milestone},
State: gitea.StateClosed,
Type: gitea.IssueTypePull,
}
if ge.Issues {
options.Type = gitea.IssueTypeIssue
}
issues, _, err := client.ListRepoIssues(ge.Owner, ge.Repo, options)
if err != nil {
return "", nil, err
}
p++
for _, pr := range results {
if pr != nil && pr.HasMerged {
p := PullRequest{
Title: pr.Title,
Index: pr.Index,
for _, issue := range issues {
if issue != nil {
if options.Type == gitea.IssueTypePull && issue.PullRequest != nil && !(issue.PullRequest.HasMerged) {
continue
}
labels := make([]Label, len(pr.Labels))
for idx, lbl := range pr.Labels {
labels[idx] = Label{
Name: lbl.Name,
}
}
p.Labels = labels
prs = append(prs, p)
entry := convertToEntry(*issue)
entries = append(entries, entry)
}
}
if len(results) != perPage {
if len(issues) != perPage {
break
}
}
return tagURL, prs, nil
return tagURL, entries, nil
}
func getGiteaTagURL(c *gitea.Client, baseURL, owner, repo, mileName, gitTag, from string, mileID int64) string {
if err := c.CheckServerVersionConstraint(">=1.12"); err != nil {
return fmt.Sprintf("## [%s](%s/%s/%s/%s?q=&type=all&state=closed&milestone=%d) - %s", mileName, baseURL, owner, repo, from, mileID, time.Now().Format("2006-01-02"))
}
return fmt.Sprintf("## [%s](%s/%s/%s/releases/tag/%s) - %s", mileName, baseURL, owner, repo, gitTag, time.Now().Format("2006-01-02"))
}
func convertToEntry(issue gitea.Issue) Entry {
entry := Entry{
Index: issue.Index,
Title: CleanTitle(issue.Title),
}
labels := make([]Label, len(issue.Labels))
for idx, lbl := range issue.Labels {
labels[idx] = Label{
Name: lbl.Name,
}
}
entry.Labels = labels
return entry
}
// Contributors returns a list of contributors from Gitea
func (ge *Gitea) Contributors() (ContributorList, error) {
client := gitea.NewClient(ge.BaseURL, ge.Token)
contributorsMap := make(map[string]bool)
milestoneID, err := ge.milestoneID(client)
client, err := gitea.NewClient(ge.BaseURL, gitea.SetToken(ge.Token))
if err != nil {
return nil, err
}
p := 1
perPage := 100
for {
results, err := client.ListRepoPullRequests(ge.Owner, ge.Repo, gitea.ListPullRequestsOptions{
Page: p,
contributorsMap := make(map[string]bool)
milestone, _, err := client.GetMilestoneByName(ge.Owner, ge.Repo, ge.Milestone)
if err != nil {
return nil, err
}
perPage := ge.perPage(client)
for p := 1; ; p++ {
results, _, err := client.ListRepoPullRequests(ge.Owner, ge.Repo, gitea.ListPullRequestsOptions{
ListOptions: gitea.ListOptions{
Page: p,
PageSize: perPage,
},
State: "closed",
Milestone: milestoneID,
Milestone: milestone.ID,
})
if err != nil {
return nil, err
}
p++
for _, pr := range results {
if pr != nil && pr.HasMerged {
@ -122,17 +157,15 @@ func (ge *Gitea) Contributors() (ContributorList, error) {
return contributors, nil
}
func (ge *Gitea) milestoneID(client *gitea.Client) (int64, error) {
milestones, err := client.ListRepoMilestones(ge.Owner, ge.Repo)
if err != nil {
return 0, err
}
for _, ms := range milestones {
if ms.Title == ge.Milestone {
return ms.ID, nil
func (ge *Gitea) perPage(client *gitea.Client) int {
// set low value so it will work in most cases
perPage := 10
if client.CheckServerVersionConstraint(">=1.13.0") == nil {
conf, _, err := client.GetGlobalAPISettings()
if err != nil {
return perPage
}
return conf.MaxResponseItems
}
return 0, fmt.Errorf("no milestone found for %s", ge.Milestone)
return perPage
}

View File

@ -6,33 +6,58 @@ package service
import (
"context"
"errors"
"fmt"
"net/http"
"os"
"strconv"
"strings"
"time"
"github.com/google/go-github/github"
"github.com/google/go-github/v50/github"
"golang.org/x/oauth2"
)
// GitHub defines a GitHub service
type GitHub struct {
Milestone string
GitTag string
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, []PullRequest, error) {
tagURL := fmt.Sprintf("## [%s](https://github.com/%s/releases/tag/v%s) - %s", gh.Milestone, gh.Repo, gh.Milestone, time.Now().Format("2006-01-02"))
client := github.NewClient(nil)
func (gh *GitHub) Generate() (string, []Entry, error) {
owner, repo := gh.OwnerRepo()
ctx := context.Background()
gh.initClient(ctx)
prs := make([]PullRequest, 0)
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)
milestoneNum, err := gh.milestoneNum(ctx)
if err != nil {
return "", nil, err
}
query := fmt.Sprintf(`repo:%s is:merged milestone:"%s"`, gh.Repo, 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,
@ -43,10 +68,12 @@ func (gh *GitHub) Generate() (string, []PullRequest, error) {
}
p++
for _, pr := range result.Issues {
if pr.IsPullRequest() {
p := PullRequest{
Title: pr.GetTitle(),
isPull := !(gh.Issues)
for _, pr := range result {
if pr.IsPullRequest() == isPull {
p := Entry{
Title: CleanTitle(pr.GetTitle()),
Index: int64(pr.GetNumber()),
}
@ -62,7 +89,7 @@ func (gh *GitHub) Generate() (string, []PullRequest, error) {
}
}
if len(result.Issues) != perPage {
if len(result) != perPage {
break
}
}
@ -72,15 +99,21 @@ func (gh *GitHub) Generate() (string, []PullRequest, error) {
// Contributors returns a list of contributors from GitHub
func (gh *GitHub) Contributors() (ContributorList, error) {
client := github.NewClient(nil)
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,
@ -91,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
}
}
@ -110,3 +143,52 @@ func (gh *GitHub) Contributors() (ContributorList, error) {
return contributors, nil
}
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 != "" {
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
cl = oauth2.NewClient(ctx, ts)
}
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")
}

View File

@ -7,18 +7,25 @@ package service
import (
"fmt"
"strings"
"unicode"
)
const defaultGitea = "https://gitea.com"
// Load returns a service from a string
func New(serviceType, repo, baseURL, milestone, token string) (Service, error) {
// New returns a service from a string
func New(serviceType, repo, baseURL, milestone, tag, token string, issues bool) (Service, error) {
if len(tag) == 0 {
tag = milestone
}
switch strings.ToLower(serviceType) {
case "github":
return &GitHub{
Milestone: milestone,
GitTag: tag,
Token: token,
Repo: repo,
Issues: issues,
}, nil
case "gitea":
ownerRepo := strings.Split(repo, "/")
@ -27,10 +34,12 @@ func New(serviceType, repo, baseURL, milestone, token string) (Service, error) {
}
return &Gitea{
Milestone: milestone,
GitTag: tag,
Token: token,
BaseURL: baseURL,
Owner: ownerRepo[0],
Repo: ownerRepo[1],
Issues: issues,
}, nil
default:
return nil, fmt.Errorf("unknown service type %s", serviceType)
@ -39,7 +48,7 @@ func New(serviceType, repo, baseURL, milestone, token string) (Service, error) {
// Service defines how a struct can be a Changelog Service
type Service interface {
Generate() (string, []PullRequest, error)
Generate() (string, []Entry, error)
Contributors() (ContributorList, error)
}
@ -48,8 +57,8 @@ type Label struct {
Name string
}
// PullRequest is the minimum information needed to make a changelog entry
type PullRequest struct {
// Entry is the minimum information needed to make a changelog entry
type Entry struct {
Title string
Index int64
Labels []Label
@ -78,3 +87,15 @@ func (cl ContributorList) Less(i, j int) bool {
func (cl ContributorList) Swap(i, j int) {
cl[i], cl[j] = cl[j], cl[i]
}
// CleanTitle returns the string with spaces trimmed and the first rune title-cased
func CleanTitle(s string) string {
s = strings.TrimSpace(s)
r := []rune(s)
r[0] = unicode.ToUpper(r[0])
s = string(r)
return s
}

View File

@ -12,3 +12,27 @@ import (
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
func TestCleanTitle(t *testing.T) {
tt := []struct {
Title string
Expected string
}{
{Title: "foo", Expected: "Foo"},
{Title: " foo", Expected: "Foo"},
{Title: "foo bar", Expected: "Foo bar"},
{Title: "Foo bar", Expected: "Foo bar"},
{Title: " Foo bar ", Expected: "Foo bar"},
{Title: "1234", Expected: "1234"},
}
for _, tc := range tt {
t.Run(tc.Title, func(t *testing.T) {
s := CleanTitle(tc.Title)
if s != tc.Expected {
t.Logf("got %q | expected %q", s, tc.Expected)
t.Fail()
}
})
}
}