From fccdc615453e2581b839aeddabce8719b3787fd6 Mon Sep 17 00:00:00 2001 From: Izrafil Archimedes Date: Mon, 23 Feb 2026 09:20:56 +0100 Subject: [PATCH] init --- .github/workflows/ci.yml | 86 ++++++++ .gitignore | 8 + .golangci.yaml | 45 +++++ .goreleaser.yaml | 30 +++ LICENSE | 21 ++ Makefile | 12 ++ README.md | 41 ++++ cmd/provider-zexlab/main.go | 15 ++ go.mod | 50 +++++ go.sum | 133 +++++++++++++ pkg/provider/data/GetCommits.json | 302 +++++++++++++++++++++++++++++ pkg/provider/data/GetRefs.json | 56 ++++++ pkg/provider/data/GetRepoInfo.json | 92 +++++++++ pkg/provider/data/Version.json | 3 + pkg/provider/test_server.go | 104 ++++++++++ pkg/provider/utils.go | 107 ++++++++++ pkg/provider/zexlab.go | 234 ++++++++++++++++++++++ pkg/provider/zexlab_test.go | 256 ++++++++++++++++++++++++ 18 files changed, 1595 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .golangci.yaml create mode 100644 .goreleaser.yaml create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 cmd/provider-zexlab/main.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 pkg/provider/data/GetCommits.json create mode 100644 pkg/provider/data/GetRefs.json create mode 100644 pkg/provider/data/GetRepoInfo.json create mode 100644 pkg/provider/data/Version.json create mode 100644 pkg/provider/test_server.go create mode 100644 pkg/provider/utils.go create mode 100644 pkg/provider/zexlab.go create mode 100644 pkg/provider/zexlab_test.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6c70233 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,86 @@ +name: CI + +on: + push: + branches: + - "**" + pull_request: + branches: + - "**" + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.24" + + - name: Install golangci-lint + run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest + + - name: Run lint + run: make lint + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.24" + + - name: Install gotestfmt + run: go install github.com/gotesttools/gotestfmt/v2/cmd/gotestfmt@latest + + - name: Run tests + run: | + set -euo pipefail + go test -json -race -covermode=atomic -coverprofile=coverage.out ./pkg/... 2>&1 | tee /tmp/gotest.log | gotestfmt + + build: + runs-on: ubuntu-latest + needs: + - lint + - test + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.24" + + - name: Build + run: make build + + release: + runs-on: ubuntu-latest + needs: build + if: github.event_name != 'pull_request' + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-go@v5 + with: + go-version: "1.24" + + - name: Build and install provider-zexlab plugin + run: | + go build -o provider-zexlab ./cmd/provider-zexlab/ + PLUGIN_DIR=".semrel/$(go env GOOS)_$(go env GOARCH)/provider-zexlab/0.0.0-dev" + mkdir -p "$PLUGIN_DIR" + mv provider-zexlab "$PLUGIN_DIR/provider-zexlab" + chmod +x "$PLUGIN_DIR/provider-zexlab" + + - uses: go-semantic-release/action@v1 + with: + github-token: ${{ secrets.ZX_TOKEN }} + hooks: goreleaser + custom-arguments: "--provider zexlab" + env: + GITEA_TOKEN: ${{ secrets.ZX_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6e79c47 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.idea/ + +# No Coverage output +**/coverage.out + +# Build artifacts +./provider-zexlab +build diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..6171ad1 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,45 @@ +version: "2" +linters: + enable: + - errorlint + - forbidigo + - gochecknoinits + - goconst + - gocritic + - gocyclo + - misspell + - revive + - unconvert + - unparam + - wastedassign + settings: + gocyclo: + min-complexity: 12 + govet: + disable: + - fieldalignment + enable-all: true + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gofumpt + - goimports + settings: + gofumpt: + extra-rules: true + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..c284a2d --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,30 @@ +gitea_urls: + api: https://zexlab.dev/api/v1 + download: https://zexlab.dev + +builds: + - env: + - CGO_ENABLED=0 + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + - linux_arm + - windows_amd64 + main: ./cmd/provider-zexlab + ldflags: + - -extldflags '-static' + - -s -w -X zexlab.dev/zexlab/go-semrel-provider/pkg/provider.PVERSION={{.Version}} + +release: + gitea: + owner: zexlab + name: go-semrel-provider + +archives: + - format: binary + name_template: "{{ .Binary }}_v{{ .Version }}_{{ .Os }}_{{ .Arch }}" + +checksum: + name_template: "{{ .ProjectName }}_v{{ .Version }}_checksums.txt" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..413d69e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Zexlab + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f01c1c3 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +all: build + +.PHONY: build + +build: + go build -o build/provider-zexlab ./cmd/provider-zexlab/ + +lint: + golangci-lint run --fix ./cmd/... ./pkg/... + +test: + go test --coverprofile coverage.out -json -v -parallel 20 ./pkg/... 2>&1 | tee /tmp/gotest.log | gotestfmt diff --git a/README.md b/README.md new file mode 100644 index 0000000..ab39de0 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# provider-zexlab + +Zexlab provider for [go-semantic-release](https://github.com/go-semantic-release/semantic-release). + +This plugin is based on [provider-gitea](https://github.com/go-semantic-release/provider-gitea) and is tailored specifically for the Zexlab Gitea instance. + +## Provider Options + +The provider options can be configured via the `--provider-opt` CLI flag. + +| Name | Description | Example | +|---|---|---| +| server_url | Gitea server url (default: `https://zexlab.dev`) | `--provider-opt server_url=https://gitea.example.com` | +| slug | The owner and repository name | `--provider-opt slug=owner/my-repo` | +| token | Personal Access Token | `--provider-opt token=xxx` | +| strip_v_tag_prefix | Strip "v" from release tag prefix (default: false) | `--provider-opt strip_v_tag_prefix=true` | + +## Usage + +``` +semantic-release \ + --provider provider-zexlab \ + --provider-opt slug=owner/my-repo \ + --provider-opt token=your-token +``` + +## Building + +``` +make build +``` + +## Testing + +``` +make test +``` + +## Licence + +The [MIT License (MIT)](http://opensource.org/licenses/MIT) diff --git a/cmd/provider-zexlab/main.go b/cmd/provider-zexlab/main.go new file mode 100644 index 0000000..0242c18 --- /dev/null +++ b/cmd/provider-zexlab/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "github.com/go-semantic-release/semantic-release/v2/pkg/plugin" + "github.com/go-semantic-release/semantic-release/v2/pkg/provider" + zexlabProvider "zexlab.dev/zexlab/go-semrel-provider/pkg/provider" +) + +func main() { + plugin.Serve(&plugin.ServeOpts{ + Provider: func() provider.Provider { + return &zexlabProvider.ZexlabRepository{} + }, + }) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d0cbdf1 --- /dev/null +++ b/go.mod @@ -0,0 +1,50 @@ +module zexlab.dev/zexlab/go-semrel-provider + +go 1.24 + +require ( + code.gitea.io/sdk/gitea v0.23.2 + github.com/Masterminds/semver/v3 v3.4.0 + github.com/go-semantic-release/semantic-release/v2 v2.31.0 + github.com/stretchr/testify v1.11.1 +) + +require ( + github.com/42wim/httpsig v1.2.3 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/davidmz/go-pageant v1.0.2 // indirect + github.com/fatih/color v1.17.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-fed/httpsig v1.1.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect + github.com/hashicorp/go-plugin v1.6.1 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/yamux v0.1.2 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/oklog/run v1.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect + github.com/sagikazarmark/locafero v0.12.0 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/spf13/viper v1.21.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.39.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.28.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.36.6 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..617911d --- /dev/null +++ b/go.sum @@ -0,0 +1,133 @@ +code.gitea.io/sdk/gitea v0.23.2 h1:iJB1FDmLegwfwjX8gotBDHdPSbk/ZR8V9VmEJaVsJYg= +code.gitea.io/sdk/gitea v0.23.2/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= +github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs= +github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +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/go-semantic-release/semantic-release/v2 v2.31.0 h1:1F8znmF6T3lkUldLv8WeYaMc8OV4mUuEAVB5IkXJiEQ= +github.com/go-semantic-release/semantic-release/v2 v2.31.0/go.mod h1:9+jcq+VWLtnUiFT7uED/aQWSAUTsVaiYyVcha4C2Eo4= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +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/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= +github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= +github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= +github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +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.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= +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-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= +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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +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/pkg/provider/data/GetCommits.json b/pkg/provider/data/GetCommits.json new file mode 100644 index 0000000..4681b4c --- /dev/null +++ b/pkg/provider/data/GetCommits.json @@ -0,0 +1,302 @@ +[ + { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef", + "sha": "deadbeef", + "created": "2024-04-23T13:20:33+12:00", + "html_url": "https://gitea.zexlab.dev/owner/test-repo/commit/deadbeef", + "commit": { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef", + "author": { + "name": "A User", + "email": "owner@noreply.zexlab.dev", + "date": "2024-04-23T13:20:33+12:00" + }, + "committer": { + "name": "A User", + "email": "owner@noreply.zexlab.dev", + "date": "2024-04-23T13:20:33+12:00" + }, + "message": "fix: Removed lint as not go project\n", + "tree": { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/trees/deadbeef", + "sha": "deadbeef", + "created": "2024-04-23T13:20:33+12:00" + }, + "verification": { + "verified": false, + "reason": "gpg.error.not_signed_commit", + "signature": "", + "signer": null, + "payload": "" + } + }, + "author": { + "id": 1, + "login": "owner", + "login_name": "", + "source_id": 0, + "full_name": "A User", + "email": "owner@noreply.zexlab.dev", + "avatar_url": "https://secure.gravatar.com/avatar/ahash?d=identicon", + "html_url": "https://gitea.zexlab.dev/owner", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2021-05-05T11:08:04+12:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "owner" + }, + "committer": { + "id": 1, + "login": "owner", + "login_name": "", + "source_id": 0, + "full_name": "A User", + "email": "owner@noreply.zexlab.dev", + "avatar_url": "https://secure.gravatar.com/avatar/ahash?d=identicon", + "html_url": "https://gitea.zexlab.dev/owner", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2021-05-05T11:08:04+12:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "owner" + }, + "parents": [ + { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef", + "sha": "deadbeef", + "created": "0001-01-01T00:00:00Z" + } + ], + "files": [ + { + "filename": ".gitea/workflows/.ci.yml", + "status": "modified" + } + ], + "stats": { + "total": 16, + "additions": 8, + "deletions": 8 + } + }, + { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef", + "sha": "deadbeef", + "created": "2024-04-23T13:17:11+12:00", + "html_url": "https://gitea.zexlab.dev/owner/test-repo/commit/deadbeef", + "commit": { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef", + "author": { + "name": "A User", + "email": "owner@noreply.zexlab.dev", + "date": "2024-04-23T13:17:11+12:00" + }, + "committer": { + "name": "A User", + "email": "owner@noreply.zexlab.dev", + "date": "2024-04-23T13:17:11+12:00" + }, + "message": "fix: Oops, need a tidyup\n", + "tree": { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/trees/deadbeef", + "sha": "deadbeef", + "created": "2024-04-23T13:17:11+12:00" + }, + "verification": { + "verified": false, + "reason": "gpg.error.not_signed_commit", + "signature": "", + "signer": null, + "payload": "" + } + }, + "author": { + "id": 1, + "login": "owner", + "login_name": "", + "source_id": 0, + "full_name": "A User", + "email": "owner@noreply.zexlab.dev", + "avatar_url": "https://secure.gravatar.com/avatar/ahash?d=identicon", + "html_url": "https://gitea.zexlab.dev/owner", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2021-05-05T11:08:04+12:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "owner" + }, + "committer": { + "id": 1, + "login": "owner", + "login_name": "", + "source_id": 0, + "full_name": "A User", + "email": "owner@noreply.zexlab.dev", + "avatar_url": "https://secure.gravatar.com/avatar/ahash?d=identicon", + "html_url": "https://gitea.zexlab.dev/owner", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2021-05-05T11:08:04+12:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "owner" + }, + "parents": [ + { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef", + "sha": "deadbeef", + "created": "0001-01-01T00:00:00Z" + } + ], + "files": [ + { + "filename": ".gitea/workflows/ci.yaml", + "status": "removed" + } + ], + "stats": { + "total": 62, + "additions": 0, + "deletions": 62 + } + }, + { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef", + "sha": "deadbeef", + "created": "2024-04-23T13:15:00+12:00", + "html_url": "https://gitea.zexlab.dev/owner/test-repo/commit/deadbeef", + "commit": { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef", + "author": { + "name": "A User", + "email": "owner@noreply.zexlab.dev", + "date": "2024-04-23T13:15:00+12:00" + }, + "committer": { + "name": "A User", + "email": "owner@noreply.zexlab.dev", + "date": "2024-04-23T13:15:00+12:00" + }, + "message": "fix: Update CI\n", + "tree": { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/trees/deadbeef", + "sha": "deadbeef", + "created": "2024-04-23T13:15:00+12:00" + }, + "verification": { + "verified": false, + "reason": "gpg.error.not_signed_commit", + "signature": "", + "signer": null, + "payload": "" + } + }, + "author": { + "id": 1, + "login": "owner", + "login_name": "", + "source_id": 0, + "full_name": "A User", + "email": "owner@noreply.zexlab.dev", + "avatar_url": "https://secure.gravatar.com/avatar/ahash?d=identicon", + "html_url": "https://gitea.zexlab.dev/owner", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2021-05-05T11:08:04+12:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "owner" + }, + "committer": { + "id": 1, + "login": "owner", + "login_name": "", + "source_id": 0, + "full_name": "A User", + "email": "owner@noreply.zexlab.dev", + "avatar_url": "https://secure.gravatar.com/avatar/ahash?d=identicon", + "html_url": "https://gitea.zexlab.dev/owner", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2021-05-05T11:08:04+12:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "owner" + }, + "parents": [ + { + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef", + "sha": "deadbeef", + "created": "0001-01-01T00:00:00Z" + } + ], + "files": [ + { + "filename": ".gitea/workflows/.ci.yml", + "status": "added" + } + ], + "stats": { + "total": 36, + "additions": 36, + "deletions": 0 + } + } +] diff --git a/pkg/provider/data/GetRefs.json b/pkg/provider/data/GetRefs.json new file mode 100644 index 0000000..7d2eb4f --- /dev/null +++ b/pkg/provider/data/GetRefs.json @@ -0,0 +1,56 @@ +[ + { + "ref": "refs/tags/v2.0.0", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/refs/tags/v2.0.0", + "object": { + "type": "commit", + "sha": "deadbeef", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef" + } + }, + { + "ref": "refs/tags/4.0.0-beta", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/refs/tags/4.0.0-beta", + "object": { + "type": "commit", + "sha": "deadbeef", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef" + } + }, + { + "ref": "refs/tags/3.0.0-beta.2", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/refs/tags/3.0.0-beta.2", + "object": { + "type": "commit", + "sha": "deadbeef", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef" + } + }, + { + "ref": "refs/tags/2.1.0-beta", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/refs/tags/2.1.0-beta", + "object": { + "type": "commit", + "sha": "deadbeef", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef" + } + }, + { + "ref": "refs/tags/2.0.0", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/refs/tags/2.0.0", + "object": { + "type": "commit", + "sha": "deadbeef", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef" + } + }, + { + "ref": "refs/tags/2020.4.19", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/refs/tags/2020.4.19", + "object": { + "type": "commit", + "sha": "deadbeef", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/git/commits/deadbeef" + } + } +] diff --git a/pkg/provider/data/GetRepoInfo.json b/pkg/provider/data/GetRepoInfo.json new file mode 100644 index 0000000..c85ed7b --- /dev/null +++ b/pkg/provider/data/GetRepoInfo.json @@ -0,0 +1,92 @@ +{ + "id": 79, + "owner": { + "id": 5, + "login": "owner", + "login_name": "", + "source_id": 0, + "full_name": "some user name", + "email": "hey@zexlab.dev", + "avatar_url": "https://gitea.zexlab.dev/avatars/somehash", + "html_url": "https://gitea.zexlab.dev/owner", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2023-02-17T11:23:47+13:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "owner" + }, + "name": "test-repo", + "full_name": "owner/test-repo", + "description": "", + "empty": false, + "private": true, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 115, + "language": "Go", + "languages_url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo/languages", + "html_url": "https://gitea.zexlab.dev/owner/test-repo", + "url": "https://gitea.zexlab.dev/api/v1/repos/owner/test-repo", + "link": "", + "ssh_url": "git@gitea.zexlab.dev:owner/test-repo.git", + "clone_url": "https://gitea.zexlab.dev/owner/test-repo.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 4, + "default_branch": "master", + "archived": false, + "created_at": "2024-07-20T23:06:00+12:00", + "updated_at": "2024-07-23T15:39:08+12:00", + "archived_at": "1970-01-01T12:00:00+12:00", + "permissions": { + "admin": false, + "push": false, + "pull": true + }, + "has_issues": true, + "internal_tracker": { + "enable_time_tracker": true, + "allow_only_contributors_to_track_time": true, + "enable_issue_dependencies": true + }, + "has_wiki": true, + "has_pull_requests": true, + "has_projects": true, + "projects_mode": "all", + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "merge", + "default_allow_maintainer_edit": false, + "avatar_url": "https://gitea.zexlab.dev/", + "internal": false, + "mirror_interval": "", + "object_format_name": "sha1", + "mirror_updated": "0001-01-01T00:00:00Z", + "repo_transfer": null +} diff --git a/pkg/provider/data/Version.json b/pkg/provider/data/Version.json new file mode 100644 index 0000000..ef5ca67 --- /dev/null +++ b/pkg/provider/data/Version.json @@ -0,0 +1,3 @@ +{ + "version": "1.21.1" +} diff --git a/pkg/provider/test_server.go b/pkg/provider/test_server.go new file mode 100644 index 0000000..2346b50 --- /dev/null +++ b/pkg/provider/test_server.go @@ -0,0 +1,104 @@ +//coverage:ignore +package provider + +import ( + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + + "code.gitea.io/sdk/gitea" +) + +var validTags = map[string]bool{ + "v5.0.0": true, + "5.0.0": true, +} + +var ( + server *httptest.Server + zexlabUser = "owner" + zexlabRepo = "test-repo" + zexlabDefaultBranch = "master" + zexlabCommits = []*gitea.Commit{ + createGiteaCommit(testSHA, "fix: Removed lint as not go project\n", "2024-04-23T13:20:33+12:00"), + createGiteaCommit(testSHA, "fix: Oops, need a tidyup\n", "2024-04-23T13:17:11+12:00"), + createGiteaCommit(testSHA, "fix: Update CI\n", "2024-04-23T13:15:00+12:00"), + } + testSHA = "deadbeef" +) + +func CreateTestServer() *httptest.Server { + ts := httptest.NewServer(http.HandlerFunc(ZexlabHandler)) + + return ts +} + +//gocyclo:ignore +func ZexlabHandler(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodGet && r.URL.Path == "/api/v1/version" { + // Client performs a request to check version + // Get json string from file + data, _ := retrieveData("data/Version.json") + _, _ = fmt.Fprint(w, string(data)) + return + } + + if r.Method == http.MethodGet && r.URL.Path == fmt.Sprintf("/api/v1/repos/%s/%s", zexlabUser, zexlabRepo) { + // Get json string from file + data, _ := retrieveData("data/GetRepoInfo.json") + _, _ = fmt.Fprint(w, string(data)) + return + } + + if r.Method == http.MethodGet && r.URL.Path == fmt.Sprintf("/api/v1/repos/%s/%s/commits", zexlabUser, zexlabRepo) { + // Get json string from file + data, _ := retrieveData("data/GetCommits.json") + _, _ = fmt.Fprint(w, string(data)) + return + } + + if r.Method == http.MethodGet && r.URL.Path == fmt.Sprintf("/api/v1/repos/%s/%s/git/refs/", zexlabUser, zexlabRepo) { + // Get json string from file + data, _ := retrieveData("data/GetRefs.json") + _, _ = fmt.Fprint(w, string(data)) + return + } + + if r.Method == http.MethodPost && r.URL.Path == fmt.Sprintf("/api/v1/repos/%s/%s/releases", + zexlabUser, + zexlabRepo) { + var data map[string]string + _ = json.NewDecoder(r.Body).Decode(&data) + _ = r.Body.Close() + + if _, ok := validTags[data["tag_name"]]; !ok { + http.Error(w, "invalid tag name", http.StatusBadRequest) + return + } + + fmt.Fprint(w, "{}") + return + } + + http.Error(w, "invalid route", http.StatusNotImplemented) +} + +func ZexlabHandlerFailed(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodGet && r.URL.Path == "/api/v1/version" { + // Client performs a request to check version + // Get json string from file + data, _ := retrieveData("data/Version.json") + _, _ = fmt.Fprint(w, string(data)) + return + } + + if r.Method == http.MethodGet && r.URL.Path == fmt.Sprintf("/api/v1/repos/%s/%s", zexlabUser, zexlabRepo) { + // Get json string from file + data, _ := retrieveData("data/GetRepoInfo.json") + _, _ = fmt.Fprint(w, string(data)) + return + } + + http.Error(w, "invalid route", http.StatusNotImplemented) +} diff --git a/pkg/provider/utils.go b/pkg/provider/utils.go new file mode 100644 index 0000000..f3309f1 --- /dev/null +++ b/pkg/provider/utils.go @@ -0,0 +1,107 @@ +package provider + +import ( + "fmt" + "io" + "os" + "testing" + "time" + + "code.gitea.io/sdk/gitea" + + "github.com/stretchr/testify/require" +) + +func createGiteaCommit(sha, message, date string) *gitea.Commit { + tDate, _ := time.Parse("2006-01-02T15:04:05±hh:mm", date) + return &gitea.Commit{ + CommitMeta: &gitea.CommitMeta{ + URL: "", + SHA: sha, + Created: tDate, + }, + HTMLURL: "", + RepoCommit: &gitea.RepoCommit{ + URL: "", + Author: &gitea.CommitUser{ + Identity: gitea.Identity{ + Name: "A User", + Email: "owner@noreply.zexlab.dev", + }, + Date: date, + }, + Committer: &gitea.CommitUser{ + Identity: gitea.Identity{ + Name: "A User", + Email: "owner@noreply.zexlab.dev", + }, + Date: date, + }, + Message: message, + Tree: &gitea.CommitMeta{ + URL: "", + SHA: "", + Created: tDate, + }, + Verification: &gitea.PayloadCommitVerification{ + Verified: false, + Reason: "", + Signature: "", + Payload: "", + }, + }, + Author: &gitea.User{ + ID: 0, + UserName: "owner", + FullName: "A User", + Email: "owner@noreply.zexlab.dev", + }, + Committer: &gitea.User{ + ID: 0, + UserName: "owner", + FullName: "A User", + Email: "owner@noreply.zexlab.dev", + }, + Parents: nil, + Files: nil, + Stats: &gitea.CommitStats{ + Total: 0, + Additions: 0, + Deletions: 0, + }, + } +} + +func retrieveData(filepath string) ([]byte, error) { + jsonFile, err := os.Open(filepath) + if err != nil { + return nil, err + } + defer func(jsonFile *os.File) { + _ = jsonFile.Close() + }(jsonFile) + + byteValue, _ := io.ReadAll(jsonFile) + return byteValue, nil +} + +func setup() { + server = CreateTestServer() +} + +func createTestZexlabRepo(t *testing.T) *ZexlabRepository { + assertions := require.New(t) + repo := &ZexlabRepository{} + + err := repo.Init(map[string]string{ + "server_url": server.URL, + "slug": fmt.Sprintf("%s/%s", zexlabUser, zexlabRepo), + "token": "token", + }) + assertions.NoError(err) + return repo +} + +func teardown() { + server.Close() +} diff --git a/pkg/provider/zexlab.go b/pkg/provider/zexlab.go new file mode 100644 index 0000000..3b4d954 --- /dev/null +++ b/pkg/provider/zexlab.go @@ -0,0 +1,234 @@ +package provider + +import ( + "context" + "fmt" + "os" + "regexp" + "strconv" + "strings" + + "code.gitea.io/sdk/gitea" + "github.com/Masterminds/semver/v3" + "github.com/go-semantic-release/semantic-release/v2/pkg/provider" + "github.com/go-semantic-release/semantic-release/v2/pkg/semrel" +) + +var PVERSION = "dev" + +var zexlabServerURL = "https://zexlab.dev" + +type ZexlabRepository struct { + client *gitea.Client + repo string + owner string + stripVTagPrefix bool +} + +// gocyclo:ignore +func (repo *ZexlabRepository) Init(config map[string]string) error { + serverURL := config["server_url"] + if serverURL == "" { + serverURL = zexlabServerURL + } + + slug := config["slug"] + + if slug == "" { + slug = os.Getenv("GITHUB_REPOSITORY") + } + // Maybe we are running in Gitea Actions + if slug == "" { + slug = os.Getenv("GITEA_REPOSITORY") + } + // Maybe we are running in WoodpeckerCI + if slug == "" { + slug = os.Getenv("CI_REPO_NAME") + } + + token := config["token"] + if token == "" { + token = os.Getenv("GITEA_TOKEN") + } + if token == "" { + return fmt.Errorf("zexlab token missing") + } + + if !strings.Contains(slug, "/") { + return fmt.Errorf("invalid slug") + } + split := strings.Split(slug, "/") + // This could be due to act locally + // We'll work backwards to get the values + repo.owner = split[len(split)-2] + repo.repo = split[len(split)-1] + + // Ensure no .git suffix remains + repo.repo = strings.TrimSuffix(repo.repo, ".git") + + ctx := context.Background() + + client, err := gitea.NewClient(serverURL, + gitea.SetToken(token), + gitea.SetContext(ctx)) + if err != nil { + return err + } + + repo.client = client + + stripVTagPrefix := config["strip_v_tag_prefix"] + repo.stripVTagPrefix, err = strconv.ParseBool(stripVTagPrefix) + + if stripVTagPrefix != "" && err != nil { + return fmt.Errorf("failed to set property strip_v_tag_prefix: %w", err) + } + + return nil +} + +func (repo *ZexlabRepository) GetInfo() (*provider.RepositoryInfo, error) { + r, _, err := repo.client.GetRepo(repo.owner, repo.repo) + if err != nil { + return nil, err + } + return &provider.RepositoryInfo{ + Owner: r.Owner.UserName, + Repo: r.Name, + DefaultBranch: r.DefaultBranch, + Private: r.Private, + }, nil +} + +func (repo *ZexlabRepository) GetCommits(_, toSha string) ([]*semrel.RawCommit, error) { + allCommits := make([]*semrel.RawCommit, 0) + opts := &gitea.ListOptions{PageSize: 100} + for { + commits, resp, err := repo.client.ListRepoCommits(repo.owner, repo.repo, gitea.ListCommitOptions{ + SHA: toSha, + ListOptions: *opts, + }) + if err != nil { + return nil, err + } + for _, commit := range commits { + sha := commit.SHA + + // Resolve author info: prefer Gitea user, fallback to git commit data + authorLogin := "" + authorName := commit.RepoCommit.Author.Name + authorEmail := commit.RepoCommit.Author.Email + if commit.Author != nil { + authorLogin = commit.Author.UserName + authorName = commit.Author.FullName + authorEmail = commit.Author.Email + } + + // Resolve committer info: prefer Gitea user, fallback to git commit data + committerLogin := "" + committerName := commit.RepoCommit.Committer.Name + committerEmail := commit.RepoCommit.Committer.Email + if commit.Committer != nil { + committerLogin = commit.Committer.UserName + committerName = commit.Committer.FullName + committerEmail = commit.Committer.Email + } + + allCommits = append(allCommits, &semrel.RawCommit{ + SHA: sha, + RawMessage: commit.RepoCommit.Message, + Annotations: map[string]string{ + "author_login": authorLogin, + "author_name": authorName, + "author_email": authorEmail, + "author_date": commit.RepoCommit.Author.Date, + "committer_login": committerLogin, + "committer_name": committerName, + "committer_email": committerEmail, + "committer_date": commit.RepoCommit.Committer.Date, + }, + }) + } + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + return allCommits, nil +} + +//gocyclo:ignore +func (repo *ZexlabRepository) GetReleases(rawRe string) ([]*semrel.Release, error) { + re := regexp.MustCompile(rawRe) + allReleases := make([]*semrel.Release, 0) + + refs, resp, err := repo.client.GetRepoRefs(repo.owner, repo.repo, "") + if resp != nil && resp.StatusCode == 404 { + return allReleases, nil + } + if err != nil { + return nil, err + } + + for _, r := range refs { + tag := strings.TrimPrefix(r.Ref, "refs/tags/") + if rawRe != "" && !re.MatchString(tag) { + continue + } + objType := r.Object.Type + if objType != "commit" && objType != "tag" { + continue + } + foundSha := r.Object.SHA + // resolve annotated tag + if objType == "tag" { + resTag, _, err := repo.client.GetRepoRef(repo.owner, repo.repo, foundSha) + if err != nil { + continue + } + if resTag.Object.Type != "commit" { + continue + } + foundSha = resTag.Object.SHA + } + version, err := semver.NewVersion(tag) + if err != nil { + continue + } + allReleases = append(allReleases, &semrel.Release{SHA: foundSha, Version: version.String()}) + } + + return allReleases, nil +} + +func (repo *ZexlabRepository) CreateRelease(release *provider.CreateReleaseConfig) error { + prefix := "v" + if repo.stripVTagPrefix { + prefix = "" + } + + tag := prefix + release.NewVersion + isPrerelease := release.Prerelease || semver.MustParse(release.NewVersion).Prerelease() != "" + + opt := gitea.CreateReleaseOption{ + TagName: tag, + Target: release.Branch, + Title: tag, + Note: release.Changelog, + IsPrerelease: isPrerelease, + } + + _, _, err := repo.client.CreateRelease(repo.owner, repo.repo, opt) + if err != nil { + return fmt.Errorf("error returned %w, tag value [%s]", err, tag) + } + return nil +} + +func (repo *ZexlabRepository) Name() string { + return "Zexlab" +} + +func (repo *ZexlabRepository) Version() string { + return PVERSION +} diff --git a/pkg/provider/zexlab_test.go b/pkg/provider/zexlab_test.go new file mode 100644 index 0000000..e8ed9c1 --- /dev/null +++ b/pkg/provider/zexlab_test.go @@ -0,0 +1,256 @@ +package provider + +import ( + "fmt" + "os" + "testing" + + "github.com/go-semantic-release/semantic-release/v2/pkg/provider" + "github.com/go-semantic-release/semantic-release/v2/pkg/semrel" + "github.com/stretchr/testify/require" +) + +func TestNewZexlabRepository(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + + var repo *ZexlabRepository + repo = &ZexlabRepository{} + err := repo.Init(map[string]string{}) + assertions.EqualError(err, "zexlab token missing") + + repo = &ZexlabRepository{} + + err = repo.Init(map[string]string{ + "server_url": server.URL, + "slug": fmt.Sprintf("%s/%s", zexlabUser, zexlabRepo), + "token": "token", + }) + assertions.NoError(err) +} + +func TestVersionAndNameReturn(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + repo := createTestZexlabRepo(t) + assertions.Equal("dev", repo.Version()) + assertions.Equal("Zexlab", repo.Name()) +} + +func TestZexlabGetInfo(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + repo := createTestZexlabRepo(t) + + repoInfo, err := repo.GetInfo() + + assertions.NoError(err) + assertions.Equal(zexlabDefaultBranch, repoInfo.DefaultBranch) + assertions.True(repoInfo.Private) + assertions.Equal(zexlabUser, repoInfo.Owner) + assertions.Equal(zexlabRepo, repoInfo.Repo) +} + +func TestZexlabGetCommits(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + repo := createTestZexlabRepo(t) + + commits, err := repo.GetCommits("", "sa213445t6") + + assertions.NoError(err) + for i, c := range commits { + assertions.Equal(c.SHA, zexlabCommits[i].SHA) + assertions.Equal(c.RawMessage, zexlabCommits[i].RepoCommit.Message) + assertions.Equal(c.Annotations["author_name"], zexlabCommits[i].Author.FullName) + assertions.Equal(c.Annotations["author_email"], zexlabCommits[i].Author.Email) + assertions.Equal(c.Annotations["committer_name"], zexlabCommits[i].Committer.FullName) + assertions.Equal(c.Annotations["committer_email"], zexlabCommits[i].Committer.Email) + assertions.Equal(c.Annotations["author_date"], zexlabCommits[i].RepoCommit.Author.Date) + assertions.Equal(c.Annotations["committer_date"], zexlabCommits[i].RepoCommit.Committer.Date) + } +} + +func TestZexlabGetReleases(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + repo := createTestZexlabRepo(t) + + testCases := []struct { + vRange string + re string + expectedSHA string + expectedVersion string + }{ + {"", "", testSHA, "2020.4.19"}, + {"", "^v[0-9]*", testSHA, "2.0.0"}, + {"2-beta", "", testSHA, "2.1.0-beta"}, + {"3-beta", "", testSHA, "3.0.0-beta.2"}, + {"4-beta", "", testSHA, "4.0.0-beta"}, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("VersionRange: %s, Regex: %s", tc.vRange, tc.re), func(t *testing.T) { + releases, err := repo.GetReleases(tc.re) + assertions.NoError(err) + release, err := semrel.GetLatestReleaseFromReleases(releases, tc.vRange) + require.NoError(t, err) + assertions.Equal(tc.expectedSHA, release.SHA) + assertions.Equal(tc.expectedVersion, release.Version) + }) + } +} + +func TestZexlabCreateRelease(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + repo := createTestZexlabRepo(t) + + err := repo.CreateRelease(&provider.CreateReleaseConfig{ + NewVersion: "5.0.0", + Prerelease: false, + Branch: "", + SHA: testSHA, + }) + assertions.NoError(err) +} + +func TestZexlabCreateReleaseStripPrefix(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + repo := &ZexlabRepository{} + + err := repo.Init(map[string]string{ + "server_url": server.URL, + "slug": fmt.Sprintf("%s/%s", zexlabUser, zexlabRepo), + "token": "token", + "strip_v_tag_prefix": "true", + }) + + assertions.NoError(err) + + err = repo.CreateRelease(&provider.CreateReleaseConfig{ + NewVersion: "5.0.0", + Prerelease: false, + Branch: "", + SHA: testSHA, + }) + assertions.NoError(err) +} + +func TestZexlabInvalidTag(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + repo := &ZexlabRepository{} + + err := repo.Init(map[string]string{ + "server_url": server.URL, + "slug": fmt.Sprintf("%s/%s", zexlabUser, zexlabRepo), + "token": "token", + }) + + assertions.NoError(err) + + err = repo.CreateRelease(&provider.CreateReleaseConfig{ + NewVersion: "1.0.1", + Prerelease: false, + Branch: "", + SHA: testSHA, + }) + assertions.Errorf(err, "invalid tag name") +} + +func TestZexlabEnvironmentVars(t *testing.T) { + setup() + defer teardown() + + testCases := []struct { + name string + envVarName string + envVarValue string + }{ + { + "Gitea Environment Var Slug", + "GITEA_REPOSITORY", + fmt.Sprintf("%s/%s", + zexlabUser, + zexlabRepo), + }, + { + "GitHub Actions Environment Var Slug", + "GITHUB_REPOSITORY", + fmt.Sprintf("%s/%s", + zexlabUser, + zexlabRepo), + }, + { + "WoodpeckerCI Environment Var Slug", + "CI_REPO_NAME", + fmt.Sprintf("%s/%s", + zexlabUser, + zexlabRepo), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + _ = os.Setenv(tc.envVarName, tc.envVarValue) + + repo := &ZexlabRepository{} + err := repo.Init(map[string]string{ + "server_url": server.URL, + "token": "token", + }) + + require.NoError(t, err) + _ = os.Unsetenv(tc.envVarName) + }) + } +} + +func TestZexlabTokenNotSet(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + + repo := &ZexlabRepository{} + err := repo.Init(map[string]string{ + "server_url": server.URL, + }) + + assertions.Errorf(err, "zexlab token missing") +} + +func TestZexlabNonBooleanStripPrefix(t *testing.T) { + setup() + defer teardown() + + assertions := require.New(t) + + repo := &ZexlabRepository{} + err := repo.Init(map[string]string{ + "server_url": server.URL, + "slug": fmt.Sprintf("%s/%s", zexlabUser, zexlabRepo), + "strip_v_tag_prefix": "something", + "token": "token", + }) + + assertions.Errorf(err, "failed to set property strip_v_tag_prefix: strconv.ParseBool: parsing \"something\": invalid syntax") +}