diff --git a/.changelog/changelog.tmpl b/.changelog/changelog.tmpl new file mode 100644 index 00000000..83bdb965 --- /dev/null +++ b/.changelog/changelog.tmpl @@ -0,0 +1,55 @@ +{{- if index .NotesByType "breaking-change" -}} +BREAKING CHANGES: + +{{range index .NotesByType "breaking-change" -}} +* {{ template "note" .}} +{{ end -}} +{{- end -}} + +{{- if .NotesByType.security }} +SECURITY: + +{{range .NotesByType.security -}} +* {{ template "note" .}} +{{ end -}} +{{- end -}} + +{{- if .NotesByType.deprecation -}} +DEPRECATIONS: + +{{range .NotesByType.deprecation -}} +* {{ template "note" .}} +{{ end -}} +{{- end -}} + +{{- if .NotesByType.feature }} +FEATURES: + +{{range .NotesByType.feature -}} +* {{ template "note" . }} +{{ end -}} +{{- end -}} + +{{- if .NotesByType.improvement }} +IMPROVEMENTS: + +{{range .NotesByType.improvement -}} +* {{ template "note" . }} +{{ end -}} +{{- end -}} + +{{- if .NotesByType.bug }} +BUG FIXES: + +{{range .NotesByType.bug -}} +* {{ template "note" . }} +{{ end -}} +{{- end -}} + +{{- if .NotesByType.note -}} +NOTES: + +{{range .NotesByType.note -}} +* {{ template "note" .}} +{{ end -}} +{{- end -}} diff --git a/.changelog/release-note.tmpl b/.changelog/release-note.tmpl new file mode 100644 index 00000000..cc239982 --- /dev/null +++ b/.changelog/release-note.tmpl @@ -0,0 +1,3 @@ +{{- define "note" -}} +{{.Body}} [[GH-{{- .Issue -}}](https://github.com/hashicorp/hcp/issues/{{- .Issue -}})] +{{- end -}} diff --git a/.changelog/types.txt b/.changelog/types.txt new file mode 100644 index 00000000..df4f8749 --- /dev/null +++ b/.changelog/types.txt @@ -0,0 +1,7 @@ +breaking-change +security +deprecation +feature +improvement +bug +note diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..628fe421 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,17 @@ +### Changes proposed in this PR: + +### How I've tested this PR: + +### How I expect reviewers to test this PR: + + + +### Checklist: +- [ ] Tests added +- [ ] CHANGELOG entry added + > Run `make changelog-entry` for guidance in authoring a changelog entry, and + > commit the resulting file, which should have a name matching your PR number. + > Entries should use imperative present tense (e.g. Add support for...) diff --git a/.github/scripts/changelog_checker.sh b/.github/scripts/changelog_checker.sh new file mode 100644 index 00000000..c56b1b91 --- /dev/null +++ b/.github/scripts/changelog_checker.sh @@ -0,0 +1,30 @@ +set -euo pipefail + +# check if there is a diff in the .changelog directory +# for PRs against the main branch, the changelog file name should match the PR number +if [ "$GITHUB_BASE_REF" = "$GITHUB_DEFAULT_BRANCH" ]; then + enforce_matching_pull_request_number="matching this PR number " + changelog_file_path=".changelog/(_)?$PR_NUMBER.txt" +else + changelog_file_path=".changelog/[_0-9]*.txt" +fi + +changelog_files=$(git --no-pager diff --name-only HEAD "$(git merge-base HEAD "origin/main")" | egrep "${changelog_file_path}") + +# If we do not find a file in .changelog/, we fail the check +if [ -z "$changelog_files" ]; then + # Fail status check when no .changelog entry was found on the PR + echo "Did not find a .changelog entry ${enforce_matching_pull_request_number}and the 'pr/no-changelog' label was not applied." + exit 1 +fi + +# Validate format with make changelog-check, exit with error if any note has an +# invalid format +for file in $changelog_files; do + if ! cat $file | make changelog/check; then + echo "Found a changelog entry ${enforce_matching_pull_request_number}but the note format in ${file} was invalid." + exit 1 + fi +done + +echo "Found valid changelog entry!" diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 00000000..7c3dca5e --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,31 @@ +# This workflow checks that there is either a 'pr/no-changelog' label applied to a PR +# or there is a .changelog/.txt file associated with a PR for a changelog entry + +name: Changelog Checker + +on: + pull_request: + types: [opened, synchronize, labeled] + # Runs on PRs to main and all release branches + branches: + - main + - release/* + +jobs: + # checks that a .changelog entry is present for a PR + changelog-check: + # If there a `pr/no-changelog` label we ignore this check. + if: "! ( contains(github.event.pull_request.labels.*.name, 'pr/no-changelog')" + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 # by default the checkout action doesn't checkout all branches + - name: Check for changelog entry in diff + run: ./.github/scripts/changelog_checker.sh + env: + GITHUB_BASE_REF: ${{ github.event.pull_request.base.ref }} + GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + PR_NUMBER: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index ab1a941b..63cb56c3 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: "1.21" + go-version: "1.22" - name: go mod tidy check run: | @@ -30,5 +30,5 @@ jobs: version: latest - name: Test # Run the golang tests! - run: make test + run: make go/test diff --git a/Makefile b/Makefile index 4685bedc..d915f662 100644 --- a/Makefile +++ b/Makefile @@ -49,10 +49,39 @@ go/mocks: ## Generates Go mock files. mockery; \ done -.PHONY: test -test: ## Run the unit tests +.PHONY: go/test +go/test: ## Run the unit tests @go test -v -cover ./... +.PHONY: changelog/build +changelog/build: +ifeq (, $(shell which changelog-build)) + @go install github.com/hashicorp/go-changelog/cmd/changelog-build@latest +endif +ifeq (, $(LAST_RELEASE_GIT_TAG)) + @echo "Please set the LAST_RELEASE_GIT_TAG environment variable to generate a changelog section of notes since the last release." +else + changelog-build -last-release ${LAST_RELEASE_GIT_TAG} -entries-dir .changelog/ -changelog-template .changelog/changelog.tmpl -note-template .changelog/release-note.tmpl -this-release $(shell git rev-parse HEAD) +endif + +.PHONY: changelog/new-entry +changelog/new-entry: +ifeq (, $(shell which changelog-entry)) + @go install github.com/hashicorp/go-changelog/cmd/changelog-entry@latest +endif +ifeq (, $(CHANGELOG_PR)) + @echo "Please set the CHANGELOG_PR environment variable to the PR number to associate with the changelog." +else + changelog-entry -dir .changelog -allowed-types-file .changelog/types.txt -pr ${CHANGELOG_PR} +endif + +.PHONY: changelog/check +changelog/check: +ifeq (, $(shell which changelog-check)) + @go install github.com/hashicorp/go-changelog/cmd/changelog-check@latest +endif + @changelog-check + # Docker build and publish variables and targets REGISTRY_NAME?=docker.io/hashicorp IMAGE_NAME=hcp diff --git a/internal/commands/hcp/hcp.go b/internal/commands/hcp/hcp.go index 2a217024..e746e5f7 100644 --- a/internal/commands/hcp/hcp.go +++ b/internal/commands/hcp/hcp.go @@ -18,6 +18,15 @@ func NewCmdHcp(ctx *cmd.Context) *cmd.Command { LongHelp: "The HCP Command Line Interface is a unified tool to manage your HCP services.", } + // _ _ ___ _____ _____ + // | \ | |/ _ \_ _| ____| + // | \| | | | || | | _| + // | |\ | |_| || | | |___ + // |_| \_|\___/ |_| |_____| + // + // When adding a top level command group, be sure to regenerate the + // screenshot in the README by running `make gen/screenshot`. + // Add the subcommands c.AddChild(version.NewCmdVersion(ctx)) c.AddChild(auth.NewCmdAuth(ctx))