diff --git a/.dictionary b/.dictionary new file mode 100644 index 0000000..177198d --- /dev/null +++ b/.dictionary @@ -0,0 +1,5 @@ +api +github +url +gh +wp-gitea-release diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index c13ca3f..0000000 --- a/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!release/ diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index 68d9fb2..0000000 --- a/.drone.yml +++ /dev/null @@ -1,254 +0,0 @@ -kind: pipeline -type: vm -name: testing -platform: - os: linux - arch: amd64 -pool: - use: ubuntu - -steps: - - name: lint - image: golang:1.20 - pull: always - commands: - - go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest - - golangci-lint version - - golangci-lint run - volumes: - - name: gopath - path: "/go" - - name: test - image: golang:1.20 - commands: - - go test -cover ./... - volumes: - - name: gopath - path: "/go" -volumes: - - name: gopath - temp: {} -trigger: - ref: - - refs/heads/master - - refs/tags/** - - refs/pull/** - ---- -kind: pipeline -type: vm -name: linux-amd64 -platform: - os: linux - arch: amd64 -pool: - use: ubuntu - -steps: - - name: environment - image: golang:1.20 - pull: always - environment: - CGO_ENABLED: "0" - commands: - - go version - - go env - - name: build - image: golang:1.20 - environment: - CGO_ENABLED: "0" - commands: - - go build -v -ldflags "-X main.version=" -a -tags netgo -o release/linux/amd64/drone-gitea-release . - - name: docker - image: plugins/docker - settings: - dockerfile: docker/Dockerfile.linux.amd64 - repo: plugins/gitea-release - username: - from_secret: docker_username - password: - from_secret: docker_password - auto_tag: true - auto_tag_suffix: linux-amd64 -depends_on: - - testing -trigger: - ref: - - refs/heads/master - - refs/tags/** - - refs/pull/** - ---- -kind: pipeline -type: vm -name: linux-arm64 -platform: - os: linux - arch: arm64 -pool: - use: ubuntu_arm64 - -steps: - - name: environment - image: golang:1.20 - pull: always - environment: - CGO_ENABLED: "0" - commands: - - go version - - go env - - name: build - image: golang:1.20 - environment: - CGO_ENABLED: "0" - commands: - - go build -v -ldflags "-X main.version=" -a -tags netgo -o release/linux/arm64/drone-gitea-release . - - name: docker - image: plugins/docker - settings: - dockerfile: docker/Dockerfile.linux.arm64 - repo: plugins/gitea-release - username: - from_secret: docker_username - password: - from_secret: docker_password - auto_tag: true - auto_tag_suffix: linux-arm64 -depends_on: - - testing -trigger: - ref: - - refs/heads/master - - refs/tags/** - - refs/pull/** - ---- -kind: pipeline -type: vm -name: windows-1809 -platform: - os: windows - arch: amd64 -pool: - use: windows - -steps: - - name: environment - image: golang:1.20 - pull: always - environment: - CGO_ENABLED: "0" - commands: - - go version - - go env - - name: build - image: golang:1.20 - environment: - CGO_ENABLED: "0" - commands: - - go build -v -ldflags "-X main.version=" -a -tags netgo -o release/windows/amd64/drone-gitea-release.exe . - - name: docker - image: plugins/docker - settings: - dockerfile: docker/Dockerfile.windows.1809 - repo: plugins/gitea-release - username: - from_secret: docker_username - password: - from_secret: docker_password - auto_tag: true - auto_tag_suffix: windows-1809-amd64 - daemon_off: true - purge: false - when: - ref: - - refs/heads/master - - refs/tags/** -depends_on: - - testing -trigger: - ref: - - refs/heads/master - - refs/tags/** - - refs/pull/** - ---- -kind: pipeline -type: vm -name: windows-ltsc2022 -platform: - os: windows - arch: amd64 -pool: - use: windows-2022 - -steps: - - name: environment - image: golang:1.20 - pull: always - environment: - CGO_ENABLED: "0" - commands: - - go version - - go env - - name: build - image: golang:1.20 - environment: - CGO_ENABLED: "0" - commands: - - go build -v -ldflags "-X main.version=" -a -tags netgo -o release/windows/amd64/drone-gitea-release.exe . - - name: docker - image: plugins/docker - settings: - dockerfile: docker/Dockerfile.windows.ltsc2022 - repo: plugins/gitea-release - username: - from_secret: docker_username - password: - from_secret: docker_password - auto_tag: true - auto_tag_suffix: windows-ltsc2022-amd64 - daemon_off: true - purge: false - when: - ref: - - refs/heads/master - - refs/tags/** -depends_on: - - testing -trigger: - ref: - - refs/heads/master - - refs/tags/** - - refs/pull/** - ---- -kind: pipeline -type: vm -name: manifest -platform: - os: linux - arch: amd64 -pool: - use: ubuntu - -steps: - - name: manifest - image: plugins/manifest - settings: - auto_tag: "true" - username: - from_secret: docker_username - password: - from_secret: docker_password - spec: docker/manifest.tmpl - ignore_missing: true -depends_on: - - linux-amd64 - - linux-arm64 - - windows-1809 - - windows-ltsc2022 -trigger: - ref: - - refs/heads/master - - refs/tags/** diff --git a/.github/issue_template.md b/.github/issue_template.md deleted file mode 100644 index 3f95605..0000000 --- a/.github/issue_template.md +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index e69de29..0000000 diff --git a/.github/settings.yml b/.github/settings.yml index d01b75f..89a6a25 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -1,15 +1,15 @@ repository: - name: drone-gitea-release - description: Drone plugin for creating and tagging Gitea releases - homepage: http://plugins.drone.io/drone-plugins/drone-gitea-release - topics: drone, drone-plugin + name: wp-gitea-release + description: Woodpecker CI plugin to add comments to GitHub Issues and Pull Requests + homepage: https://woodpecker-plugins.geekdocs.de/plugins/wp-gitea-release + topics: woodpecker-ci, woodpecker, woodpecker-plugin private: false has_issues: true has_wiki: false - has_downloads: false + has_downloads: true - default_branch: master + default_branch: main allow_squash_merge: true allow_merge_commit: true @@ -19,6 +19,9 @@ labels: - name: bug color: d73a4a description: Something isn't working + - name: documentation + color: 0075ca + description: Improvements or additions to documentation - name: duplicate color: cfd3d7 description: This issue or pull request already exists @@ -37,37 +40,32 @@ labels: - name: question color: d876e3 description: Further information is requested - - name: renovate - color: e99695 - description: Automated action from Renovate - name: wontfix color: ffffff description: This will not be worked on -teams: - - name: Admins - permission: admin - - name: Captain - permission: admin - - name: Maintainers - permission: push - branches: - - name: master + - name: main protection: - required_pull_request_reviews: - required_approving_review_count: 1 - dismiss_stale_reviews: false - require_code_owner_reviews: false - dismissal_restrictions: - teams: - - Admins - - Captain + required_pull_request_reviews: null required_status_checks: - strict: true + strict: false contexts: - - continuous-integration/drone/pr + - ci/woodpecker/pr/test + - ci/woodpecker/pr/build-package + - ci/woodpecker/pr/build-container + - ci/woodpecker/pr/docs enforce_admins: false + required_linear_history: true + restrictions: null + - name: docs + protection: + required_pull_request_reviews: null + required_status_checks: null + enforce_admins: true + required_linear_history: true restrictions: + apps: [] users: [] - teams: [] + teams: + - bot diff --git a/.gitignore b/.gitignore index aaa10cf..9d07dee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,30 +1,7 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -release/ -vendor/ +/dist +/release +/wp-gitea-release* +docs/data/data-raw.yaml coverage.out -drone-gitea-release +CHANGELOG.md diff --git a/.gitsv/config.yml b/.gitsv/config.yml new file mode 100644 index 0000000..acaf506 --- /dev/null +++ b/.gitsv/config.yml @@ -0,0 +1,47 @@ +--- +version: "1.1" + +versioning: + update-major: [] + update-minor: [feat] + update-patch: [fix, perf, refactor, chore, test, ci, docs] + +tag: + pattern: "v%d.%d.%d" + +release-notes: + sections: + - name: Features + commit-types: [feat] + section-type: commits + - name: Bug Fixes + commit-types: [fix] + section-type: commits + - name: Performance Improvements + commit-types: [perf] + section-type: commits + - name: Code Refactoring + commit-types: [refactor] + section-type: commits + - name: Others + commit-types: [chore] + section-type: commits + - name: Testing + commit-types: [test] + section-type: commits + - name: CI Pipeline + commit-types: [ci] + section-type: commits + - name: Documentation + commit-types: [docs] + section-type: commits + - name: BREAKING CHANGES + section-type: breaking-changes + +commit-message: + footer: + issue: + key: issue + add-value-prefix: "#" + issue: + regex: "#?[0-9]+" diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..5de88c8 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,97 @@ +linters: + enable-all: false + disable-all: true + enable: + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - typecheck + - unused + - asasalint + - asciicheck + - bidichk + - bodyclose + - containedctx + - contextcheck + - decorder + - dogsled + - dupl + - dupword + - durationcheck + - errchkjson + - errname + - errorlint + - execinquery + - exhaustive + - exportloopref + - forcetypeassert + - ginkgolinter + - gocheckcompilerdirectives + - gochecknoglobals + - gochecknoinits + - gocognit + - goconst + - gocritic + - gocyclo + - godot + - godox + - goerr113 + - gofmt + - gofumpt + - goheader + - goimports + - gomnd + - gomoddirectives + - gomodguard + - goprintffuncname + - gosec + - grouper + - importas + - interfacebloat + - ireturn + - lll + - loggercheck + - maintidx + - makezero + - misspell + - musttag + - nakedret + - nestif + - nilerr + - nilnil + - nlreturn + - noctx + - nolintlint + - nonamedreturns + - nosprintfhostport + - prealloc + - predeclared + - promlinter + - reassign + - revive + # - rowserrcheck + # - sqlclosecheck + # - structcheck + - stylecheck + - tagliatelle + - tenv + - testableexamples + - thelper + - tparallel + - unconvert + - unparam + - usestdlibvars + # - wastedassign + - whitespace + - wsl + - zerologlint + fast: false + +run: + timeout: 3m + +linters-settings: + gofumpt: + extra-rules: true diff --git a/.lycheeignore b/.lycheeignore new file mode 100644 index 0000000..e98d40b --- /dev/null +++ b/.lycheeignore @@ -0,0 +1 @@ +https://hub.docker.com/r/thegeeklab/* diff --git a/.markdownlint.yml b/.markdownlint.yml new file mode 100644 index 0000000..b59a114 --- /dev/null +++ b/.markdownlint.yml @@ -0,0 +1,6 @@ +--- +default: True +MD013: False +MD041: False +MD004: + style: dash diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..135c35d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +*.tpl.md +LICENSE diff --git a/.woodpecker/build-container.yml b/.woodpecker/build-container.yml new file mode 100644 index 0000000..fab03d6 --- /dev/null +++ b/.woodpecker/build-container.yml @@ -0,0 +1,66 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: dryrun + image: quay.io/thegeeklab/wp-docker-buildx:2 + settings: + containerfile: Containerfile.multiarch + dry_run: true + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + repo: ${CI_REPO} + when: + - event: [pull_request] + + - name: publish-dockerhub + image: quay.io/thegeeklab/wp-docker-buildx:2 + group: container + settings: + auto_tag: true + containerfile: Containerfile.multiarch + password: + from_secret: docker_password + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + repo: ${CI_REPO} + username: + from_secret: docker_username + when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + + - name: publish-quay + image: quay.io/thegeeklab/wp-docker-buildx:2 + group: container + settings: + auto_tag: true + containerfile: Containerfile.multiarch + password: + from_secret: quay_password + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + registry: quay.io + repo: quay.io/${CI_REPO} + username: + from_secret: quay_username + when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +depends_on: + - test diff --git a/.woodpecker/build-package.yml b/.woodpecker/build-package.yml new file mode 100644 index 0000000..0a86916 --- /dev/null +++ b/.woodpecker/build-package.yml @@ -0,0 +1,41 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: build + image: docker.io/techknowlogick/xgo:go-1.21.x + commands: + - ln -s $(pwd) /source + - make release + + - name: executable + image: quay.io/thegeeklab/alpine-tools + commands: + - $(find dist/ -executable -type f -iname ${CI_REPO_NAME}-linux-amd64) --help + + - name: changelog + image: quay.io/thegeeklab/git-sv + commands: + - git sv current-version + - git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md + - cat CHANGELOG.md + + - name: publish-github + image: docker.io/plugins/github-release + settings: + api_key: + from_secret: github_token + files: + - dist/* + note: CHANGELOG.md + overwrite: true + title: ${CI_COMMIT_TAG} + when: + - event: [tag] + +depends_on: + - test diff --git a/.woodpecker/docs.yml b/.woodpecker/docs.yml new file mode 100644 index 0000000..db29f1f --- /dev/null +++ b/.woodpecker/docs.yml @@ -0,0 +1,80 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: markdownlint + image: quay.io/thegeeklab/markdownlint-cli + group: test + commands: + - markdownlint 'README.md' 'CONTRIBUTING.md' + + - name: spellcheck + image: quay.io/thegeeklab/alpine-tools + group: test + commands: + - spellchecker --files 'docs/**/*.md' 'README.md' 'CONTRIBUTING.md' -d .dictionary -p spell indefinite-article syntax-urls + environment: + FORCE_COLOR: "true" + + - name: link-validation + image: docker.io/lycheeverse/lychee + group: test + commands: + - lychee --no-progress --format detailed docs/content README.md + + - name: publish + image: quay.io/thegeeklab/wp-git-action + settings: + action: + - pages + author_email: bot@thegeeklab.de + author_name: thegeeklab-bot + branch: docs + message: "[skip ci] auto-update documentation" + netrc_password: + from_secret: github_token + pages_directory: docs/ + when: + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + status: [success, failure] + + - name: pushrm-dockerhub + image: docker.io/chko/docker-pushrm:1 + secrets: + - source: docker_password + target: DOCKER_PASS + - source: docker_username + target: DOCKER_USER + environment: + PUSHRM_FILE: README.md + PUSHRM_SHORT: Woodpecker CI plugin to add comments to GitHub Issues and Pull Requests + PUSHRM_TARGET: ${CI_REPO} + when: + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + status: [success] + + - name: pushrm-quay + image: docker.io/chko/docker-pushrm:1 + secrets: + - source: quay_token + target: APIKEY__QUAY_IO + environment: + PUSHRM_FILE: README.md + PUSHRM_TARGET: quay.io/${CI_REPO} + when: + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + status: [success] + +depends_on: + - build-package + - build-container diff --git a/.woodpecker/notify.yml b/.woodpecker/notify.yml new file mode 100644 index 0000000..9957125 --- /dev/null +++ b/.woodpecker/notify.yml @@ -0,0 +1,26 @@ +--- +when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +runs_on: [success, failure] + +steps: + - name: matrix + image: quay.io/thegeeklab/wp-matrix + settings: + homeserver: + from_secret: matrix_homeserver + password: + from_secret: matrix_password + roomid: + from_secret: matrix_roomid + username: + from_secret: matrix_username + when: + - status: [success, failure] + +depends_on: + - docs diff --git a/.woodpecker/test.yml b/.woodpecker/test.yml new file mode 100644 index 0000000..65b7d81 --- /dev/null +++ b/.woodpecker/test.yml @@ -0,0 +1,17 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: lint + image: docker.io/library/golang:1.21 + commands: + - make lint + + - name: test + image: docker.io/library/golang:1.21 + commands: + - make test diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..72264c4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing + +## Security + +If you think you have found a **security issue**, please do not mention it in this repository. +Instead, send an email to `security@thegeeklab.de` with as many details as possible so it can be handled confidential. + +## Bug Reports and Feature Requests + +If you have found a **bug** or have a **feature request** please use the search first in case a similar issue already exists. +If not, please create an issue in this repository + +## Code + +If you would like to fix a bug or implement a feature, please fork the repository and create a Pull Request. + +Before you start any Pull Request, it is recommended that you create an issue to discuss first if you have any +doubts about requirement or implementation. That way you can be sure that the maintainer(s) agree on what to change and how, +and you can hopefully get a quick merge afterwards. + +Pull Requests can only be merged once all status checks are green. + +## Do not force push to your Pull Request branch + +Please do not force push to your Pull Requests branch after you have created your Pull Request, as doing so makes it harder for us to review your work. +Pull Requests will always be squashed by us when we merge your work. Commit as many times as you need in your Pull Request branch. + +## Re-requesting a review + +Please do not ping your reviewer(s) by mentioning them in a new comment. Instead, use the re-request review functionality. +Read more about this in the [GitHub docs, Re-requesting a review](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request#re-requesting-a-review). diff --git a/Containerfile.multiarch b/Containerfile.multiarch new file mode 100644 index 0000000..99d7d2e --- /dev/null +++ b/Containerfile.multiarch @@ -0,0 +1,21 @@ +FROM --platform=$BUILDPLATFORM golang:1.21@sha256:672a2286da3ee7a854c3e0a56e0838918d0dbb1c18652992930293312de898a6 as build + +ARG TARGETOS +ARG TARGETARCH + +ADD . /src +WORKDIR /src + +RUN make build + +FROM alpine:3.19@sha256:51b67269f354137895d43f3b3d810bfacd3945438e94dc5ac55fdac340352f48 + +LABEL maintainer="Robert Kaussow " +LABEL org.opencontainers.image.authors="Robert Kaussow " +LABEL org.opencontainers.image.title="wp-gitea-release" +LABEL org.opencontainers.image.url="https://github.com/thegeeklab/wp-gitea-release" +LABEL org.opencontainers.image.source="https://github.com/thegeeklab/wp-gitea-release" +LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/wp-gitea-release" + +COPY --from=build /src/dist/wp-gitea-release /bin/wp-gitea-release +ENTRYPOINT ["/bin/wp-gitea-release"] diff --git a/LICENSE b/LICENSE index 8dada3e..c9faf00 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,4 @@ + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -178,7 +179,7 @@ APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" + boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -186,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright 2022 Robert Kaussow Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8038078 --- /dev/null +++ b/Makefile @@ -0,0 +1,107 @@ +# renovate: datasource=github-releases depName=mvdan/gofumpt +GOFUMPT_PACKAGE_VERSION := v0.5.0 +# renovate: datasource=github-releases depName=golangci/golangci-lint +GOLANGCI_LINT_PACKAGE_VERSION := v1.55.2 + +EXECUTABLE := wp-gitea-release + +DIST := dist +DIST_DIRS := $(DIST) +IMPORT := github.com/thegeeklab/$(EXECUTABLE) + +GO ?= go +CWD ?= $(shell pwd) +PACKAGES ?= $(shell go list ./...) +SOURCES ?= $(shell find . -name "*.go" -type f) + +GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@$(GOFUMPT_PACKAGE_VERSION) +GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_PACKAGE_VERSION) +XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest +GOTESTSUM_PACKAGE ?= gotest.tools/gotestsum@latest + +GENERATE ?= +XGO_VERSION := go-1.21.x +XGO_TARGETS ?= linux/amd64,linux/arm-6,linux/arm-7,linux/arm64 + +TARGETOS ?= linux +TARGETARCH ?= amd64 +ifneq ("$(TARGETVARIANT)","") +GOARM ?= $(subst v,,$(TARGETVARIANT)) +endif +TAGS ?= netgo + +ifndef VERSION + ifneq ($(CI_COMMIT_TAG),) + VERSION ?= $(subst v,,$(CI_COMMIT_TAG)) + else + VERSION ?= $(shell git rev-parse --short HEAD) + endif +endif + +ifndef DATE + DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%S%z") +endif + +LDFLAGS += -s -w -X "main.BuildVersion=$(VERSION)" -X "main.BuildDate=$(DATE)" + +.PHONY: all +all: clean build + +.PHONY: clean +clean: + $(GO) clean -i ./... + rm -rf $(DIST_DIRS) + +.PHONY: fmt +fmt: + $(GO) run $(GOFUMPT_PACKAGE) -extra -w $(SOURCES) + +.PHONY: golangci-lint +golangci-lint: + $(GO) run $(GOLANGCI_LINT_PACKAGE) run + +.PHONY: lint +lint: golangci-lint + +.PHONY: generate +generate: + $(GO) generate $(GENERATE) + +.PHONY: generate-docs +generate-docs: + $(GO) generate ./cmd/$(EXECUTABLE)/flags.go + +.PHONY: test +test: + $(GO) run $(GOTESTSUM_PACKAGE) --no-color=false -- -coverprofile=coverage.out $(PACKAGES) + +.PHONY: build +build: $(DIST)/$(EXECUTABLE) + +$(DIST)/$(EXECUTABLE): $(SOURCES) + GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) GOARM=$(GOARM) $(GO) build -v -tags '$(TAGS)' -ldflags '-extldflags "-static" $(LDFLAGS)' -o $@ ./cmd/$(EXECUTABLE) + +$(DIST_DIRS): + mkdir -p $(DIST_DIRS) + +.PHONY: xgo +xgo: | $(DIST_DIRS) + $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -v -ldflags '-extldflags "-static" $(LDFLAGS)' -tags '$(TAGS)' -targets '$(XGO_TARGETS)' -out $(EXECUTABLE) --pkg cmd/$(EXECUTABLE) . + cp /build/* $(CWD)/$(DIST) + ls -l $(CWD)/$(DIST) + +.PHONY: checksum +checksum: + cd $(DIST); $(foreach file,$(wildcard $(DIST)/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;) + ls -l $(CWD)/$(DIST) + +.PHONY: release +release: xgo checksum + +.PHONY: deps +deps: + $(GO) mod download + $(GO) install $(GOFUMPT_PACKAGE) + $(GO) install $(GOLANGCI_LINT_PACKAGE) + $(GO) install $(XGO_PACKAGE) + $(GO) install $(GOTESTSUM_PACKAGE) diff --git a/README.md b/README.md index ba351ff..9940206 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,21 @@ -# drone-gitea-release +# wp-gitea-release -[![Build Status](http://cloud.drone.io/api/badges/drone-plugins/drone-gitea-release/status.svg)](http://cloud.drone.io/drone-plugins/drone-gitea-release) -[![Gitter chat](https://badges.gitter.im/drone/drone.png)](https://gitter.im/drone/drone) -[![Join the discussion at https://discourse.drone.io](https://img.shields.io/badge/discourse-forum-orange.svg)](https://discourse.drone.io) -[![Drone questions at https://stackoverflow.com](https://img.shields.io/badge/drone-stackoverflow-orange.svg)](https://stackoverflow.com/questions/tagged/drone.io) -[![](https://images.microbadger.com/badges/image/plugins/gitea-release.svg)](https://microbadger.com/images/plugins/gitea-release "Get your own image badge on microbadger.com") -[![Go Doc](https://godoc.org/github.com/drone-plugins/drone-gitea-release?status.svg)](http://godoc.org/github.com/drone-plugins/drone-gitea-release) -[![Go Report](https://goreportcard.com/badge/github.com/drone-plugins/drone-gitea-release)](https://goreportcard.com/report/github.com/drone-plugins/drone-gitea-release) +Woodpecker CI plugin to add comments to GitHub Issues and Pull Requests -Drone plugin to publish files and artifacts to Gitea release. For the usage information and a listing of the available options please take a look at [the docs](http://plugins.drone.io/drone-plugins/drone-gitea-release/). +[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/wp-gitea-release/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/wp-gitea-release) +[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/wp-gitea-release) +[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/wp-gitea-release) +[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/wp-gitea-release)](https://goreportcard.com/report/github.com/thegeeklab/wp-gitea-release) +[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/wp-gitea-release)](https://github.com/thegeeklab/wp-gitea-release/graphs/contributors) +[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/wp-gitea-release) +[![License: Apache-2.0](https://img.shields.io/github/license/thegeeklab/wp-gitea-release)](https://github.com/thegeeklab/wp-gitea-release/blob/main/LICENSE) -## Build +Woodpecker CI plugin to add comments to GitHub Issues and Pull Requests. You can find the full documentation at [https://woodpecker-plugins.geekdocs.de](https://woodpecker-plugins.geekdocs.de/plugins/wp-gitea-release). -Build the binary with the following command: +## Contributors -```console -export GOOS=linux -export GOARCH=amd64 -export CGO_ENABLED=0 -export GO111MODULE=on +Special thanks to all [contributors](https://github.com/thegeeklab/wp-gitea-release/graphs/contributors). If you would like to contribute, please see the [instructions](https://github.com/thegeeklab/wp-gitea-release/blob/main/CONTRIBUTING.md). -go build -v -a -tags netgo -o release/linux/amd64/drone-gitea-release -``` +## License -## Docker - -Build the Docker image with the following command: - -```console -docker build \ - --label org.label-schema.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ - --label org.label-schema.vcs-ref=$(git rev-parse --short HEAD) \ - --file docker/Dockerfile.linux.amd64 --tag plugins/gitea-release . -``` - -## Usage - -```console -docker run --rm \ - -e PLUGIN_BASE_URL=https://try.gitea.io \ - -e PLUGIN_API_KEY=your-api-key \ - -e PLUGIN_FILES=build/* \ - -e DRONE_REPO_OWNER=gitea \ - -e DRONE_REPO_NAME=test \ - -e DRONE_BUILD_EVENT=tag \ - -v $(pwd):$(pwd) \ - -w $(pwd) \ - plugins/gitea-release -``` +This project is licensed under the Apache-2.0 License - see the [LICENSE](https://github.com/thegeeklab/wp-gitea-release/blob/main/LICENSE) file for details. diff --git a/cmd/wp-gitea-release/docs.go b/cmd/wp-gitea-release/docs.go new file mode 100644 index 0000000..37b319d --- /dev/null +++ b/cmd/wp-gitea-release/docs.go @@ -0,0 +1,58 @@ +//go:build generate +// +build generate + +package main + +import ( + "bytes" + "embed" + "fmt" + "os" + "text/template" + + "github.com/thegeeklab/wp-gitea-release/plugin" + "github.com/thegeeklab/wp-plugin-go/docs" + wp "github.com/thegeeklab/wp-plugin-go/plugin" + wp_template "github.com/thegeeklab/wp-plugin-go/template" + "github.com/urfave/cli/v2" +) + +//go:embed templates/docs-data.yaml.tmpl +var yamlTemplate embed.FS + +func main() { + settings := &plugin.Settings{} + app := &cli.App{ + Flags: settingsFlags(settings, wp.FlagsPluginCategory), + } + + out, err := toYAML(app) + if err != nil { + panic(err) + } + + fi, err := os.Create("../../docs/data/data-raw.yaml") + if err != nil { + panic(err) + } + defer fi.Close() + if _, err := fi.WriteString(out); err != nil { + panic(err) + } +} + +func toYAML(app *cli.App) (string, error) { + var w bytes.Buffer + + yamlTmpl, err := template.New("docs").Funcs(wp_template.LoadFuncMap()).ParseFS(yamlTemplate, "templates/docs-data.yaml.tmpl") + if err != nil { + fmt.Println(yamlTmpl) + return "", err + } + + if err := yamlTmpl.ExecuteTemplate(&w, "docs-data.yaml.tmpl", docs.GetTemplateData(app)); err != nil { + return "", err + } + + return w.String(), nil +} diff --git a/cmd/wp-gitea-release/flags.go b/cmd/wp-gitea-release/flags.go new file mode 100644 index 0000000..3d0dbe9 --- /dev/null +++ b/cmd/wp-gitea-release/flags.go @@ -0,0 +1,108 @@ +package main + +import ( + "github.com/thegeeklab/wp-gitea-release/plugin" + "github.com/urfave/cli/v2" +) + +// settingsFlags has the cli.Flags for the plugin.Settings. +// +//go:generate go run docs.go flags.go +func settingsFlags(settings *plugin.Settings, category string) []cli.Flag { + return []cli.Flag{ + &cli.StringFlag{ + Name: "api-key", + Usage: "api key to access gitea api", + EnvVars: []string{"PLUGIN_API_KEY", "GITEA_RELEASE_API_KEY", "GITEA_TOKEN"}, + Destination: &settings.APIKey, + Category: category, + Required: true, + }, + &cli.StringSliceFlag{ + Name: "files", + Usage: "list of files to upload", + EnvVars: []string{"PLUGIN_FILES", "GITEA_RELEASE_FILES"}, + Category: category, + }, + &cli.StringFlag{ + Name: "file-exists", + Value: "overwrite", + Usage: "what to do if file already exist", + EnvVars: []string{"PLUGIN_FILE_EXIST", "GITEA_RELEASE_FILE_EXIST"}, + Destination: &settings.FileExists, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "checksum", + Usage: "generate specific checksums", + EnvVars: []string{"PLUGIN_CHECKSUM", "GITEA_RELEASE_CHECKSUM"}, + Destination: &settings.Checksum, + Category: category, + }, + &cli.BoolFlag{ + Name: "draft", + Usage: "create a draft release", + EnvVars: []string{"PLUGIN_DRAFT", "GITEA_RELEASE_DRAFT"}, + Destination: &settings.Draft, + Category: category, + }, + &cli.BoolFlag{ + Name: "prerelease", + Usage: "set the release as prerelease", + EnvVars: []string{"PLUGIN_PRERELEASE", "GITEA_RELEASE_PRERELEASE"}, + Destination: &settings.PreRelease, + Category: category, + }, + &cli.StringFlag{ + Name: "base-url", + Usage: "url of the gitea instance", + EnvVars: []string{"PLUGIN_BASE_URL", "GITEA_RELEASE_BASE_URL"}, + Category: category, + Required: true, + }, + &cli.StringFlag{ + Name: "note", + Usage: "file or string with notes for the release (example: changelog)", + EnvVars: []string{"PLUGIN_NOTE", "GITEA_RELEASE_NOTE"}, + Destination: &settings.Note, + Category: category, + }, + &cli.StringFlag{ + Name: "title", + Usage: "file or string for the title shown in the gitea release", + EnvVars: []string{"PLUGIN_TITLE", "GITEA_RELEASE_TITLE"}, + Destination: &settings.Title, + Category: category, + }, + &cli.StringFlag{ + Name: "repo.owner", + Usage: "repository owner", + EnvVars: []string{"CI_REPO_OWNER"}, + Destination: &settings.Repo.Owner, + Category: category, + }, + &cli.StringFlag{ + Name: "repo.name", + Usage: "repository name", + EnvVars: []string{"CI_REPO_NAME"}, + Destination: &settings.Repo.Name, + Category: category, + }, + &cli.StringFlag{ + Name: "event", + Value: "push", + Usage: "build event", + EnvVars: []string{"CI_PIPELINE_EVENT"}, + Destination: &settings.Event, + Category: category, + }, + &cli.StringFlag{ + Name: "commit-ref", + Value: "refs/heads/main", + Usage: "git commit ref", + EnvVars: []string{"CI_COMMIT_REF"}, + Destination: &settings.CommitRef, + Category: category, + }, + } +} diff --git a/cmd/wp-gitea-release/main.go b/cmd/wp-gitea-release/main.go new file mode 100644 index 0000000..7b12ff6 --- /dev/null +++ b/cmd/wp-gitea-release/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" + + "github.com/thegeeklab/wp-gitea-release/plugin" + + wp "github.com/thegeeklab/wp-plugin-go/plugin" +) + +//nolint:gochecknoglobals +var ( + BuildVersion = "devel" + BuildDate = "00000000" +) + +func main() { + settings := &plugin.Settings{} + options := wp.Options{ + Name: "wp-gitea-release", + Description: "Add comments to GitHub Issues and Pull Requests", + Version: BuildVersion, + VersionMetadata: fmt.Sprintf("date=%s", BuildDate), + Flags: settingsFlags(settings, wp.FlagsPluginCategory), + } + + plugin.New(options, settings).Run() +} diff --git a/cmd/wp-gitea-release/templates/docs-data.yaml.tmpl b/cmd/wp-gitea-release/templates/docs-data.yaml.tmpl new file mode 100644 index 0000000..e453a95 --- /dev/null +++ b/cmd/wp-gitea-release/templates/docs-data.yaml.tmpl @@ -0,0 +1,18 @@ +--- +{{- if .GlobalArgs }} +properties: +{{- range $v := .GlobalArgs }} + - name: {{ $v.Name }} + {{- with $v.Description }} + description: | + {{ . | ToSentence }} + {{- end }} + {{- with $v.Type }} + type: {{ . }} + {{- end }} + {{- with $v.Default }} + defaultValue: {{ . }} + {{- end }} + required: {{ default false $v.Required }} +{{ end -}} +{{ end -}} diff --git a/docker/Dockerfile.linux.amd64 b/docker/Dockerfile.linux.amd64 deleted file mode 100644 index decf980..0000000 --- a/docker/Dockerfile.linux.amd64 +++ /dev/null @@ -1,9 +0,0 @@ -FROM plugins/base:multiarch - -LABEL maintainer="Drone.IO Community " \ - org.label-schema.name="Drone Gitea Release" \ - org.label-schema.vendor="Drone.IO Community" \ - org.label-schema.schema-version="1.0" - -ADD release/linux/amd64/drone-gitea-release /bin/ -ENTRYPOINT ["/bin/drone-gitea-release"] diff --git a/docker/Dockerfile.linux.arm64 b/docker/Dockerfile.linux.arm64 deleted file mode 100644 index 45e8d0c..0000000 --- a/docker/Dockerfile.linux.arm64 +++ /dev/null @@ -1,9 +0,0 @@ -FROM plugins/base:multiarch - -LABEL maintainer="Drone.IO Community " \ - org.label-schema.name="Drone Gitea Release" \ - org.label-schema.vendor="Drone.IO Community" \ - org.label-schema.schema-version="1.0" - -ADD release/linux/arm64/drone-gitea-release /bin/ -ENTRYPOINT [ "/bin/drone-gitea-release" ] diff --git a/docker/Dockerfile.windows.1809 b/docker/Dockerfile.windows.1809 deleted file mode 100644 index 0c5e07a..0000000 --- a/docker/Dockerfile.windows.1809 +++ /dev/null @@ -1,10 +0,0 @@ -# escape=` -FROM plugins/base:windows-1809-amd64@sha256:61095306fa56d51adc841f2b0f93f511efb5792d12f2549bb2eb1cbce02c1f05 - -LABEL maintainer="Drone.IO Community " ` - org.label-schema.name="Drone Gitea Release" ` - org.label-schema.vendor="Drone.IO Community" ` - org.label-schema.schema-version="1.0" - -ADD release/windows/amd64/drone-gitea-release.exe C:/bin/drone-gitea-release.exe -ENTRYPOINT [ "C:\\bin\\drone-gitea-release.exe" ] diff --git a/docker/Dockerfile.windows.ltsc2022 b/docker/Dockerfile.windows.ltsc2022 deleted file mode 100644 index 4ae8cfa..0000000 --- a/docker/Dockerfile.windows.ltsc2022 +++ /dev/null @@ -1,10 +0,0 @@ -# escape=` -FROM plugins/base:windows-ltsc2022-amd64@sha256:0f90d5bceb432f1ee6f93cf44eed6a38c322834edd55df8a6648c9e6f15131f4 - -LABEL maintainer="Drone.IO Community " ` - org.label-schema.name="Drone Gitea Release" ` - org.label-schema.vendor="Drone.IO Community" ` - org.label-schema.schema-version="1.0" - -ADD release/windows/amd64/drone-gitea-release.exe C:/bin/drone-gitea-release.exe -ENTRYPOINT [ "C:\\bin\\drone-gitea-release.exe" ] diff --git a/docker/manifest.tmpl b/docker/manifest.tmpl deleted file mode 100644 index 1e7cb45..0000000 --- a/docker/manifest.tmpl +++ /dev/null @@ -1,31 +0,0 @@ -image: plugins/gitea-release:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}} -{{#if build.tags}} -tags: -{{#each build.tags}} - - {{this}} -{{/each}} -{{/if}} -manifests: - - - image: plugins/gitea-release:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64 - platform: - architecture: amd64 - os: linux - - - image: plugins/gitea-release:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64 - platform: - architecture: arm64 - os: linux - variant: v8 - - - image: plugins/gitea-release:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}windows-1809 - platform: - architecture: amd64 - os: windows - version: 1809 - - - image: plugins/gitea-release:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}ltsc2022-amd64 - platform: - architecture: amd64 - os: windows - version: ltsc2022-amd64 \ No newline at end of file diff --git a/docs/content/_index.md b/docs/content/_index.md new file mode 100644 index 0000000..037f91a --- /dev/null +++ b/docs/content/_index.md @@ -0,0 +1,79 @@ +--- +title: wp-gitea-release +--- + +[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/wp-gitea-release/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/wp-gitea-release) +[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/wp-gitea-release) +[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/wp-gitea-release) +[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/wp-gitea-release)](https://goreportcard.com/report/github.com/thegeeklab/wp-gitea-release) +[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/wp-gitea-release)](https://github.com/thegeeklab/wp-gitea-release/graphs/contributors) +[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/wp-gitea-release) +[![License: Apache-2.0](https://img.shields.io/github/license/thegeeklab/wp-gitea-release)](https://github.com/thegeeklab/wp-gitea-release/blob/main/LICENSE) + +Woodpecker CI plugin to add comments to GitHub Issues and Pull Requests. + + + +{{< toc >}} + + + +## Usage + +{{< hint type=important >}} +Due to the nature of this plugin, a secret for the GitHub token may need to be exposed for pull request events in Woodpecker. Please be careful with this option, as a malicious actor may submit a pull request that exposes your secrets. Do not disclose secrets to pull requests in public environments without further protection. +{{< /hint >}} + +{{< hint type=note >}} +Only pull request events are supported by this plugin. Running the plugin on other events will result in an error. +{{< /hint >}} + +```YAML +kind: pipeline +name: default + +steps: + - name: pr-comment + image: quay.io/thegeeklab/wp-gitea-release + settings: + api_key: ghp_3LbMg9Kncpdkhjp3bh3dMnKNXLjVMTsXk4sM + message: "CI run completed successfully" + update: true +``` + +### Parameters + + + +{{< propertylist name=wp-gitea-release.data sort=name >}} + + + +## Build + +Build the binary with the following command: + +```shell +make build +``` + +Build the container image with the following command: + +```shell +docker build --file Containerfile.multiarch --tag thegeeklab/wp-gitea-release . +``` + +## Test + +```Shell +docker run --rm \ + -e CI_PIPELINE_EVENT=pull_request \ + -e CI_REPO_OWNER=octocat \ + -e CI_REPO_NAME=foo \ + -e CI_COMMIT_PULL_REQUEST=1 + -e PLUGIN_API_KEY=abc123 \ + -e PLUGIN_MESSAGE="Demo comment" \ + -v $(pwd):/build:z \ + -w /build \ + thegeeklab/wp-gitea-release +``` diff --git a/docs/data/data.yaml b/docs/data/data.yaml new file mode 100644 index 0000000..09e47e7 --- /dev/null +++ b/docs/data/data.yaml @@ -0,0 +1,44 @@ +--- +properties: + - name: api_key + description: | + Personal access token to access the GitHub API. + type: string + required: true + + - name: base_url + description: | + Api url. + + Only need to be changed for GitHub enterprise in most cases. + type: string + defaultValue: "https://api.github.com/" + required: false + + - name: key + description: | + Unique identifier to assign to a comment. + + The identifier is used to update an existing comment. + type: string + required: false + + - name: message + description: | + Path to file or string that contains the comment text. + type: string + required: true + + - name: skip_missing + description: | + Skip comment creation if the given message file does not exist. + type: bool + defaultValue: false + required: false + + - name: update + description: | + Enable update of an existing comment that matches the key. + type: bool + defaultValue: false + required: false diff --git a/go.mod b/go.mod index 3931053..734e123 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,35 @@ -module github.com/drone-plugins/drone-gitea-release +module github.com/thegeeklab/wp-gitea-release -go 1.20 +go 1.21 require ( - code.gitea.io/sdk/gitea v0.15.1 - github.com/joho/godotenv v1.4.0 - github.com/sirupsen/logrus v1.9.0 - github.com/urfave/cli v1.22.10 - golang.org/x/crypto v0.4.0 + code.gitea.io/sdk/gitea v0.17.1 + github.com/rs/zerolog v1.31.0 + github.com/thegeeklab/wp-plugin-go v1.5.0 + github.com/urfave/cli/v2 v2.27.1 + golang.org/x/crypto v0.17.0 ) require ( + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/davidmz/go-pageant v1.0.2 // indirect + github.com/go-fed/httpsig v1.1.0 // indirect + github.com/google/uuid v1.1.1 // indirect github.com/hashicorp/go-version v1.6.0 // indirect + github.com/huandu/xstrings v1.3.3 // indirect + github.com/imdario/mergo v0.3.11 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mitchellh/copystructure v1.0.0 // indirect + github.com/mitchellh/reflectwalk v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - golang.org/x/sys v0.3.0 // indirect + github.com/shopspring/decimal v1.2.0 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sys v0.15.0 // indirect ) diff --git a/go.sum b/go.sum index 898a894..21fc7d8 100644 --- a/go.sum +++ b/go.sum @@ -1,55 +1,126 @@ -code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= -code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M= -code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +code.gitea.io/sdk/gitea v0.17.1 h1:3jCPOG2ojbl8AcfaUCRYLT5MUcBMFwS0OSK2mA5Zok8= +code.gitea.io/sdk/gitea v0.17.1/go.mod h1:aCnBqhHpoEWA180gMbaCtdX9Pl6BWBAuuP2miadoTNM= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0= +github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE= +github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= +github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= -github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= -github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/thegeeklab/wp-plugin-go v1.5.0 h1:fA/kQwQrntjxdxePKKGecMRnPbj1xwpy6D2JrrPD2qA= +github.com/thegeeklab/wp-plugin-go v1.5.0/go.mod h1:ULBD5SNC7bkIB/UbLMQpcPWj7iZObCTWg8bqXf1zqsA= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= -golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go deleted file mode 100644 index f505422..0000000 --- a/main.go +++ /dev/null @@ -1,139 +0,0 @@ -package main - -import ( - "os" - - "github.com/joho/godotenv" - "github.com/sirupsen/logrus" - "github.com/urfave/cli" -) - -var ( - version = "unknown" -) - -func main() { - app := cli.NewApp() - app.Name = "gitea-release plugin" - app.Usage = "gitea-release plugin" - app.Action = run - app.Version = version - app.Flags = []cli.Flag{ - cli.StringFlag{ - Name: "api-key", - Usage: "api key to access gitea api", - EnvVar: "PLUGIN_API_KEY,GITEA_RELEASE_API_KEY,GITEA_TOKEN", - }, - cli.StringSliceFlag{ - Name: "files", - Usage: "list of files to upload", - EnvVar: "PLUGIN_FILES,GITEA_RELEASE_FILES", - }, - cli.StringFlag{ - Name: "file-exists", - Value: "overwrite", - Usage: "what to do if file already exist", - EnvVar: "PLUGIN_FILE_EXISTS,GITEA_RELEASE_FILE_EXISTS", - }, - cli.StringSliceFlag{ - Name: "checksum", - Usage: "generate specific checksums", - EnvVar: "PLUGIN_CHECKSUM,GITEA_RELEASE_CHECKSUM", - }, - cli.BoolFlag{ - Name: "draft", - Usage: "create a draft release", - EnvVar: "PLUGIN_DRAFT,GITEA_RELEASE_DRAFT", - }, - cli.BoolFlag{ - Name: "insecure", - Usage: "visit base-url via insecure https protocol", - EnvVar: "PLUGIN_INSECURE,GITEA_RELEASE_INSECURE", - }, - cli.BoolFlag{ - Name: "prerelease", - Usage: "set the release as prerelease", - EnvVar: "PLUGIN_PRERELEASE,GITEA_RELEASE_PRERELEASE", - }, - cli.StringFlag{ - Name: "base-url", - Usage: "url of the gitea instance", - EnvVar: "PLUGIN_BASE_URL,GITEA_RELEASE_BASE_URL", - }, - cli.StringFlag{ - Name: "note", - Value: "", - Usage: "file or string with notes for the release (example: changelog)", - EnvVar: "PLUGIN_NOTE,GITEA_RELEASE_NOTE", - }, - cli.StringFlag{ - Name: "title", - Value: "", - Usage: "file or string for the title shown in the gitea release", - EnvVar: "PLUGIN_TITLE,GITEA_RELEASE_TITLE", - }, - cli.StringFlag{ - Name: "repo.owner", - Usage: "repository owner", - EnvVar: "DRONE_REPO_OWNER", - }, - cli.StringFlag{ - Name: "repo.name", - Usage: "repository name", - EnvVar: "DRONE_REPO_NAME", - }, - cli.StringFlag{ - Name: "build.event", - Value: "push", - Usage: "build event", - EnvVar: "DRONE_BUILD_EVENT", - }, - cli.StringFlag{ - Name: "commit.ref", - Value: "refs/heads/master", - Usage: "git commit ref", - EnvVar: "DRONE_COMMIT_REF", - }, - cli.StringFlag{ - Name: "env-file", - Usage: "source env file", - }, - } - - if err := app.Run(os.Args); err != nil { - logrus.Fatal(err) - } -} - -func run(c *cli.Context) error { - if c.String("env-file") != "" { - _ = godotenv.Load(c.String("env-file")) - } - - plugin := Plugin{ - Repo: Repo{ - Owner: c.String("repo.owner"), - Name: c.String("repo.name"), - }, - Build: Build{ - Event: c.String("build.event"), - }, - Commit: Commit{ - Ref: c.String("commit.ref"), - }, - Config: Config{ - APIKey: c.String("api-key"), - Files: c.StringSlice("files"), - FileExists: c.String("file-exists"), - Checksum: c.StringSlice("checksum"), - Draft: c.Bool("draft"), - PreRelease: c.Bool("prerelease"), - BaseURL: c.String("base-url"), - Insecure: c.Bool("insecure"), - Title: c.String("title"), - Note: c.String("note"), - }, - } - - return plugin.Exec() -} diff --git a/plugin.go b/plugin.go deleted file mode 100644 index 2a31c33..0000000 --- a/plugin.go +++ /dev/null @@ -1,171 +0,0 @@ -package main - -import ( - "crypto/tls" - "fmt" - "net/http" - "net/http/cookiejar" - "os" - "path/filepath" - "strings" - - "code.gitea.io/sdk/gitea" -) - -type ( - Repo struct { - Owner string - Name string - } - - Build struct { - Event string - } - - Commit struct { - Ref string - } - - Config struct { - APIKey string - Files []string - FileExists string - Checksum []string - Draft bool - PreRelease bool - Insecure bool - BaseURL string - Title string - Note string - } - - Plugin struct { - Repo Repo - Build Build - Commit Commit - Config Config - } -) - -func (p Plugin) Exec() error { - var ( - files []string - ) - - if p.Build.Event != "tag" { - return fmt.Errorf("The Gitea Release plugin is only available for tags") - } - - if p.Config.APIKey == "" { - return fmt.Errorf("You must provide an API key") - } - - if !fileExistsValues[p.Config.FileExists] { - return fmt.Errorf("Invalid value for file_exists") - } - - if p.Config.BaseURL == "" { - return fmt.Errorf("You must provide a base url.") - } - - if !strings.HasSuffix(p.Config.BaseURL, "/") { - p.Config.BaseURL = p.Config.BaseURL + "/" - } - - var err error - if p.Config.Note != "" { - if p.Config.Note, err = readStringOrFile(p.Config.Note); err != nil { - return fmt.Errorf("error while reading %s: %v", p.Config.Note, err) - } - } - - if p.Config.Title != "" { - if p.Config.Title, err = readStringOrFile(p.Config.Title); err != nil { - return fmt.Errorf("error while reading %s: %v", p.Config.Note, err) - } - } - - for _, glob := range p.Config.Files { - globed, err := filepath.Glob(glob) - - if err != nil { - return fmt.Errorf("Failed to glob %s. %s", glob, err) - } - - if globed != nil { - files = append(files, globed...) - } - } - - if len(p.Config.Checksum) > 0 { - var ( - err error - ) - - files, err = writeChecksums(files, p.Config.Checksum) - - if err != nil { - return fmt.Errorf("Failed to write checksums. %s", err) - } - } - - httpClient := &http.Client{} - if p.Config.Insecure { - cookieJar, _ := cookiejar.New(nil) - httpClient = &http.Client{ - Jar: cookieJar, - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - }, - } - } - client, err := gitea.NewClient(p.Config.BaseURL, gitea.SetToken(p.Config.APIKey), gitea.SetHTTPClient(httpClient)) - if err != nil { - return err - } - - rc := releaseClient{ - Client: client, - Owner: p.Repo.Owner, - Repo: p.Repo.Name, - Tag: strings.TrimPrefix(p.Commit.Ref, "refs/tags/"), - Draft: p.Config.Draft, - Prerelease: p.Config.PreRelease, - FileExists: p.Config.FileExists, - Title: p.Config.Title, - Note: p.Config.Note, - } - - // if the title was not provided via .drone.yml we use the tag instead - // fixes https://github.com/drone-plugins/drone-gitea-release/issues/26 - if rc.Title == "" { - rc.Title = rc.Tag - } - - release, err := rc.buildRelease() - - if err != nil { - return fmt.Errorf("Failed to create the release. %s", err) - } - - if err := rc.uploadFiles(release.ID, files); err != nil { - return fmt.Errorf("Failed to upload the files. %s", err) - } - - return nil -} - -func readStringOrFile(input string) (string, error) { - // Check if input is a file path - if _, err := os.Stat(input); err != nil && os.IsNotExist(err) { - // No file found => use input as result - return input, nil - } else if err != nil { - return "", err - } - result, err := os.ReadFile(input) - if err != nil { - return "", err - } - return string(result), nil -} diff --git a/plugin/impl.go b/plugin/impl.go new file mode 100644 index 0000000..fc3bb76 --- /dev/null +++ b/plugin/impl.go @@ -0,0 +1,154 @@ +package plugin + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "path/filepath" + "strings" + + "code.gitea.io/sdk/gitea" +) + +var ( + ErrPluginEventNotSupported = errors.New("event not supported") + ErrFileExistInvalid = errors.New("invalid file_exist value") +) + +//nolint:revive +func (p *Plugin) run(ctx context.Context) error { + if err := p.FlagsFromContext(); err != nil { + return fmt.Errorf("validation failed: %w", err) + } + + if err := p.Validate(); err != nil { + return fmt.Errorf("validation failed: %w", err) + } + + if err := p.Execute(); err != nil { + return fmt.Errorf("execution failed: %w", err) + } + + return nil +} + +// Validate handles the settings validation of the plugin. +func (p *Plugin) Validate() error { + var err error + + fileExistsValues := map[string]bool{ + "overwrite": true, + "fail": true, + "skip": true, + } + + if p.Settings.Event != "tag" { + return fmt.Errorf("%w: %s", ErrPluginEventNotSupported, p.Metadata.Pipeline.Event) + } + + if !fileExistsValues[p.Settings.FileExists] { + return ErrFileExistInvalid + } + + if p.Settings.Note != "" { + if p.Settings.Note, _, err = readStringOrFile(p.Settings.Note); err != nil { + return fmt.Errorf("error while reading %s: %w", p.Settings.Note, err) + } + } + + if p.Settings.Title != "" { + if p.Settings.Title, _, err = readStringOrFile(p.Settings.Title); err != nil { + return fmt.Errorf("error while reading %s: %w", p.Settings.Title, err) + } + } + + return nil +} + +// Execute provides the implementation of the plugin. +func (p *Plugin) Execute() error { + httpClient := &http.Client{} + + client, err := gitea.NewClient( + p.Settings.baseURL.String(), + gitea.SetToken(p.Settings.APIKey), + gitea.SetHTTPClient(httpClient), + ) + if err != nil { + return err + } + + rc := releaseClient{ + Client: client, + Owner: p.Settings.Repo.Owner, + Repo: p.Settings.Repo.Name, + Tag: strings.TrimPrefix(p.Settings.CommitRef, "refs/tags/"), + Draft: p.Settings.Draft, + Prerelease: p.Settings.PreRelease, + FileExists: p.Settings.FileExists, + Title: p.Settings.Title, + Note: p.Settings.Note, + } + + // if the title was not provided via .drone.yml we use the tag instead + // fixes https://github.com/drone-plugins/drone-gitea-release/issues/26 + if rc.Title == "" { + rc.Title = rc.Tag + } + + release, err := rc.buildRelease() + if err != nil { + return fmt.Errorf("failed to create the release: %w", err) + } + + if err := rc.uploadFiles(release.ID, p.Settings.files); err != nil { + return fmt.Errorf("failed to upload the files: %w", err) + } + + return nil +} + +func (p *Plugin) FlagsFromContext() error { + var err error + + baseURL := p.Context.String("base-url") + + if !strings.HasSuffix(baseURL, "/") { + baseURL += "/" + } + + p.Settings.baseURL, err = url.Parse(baseURL) + if err != nil { + return fmt.Errorf("failed to parse base url: %w", err) + } + + var files []string + + rawFiles := p.Context.StringSlice("files") + for _, glob := range rawFiles { + globed, err := filepath.Glob(glob) + if err != nil { + return fmt.Errorf("failed to glob %s: %w", glob, err) + } + + if globed != nil { + files = append(files, globed...) + } + } + + if len(p.Settings.Checksum.Value()) > 0 { + var err error + + files, err = writeChecksums(files, p.Settings.Checksum.Value()) + + if err != nil { + return fmt.Errorf("failed to write checksums: %w", err) + } + } + + p.Settings.files = files + + return nil +} diff --git a/plugin/plugin.go b/plugin/plugin.go new file mode 100644 index 0000000..b8da69a --- /dev/null +++ b/plugin/plugin.go @@ -0,0 +1,48 @@ +package plugin + +import ( + "net/url" + + wp "github.com/thegeeklab/wp-plugin-go/plugin" + "github.com/urfave/cli/v2" +) + +// Plugin implements provide the plugin. +type Plugin struct { + *wp.Plugin + Settings *Settings +} + +// Settings for the Plugin. +type Settings struct { + APIKey string + FileExists string + Checksum cli.StringSlice + Draft bool + PreRelease bool + Title string + Note string + CommitRef string + Event string + + baseURL *url.URL + files []string + + Repo Repo +} + +type Repo struct { + Owner string + Name string +} + +func New(options wp.Options, settings *Settings) *Plugin { + p := &Plugin{} + + options.Execute = p.run + + p.Plugin = wp.New(options) + p.Settings = settings + + return p +} diff --git a/release.go b/plugin/release.go similarity index 65% rename from release.go rename to plugin/release.go index e80d84b..28f355c 100644 --- a/release.go +++ b/plugin/release.go @@ -1,11 +1,18 @@ -package main +package plugin import ( + "errors" "fmt" "os" "path" "code.gitea.io/sdk/gitea" + "github.com/rs/zerolog/log" +) + +var ( + ErrReleaseNotFound = errors.New("release not found") + ErrFileExists = errors.New("asset file already exist") ) // Release holds ties the drone env data and gitea client together. @@ -35,7 +42,7 @@ func (rc *releaseClient) buildRelease() (*gitea.Release, error) { release, err = rc.newRelease() if err != nil { - return nil, fmt.Errorf("Failed to retrieve or create a release: %s", err) + return nil, fmt.Errorf("failed to retrieve or create a release: %w", err) } return release, nil @@ -49,11 +56,13 @@ func (rc *releaseClient) getRelease() (*gitea.Release, error) { for _, release := range releases { if release.TagName == rc.Tag { - fmt.Printf("Successfully retrieved %s release\n", rc.Tag) + log.Info().Msgf("successfully retrieved %s release", rc.Tag) + return release, nil } } - return nil, fmt.Errorf("Release %s not found", rc.Tag) + + return nil, fmt.Errorf("%w: %s", ErrReleaseNotFound, rc.Tag) } func (rc *releaseClient) newRelease() (*gitea.Release, error) { @@ -67,18 +76,23 @@ func (rc *releaseClient) newRelease() (*gitea.Release, error) { release, _, err := rc.Client.CreateRelease(rc.Owner, rc.Repo, r) if err != nil { - return nil, fmt.Errorf("Failed to create release: %s", err) + return nil, fmt.Errorf("failed to create release: %w", err) } - fmt.Printf("Successfully created %s release\n", rc.Tag) + log.Info().Msgf("successfully created %s release", rc.Tag) + return release, nil } func (rc *releaseClient) uploadFiles(releaseID int64, files []string) error { - attachments, _, err := rc.Client.ListReleaseAttachments(rc.Owner, rc.Repo, releaseID, gitea.ListReleaseAttachmentsOptions{}) - + attachments, _, err := rc.Client.ListReleaseAttachments( + rc.Owner, + rc.Repo, + releaseID, + gitea.ListReleaseAttachmentsOptions{}, + ) if err != nil { - return fmt.Errorf("Failed to fetch existing assets: %s", err) + return fmt.Errorf("failed to fetch existing assets: %w", err) } var uploadFiles []string @@ -91,12 +105,11 @@ files: case "overwrite": // do nothing case "fail": - return fmt.Errorf("Asset file %s already exists", path.Base(file)) + return fmt.Errorf("%w: %s", ErrFileExists, path.Base(file)) case "skip": - fmt.Printf("Skipping pre-existing %s artifact\n", attachment.Name) + log.Warn().Msgf("skipping pre-existing %s artifact", attachment.Name) + continue files - default: - return fmt.Errorf("Internal error, unkown file_exist value %s", rc.FileExists) } } } @@ -106,26 +119,25 @@ files: for _, file := range uploadFiles { handle, err := os.Open(file) - if err != nil { - return fmt.Errorf("Failed to read %s artifact: %s", file, err) + return fmt.Errorf("failed to read %s artifact: %w", file, err) } for _, attachment := range attachments { if attachment.Name == path.Base(file) { if _, err := rc.Client.DeleteReleaseAttachment(rc.Owner, rc.Repo, releaseID, attachment.ID); err != nil { - return fmt.Errorf("Failed to delete %s artifact: %s", file, err) + return fmt.Errorf("failed to delete %s artifact: %w", file, err) } - fmt.Printf("Successfully deleted old %s artifact\n", attachment.Name) + log.Info().Msgf("successfully deleted old %s artifact", attachment.Name) } } if _, _, err = rc.Client.CreateReleaseAttachment(rc.Owner, rc.Repo, releaseID, handle, path.Base(file)); err != nil { - return fmt.Errorf("Failed to upload %s artifact: %s", file, err) + return fmt.Errorf("failed to upload %s artifact: %w", file, err) } - fmt.Printf("Successfully uploaded %s artifact\n", file) + log.Info().Msgf("successfully uploaded %s artifact", file) } return nil diff --git a/utils.go b/plugin/utils.go similarity index 65% rename from utils.go rename to plugin/utils.go index a406aa3..6dd1793 100644 --- a/utils.go +++ b/plugin/utils.go @@ -1,10 +1,11 @@ -package main +package plugin import ( - "crypto/md5" - "crypto/sha1" + "crypto/md5" //nolint:gosec + "crypto/sha1" //nolint:gosec "crypto/sha256" "crypto/sha512" + "errors" "fmt" "hash/adler32" "hash/crc32" @@ -16,25 +17,43 @@ import ( "golang.org/x/crypto/blake2s" ) -var ( - fileExistsValues = map[string]bool{ - "overwrite": true, - "fail": true, - "skip": true, +var ErrHashMethodNotSupported = errors.New("hash method not supported") + +//nolint:unparam +func readStringOrFile(input string) (string, bool, error) { + //nolint:gomnd + if len(input) > 255 { + return input, false, nil } -) + + // Check if input is a file path + if _, err := os.Stat(input); err != nil && os.IsNotExist(err) { + // No file found => use input as result + return input, false, nil + } else if err != nil { + return "", false, err + } + + result, err := os.ReadFile(input) + if err != nil { + return "", true, err + } + + return string(result), true, nil +} func checksum(r io.Reader, method string) (string, error) { b, err := io.ReadAll(r) - if err != nil { return "", err } switch method { case "md5": + //nolint:gosec return fmt.Sprintf("%x", md5.Sum(b)), nil case "sha1": + //nolint:gosec return fmt.Sprintf("%x", sha1.Sum(b)), nil case "sha256": return fmt.Sprintf("%x", sha256.Sum256(b)), nil @@ -50,7 +69,7 @@ func checksum(r io.Reader, method string) (string, error) { return fmt.Sprintf("%x", blake2s.Sum256(b)), nil } - return "", fmt.Errorf("Hashing method %s is not supported", method) + return "", fmt.Errorf("%w: %q", ErrHashMethodNotSupported, method) } func writeChecksums(files, methods []string) ([]string, error) { @@ -59,15 +78,13 @@ func writeChecksums(files, methods []string) ([]string, error) { for _, method := range methods { for _, file := range files { handle, err := os.Open(file) - if err != nil { - return nil, fmt.Errorf("Failed to read %s artifact: %s", file, err) + return nil, fmt.Errorf("failed to read %q artifact: %w", file, err) } hash, err := checksum(handle, method) - if err != nil { - return nil, err + return nil, fmt.Errorf("could not checksum %q file: %w", file, err) } checksums[method] = append(checksums[method], hash, file) @@ -76,8 +93,8 @@ func writeChecksums(files, methods []string) ([]string, error) { for method, results := range checksums { filename := method + "sum.txt" - f, err := os.Create(filename) + f, err := os.Create(filename) if err != nil { return nil, err } diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..45d1c03 --- /dev/null +++ b/renovate.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["github>thegeeklab/renovate-presets:golang"] +}