From 6be1284c6e5994c84e030d11a3e86cb7c432cfbe Mon Sep 17 00:00:00 2001 From: Derek Smith Date: Thu, 17 Jun 2021 13:46:09 -0500 Subject: [PATCH] ci: add all automation configuration Signed-off-by: Derek Smith --- .chglog/CHANGELOG.tpl.md | 56 ++++++++++++++++++ .chglog/config.yml | 29 ++++++++++ .github/renovate.json | 26 +++++++++ .github/workflows/edge.yml | 36 ++++++++++++ .github/workflows/lint.yml | 12 ++++ .github/workflows/release.yml | 39 +++++++++++++ .github/workflows/warm.yaml | 15 +++++ .golangci.yml | 21 +++++++ .goreleaser.yml | 58 +++++++++++++++++++ CONTRIBUTING.md | 76 ++++++++++++++++++++++++ Dockerfile | 9 +++ Makefile | 106 ++++++++++++++++++++++++++++++++++ main.go | 2 +- release.sh | 99 +++++++++++++++++++++++++++++++ 14 files changed, 583 insertions(+), 1 deletion(-) create mode 100755 .chglog/CHANGELOG.tpl.md create mode 100755 .chglog/config.yml create mode 100644 .github/renovate.json create mode 100644 .github/workflows/edge.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/warm.yaml create mode 100644 .golangci.yml create mode 100644 .goreleaser.yml create mode 100644 CONTRIBUTING.md create mode 100644 Dockerfile create mode 100644 Makefile create mode 100755 release.sh diff --git a/.chglog/CHANGELOG.tpl.md b/.chglog/CHANGELOG.tpl.md new file mode 100755 index 0000000..8532ec1 --- /dev/null +++ b/.chglog/CHANGELOG.tpl.md @@ -0,0 +1,56 @@ +{{ if .Versions -}} + +## [Unreleased] + +{{ if .Unreleased.CommitGroups -}} +{{ range .Unreleased.CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} + {{ end }} + {{ end -}} + {{ end -}} + {{ end -}} + +{{ range .Versions }} + +## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }} +{{ range .CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} + {{ end }} + {{ end -}} + +{{- if .RevertCommits -}} +### Reverts +{{ range .RevertCommits -}} +- {{ .Revert.Header }} + {{ end }} + {{ end -}} + +{{- if .MergeCommits -}} +### Pull Requests +{{ range .MergeCommits -}} +- {{ .Header }} + {{ end }} + {{ end -}} + +{{- if .NoteGroups -}} +{{ range .NoteGroups -}} +### {{ .Title }} +{{ range .Notes }} +{{ .Body }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{- if .Versions }} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD +{{ range .Versions -}} +{{ if .Tag.Previous -}} +[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} +{{ end -}} +{{ end -}} +{{ end -}} \ No newline at end of file diff --git a/.chglog/config.yml b/.chglog/config.yml new file mode 100755 index 0000000..700ef94 --- /dev/null +++ b/.chglog/config.yml @@ -0,0 +1,29 @@ +style: github +template: CHANGELOG.tpl.md +info: + title: CHANGELOG + repository_url: https://github.com/clok/sm +options: + commits: + commit_groups: + title_maps: + feat: Features + fix: Bug Fixes + bugfix: Bug Fixes + perf: Performance Improvements + refactor: Code Refactoring + chore: Chore + devops: DevOps + header: + pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.+)$" + pattern_maps: + - Type + - Scope + - Subject + merges: + pattern: "^(.*#\\d+.*)$" + pattern_maps: + - Source + notes: + keywords: + - BREAKING CHANGE diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..827c720 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,26 @@ +{ + "semanticCommits": true, + "prHourlyLimit": 5, + "reviewersFromCodeOwners": true, + "labels": [ + "dependencies" + ], + "extends": [ + "config:base", + ":pinAllExceptPeerDependencies", + "group:allNonMajor" + ], + "postUpdateOptions": ["gomodTidy"], + "major": { + "labels": [ + "dependencies", + "major" + ] + }, + "minor": { + "labels": [ + "dependencies", + "minor" + ] + } +} diff --git a/.github/workflows/edge.yml b/.github/workflows/edge.yml new file mode 100644 index 0000000..d179bb4 --- /dev/null +++ b/.github/workflows/edge.yml @@ -0,0 +1,36 @@ +name: docker + +on: + push: + branches: + - main + +env: + GO_VERSION: "1.16" + DOCKER_REGISTRY: "ghcr.io" + +jobs: + edge: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Login to GitHub Packages Docker Registry + uses: docker/login-action@v1 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and Push docker image + run: | + DOCKER_TAG=edge make docker + docker push ${{ env.DOCKER_REGISTRY }}/clok/sm:edge \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..3c9671e --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,12 @@ +name: lint +on: [ push, pull_request ] +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: v1.38 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..eecde35 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,39 @@ +name: goreleaser + +on: + push: + tags: + - '*' + +env: + GO_VERSION: "1.16" + DOCKER_REGISTRY: "ghcr.io" + +jobs: + goreleaser: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Login to GitHub Packages Docker Registry + uses: docker/login-action@v1 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GORELEASER_TOKEN }} diff --git a/.github/workflows/warm.yaml b/.github/workflows/warm.yaml new file mode 100644 index 0000000..1ef18db --- /dev/null +++ b/.github/workflows/warm.yaml @@ -0,0 +1,15 @@ +on: + release: + types: + - created + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + - '**/v[0-9]+.[0-9]+.[0-9]+' + +jobs: + build: + name: Renew documentation + runs-on: ubuntu-latest + steps: + - name: Pull new module version + uses: clok/go-proxy-pull-action@master \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..848c27e --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,21 @@ +# https://golangci-lint.run/usage/configuration/ +run: + timeout: 2m + +output: + format: tab + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 + +linters: + enable: + - dupl + - depguard + - gocritic + - gocyclo + - gofmt + - golint + - misspell + - unconvert diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..d42d80b --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,58 @@ +# This is an example .goreleaser.yml file with some sane defaults. +# Make sure to check the documentation at http://goreleaser.com +project_name: sm + +before: + hooks: + # You may remove this if you don't use go modules. + - go mod download + +builds: + - env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + goarch: + - 386 + - amd64 + - arm + - arm64 + +archives: + - wrap_in_directory: true + format_overrides: + - goos: windows + format: zip + +checksum: + name_template: 'checksums.txt' + +changelog: + sort: desc + filters: + exclude: + - '^Merge' + +snapshot: + name_template: "{{ .Tag }}-next" + +dockers: + - ids: + - sm + image_templates: + - "ghcr.io/clok/sm:{{ .RawVersion }}" + - "ghcr.io/clok/sm:latest" + +brews: + - tap: + owner: clok + name: homebrew-sm + homepage: "https://clokwork.net/sm/" + description: "AWS Secrets Manager CLI Tool" + license: "MIT" + test: | + system "#{bin}/sm --help" + install: | + bin.install "sm" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6477eb4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,76 @@ +# Contributing + +When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other +method with the maintainers of this repository before making a change. + +Please note we have a code of conduct, please follow it in all your interactions with the project. + +## Pull Request Process + +1. Ensure any install or build dependencies are removed before submitting a Pull Request. +2. Update the [README.md](README.md) with details of changes to the interface, this includes new environment variables, + exposed ports, useful file locations and container parameters. +3. You may merge the Pull Request in once you have the sign-off of two other developers, or if you do not have + permission to do that, you may request the second reviewer to merge it for you. + +## Code of Conduct + +### Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making +participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, +disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, +religion, or sexual identity and orientation. + +### Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +### Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take +appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, +issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +### Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the +project or its community. Examples of representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed representative at an online or offline +event. Representation of a project may be further defined and clarified by project maintainers. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. +All complaints will be reviewed and investigated and will result in a response that is deemed necessary +and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the +reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent +repercussions as determined by other members of the project's leadership. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available +at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org + +[version]: http://contributor-covenant.org/version/1/4/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8d3b16f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM alpine:3.14.0 + +COPY sm /usr/local/bin/sm +RUN chmod +x /usr/local/bin/sm + +RUN mkdir /workdir +WORKDIR /workdir + +ENTRYPOINT [ "/usr/local/bin/sm" ] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..267c564 --- /dev/null +++ b/Makefile @@ -0,0 +1,106 @@ +# Build Variables +NAME = sm +VERSION ?= $(shell git describe --tags --always) + +# Go variables +GO ?= go +GOOS ?= $(shell $(GO) env GOOS) +GOARCH ?= $(shell $(GO) env GOARCH) +GOHOST ?= GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO) + +LDFLAGS ?= "-X main.version=$(VERSION)" + +.PHONY: all +all: help + +############### +##@ Development + +.PHONY: clean +clean: ## Clean workspace + @ $(MAKE) --no-print-directory log-$@ + rm -rf bin/ + rm -rf build/ + rm -rf dist/ + rm -rf cover.out + rm -f ./$(NAME) + go mod tidy + +.PHONY: test +test: ## Run tests + @ $(MAKE) --no-print-directory log-$@ + $(GOHOST) test -covermode atomic -coverprofile cover.out -v ./... + +.PHONY: lint +lint: ## Run linters + @ $(MAKE) --no-print-directory log-$@ + golangci-lint run + +######### +##@ Build + +.PHONY: build +build: clean ## Build sm + @ $(MAKE) --no-print-directory log-$@ + @mkdir -p bin/ + CGO_ENABLED=0 $(GOHOST) build -ldflags=$(LDFLAGS) -o bin/$(NAME) ./main.go + +alpine: clean ## Build binary for alpine docker image + @ $(MAKE) --no-print-directory log-$@ + env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags=$(LDFLAGS) -o $(NAME) ./main.go + +.PHONY: docker +docker: DOCKER_TAG ?= dev +docker: alpine ## Build Docker image + @ $(MAKE) --no-print-directory log-$@ + docker build --pull --tag ghcr.io/clok/$(NAME):$(DOCKER_TAG) . + make clean + +########### +##@ Release + +.PHONY: changelog +changelog: ## Generate changelog + @ $(MAKE) --no-print-directory log-$@ + git-chglog --next-tag $(VERSION) -o CHANGELOG.md + +.PHONY: release +release: ## Release a new tag + @ $(MAKE) --no-print-directory log-$@ + ./release.sh $(VERSION) + +.PHONY: docs +docs: ## Generate new docs + @ $(MAKE) --no-print-directory log-$@ + DOCS_MD=1 go run ./main.go > docs/$(NAME).md + DOCS_MAN=1 go run ./main.go > docs/$(NAME).8 + +######## +##@ Help + +.PHONY: help +help: ## Display this help + @awk \ + -v "col=\033[36m" -v "nocol=\033[0m" \ + ' \ + BEGIN { \ + FS = ":.*##" ; \ + printf "Usage:\n make %s%s\n", col, nocol \ + } \ + /^[a-zA-Z_-]+:.*?##/ { \ + printf " %s%-12s%s %s\n", col, $$1, nocol, $$2 \ + } \ + /^##@/ { \ + printf "\n%s%s%s\n", nocol, substr($$0, 5), nocol \ + } \ + ' $(MAKEFILE_LIST) + +log-%: + @grep -h -E '^$*:.*?## .*$$' $(MAKEFILE_LIST) | \ + awk \ + 'BEGIN { \ + FS = ":.*?## " \ + }; \ + { \ + printf "\033[36m==> %s\033[0m\n", $$2 \ + }' diff --git a/main.go b/main.go index 5701764..5887a60 100644 --- a/main.go +++ b/main.go @@ -32,7 +32,7 @@ func main() { Authors: []*cli.Author{ { Name: "Derek Smith", - Email: "dsmith@goodwaygroup.com", + Email: "derek@clokwork.net", }, { Name: info.AppRepoOwner, diff --git a/release.sh b/release.sh new file mode 100755 index 0000000..7b92671 --- /dev/null +++ b/release.sh @@ -0,0 +1,99 @@ +#!/bin/bash + +set +e + +NAME=sm + +# +# Set Colors +# + +bold="\e[1m" +dim="\e[2m" +underline="\e[4m" +blink="\e[5m" +reset="\e[0m" +red="\e[31m" +green="\e[32m" +blue="\e[34m" + +# +# Common Output Styles +# + +h1() { + printf "\n${bold}${underline}%s${reset}\n" "$(echo "$@" | sed '/./,$!d')" +} +h2() { + printf "\n${bold}%s${reset}\n" "$(echo "$@" | sed '/./,$!d')" +} +info() { + printf "${dim}➜ %s${reset}\n" "$(echo "$@" | sed '/./,$!d')" +} +success() { + printf "${green}✔ %s${reset}\n" "$(echo "$@" | sed '/./,$!d')" +} +error() { + printf "${red}${bold}✖ %s${reset}\n" "$(echo "$@" | sed '/./,$!d')" +} +warnError() { + printf "${red}✖ %s${reset}\n" "$(echo "$@" | sed '/./,$!d')" +} +warnNotice() { + printf "${blue}✖ %s${reset}\n" "$(echo "$@" | sed '/./,$!d')" +} +note() { + printf "\n${bold}${blue}Note:${reset} ${blue}%s${reset}\n" "$(echo "$@" | sed '/./,$!d')" +} + +typeExists() { + if [ $(type -P $1) ]; then + return 0 + fi + return 1 +} + +if ! typeExists "git-chglog"; then + error "git-chglog is not installed" + note "To install run: go get -u github.com/git-chglog/git-chglog/cmd/git-chglog" + exit 1 +fi + +VERSION=${1} + +if [ "x${VERSION}x" = "xx" ]; then + error "Must supply version number as first argument" + exit 1 +fi + +if [[ "$(git tag -l | grep -c "$VERSION" 2>/dev/null)" != "0" ]]; then + error "Tag $VERSION already exists in this repo. Please use a different version." + exit 1 +fi + +h1 "Preparing release of $VERSION for $NAME" + +h2 "Updating docs" +make docs +if [[ "$(git status -s docs/${NAME}.* 2>/dev/null | wc -l)" == "0" ]]; then + note "No changes to docs" +else + note "Committing changes to docs" + git add docs/${NAME}.* + git commit -m "chore(docs): updating docs for version $VERSION" +fi + +h2 "Updating CHANGELOG.md" +make changelog +git add CHANGELOG.md +git commit -m "chore(release): $VERSION" + +h2 "Tagging version: $VERSION" +git tag "$VERSION" + +BRANCH="$(git rev-parse --abbrev-ref HEAD)" +note "Pushing branch: git push origin $BRANCH" +git push origin "$BRANCH" + +note "Pushing tag: git push origin $VERSION" +git push origin "$VERSION"