From 31e4812a892d4baf6c346000f92668b82ae05709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oscar=20S=C3=B6derlund?= Date: Wed, 23 Dec 2020 15:11:50 +0100 Subject: [PATCH] ci: add default CI setup for Go library Makefile and GitHub Actions pipeline with build, lint, test and releases. --- .github/CODEOWNERS | 1 + .github/dependabot.yml | 7 +++ .github/workflows/ci.yml | 52 +++++++++++++++++++ .gitignore | 3 ++ .golangci.yml | 21 ++++++++ Makefile | 27 ++++++++++ README.md | 5 ++ doc.go | 2 + tools/commitlint/.commitlintrc.js | 8 +++ tools/commitlint/package.json | 6 +++ tools/commitlint/rules.mk | 16 ++++++ .../git-verify-nodiff/git-verify-nodiff.bash | 9 ++++ tools/git-verify-nodiff/rules.mk | 7 +++ tools/golangci-lint/rules.mk | 24 +++++++++ tools/goreview/rules.mk | 18 +++++++ tools/prettier/.prettierignore | 5 ++ tools/prettier/package.json | 5 ++ tools/prettier/rules.mk | 17 ++++++ tools/semantic-release/.releaserc.yaml | 19 +++++++ tools/semantic-release/package.json | 8 +++ tools/semantic-release/rules.mk | 12 +++++ 21 files changed, 272 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .golangci.yml create mode 100644 Makefile create mode 100644 README.md create mode 100644 doc.go create mode 100644 tools/commitlint/.commitlintrc.js create mode 100644 tools/commitlint/package.json create mode 100644 tools/commitlint/rules.mk create mode 100755 tools/git-verify-nodiff/git-verify-nodiff.bash create mode 100644 tools/git-verify-nodiff/rules.mk create mode 100644 tools/golangci-lint/rules.mk create mode 100644 tools/goreview/rules.mk create mode 100644 tools/prettier/.prettierignore create mode 100644 tools/prettier/package.json create mode 100644 tools/prettier/rules.mk create mode 100644 tools/semantic-release/.releaserc.yaml create mode 100644 tools/semantic-release/package.json create mode 100644 tools/semantic-release/rules.mk diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..af369c67e0 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ + * @odsod diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..72a5fc35de --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 + +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..c7466b1af4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +name: CI + +on: + push: + branches: + - master + pull_request: + branches: + - "*" + +jobs: + make: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: ^1.15 + + - name: Setup Node + uses: actions/setup-node@v2-beta + with: + node-version: 12 + + - name: Make + run: make + + release: + needs: [make] + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: ^1.15 + + - name: Setup Node + uses: actions/setup-node@v2-beta + with: + node-version: 12 + + - name: Run semantic-release + run: make semantic-release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..dc86b929a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +tools/*/*/ +node_modules/ diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000000..f5a3bcc6bd --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,21 @@ +run: + timeout: 5m + +linters: + enable-all: true + disable: + - dupl # allow duplication + - funlen # allow long functions + - gomnd # allow some magic numbers + - wsl # unwanted amount of whitespace + - godox # allow TODOs + - interfacer # deprecated by the author for having too many false positives + - gocognit # allow higher cognitive complexity + - testpackage # unwanted convention + - nestif # allow deep nesting + - unparam # allow constant parameters + - goerr113 # allow "dynamic" errors + - dogsled # allow blank identifiers + - gocyclo # allow complex functions + - nlreturn # allow return/break without whitespace + - exhaustivestruct # don't require exhaustive fields in struct initializers diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..63c6bee36e --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +SHELL := /bin/bash + +all: \ + commitlint \ + prettier-markdown \ + go-lint \ + go-review \ + go-test \ + go-mod-tidy \ + git-verify-nodiff + +include tools/commitlint/rules.mk +include tools/git-verify-nodiff/rules.mk +include tools/golangci-lint/rules.mk +include tools/goreview/rules.mk +include tools/prettier/rules.mk +include tools/semantic-release/rules.mk + +.PHONY: go-mod-tidy +go-mod-tidy: + $(info [$@] tidying Go module files...) + @go mod tidy -v + +.PHONY: go-test +go-test: + $(info [$@] running Go tests...) + @go test -count 1 -cover -race ./... diff --git a/README.md b/README.md new file mode 100644 index 0000000000..67188b0734 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# AIP Go + +Go SDK for implementing [Google API Improvement Proposals][google-aip] (AIP). + +[google-aip]: https://google.aip.dev/ diff --git a/doc.go b/doc.go new file mode 100644 index 0000000000..454fbc9f5f --- /dev/null +++ b/doc.go @@ -0,0 +1,2 @@ +// Package aip provides primitives for implementing API Improvement Proposals (AIP). +package aip diff --git a/tools/commitlint/.commitlintrc.js b/tools/commitlint/.commitlintrc.js new file mode 100644 index 0000000000..92e3aec657 --- /dev/null +++ b/tools/commitlint/.commitlintrc.js @@ -0,0 +1,8 @@ +module.exports = { + extends: ['@commitlint/config-conventional'], + rules: { + // Treat as warning until Dependabot supports commitlint. + // https://github.com/dependabot/dependabot-core/issues/2445 + "body-max-line-length": [1, "always", 100], + } +}; diff --git a/tools/commitlint/package.json b/tools/commitlint/package.json new file mode 100644 index 0000000000..2f668224b3 --- /dev/null +++ b/tools/commitlint/package.json @@ -0,0 +1,6 @@ +{ + "devDependencies": { + "@commitlint/cli": "^11.0.0", + "@commitlint/config-conventional": "^11.0.0" + } +} diff --git a/tools/commitlint/rules.mk b/tools/commitlint/rules.mk new file mode 100644 index 0000000000..0d3eb3b671 --- /dev/null +++ b/tools/commitlint/rules.mk @@ -0,0 +1,16 @@ +commitlint_cwd := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +commitlint := $(commitlint_cwd)/node_modules/.bin/commitlint + +$(commitlint): $(commitlint_cwd)/package.json + $(info [commitlint] installing package...) + @cd $(commitlint_cwd) && npm install --no-save --no-audit &> /dev/null + @touch $@ + +.PHONY: commitlint +commitlint: $(commitlint_cwd)/.commitlintrc.js $(commitlint) + $(info [$@] linting commit messages...) + @git fetch --tags + @NODE_PATH=$(commitlint_cwd)/node_modules $(commitlint) \ + --config $< \ + --from origin/master \ + --to HEAD diff --git a/tools/git-verify-nodiff/git-verify-nodiff.bash b/tools/git-verify-nodiff/git-verify-nodiff.bash new file mode 100755 index 0000000000..0dd1f0c631 --- /dev/null +++ b/tools/git-verify-nodiff/git-verify-nodiff.bash @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +if [[ -n $(git status --porcelain) ]]; then + echo "Staging area is dirty, please add all files created by the build to .gitignore" + git diff --patch + exit 1 +fi diff --git a/tools/git-verify-nodiff/rules.mk b/tools/git-verify-nodiff/rules.mk new file mode 100644 index 0000000000..0f8e5906ff --- /dev/null +++ b/tools/git-verify-nodiff/rules.mk @@ -0,0 +1,7 @@ +git_verify_nodiff_cwd := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +git_verify_nodiff := $(git_verify_nodiff_cwd)/git-verify-nodiff.bash + +.PHONY: git-verify-nodiff +git-verify-nodiff: + $(info [$@] verifying that git has no diff...) + @$(git_verify_nodiff) diff --git a/tools/golangci-lint/rules.mk b/tools/golangci-lint/rules.mk new file mode 100644 index 0000000000..907245f070 --- /dev/null +++ b/tools/golangci-lint/rules.mk @@ -0,0 +1,24 @@ +golangci_lint_cwd := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +golangci_lint_version := 1.33.0 +golangci_lint := $(golangci_lint_cwd)/$(golangci_lint_version)/golangci-lint + +ifeq ($(shell uname),Linux) +golangci_lint_archive_url := https://github.com/golangci/golangci-lint/releases/download/v${golangci_lint_version}/golangci-lint-${golangci_lint_version}-linux-amd64.tar.gz +else ifeq ($(shell uname),Darwin) +golangci_lint_archive_url := https://github.com/golangci/golangci-lint/releases/download/v${golangci_lint_version}/golangci-lint-${golangci_lint_version}-darwin-amd64.tar.gz +else +$(error unsupported OS: $(shell uname)) +endif + +$(golangci_lint): + $(info [golangci-lint] fetching version $(golangci_lint) binary...) + @mkdir -p $(dir $@) + @curl -sSL $(golangci_lint_archive_url) -o - | \ + tar -xz --directory $(dir $@) --strip-components 1 + @chmod +x $@ + @touch $@ + +.PHONY: go-lint +go-lint: $(golangci_lint) + $(info [$@] linting Go code...) + @$(golangci_lint) run diff --git a/tools/goreview/rules.mk b/tools/goreview/rules.mk new file mode 100644 index 0000000000..9687199495 --- /dev/null +++ b/tools/goreview/rules.mk @@ -0,0 +1,18 @@ +goreview_cwd := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +goreview_version := 0.16.0 +goreview := $(goreview_cwd)/$(goreview_version)/goreview + +goreview_archive_url := https://github.com/einride/goreview/releases/download/v$(goreview_version)/goreview_$(goreview_version)_$(shell uname)_$(shell uname -m).tar.gz + +$(goreview): $(goreview_cwd)/rules.mk + $(info [go-review] fetching $(goreview_version) binary...) + @mkdir -p $(dir $@) + @curl -sSL $(goreview_archive_url) -o - | tar -xz --directory $(dir $@) + @chmod +x $@ + @touch $@ + +# go-review: review Go code for Einride-specific conventions +.PHONY: go-review +go-review: $(goreview) + $(info [$@] reviewing Go code for Einride-specific conventions...) + @$(goreview) -c 1 ./... diff --git a/tools/prettier/.prettierignore b/tools/prettier/.prettierignore new file mode 100644 index 0000000000..2e4c9ed70a --- /dev/null +++ b/tools/prettier/.prettierignore @@ -0,0 +1,5 @@ +# paths are relative to this file + +../ +../vendor +../node_modules diff --git a/tools/prettier/package.json b/tools/prettier/package.json new file mode 100644 index 0000000000..9caf44e62a --- /dev/null +++ b/tools/prettier/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "prettier": "^2.2.1" + } +} diff --git a/tools/prettier/rules.mk b/tools/prettier/rules.mk new file mode 100644 index 0000000000..ab6b6b7be9 --- /dev/null +++ b/tools/prettier/rules.mk @@ -0,0 +1,17 @@ +prettier_cwd := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +prettier := $(prettier_cwd)/node_modules/.bin/prettier + +$(prettier): $(prettier_cwd)/package.json + $(info [prettier] installing...) + @cd $(prettier_cwd) && npm install --no-save --no-audit &> /dev/null + @touch $@ + +.PHONY: prettier-markdown +prettier-markdown: $(prettier_cwd)/.prettierignore $(prettier) + $(info [$@] formatting Markdown files...) + @$(prettier) \ + --loglevel warn \ + --ignore-path $< \ + --parser markdown \ + --prose-wrap always \ + --write **/*.md diff --git a/tools/semantic-release/.releaserc.yaml b/tools/semantic-release/.releaserc.yaml new file mode 100644 index 0000000000..1a68877822 --- /dev/null +++ b/tools/semantic-release/.releaserc.yaml @@ -0,0 +1,19 @@ +plugins: + - - "@semantic-release/commit-analyzer" + - preset: "conventionalcommits" + releaseRules: + # Given Go v2+ conventions we disable major releases on + # breaking changes and leave it up to the developer + # to make major releases + - breaking: true + release: "minor" + - "@semantic-release/release-notes-generator" + - "@semantic-release/github" + +branches: ["master"] +# github plugin is the only one running this step and we're not interested +# in its updates to PR and issues +success: false +# github plugin is the only one running this step and we're not interested +# the issues it creates due to failed releases +fail: false diff --git a/tools/semantic-release/package.json b/tools/semantic-release/package.json new file mode 100644 index 0000000000..3069fdc8b9 --- /dev/null +++ b/tools/semantic-release/package.json @@ -0,0 +1,8 @@ +{ + "devDependencies": { + "semantic-release": "^17.3.0", + "@semantic-release/github": "^7.2.0", + "@semantic-release/release-notes-generator": "^9.0.1", + "conventional-changelog-conventionalcommits": "^4.5.0" + } +} diff --git a/tools/semantic-release/rules.mk b/tools/semantic-release/rules.mk new file mode 100644 index 0000000000..2992c1a849 --- /dev/null +++ b/tools/semantic-release/rules.mk @@ -0,0 +1,12 @@ +semantic_release_cwd := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +semantic_release := $(semantic_release_cwd)/node_modules/.bin/semantic-release + +$(semantic_release): $(semantic_release_cwd)/package.json + $(info [semantic-release] installing packages...) + @cd $(semantic_release_cwd) && npm install --no-save --no-audit --ignore-scripts &> /dev/null + @touch $@ + +.PHONY: semantic-release +semantic-release: $(semantic_release_cwd)/.releaserc.yaml $(semantic_release) + $(info [$@] creating release...) + @cd $(semantic_release_cwd) && $(semantic_release)