Skip to content

Commit

Permalink
workflows: add more automation for changelogs
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobbednarz committed Jul 20, 2022
1 parent e103aee commit 2506863
Show file tree
Hide file tree
Showing 13 changed files with 469 additions and 1 deletion.
21 changes: 21 additions & 0 deletions .github/workflows/changelog-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Changelog check
on: [pull_request_target]

jobs:
changelog-check:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ^1.17
- run: make tools
- run: go run tools/cmd/changelog-check/main.go ${{ github.event.pull_request.number }}
env:
GITHUB_OWNER: cloudflare
GITHUB_REPO: cloudflare-go
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 changes: 35 additions & 0 deletions .github/workflows/dependabot-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Add CHANGELOG for dependabot changes
on: pull_request_target
permissions:
pull-requests: write
issues: write
repository-projects: write
contents: write
jobs:
dependabot:
runs-on: ubuntu-latest
if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
steps:
- name: Fetch dependabot metadata
id: dependabot-metadata
uses: dependabot/[email protected]
- uses: actions/checkout@v3
- run: |
gh pr checkout $PR_URL
cat << EOF > .changelog/$PR_NUMBER.txt
\`\`\`release-note:dependency
provider: bumps $DEP_NAME from $DEP_PREV_VERSION to $DEP_NEXT_VERSION
\`\`\`
EOF
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git add .changelog/$PR_NUMBER.txt
git commit -m "add CHANGELOG for #$PR_NUMBER"
git push
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}
PR_NUMBER: ${{ github.event.pull_request.number }}
DEP_NAME: ${{ steps.dependabot-metadata.outputs.dependency-names }}
DEP_PREV_VERSION: ${{ steps.dependabot-metadata.outputs.previous-version }}
DEP_NEXT_VERSION: ${{ steps.dependabot-metadata.outputs.new-version }}
28 changes: 28 additions & 0 deletions .github/workflows/generate-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Generate CHANGELOG
on:
pull_request_target:
types: [closed]
workflow_dispatch:
jobs:
GenerateChangelog:
if: github.event.pull_request.merged || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: cd tools && go install github.com/hashicorp/go-changelog/cmd/changelog-build
- run: ./scripts/generate-changelog.sh
- run: |
if [[ `git status --porcelain` ]]; then
if ${{github.event_name == 'workflow_dispatch'}}; then
MSG="Update CHANGELOG.md (Manual Trigger)"
else
MSG="Update CHANGELOG.md for #${{ github.event.pull_request.number }}"
fi
git config --local user.email [email protected]
git config --local user.name changelogbot
git add CHANGELOG.md
git commit -m "$MSG"
git push
fi
25 changes: 25 additions & 0 deletions .github/workflows/milestones.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
on:
pull_request_target:
types: [closed]
name: Add merged PR and linked issues to current milestone of target branch
jobs:
add-merged-to-current-milestone:
if: github.event.pull_request.merged
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.base.ref }}
- id: get-current-milestone
run: |
echo ::set-output name=current_milestone::v$(head -1 CHANGELOG.md | cut -d " " -f 2)
- run: echo ${{ steps.get-current-milestone.outputs.current_milestone }}
- id: get-milestone-id
run: |
echo ::set-output name=milestone_id::$(curl -H "Authorization: Bearer ${{secrets.GITHUB_TOKEN}}" https://api.github.com/repos/${{ github.repository_owner }}/${{ github.event.repository.name }}/milestones | jq 'map(select(.title == "${{ steps.get-current-milestone.outputs.current_milestone }}"))[0].number')
- run: echo ${{ steps.get-milestone-id.outputs.milestone_id }}
- uses: breathingdust/current-milestone-action@v4
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
pull_number: ${{ github.event.pull_request.number }}
milestone_number: ${{ steps.get-milestone-id.outputs.milestone_id }}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.46.0 (Unreleased)
96 changes: 96 additions & 0 deletions docs/changelog-process.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
## Changelog Process

We use the [go-changelog](https://github.com/hashicorp/go-changelog) to generate and update the changelog from files created in the `.changelog/` directory. It is important that when you raise your Pull Request, there is a changelog entry which describes the changes your contribution makes. Not all changes require an entry in the CHANGELOG, guidance follows on what changes do.

### Changelog Format

The changelog format requires an entry in the following format, where HEADER corresponds to the changelog category, and the entry is the changelog entry itself. The entry should be included in a file in the `.changelog` directory with the naming convention `{PR-NUMBER}.txt`. For example, to create a changelog entry for pull request 1234, there should be a file named `.changelog/1234.txt`.

````markdown
```release-note:{HEADER}
{ENTRY}
```
````

If a pull request should contain multiple changelog entries, then multiple blocks can be added to the same changelog file. For example:

````markdown
```release-note:note
foo: The `broken` attribute has been deprecated. All configurations using `broken` should be updated to use the new `not_broken` attribute instead.
```

```release-note:enhancement
foo: Add `not_broken` attribute
```
````

### Skipping changelog entries

In order to skip/pass the automated checks where a CHANGELOG entry is not required, apply the `workflow/skip-changelog-entry` label.

### Pull Request Types to CHANGELOG

The CHANGELOG is intended to show operator-impacting changes to the codebase for a particular version. If every change or commit to the code resulted in an entry, the CHANGELOG would become less useful for operators. The lists below are general guidelines and examples for when a decision needs to be made to decide whether a change should have an entry.

#### Changes that should have a CHANGELOG entry

##### Resource and provider bug fixes

A new bug entry should use the `release-note:bug` header and have a prefix indicating the file/service it corresponds to, a colon, then followed by a brief summary.

````markdown
```release-note:bug
foo: Fix 'thing' being optional
```
````

##### Resource and provider enhancements

A new enhancement entry should use the `release-note:enhancement` header and have a prefix indicating the file/service it corresponds to, a colon, then followed by a brief summary.

````markdown
```release-note:enhancement
foo: Add new capability
```
````

##### Deprecations

A breaking-change entry should use the `release-note:note` header and have a prefix indicating the file/service it corresponds to, a colon, then followed by a brief summary.

````markdown
```release-note:note
foo: X attribute is being deprecated in favor of the new Y attribute
```
````

##### Breaking Changes and Removals

A breaking-change entry should use the `release-note:breaking-change` header and have a prefix indicating the file/service it corresponds to, a colon, then followed by a brief summary.

````markdown
```release-note:breaking-change
foo: Resource no longer works for 'EXAMPLE' parameters
```
````

#### Changes that may have a CHANGELOG entry

Dependency updates: If the update contains relevant bug fixes or enhancements that affect operators, those should be called out.
Any changes which do not fit into the above categories but warrant highlighting.

````markdown
```release-note:note
foo: Example resource now does X slightly differently
```

```release-note:dependency
`foo` v0.1.0 => v0.1.1
```
````

#### Changes that should _not_ have a CHANGELOG entry

- Resource and provider documentation updates
- Testing updates
- Code refactoring (context dependant)
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ require (
github.com/urfave/cli/v2 v2.11.0
github.com/uudashr/gopkgs/v2 v2.1.2
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65
golang.org/x/tools/gopls v0.9.1
)

require google.golang.org/appengine v1.6.7 // indirect

require (
4d63.com/gochecknoglobals v0.1.0 // indirect
github.com/Antonboom/errname v0.1.7 // indirect
Expand Down Expand Up @@ -83,6 +85,7 @@ require (
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/go-dap v0.6.0 // indirect
github.com/google/go-github v17.0.0+incompatible
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.4.2 // indirect
Expand Down Expand Up @@ -183,6 +186,7 @@ require (
golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 // indirect
golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/oauth2 v0.0.0-20220718184931-c8730f7fcb92
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e // indirect
golang.org/x/text v0.3.7 // indirect
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-dap v0.6.0 h1:Y1RHGUtv3R8y6sXq2dtGRMYrFB2hSqyFVws7jucrzX4=
github.com/google/go-dap v0.6.0/go.mod h1:5q8aYQFnHOAZEMP+6vmq25HKYAEwE+LF5yh7JKrrhSQ=
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.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
Expand Down Expand Up @@ -1133,6 +1135,8 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y=
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand All @@ -1153,6 +1157,8 @@ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220718184931-c8730f7fcb92 h1:oVlhw3Oe+1reYsE2Nqu19PDJfLzwdU3QUUrG86rLK68=
golang.org/x/oauth2 v0.0.0-20220718184931-c8730f7fcb92/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -1464,6 +1470,7 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww
google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
Expand Down
39 changes: 39 additions & 0 deletions scripts/changelog.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{{- if index .NotesByType "breaking-change" }}
BREAKING CHANGES:

{{range index .NotesByType "breaking-change" -}}
{{ template "note" .}}
{{ end -}}
{{- end -}}

{{- if .NotesByType.note }}
NOTES:

{{range .NotesByType.note -}}
{{ template "note" .}}
{{ end -}}
{{- end -}}

{{- if .NotesByType.enhancement }}
ENHANCEMENTS:

{{range .NotesByType.enhancement | sort -}}
{{ template "note" .}}
{{ end -}}
{{- end -}}

{{- if .NotesByType.bug }}
BUG FIXES:

{{range .NotesByType.bug | sort -}}
{{ template "note" . }}
{{ end -}}
{{- end -}}

{{- if .NotesByType.dependency }}
DEPENDENCIES:

{{range .NotesByType.dependency | sort -}}
{{ template "note" . }}
{{ end -}}
{{- end -}}
53 changes: 53 additions & 0 deletions scripts/generate-changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash

set -o errexit
set -o nounset

__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__parent="$(dirname "$__dir")"

CHANGELOG_FILE_NAME="CHANGELOG.md"
CHANGELOG_TMP_FILE_NAME="CHANGELOG.tmp"
TARGET_SHA=$(git rev-parse HEAD)
PREVIOUS_RELEASE_SHA=$(git rev-list -n 1 $(git describe --abbrev=0 --match='v*.*.*' --tags))

if [ $TARGET_SHA == $PREVIOUS_RELEASE_SHA ]; then
echo "Nothing to do"
exit 0
fi

PREVIOUS_CHANGELOG=$(sed -n -e "/## $(git describe --abbrev=0 --match='v*.*.*' --tags | tr -d v)/,\$p" $__parent/$CHANGELOG_FILE_NAME)

if [ -z "$PREVIOUS_CHANGELOG" ]
then
echo "Unable to locate previous changelog contents."
exit 1
fi

CHANGELOG=$($(go env GOPATH)/bin/changelog-build -this-release $TARGET_SHA \
-last-release $PREVIOUS_RELEASE_SHA \
-git-dir $__parent \
-entries-dir .changelog \
-changelog-template $__dir/changelog.tmpl \
-note-template $__dir/release-note.tmpl)

if [ -z "$CHANGELOG" ]
then
echo "No changelog generated."
exit 0
fi

rm -f $CHANGELOG_TMP_FILE_NAME

sed -n -e "1{/## /p;}" $__parent/$CHANGELOG_FILE_NAME > $CHANGELOG_TMP_FILE_NAME
echo "$CHANGELOG" >> $CHANGELOG_TMP_FILE_NAME
echo >> $CHANGELOG_TMP_FILE_NAME
echo "$PREVIOUS_CHANGELOG" >> $CHANGELOG_TMP_FILE_NAME

cp $CHANGELOG_TMP_FILE_NAME $CHANGELOG_FILE_NAME

rm $CHANGELOG_TMP_FILE_NAME

echo "Successfully generated changelog."

exit 0
3 changes: 3 additions & 0 deletions scripts/release-note.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{- define "note" -}}
* {{.Body}} ([#{{- .Issue -}}](https://github.com/cloudflare/cloudflare-go/issues/{{- .Issue -}}))
{{- end -}}
22 changes: 22 additions & 0 deletions tools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//go:build tools
// +build tools

package tools

//go:generate go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
//go:generate go install github.com/bflad/tfproviderlint/cmd/tfproviderlintx
//go:generate go install github.com/client9/misspell/cmd/misspell
//go:generate go install github.com/golangci/golangci-lint/cmd/golangci-lint
//go:generate go install github.com/hashicorp/go-changelog/cmd/changelog-build
//go:generate go install github.com/google/go-github/github
//go:generate go install golang.org/x/oauth2

import (
_ "github.com/bflad/tfproviderlint/cmd/tfproviderlintx"
_ "github.com/client9/misspell/cmd/misspell"
_ "github.com/golangci/golangci-lint/cmd/golangci-lint"
_ "github.com/google/go-github/github"
_ "github.com/hashicorp/go-changelog/cmd/changelog-build"
_ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs"
_ "golang.org/x/oauth2"
)
Loading

0 comments on commit 2506863

Please sign in to comment.