diff --git a/.dockerignore b/.dockerignore index d7d181fa..64886aa3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,4 +4,3 @@ dist/ examples/ fixtures/ tmp/ -!/script diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c1adeafe..f515d15d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,7 +24,7 @@ jobs: - name: Tests run: | goverage -race -coverprofile=coverage.txt -covermode=atomic - make bench lint + make test/bench test/lint - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 diff --git a/.github/workflows/dockerhub.yaml b/.github/workflows/dockerhub.yaml deleted file mode 100644 index 48ac5aaa..00000000 --- a/.github/workflows/dockerhub.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Deploy Docker Image - -on: - create: ~ - -jobs: - deploy: - if: ${{ startsWith(github.ref, 'refs/tags/v') }} - runs-on: ubuntu-latest - steps: - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} - - - name: Build and push - id: docker_build - uses: docker/build-push-action@v2 - with: - push: true - tags: pseudomuto/protoc-gen-doc:${{ github.sha }}, pseudomuto/protoc-gen-doc:latest diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000..e14a0b7d --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,31 @@ +name: Release + +on: + push: + tags: + - '*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: pseudomuto + password: ${{ secrets.DOCKER_TOKEN }} + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: 1.17 + - name: Release + uses: goreleaser/goreleaser-action@v2 + with: + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GH_RELEASE_TOKEN }} diff --git a/.gitignore b/.gitignore index 0a89e775..11a78782 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,4 @@ -/_tools +/bin /coverage.txt /dist -/gen_fixtures -/protoc-gen-doc -/test/*.dat -/vendor /tmp/ diff --git a/.gofmtignore b/.gofmtignore deleted file mode 100644 index 5cecb483..00000000 --- a/.gofmtignore +++ /dev/null @@ -1,2 +0,0 @@ -/_tools/* -/vendor/* diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 00000000..a48fb053 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,48 @@ +project_name: protoc-gen-doc + +before: + hooks: + - go mod tidy + +builds: + - main: ./cmd/protoc-gen-doc + env: + - CGO_ENABLED=0 + goos: + - darwin + - linux + - windows + goarch: + - amd64 + - arm64 + +dockers: + - image_templates: + - pseudomuto/{{.ProjectName}}:latest + - pseudomuto/{{.ProjectName}}:{{.Version}} + - pseudomuto/{{.ProjectName}}:{{.Major}} + - pseudomuto/{{.ProjectName}}:{{.Major}}.{{.Minor}} + build_flag_templates: + - "--pull" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--platform=linux/amd64" + extra_files: + - LICENSE.md + - README.md + - script/entrypoint.sh + +checksum: + name_template: 'checksums.txt' + +snapshot: + name_template: "{{ incpatch .Version }}-next" + +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' diff --git a/CHANGELOG.md b/CHANGELOG.md index 532de72c..36f2fc39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased](https://github.com/pseudomuto/protoc-gen-doc/compare/v1.5.0...master) +_**CHANGELOG is now available with each release rather than in this file**_ + ### Changed * Escape special characters in markdown anchors [#460](https://github.com/pseudomuto/protoc-gen-doc/pull/460) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 39b268ca..2a1ebf74 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,10 +7,10 @@ First off, glad you're here and want to contribute! :heart: In order to work on this project, you'll need to install a few things: 1. A recent version of [Go](https://golang.org/doc/install) -1. [protoc](https://github.com/google/protobuf#protocol-compiler-installation) - The protobuf compiler -1. [Docker](https://www.docker.com/) (only required to if you need/want to build the docker container via `make docker`) +1. [Docker](https://www.docker.com/) (only required to use `make dev/docker`, `make test/docker`, or release targets). +1. [unzip](http://infozip.sourceforge.net/) -Once those are installed, running `make setup` should get you the rest of the way. +Everything else that's needed will be installed as needed and put in `./bin`. When writing tests, be sure that the package in the test file is suffixed with `_test`. Eg. `protoc_gen_doc_test`. This ensures that you'll only be testing the public interface. @@ -19,13 +19,14 @@ ensures that you'll only be testing the public interface. Here are some general guidelines for making PRs for this repo. -1. [Fork this repo](https://github.com/pseudomuto/protoc-gen-doc/fork) -1. Make a branch off of master (`git checkout -b `) -1. Make focused commits with descriptive messages -1. Add tests that fail without your code, and pass with it -1. GoFmt your code! (see to setup your editor to do this for you) -1. Be sure to run `make examples` so your changes are reflected in the example docs -1. **Ping someone on the PR** (Lots of people, including myself, won't get a notification unless pinged directly) +1. [Fork this repo](https://github.com/pseudomuto/protoc-gen-doc/fork). +1. Make a branch off of master (`git checkout -b `). +1. Make focused commits with descriptive messages. +1. Add tests that fail without your code, and pass with it. +1. GoFmt your code! (see to setup your editor to do this for you). +1. Be sure to run `make build/examples` so your changes are reflected in the example docs. +1. Running `make test/docker` should produce the same output as `make build/examples`. +1. **Ping someone on the PR** (Lots of people, including myself, won't get a notification unless pinged directly). Every PR should have a well detailed summary of the changes being made and the reasoning behind them. Make sure to add at least three sections. @@ -47,10 +48,10 @@ How has this change been tested? In your opinion what is the risk, if any, of me #### Reviewers should: 1. Identify anything that the PR author may have missed from above. -2. Test the PR through whatever means necessary, including manually, to verify it is safe to be deployed. -3. Question everything. Never assume that something was tested or fully understood, always question and ask if there is +1. Test the PR through whatever means necessary, including manually, to verify it is safe to be deployed. +1. Question everything. Never assume that something was tested or fully understood, always question and ask if there is any uncertainty. -4. Before merging the PR make sure it has _**one**_ of the `Major release`, `Minor release`, or `Patch release` labels +1. Before merging the PR make sure it has _**one**_ of the `Major release`, `Minor release`, or `Patch release` labels applied to it (useful for the changelog and determining the version for the next release). ## Release Process @@ -66,14 +67,12 @@ Look through the new (since the last release) PRs that are included in this rele ### Now that we've got the version: -* Run `make docker_test` to build the image and generate the examples. There should be no diff after this. -* Update the version in `version.go` -* Update CHANGELOG.md. Be sure to include links to PRs and highlight new features, bug fixes, and any breaking changes. -* Run `make release` +From an up-to-date master, do the following: -Now that the tag is on GitHub, we have a couple more things to do: +1. Run `make test/docker` to build the image and generate the examples. There should be no diff after this. +1. Update the version in `version.go` appropriately. +1. `git commit -am "Bump to version v`. +1. `git tag -s v`. +1. `git push origin master --tags`. -* Create a release based on the tag and copy the entry in CHANGELOG.md into the notes. -* Run `make dist` and add the tar files (in `./dist`) to the release. - -Once CI has run for the tag, Travis will push the image to DockerHub. +Once the tag is on GitHub, the release action will handle pushing to docker and creating a release in GitHub. diff --git a/Dockerfile b/Dockerfile index ddde1003..a1bad303 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,13 @@ -FROM golang:1.17-alpine AS builder -WORKDIR /build -COPY go.mod go.sum ./ -RUN go mod download -COPY . ./ -RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o protoc-gen-doc ./cmd/protoc-gen-doc - -FROM debian:bookworm-slim AS final -LABEL maintainer="pseudomuto " protoc_version="3.18.1" - +FROM alpine:3.15.0 WORKDIR / -ADD https://github.com/google/protobuf/releases/download/v3.18.1/protoc-3.18.1-linux-x86_64.zip ./ -RUN apt-get -q -y update && \ - apt-get -q -y install unzip && \ - unzip protoc-3.18.1-linux-x86_64.zip -d ./usr/local && \ - rm protoc-3.18.1-linux-x86_64.zip && \ - apt-get remove --purge -y unzip && \ - apt-get autoremove && \ - rm -rf /var/lib/apt/lists/* +RUN apk --update add bash protoc protobuf-dev && rm -rf /var/cache/apk/* -COPY --from=builder /build/protoc-gen-doc /usr/local/bin -COPY script/entrypoint.sh ./ +COPY LICENSE.md README.md script/entrypoint.sh ./ +COPY protoc-gen-doc /usr/bin/ -VOLUME ["/out", "/protos"] +VOLUME ["/out"] +VOLUME ["/protos"] -ENTRYPOINT ["/entrypoint.sh"] +ENTRYPOINT ["./entrypoint.sh"] CMD ["--doc_opt=html,index.html"] diff --git a/LICENSE.md b/LICENSE.md index 7baa276e..597ec527 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 David Muto (pseudomuto) +Copyright (c) 2022 David Muto (pseudomuto) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 883783b5..5b4d6903 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ -.PHONY: bench test build dist docker examples release lint - -export GO111MODULE=on +GORELEASER_BIN ?= https://github.com/goreleaser/goreleaser/releases/download/v1.5.0/goreleaser_Linux_x86_64.tar.gz +REVIVE_BIN ?= https://github.com/mgechev/revive/releases/download/v1.1.4/revive_1.1.4_Linux_x86_64.tar.gz +PROTOC_BIN ?= https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip EXAMPLE_DIR=$(PWD)/examples DOCS_DIR=$(EXAMPLE_DIR)/doc PROTOS_DIR=$(EXAMPLE_DIR)/proto -EXAMPLE_CMD=protoc --plugin=protoc-gen-doc \ +EXAMPLE_CMD=bin/protoc --plugin=bin/protoc-gen-doc \ -Ithirdparty -Itmp/googleapis -Iexamples/proto \ --doc_out=examples/doc @@ -14,62 +14,108 @@ DOCKER_CMD=docker run --rm \ -v $(DOCS_DIR):/out:rw \ -v $(PROTOS_DIR):/protos:ro \ -v $(EXAMPLE_DIR)/templates:/templates:ro \ - -v $(PWD)/thirdparty/github.com/mwitkow:/usr/local/include/github.com/mwitkow:ro \ - -v $(PWD)/thirdparty/github.com/envoyproxy:/usr/local/include/github.com/envoyproxy:ro \ - -v $(PWD)/tmp/googleapis/google/api:/usr/local/include/google/api:ro \ - pseudomuto/protoc-gen-doc:local + -v $(PWD)/thirdparty/github.com/mwitkow:/usr/include/github.com/mwitkow:ro \ + -v $(PWD)/thirdparty/github.com/envoyproxy:/usr/include/github.com/envoyproxy:ro \ + -v $(PWD)/tmp/googleapis/google/api:/usr/include/google/api:ro \ + pseudomuto/protoc-gen-doc:latest -VERSION = $(shell cat version.go | sed -n 's/.*const VERSION = "\(.*\)"/\1/p') +BOLD = \033[1m +CLEAR = \033[0m +CYAN = \033[36m -fixtures/fileset.pb: fixtures/*.proto fixtures/generate.go fixtures/nested/*.proto - $(info Generating fixtures...) - @cd fixtures && go generate +help: ## Display this help + @awk '\ + BEGIN {FS = ":.*##"; printf "Usage: make $(CYAN)$(CLEAR)\n"} \ + /^[a-z0-9]+([\/]%)?([\/](%-)?[a-z\-0-9%]+)*:.*? ##/ { printf " $(CYAN)%-15s$(CLEAR) %s\n", $$1, $$2 } \ + /^##@/ { printf "\n$(BOLD)%s$(CLEAR)\n", substr($$0, 5) }' \ + $(MAKEFILE_LIST) -tmp/googleapis: - rm -rf tmp/googleapis tmp/protocolbuffers - git clone --depth 1 https://github.com/googleapis/googleapis tmp/googleapis - rm -rf tmp/googleapis/.git - git clone --depth 1 https://github.com/protocolbuffers/protobuf tmp/protocolbuffers - cp -r tmp/protocolbuffers/src/* tmp/googleapis/ - rm -rf tmp/protocolbuffers - -test: fixtures/fileset.pb - @go test -cover -race ./ ./cmd/... ./extensions/... +##@: Build + +build: ## Build the main binary + @echo "$(CYAN)Building binary...$(CLEAR)" + @go build -o bin/protoc-gen-doc ./cmd/protoc-gen-doc + +build/examples: bin/protoc build tmp/googleapis examples/proto/*.proto examples/templates/*.tmpl ## Build example protos + @echo "$(CYAN)Making examples...$(CLEAR)" + @rm -f examples/doc/* + @$(EXAMPLE_CMD) --doc_opt=docbook,example.docbook:Ignore* examples/proto/*.proto + @$(EXAMPLE_CMD) --doc_opt=html,example.html:Ignore* examples/proto/*.proto + @$(EXAMPLE_CMD) --doc_opt=json,example.json:Ignore* examples/proto/*.proto + @$(EXAMPLE_CMD) --doc_opt=markdown,example.md:Ignore* examples/proto/*.proto + @$(EXAMPLE_CMD) --doc_opt=examples/templates/asciidoc.tmpl,example.txt:Ignore* examples/proto/*.proto + +##@: Dev + +dev/docker: bin/protoc tmp/googleapis release/snapshot ## Run bash in the docker container + @docker run --rm -it --entrypoint /bin/bash pseudomuto/protoc-gen-doc:latest + +##@: Test -bench: +test/bench: ## Run the bench tests + @echo "$(CYAN)Running bench tests...$(CLEAR)" @go test -bench=. -build: - @go build ./cmd/... +test/lint: bin/revive ## Lint all go files + @echo "$(CYAN)Linting go files...$(CLEAR)" + @bin/revive --config revive.toml ./... -dist: - @script/dist.sh +test/units: fixtures/fileset.pb ## Run unit tests + @echo "$(CYAN)Running unit tests...$(CLEAR)" + @go test -cover -race ./ ./cmd/... ./extensions/... -docker_test: tmp/googleapis +test/docker: bin/protoc tmp/googleapis release/snapshot ## Run the docker e2e tests + @echo "$(CYAN)Running docker e2e tests...$(CLEAR)" @rm -f examples/doc/* - @docker build -t pseudomuto/protoc-gen-doc:local . @$(DOCKER_CMD) --doc_opt=docbook,example.docbook:Ignore* @$(DOCKER_CMD) --doc_opt=html,example.html:Ignore* @$(DOCKER_CMD) --doc_opt=json,example.json:Ignore* @$(DOCKER_CMD) --doc_opt=markdown,example.md:Ignore* @$(DOCKER_CMD) --doc_opt=/templates/asciidoc.tmpl,example.txt:Ignore* -examples: build tmp/googleapis examples/proto/*.proto examples/templates/*.tmpl - $(info Making examples...) - @rm -f examples/doc/* - @$(EXAMPLE_CMD) --doc_opt=docbook,example.docbook:Ignore* examples/proto/*.proto - @$(EXAMPLE_CMD) --doc_opt=html,example.html:Ignore* examples/proto/*.proto - @$(EXAMPLE_CMD) --doc_opt=json,example.json:Ignore* examples/proto/*.proto - @$(EXAMPLE_CMD) --doc_opt=markdown,example.md:Ignore* examples/proto/*.proto - @$(EXAMPLE_CMD) --doc_opt=examples/templates/asciidoc.tmpl,example.txt:Ignore* examples/proto/*.proto +##@: Release + +release/snapshot: bin/goreleaser ## Create a local release snapshot + @echo "$(CYAN)Creating snapshot build...$(CLEAR)" + @bin/goreleaser --snapshot --rm-dist -release: - @echo Releasing v${VERSION}... - git add CHANGELOG.md version.go - git commit -m "Bump version to v${VERSION}" - git tag -m "Version ${VERSION}" "v${VERSION}" - git push && git push --tags +release/validate: bin/goreleaser ## Run goreleaser checks + @echo "$(CYAN)Validating release...$(CLEAR)" + @bin/goreleaser check -lint: - @which revive >/dev/null || go get github.com/mgechev/revive - revive --config revive.toml ./... +##@: Binaries (local installations in ./bin) + +bin/goreleaser: ## Install goreleaser + @echo "$(CYAN)Installing goreleaser...$(CLEAR)" + @mkdir -p bin + @curl -sL $(GORELEASER_BIN) | tar xzf - -C bin + @chmod +x bin/goreleaser + @rm -rf bin/LICENSE.md bin/README.md bin/completions bin/manpages + +bin/revive: ## Install revive + @echo "$(CYAN)Installing revive...$(CLEAR)" + @mkdir -p bin + @curl -sL $(REVIVE_BIN) | tar xzf - -C bin + @chmod +x bin/revive + @rm -f bin/LICENSE bin/README.md + +bin/protoc: ## Install protoc + @echo "$(CYAN)Installing protoc...$(CLEAR)" + @mkdir -p bin + @mkdir -p tmp + @curl -sLo tmp/protoc.zip $(PROTOC_BIN) + @unzip tmp/protoc.zip -x include/* readme.txt -d . + @rm -f tmp/protoc.zip + +fixtures/fileset.pb: fixtures/*.proto fixtures/generate.go fixtures/nested/*.proto + @echo "$(CYAN)Generating fixtures...$(CLEAR)" + @cd fixtures && go generate + +tmp/googleapis: + @echo "$(CYAN)Fetching googleapis...$(CLEAR)" + @rm -rf tmp/googleapis tmp/protocolbuffers + @git clone --depth 1 https://github.com/googleapis/googleapis tmp/googleapis + @rm -rf tmp/googleapis/.git + @git clone --depth 1 https://github.com/protocolbuffers/protobuf tmp/protocolbuffers + @cp -r tmp/protocolbuffers/src/* tmp/googleapis/ + @rm -rf tmp/protocolbuffers diff --git a/README.md b/README.md index cd4c6203..0185da57 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Go Report Card][goreport-svg]][goreport-url] This is a documentation generator plugin for the Google Protocol Buffers compiler (`protoc`). The plugin can generate -HTML, JSON, DocBook and Markdown documentation from comments in your `.proto` files. +HTML, JSON, DocBook, and Markdown documentation from comments in your `.proto` files. It supports proto2 and proto3, and can handle having both in the same context (see [examples](examples/) for proof). @@ -19,6 +19,8 @@ If you'd like to install this locally, you can `go get` it. `go get -u github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc` +Alternatively, you can download a pre-built release for your platform from the [releases](releases/) page. + ## Invoking the Plugin The plugin is invoked by passing the `--doc_out`, and `--doc_opt` options to the `protoc` compiler. The option has the @@ -66,8 +68,8 @@ docker run --rm \ pseudomuto/protoc-gen-doc --doc_opt=markdown,docs.md /protos/Booking.proto [OPTIONALLY LIST MORE FILES] ``` -You can also exclude proto files that match specific path expressions. This is done by passing a second option delimited by `:`. -For example, you can pass any number of comma separated patterns as the second option: +You can also exclude proto files that match specific path expressions. This is done by passing a second option delimited +by `:`. For example, you can pass any number of comma separated patterns as the second option: ``` docker run --rm \ diff --git a/script/dist.sh b/script/dist.sh deleted file mode 100755 index fd015072..00000000 --- a/script/dist.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash -set -euo pipefail - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../" && pwd)" - -package_dist() { - local build_dir="${1}" - local target="${2}" - - pushd "${build_dir}" >/dev/null - tar czf "${target}.tar.gz" "${target}" - mv "${target}.tar.gz" "${DIR}/dist" - popd >/dev/null -} - -build_dist() { - local os="${1}" - local version="${2}" - local go_version="${3}" - - local build=$(mktemp -d /tmp/protoc-gen-doc.XXXXXX) - local target="protoc-gen-doc-${version}.${os}-amd64.${go_version}" - - local ext="" - if [ "${os}" = "windows" ]; then ext=".exe"; fi - - echo -n "Building ${target}..." - GOOS="${os}" GOARCH=amd64 CGO_ENABLED=0 \ - go build -ldflags="-s -w" -o "${build}/${target}/protoc-gen-doc${ext}" ./cmd/... || exit 1 - - package_dist "${build}" "${target}" - rm -rf "${build}" - echo "done." -} - -main() { - rm -rf "${DIR}/dist" - mkdir -p "${DIR}/dist" - - local app_version=$(grep "const VERSION" "${DIR}/version.go" | awk '{print $NF }' | tr -d '"') - local go_version=$(go version | awk '{print $3}') - - for target in windows linux darwin; do - build_dist "${target}" "${app_version}" "${go_version}" - done -} - -main "$@" diff --git a/script/entrypoint.sh b/script/entrypoint.sh index 8c23e36d..d5ea048c 100755 --- a/script/entrypoint.sh +++ b/script/entrypoint.sh @@ -6,4 +6,4 @@ set -euo pipefail args=("$@") if [ "${#args[@]}" -lt 2 ]; then args+=(protos/*.proto); fi -exec protoc -Iprotos --doc_out=/out "${args[@]}" +exec protoc -I/usr/include -Iprotos --doc_out=/out "${args[@]}"