From f43d8309d578df71a4ddeeb8a28b26ee6e6446a2 Mon Sep 17 00:00:00 2001 From: Don Olmstead Date: Fri, 7 Apr 2023 15:53:53 -0700 Subject: [PATCH] Update plugin to new conventions Instead of downloading and using the manifest tool mimic the behavior of the CLI commands used. This is now possible with the v2 of the manifest tool library which can be used in this manner. Use the new coding conventions for the plugin. --- .drone.yml | 48 ++++-- README.md | 8 +- docker/Dockerfile.linux.amd64 | 10 -- docker/Dockerfile.linux.arm64 | 10 -- docker/Dockerfile.windows.1809 | 12 -- docker/Dockerfile.windows.ltsc2022 | 12 +- docker/manifest.tmpl | 2 +- go.mod | 53 ++++--- go.sum | 236 ++++++++++++++++++++++------ main.go | 244 ++++++----------------------- plugin.go | 186 ---------------------- plugin/legacy.go | 82 ++++++++++ plugin/pipeline.go | 150 ++++++++++++++++++ plugin/plugin.go | 234 +++++++++++++++++++++++++++ plugin/util.go | 37 +++++ tagging/tagging.go | 1 - tagging/tagging_test.go | 4 +- 17 files changed, 814 insertions(+), 515 deletions(-) delete mode 100644 plugin.go create mode 100644 plugin/legacy.go create mode 100644 plugin/pipeline.go create mode 100644 plugin/plugin.go create mode 100644 plugin/util.go diff --git a/.drone.yml b/.drone.yml index 39c6eed..004c02b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -9,7 +9,7 @@ pool: steps: - name: lint - image: golang:1.19 + image: golang:1.20 pull: always commands: - go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest @@ -19,7 +19,7 @@ steps: - name: gopath path: "/go" - name: test - image: golang:1.19 + image: golang:1.20 commands: - go test -cover ./... volumes: @@ -46,7 +46,7 @@ pool: steps: - name: environment - image: golang:1.19 + image: golang:1.20 pull: always environment: CGO_ENABLED: "0" @@ -54,7 +54,7 @@ steps: - go version - go env - name: build - image: golang:1.19 + image: golang:1.20 environment: CGO_ENABLED: "0" commands: @@ -70,6 +70,20 @@ steps: from_secret: docker_password auto_tag: true auto_tag_suffix: linux-amd64 + when: + ref: + - refs/heads/master + - refs/tags/** + - name: docker-dry-run + image: plugins/docker + settings: + dockerfile: docker/Dockerfile.linux.amd64 + repo: plugins/manifest + dry_run: true + tags: linux-amd64 + when: + ref: + - refs/pull/** depends_on: - testing trigger: @@ -90,7 +104,7 @@ pool: steps: - name: environment - image: golang:1.19 + image: golang:1.20 pull: always environment: CGO_ENABLED: "0" @@ -98,7 +112,7 @@ steps: - go version - go env - name: build - image: golang:1.19 + image: golang:1.20 environment: CGO_ENABLED: "0" commands: @@ -114,6 +128,20 @@ steps: from_secret: docker_password auto_tag: true auto_tag_suffix: linux-arm64 + when: + ref: + - refs/heads/master + - refs/tags/** + - name: docker-dry-run + image: plugins/docker + settings: + dockerfile: docker/Dockerfile.linux.arm64 + repo: plugins/manifest + dry_run: true + tags: linux-arm64 + when: + ref: + - refs/pull/** depends_on: - testing trigger: @@ -134,7 +162,7 @@ pool: steps: - name: environment - image: golang:1.19 + image: golang:1.20 pull: always environment: CGO_ENABLED: "0" @@ -142,7 +170,7 @@ steps: - go version - go env - name: build - image: golang:1.19 + image: golang:1.20 environment: CGO_ENABLED: "0" commands: @@ -184,7 +212,7 @@ pool: steps: - name: environment - image: golang:1.19 + image: golang:1.20 pull: always environment: CGO_ENABLED: "0" @@ -192,7 +220,7 @@ steps: - go version - go env - name: build - image: golang:1.19 + image: golang:1.20 environment: CGO_ENABLED: "0" commands: diff --git a/README.md b/README.md index 54bc568..1b96741 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # drone-manifest -[![Build Status](http://cloud.drone.io/api/badges/drone-plugins/drone-manifest/status.svg)](http://cloud.drone.io/drone-plugins/drone-manifest) -[![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) +[![Build Status](http://harness.drone.io/api/badges/drone-plugins/drone-manifest/status.svg)](http://harness.drone.io/drone-plugins/drone-manifest) +[![Slack](https://img.shields.io/badge/slack-drone-orange.svg?logo=slack)](https://join.slack.com/t/harnesscommunity/shared_invite/zt-y4hdqh7p-RVuEQyIl5Hcx4Ck8VCvzBw) +[![Join the discussion at https://community.harness.io](https://img.shields.io/badge/discourse-forum-orange.svg)](https://community.harness.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/manifest.svg)](https://microbadger.com/images/plugins/manifest "Get your own image badge on microbadger.com") [![Go Doc](https://godoc.org/github.com/drone-plugins/drone-manifest?status.svg)](http://godoc.org/github.com/drone-plugins/drone-manifest) [![Go Report](https://goreportcard.com/badge/github.com/drone-plugins/drone-manifest)](https://goreportcard.com/report/github.com/drone-plugins/drone-manifest) @@ -18,7 +17,6 @@ Build the binary with the following command: export GOOS=linux export GOARCH=amd64 export CGO_ENABLED=0 -export GO111MODULE=on go build -v -a -tags netgo -o release/linux/amd64/drone-manifest ``` diff --git a/docker/Dockerfile.linux.amd64 b/docker/Dockerfile.linux.amd64 index a5b9417..aaa1f5f 100644 --- a/docker/Dockerfile.linux.amd64 +++ b/docker/Dockerfile.linux.amd64 @@ -1,11 +1,3 @@ -FROM alpine:3.10 as base - -ENV MANIFEST_TOOL_VERSION 1.0.2 - -RUN apk add --no-cache curl && \ - curl -sSLo /bin/manifest-tool https://github.com/estesp/manifest-tool/releases/download/v${MANIFEST_TOOL_VERSION}/manifest-tool-linux-amd64 && \ - chmod +x /bin/manifest-tool - FROM plugins/base:multiarch LABEL maintainer="Drone.IO Community " \ @@ -13,7 +5,5 @@ LABEL maintainer="Drone.IO Community " \ org.label-schema.vendor="Drone.IO Community" \ org.label-schema.schema-version="1.0" -COPY --from=base /bin/manifest-tool /bin/ - ADD release/linux/amd64/drone-manifest /bin/ ENTRYPOINT ["/bin/drone-manifest"] diff --git a/docker/Dockerfile.linux.arm64 b/docker/Dockerfile.linux.arm64 index 66fd2cf..a528cb6 100644 --- a/docker/Dockerfile.linux.arm64 +++ b/docker/Dockerfile.linux.arm64 @@ -1,11 +1,3 @@ -FROM alpine:3.10 as base - -ENV MANIFEST_TOOL_VERSION 1.0.2 - -RUN apk add --no-cache curl && \ - curl -sSLo /bin/manifest-tool https://github.com/estesp/manifest-tool/releases/download/v${MANIFEST_TOOL_VERSION}/manifest-tool-linux-arm64 && \ - chmod +x /bin/manifest-tool - FROM plugins/base:multiarch LABEL maintainer="Drone.IO Community " \ @@ -13,7 +5,5 @@ LABEL maintainer="Drone.IO Community " \ org.label-schema.vendor="Drone.IO Community" \ org.label-schema.schema-version="1.0" -COPY --from=base /bin/manifest-tool /bin/ - ADD release/linux/arm64/drone-manifest /bin/ ENTRYPOINT ["/bin/drone-manifest"] diff --git a/docker/Dockerfile.windows.1809 b/docker/Dockerfile.windows.1809 index e7ca530..49dd684 100644 --- a/docker/Dockerfile.windows.1809 +++ b/docker/Dockerfile.windows.1809 @@ -1,22 +1,10 @@ # escape=` -FROM mcr.microsoft.com/windows/servercore:1809 as download - -SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] - -RUN mkdir C:\app -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` - Invoke-WebRequest 'https://github.com/estesp/manifest-tool/releases/download/v1.0.3/manifest-tool-windows-amd64.exe' -OutFile 'c:\app\manifest-tool.exe' - FROM plugins/base:windows-1809-amd64 -SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] - LABEL maintainer="Drone.IO Community " ` org.label-schema.name="Drone Manifest" ` org.label-schema.vendor="Drone.IO Community" ` org.label-schema.schema-version="1.0" -COPY --from=download /app/manifest-tool.exe C:/bin/docker.exe - ADD release/windows/amd64/drone-manifest.exe C:/bin/drone-manifest.exe ENTRYPOINT [ "C:\\bin\\drone-manifest.exe" ] diff --git a/docker/Dockerfile.windows.ltsc2022 b/docker/Dockerfile.windows.ltsc2022 index ba0930a..89469a0 100644 --- a/docker/Dockerfile.windows.ltsc2022 +++ b/docker/Dockerfile.windows.ltsc2022 @@ -1,15 +1,5 @@ # escape=` -FROM mcr.microsoft.com/windows/servercore:ltsc2022 as download - -SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] - -RUN mkdir C:\app -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` - Invoke-WebRequest 'https://github.com/estesp/manifest-tool/releases/download/v1.0.3/manifest-tool-windows-amd64.exe' -OutFile 'c:\app\manifest-tool.exe' - -FROM plugins/base:windows-ltsc2022-amd64@sha256:0f90d5bceb432f1ee6f93cf44eed6a38c322834edd55df8a6648c9e6f15131f4 - -SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] +FROM plugins/base:windows-ltsc2022-amd64 LABEL maintainer="Drone.IO Community " ` org.label-schema.name="Drone Manifest" ` diff --git a/docker/manifest.tmpl b/docker/manifest.tmpl index 033a248..2e05545 100644 --- a/docker/manifest.tmpl +++ b/docker/manifest.tmpl @@ -28,4 +28,4 @@ manifests: platform: architecture: amd64 os: windows - version: ltsc2022 \ No newline at end of file + version: ltsc2022 diff --git a/go.mod b/go.mod index feddfe0..5b3c063 100644 --- a/go.mod +++ b/go.mod @@ -1,29 +1,42 @@ module github.com/drone-plugins/drone-manifest -go 1.19 +go 1.20 require ( - github.com/coreos/go-semver v0.3.0 - github.com/drone/drone-template-lib v1.0.1-0.20201006172840-a58a3f26ebca - github.com/pkg/errors v0.9.1 - github.com/urfave/cli v1.22.10 + github.com/coreos/go-semver v0.3.1 + github.com/drone/drone-go v1.7.1 + github.com/drone/drone-template-lib v1.0.0 + github.com/estesp/manifest-tool/v2 v2.0.8 + github.com/kelseyhightower/envconfig v1.4.0 + github.com/opencontainers/image-spec v1.1.0-rc2 + github.com/sirupsen/logrus v1.9.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.1.0 // indirect - github.com/Masterminds/sprig/v3 v3.1.0 // indirect + github.com/Masterminds/goutils v1.1.0 // indirect + github.com/Masterminds/semver v1.4.2 // indirect + github.com/Masterminds/sprig v2.18.0+incompatible // indirect github.com/aymerick/raymond v2.0.2+incompatible // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/huandu/xstrings v1.4.0 // indirect - github.com/imdario/mergo v0.3.13 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/spf13/cast v1.3.1 // indirect - github.com/stretchr/testify v1.8.1 // indirect - golang.org/x/crypto v0.4.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + github.com/containerd/containerd v1.6.18 // indirect + github.com/docker/cli v23.0.1+incompatible // indirect + github.com/docker/distribution v2.8.1+incompatible // indirect + github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/uuid v1.2.0 // indirect + github.com/huandu/xstrings v1.2.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/klauspost/compress v1.13.6 // indirect + github.com/moby/locker v1.0.1 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect + golang.org/x/net v0.7.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.5.0 // indirect + google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect + google.golang.org/grpc v1.47.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect + oras.land/oras-go/v2 v2.0.0 // indirect ) diff --git a/go.sum b/go.sum index 38f87cc..b9ed96a 100644 --- a/go.sum +++ b/go.sum @@ -1,72 +1,212 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -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.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk= -github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.1.0 h1:j7GpgZ7PdFqNsmncycTHsLmVPf5/3wJtlgW9TNDYD9Y= -github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA= +github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.18.0+incompatible h1:QoGhlbC6pter1jxKnjMFxT8EqsLuDE6FEcNbWEpw+lI= +github.com/Masterminds/sprig v2.18.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0= github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -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/bouk/monkey v1.0.0 h1:k6z8fLlPhETfn5l9rlWVE7Q6B23DoaqosTdArvNQRdc= +github.com/bouk/monkey v1.0.0/go.mod h1:PG/63f4XEUlVyW1ttIeOJmJhhe1+t9EC/je3eTjvFhE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/containerd/containerd v1.6.18 h1:qZbsLvmyu+Vlty0/Ex5xc0z2YtKpIsb5n45mAMI+2Ns= +github.com/containerd/containerd v1.6.18/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= 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/drone/drone-template-lib v1.0.1-0.20201006172840-a58a3f26ebca h1:8kk7qaQJ1R3aIDMQ04NhKRZQZZgBE9veNYme2Wjudts= -github.com/drone/drone-template-lib v1.0.1-0.20201006172840-a58a3f26ebca/go.mod h1:4DHXhrDoAGam5Sx6LHygmi2tkhWt2dWXqNFLQNxmWTc= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= -github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/docker/cli v23.0.1+incompatible h1:LRyWITpGzl2C9e9uGxzisptnxAn1zfZKXy13Ul2Q5oM= +github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= +github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= +github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/drone/drone-go v1.7.1 h1:ZX+3Rs8YHUSUQ5mkuMLmm1zr1ttiiE2YGNxF3AnyDKw= +github.com/drone/drone-go v1.7.1/go.mod h1:fxCf9jAnXDZV1yDr0ckTuWd1intvcQwfJmTRpTZ1mXg= +github.com/drone/drone-template-lib v1.0.0 h1:PNBBfUhifRnrPCoWBlTitk3jipXdv8u8WLbIf7h7j00= +github.com/drone/drone-template-lib v1.0.0/go.mod h1:Hqy1tgqPH5mtbFOZmow19l4jOkZvp+WZ00cB4W3MJhg= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/estesp/manifest-tool/v2 v2.0.8 h1:hNiSguGbIcul1xAhI7Ua8HJvIU6V4VmM4FBxq5Cxx6g= +github.com/estesp/manifest-tool/v2 v2.0.8/go.mod h1:oDk8Oj2enRtzjlCMGn3KR6PDRS8PVd21mxK5EZs0WCc= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= +github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 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/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/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -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.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= -github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tkuchiki/faketime v0.0.0-20170607100027-a4500a4f4643 h1:ii/sHfgFMByozryLeiDmn1ClZ/Pena4NgpJ4P7UuX9o= +github.com/tkuchiki/faketime v0.0.0-20170607100027-a4500a4f4643/go.mod h1:RXY/TXAwGGL36IKDjrHFMcjpUrEiyWSEtLhFPw3UWF0= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -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/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/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= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +oras.land/oras-go/v2 v2.0.0 h1:+LRAz92WF7AvYQsQjPEAIw3Xb2zPPhuydjpi4pIHmc0= +oras.land/oras-go/v2 v2.0.0/go.mod h1:iVExH1NxrccIxjsiq17L91WCZ4KIw6jVQyCLsZsu1gc= diff --git a/main.go b/main.go index 5265cf1..b744496 100644 --- a/main.go +++ b/main.go @@ -1,217 +1,63 @@ +// Copyright (c) 2023, the Drone Plugins project authors. +// Please see the AUTHORS file for details. All rights reserved. +// Use of this source code is governed by an Apache 2.0 license that can be +// found in the LICENSE file. + package main import ( - "log" - "os" + "bytes" + "context" + "strings" - "github.com/drone-plugins/drone-manifest/tagging" - "github.com/urfave/cli" -) + "github.com/drone-plugins/drone-manifest/plugin" -var ( - version = "unknown" + "github.com/kelseyhightower/envconfig" + "github.com/sirupsen/logrus" ) func main() { - app := cli.NewApp() - app.Name = "manifest plugin" - app.Usage = "manifest plugin" - app.Action = run - app.Version = version - app.Flags = []cli.Flag{ - cli.StringFlag{ - Name: "username", - Usage: "username for registry", - EnvVar: "PLUGIN_USERNAME,MANIFEST_USERNAME,DOCKER_USERNAME", - }, - cli.StringFlag{ - Name: "password", - Usage: "password for registry", - EnvVar: "PLUGIN_PASSWORD,MANIFEST_PASSWORD,DOCKER_PASSWORD", - }, - cli.BoolFlag{ - Name: "insecure", - Usage: "enable allow insecure registry", - EnvVar: "PLUGIN_INSECURE", - }, - cli.StringSliceFlag{ - Name: "platforms", - Usage: "platforms for manifests", - EnvVar: "PLUGIN_PLATFORMS", - }, - cli.StringFlag{ - Name: "target", - Usage: "target for manifests", - EnvVar: "PLUGIN_TARGET", - }, - cli.StringFlag{ - Name: "template", - Usage: "template for manifests", - EnvVar: "PLUGIN_TEMPLATE", - }, - cli.StringFlag{ - Name: "spec", - Usage: "path to manifest spec", - EnvVar: "PLUGIN_SPEC", - }, - cli.BoolFlag{ - Name: "ignore-missing", - Usage: "ignore missing images", - EnvVar: "PLUGIN_IGNORE_MISSING", - }, - cli.StringSliceFlag{ - Name: "tags", - Usage: "list of additional tags", - Value: &cli.StringSlice{}, - EnvVar: "PLUGIN_TAG,PLUGIN_TAGS", - FilePath: ".tags", - }, - cli.BoolFlag{ - Name: "tags.auto", - Usage: "automatically build tags", - EnvVar: "PLUGIN_DEFAULT_TAGS,PLUGIN_AUTO_TAG", - }, - cli.BoolFlag{ - Name: "dump", - Usage: "dump the spec to stdout for debug purposes", - EnvVar: "PLUGIN_DUMP", - }, - cli.StringFlag{ - Name: "path", - Usage: "git clone path", - EnvVar: "DRONE_WORKSPACE", - }, - 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: "repo.branch", - Usage: "repository default branch", - EnvVar: "DRONE_REPO_BRANCH", - }, - cli.StringFlag{ - Name: "commit.sha", - Usage: "git commit sha", - EnvVar: "DRONE_COMMIT_SHA", - Value: "00000000", - }, - cli.StringFlag{ - Name: "commit.ref", - Usage: "git commit ref", - EnvVar: "DRONE_COMMIT_REF", - }, - cli.StringFlag{ - Name: "commit.branch", - Value: "master", - Usage: "git commit branch", - EnvVar: "DRONE_COMMIT_BRANCH", - }, - cli.StringFlag{ - Name: "commit.pull", - Usage: "git pull request", - EnvVar: "DRONE_PULL_REQUEST", - }, - cli.StringFlag{ - Name: "build.event", - Value: "push", - Usage: "build event", - EnvVar: "DRONE_BUILD_EVENT", - }, - cli.IntFlag{ - Name: "build.number", - Usage: "build number", - EnvVar: "DRONE_BUILD_NUMBER", - }, - cli.StringFlag{ - Name: "build.status", - Usage: "build status", - Value: "success", - EnvVar: "DRONE_BUILD_STATUS", - }, - cli.StringFlag{ - Name: "build.link", - Usage: "build link", - EnvVar: "DRONE_BUILD_LINK", - }, - cli.Int64Flag{ - Name: "build.started", - Usage: "build started", - EnvVar: "DRONE_BUILD_STARTED", - }, - cli.Int64Flag{ - Name: "build.created", - Usage: "build created", - EnvVar: "DRONE_BUILD_CREATED", - }, - cli.StringFlag{ - Name: "build.tag", - Usage: "build tag", - EnvVar: "DRONE_TAG", - }, - cli.Int64Flag{ - Name: "job.started", - Usage: "job started", - EnvVar: "DRONE_JOB_STARTED", - }, + logrus.SetFormatter(new(formatter)) + + var args plugin.Args + if err := envconfig.Process("", &args); err != nil { + logrus.Fatalln(err) } - if err := app.Run(os.Args); err != nil { - log.Fatal(err) + switch args.Level { + case "debug": + logrus.SetFormatter(textFormatter) + logrus.SetLevel(logrus.DebugLevel) + case "trace": + logrus.SetFormatter(textFormatter) + logrus.SetLevel(logrus.TraceLevel) + } + + if err := plugin.Exec(context.Background(), &args); err != nil { + logrus.Fatalln(err) } } -func run(c *cli.Context) error { - plugin := Plugin{ - Repo: Repo{ - Owner: c.String("repo.owner"), - Name: c.String("repo.name"), - Branch: c.String("repo.branch"), - }, - Build: Build{ - Path: c.String("path"), - Tag: c.String("build.tag"), - Number: c.Int("build.number"), - Event: c.String("build.event"), - Status: c.String("build.status"), - Commit: c.String("commit.sha"), - Ref: c.String("commit.ref"), - Branch: c.String("commit.branch"), - Pull: c.String("commit.pull"), - Started: c.Int64("build.started"), - Created: c.Int64("build.created"), - Tags: c.StringSlice("tags"), - }, - Job: Job{ - Started: c.Int64("job.started"), - }, - Config: Config{ - Username: c.String("username"), - Password: c.String("password"), - Insecure: c.Bool("insecure"), - Platforms: c.StringSlice("platforms"), - Target: c.String("target"), - Template: c.String("template"), - Spec: c.String("spec"), - IgnoreMissing: c.Bool("ignore-missing"), - Dump: c.Bool("dump"), - }, +// default formatter that writes logs without including timestamp or level information. +type formatter struct{} + +func (*formatter) Format(entry *logrus.Entry) ([]byte, error) { + var b *bytes.Buffer + if entry.Buffer != nil { + b = entry.Buffer + } else { + b = &bytes.Buffer{} } - if c.Bool("tags.auto") { - if tagging.UseDefaultTag(c.String("commit.ref"), c.String("repo.branch")) { - plugin.Build.Tags = tagging.DefaultTags(c.String("commit.ref")) - } else { - log.Printf("skipping automated tags for %s", c.String("commit.ref")) - return nil - } + b.WriteString(entry.Message) + if !strings.HasSuffix(entry.Message, "\n") { + b.WriteByte('\n') } - return plugin.Exec() + return b.Bytes(), nil +} + +// text formatter that writes logs with level information. +var textFormatter = &logrus.TextFormatter{ + DisableTimestamp: true, } diff --git a/plugin.go b/plugin.go deleted file mode 100644 index 8f4d547..0000000 --- a/plugin.go +++ /dev/null @@ -1,186 +0,0 @@ -package main - -import ( - "fmt" - - "log" - "os" - "os/exec" - "runtime" - "strings" - - "github.com/drone/drone-template-lib/template" - "github.com/pkg/errors" -) - -type ( - Repo struct { - Owner string - Name string - Branch string - } - - Build struct { - Path string - Tag string - Event string - Number int - Commit string - Ref string - Branch string - Author string - Pull string - Message string - DeployTo string - Status string - Link string - Started int64 - Created int64 - Tags []string - } - - Job struct { - Started int64 - } - - Config struct { - Username string - Password string - Insecure bool - Platforms []string - Target string - Template string - Spec string - IgnoreMissing bool - Dump bool - } - - Plugin struct { - Repo Repo - Build Build - Job Job - Config Config - } -) - -func mainfestToolPath() string { - if runtime.GOOS == "windows" { - return "C:/bin/manifest-tool.exe" - } - - return "/bin/manifest-tool" -} - -func (p *Plugin) Exec() error { - args := []string{} - - if p.Config.Username == "" && p.Config.Password != "" { - return errors.New("you must provide a username") - } else { - args = append(args, fmt.Sprintf("--username=%s", p.Config.Username)) - } - - if p.Config.Password == "" && p.Config.Username != "" { - return errors.New("you must provide a password") - } else { - args = append(args, fmt.Sprintf("--password=%s", p.Config.Password)) - } - - if p.Config.Insecure { - args = append(args, "--insecure") - } - - args = append(args, "push") - - if p.Config.Spec != "" { - var raw []byte - // if spec is not a valid file, assume inlining - if _, err := os.Stat(p.Config.Spec); os.IsNotExist(err) { - raw = []byte(p.Config.Spec) - } else { // otherwise read it - raw, err = os.ReadFile(p.Config.Spec) - - if err != nil { - return errors.Wrap(err, "failed to read template") - } - } - - spec, err := template.RenderTrim(string(raw), p) - - if err != nil { - return errors.Wrap(err, "failed to render template") - } - - tmpfile, err := os.CreateTemp(p.Build.Path, "manifest-") - - if err != nil { - return errors.Wrap(err, "failed to create tempfile") - } - - defer os.Remove(tmpfile.Name()) - - if _, err := tmpfile.Write([]byte(spec)); err != nil { - return errors.Wrap(err, "failed to write tempfile") - } - - if err := tmpfile.Close(); err != nil { - return errors.Wrap(err, "failed to close tempfile") - } - - if p.Config.Dump { - println(spec) - } - - args = append(args, "from-spec") - args = append(args, tmpfile.Name()) - - log.Printf( - "pushing by spec", - ) - } else { - args = append(args, "from-args") - - if len(p.Config.Platforms) == 0 { - return errors.New("you must provide platforms") - } else { - args = append(args, fmt.Sprintf("--platforms=%s", strings.Join(p.Config.Platforms, ","))) - } - - if p.Config.Target == "" { - return errors.New("you must provide a target") - } else { - args = append(args, fmt.Sprintf("--target=%s", p.Config.Target)) - } - - if p.Config.Template == "" { - return errors.New("you must provide a template") - } else { - args = append(args, fmt.Sprintf("--template=%s", p.Config.Template)) - } - - log.Printf( - "pushing %s to %s for %s", - p.Config.Template, - p.Config.Target, - strings.Join(p.Config.Platforms, ", "), - ) - } - - if p.Config.IgnoreMissing { - args = append(args, "--ignore-missing") - } - - cmd := exec.Command( - mainfestToolPath(), - args..., - ) - - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - if p.Build.Path != "" { - cmd.Dir = p.Build.Path - } - - return cmd.Run() -} diff --git a/plugin/legacy.go b/plugin/legacy.go new file mode 100644 index 0000000..461f879 --- /dev/null +++ b/plugin/legacy.go @@ -0,0 +1,82 @@ +// Copyright (c) 2023, the Drone Plugins project authors. +// Please see the AUTHORS file for details. All rights reserved. +// Use of this source code is governed by an Apache 2.0 license that can be +// found in the LICENSE file. + +package plugin + +import ( + "os" + "strconv" +) + +type ( + legacyRepo struct { + Owner string + Name string + Branch string + } + + legacyBuild struct { + Path string + Tag string + Event string + Number int + Commit string + Ref string + Branch string + Author string + Pull string + Message string + DeployTo string + Status string + Link string + Started int64 + Created int64 + Tags []string + } + + legacyJob struct { + Started int64 + } + + legacyPlugin struct { + Repo legacyRepo + Build legacyBuild + Job legacyJob + } +) + +func toLegacyPlugin(args *Args) legacyPlugin { + return legacyPlugin{ + Repo: legacyRepo{ + Owner: args.Repo.Namespace, + Name: args.Repo.Name, + Branch: args.Repo.Branch, + }, + Build: legacyBuild{ + Path: getEnv("DRONE_WORKSPACE", ""), + Tag: args.Tag.Name, + Number: args.Build.Number, + Event: args.Build.Event, + Status: args.Build.Status, + Commit: args.Commit.Rev, + Ref: args.Commit.Ref, + Branch: args.Commit.Branch, + Pull: strconv.FormatInt(int64(args.PullRequest.Number), 10), // c.String("commit.pull"), + Started: args.Build.Started, + Created: args.Build.Created, + Tags: args.Tags, + }, + Job: legacyJob{ + Started: 0, + }, + } +} + +func getEnv(key, fallback string) string { + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback +} diff --git a/plugin/pipeline.go b/plugin/pipeline.go new file mode 100644 index 0000000..ddab858 --- /dev/null +++ b/plugin/pipeline.go @@ -0,0 +1,150 @@ +// Copyright (c) 2023, the Drone Plugins project authors. +// Please see the AUTHORS file for details. All rights reserved. +// Use of this source code is governed by an Apache 2.0 license that can be +// found in the LICENSE file. + +package plugin + +// Pipeline provides Pipeline metadata from the environment. +type Pipeline struct { + // Build provides build metadata. + Build struct { + Branch string `envconfig:"DRONE_BUILD_BRANCH"` + Number int `envconfig:"DRONE_BUILD_NUMBER"` + Parent int `envconfig:"DRONE_BUILD_PARENT"` + Event string `envconfig:"DRONE_BUILD_EVENT"` + Action string `envconfig:"DRONE_BUILD_ACTION"` + Status string `envconfig:"DRONE_BUILD_STATUS"` + Created int64 `envconfig:"DRONE_BUILD_CREATED"` + Started int64 `envconfig:"DRONE_BUILD_STARTED"` + Finished int64 `envconfig:"DRONE_BUILD_FINISHED"` + Link string `envconfig:"DRONE_BUILD_LINK"` + } + + // Calver provides the calver details parsed from the + // git tag. If the git tag is empty or is not a valid + // calver, the values will be empty. + Calver struct { + Version string `envconfig:"DRONE_CALVER"` + Short string `envconfig:"DRONE_CALVER_SHORT"` + MajorMinor string `envconfig:"DRONE_CALVER_MAJOR_MINOR"` + Major string `envconfig:"DRONE_CALVER_MAJOR"` + Minor string `envconfig:"DRONE_CALVER_MINOR"` + Micro string `envconfig:"DRONE_CALVER_MICRO"` + Modifier string `envconfig:"DRONE_CALVER_MODIFIER"` + } + + // Card provides adaptive card configuration options. + Card struct { + Path string `envconfig:"DRONE_CARD_PATH"` + } + + // Commit provides the commit metadata. + Commit struct { + Rev string `envconfig:"DRONE_COMMIT_SHA"` + Before string `envconfig:"DRONE_COMMIT_BEFORE"` + After string `envconfig:"DRONE_COMMIT_AFTER"` + Ref string `envconfig:"DRONE_COMMIT_REF"` + Branch string `envconfig:"DRONE_COMMIT_BRANCH"` + Source string `envconfig:"DRONE_COMMIT_SOURCE"` + Target string `envconfig:"DRONE_COMMIT_TARGET"` + Link string `envconfig:"DRONE_COMMIT_LINK"` + Message string `envconfig:"DRONE_COMMIT_MESSAGE"` + + Author struct { + Username string `envconfig:"DRONE_COMMIT_AUTHOR"` + Name string `envconfig:"DRONE_COMMIT_AUTHOR_NAME"` + Email string `envconfig:"DRONE_COMMIT_AUTHOR_EMAIL"` + Avatar string `envconfig:"DRONE_COMMIT_AUTHOR_AVATAR"` + } + } + + // Deploy provides the deployment metadata. + Deploy struct { + ID string `envconfig:"DRONE_DEPLOY_TO"` + Target string `envconfig:"DRONE_DEPLOY_ID"` + } + + // Failed provides a list of failed steps and failed stages + // for the current pipeline. + Failed struct { + Steps []string `envconfig:"DRONE_FAILED_STEPS"` + Stages []string `envconfig:"DRONE_FAILED_STAGES"` + } + + // Git provides the git repository metadata. + Git struct { + HTTPURL string `envconfig:"DRONE_GIT_HTTP_URL"` + SSHURL string `envconfig:"DRONE_GIT_SSH_URL"` + } + + // PullRequest provides the pull request metadata. + PullRequest struct { + Number int `envconfig:"DRONE_PULL_REQUEST"` + } + + // Repo provides the repository metadata. + Repo struct { + Branch string `envconfig:"DRONE_REPO_BRANCH"` + Link string `envconfig:"DRONE_REPO_LINK"` + Namespace string `envconfig:"DRONE_REPO_NAMESPACE"` + Name string `envconfig:"DRONE_REPO_NAME"` + Private bool `envconfig:"DRONE_REPO_PRIVATE"` + Remote string `envconfig:"DRONE_GIT_HTTP_URL"` + SCM string `envconfig:"DRONE_REPO_SCM"` + Slug string `envconfig:"DRONE_REPO"` + Visibility string `envconfig:"DRONE_REPO_VISIBILITY"` + } + + // Stage provides the stage metadata. + Stage struct { + Kind string `envconfig:"DRONE_STAGE_KIND"` + Type string `envconfig:"DRONE_STAGE_TYPE"` + Name string `envconfig:"DRONE_STAGE_NAME"` + Number int `envconfig:"DRONE_STAGE_NUMBER"` + Machine string `envconfig:"DRONE_STAGE_MACHINE"` + OS string `envconfig:"DRONE_STAGE_OS"` + Arch string `envconfig:"DRONE_STAGE_ARCH"` + Variant string `envconfig:"DRONE_STAGE_VARIANT"` + Status string `envconfig:"DRONE_STAGE_STATUS"` + Started int64 `envconfig:"DRONE_STAGE_STARTED"` + Finished int64 `envconfig:"DRONE_STAGE_FINISHED"` + DependsOn []string `envconfig:"DRONE_STAGE_DEPENDS_ON"` + } + + // Step provides the step metadata. + Step struct { + Number int `envconfig:"DRONE_STEP_NUMBER"` + Name string `envconfig:"DRONE_STEP_NAME"` + } + + // Semver provides the semver details parsed from the + // git tag. If the git tag is empty or is not a valid + // semver, the values will be empty and the error field + // will be populated with the parsing error. + Semver struct { + Version string `envconfig:"DRONE_SEMVER"` + Short string `envconfig:"DRONE_SEMVER_SHORT"` + Major string `envconfig:"DRONE_SEMVER_MAJOR"` + Minor string `envconfig:"DRONE_SEMVER_MINOR"` + Patch string `envconfig:"DRONE_SEMVER_PATCH"` + Build string `envconfig:"DRONE_SEMVER_BUILD"` + PreRelease string `envconfig:"DRONE_SEMVER_PRERELEASE"` + Error string `envconfig:"DRONE_SEMVER_ERROR"` + } + + // System provides the Drone system metadata, including + // the system version of details required to create the + // drone website address. + System struct { + Proto string `envconfig:"DRONE_SYSTEM_PROTO"` + Host string `envconfig:"DRONE_SYSTEM_HOST"` + Hostname string `envconfig:"DRONE_SYSTEM_HOSTNAME"` + Version string `envconfig:"DRONE_SYSTEM_VERSION"` + } + + // Tag provides the git tag details. + Tag struct { + Name string `envconfig:"DRONE_TAG"` + } +} diff --git a/plugin/plugin.go b/plugin/plugin.go new file mode 100644 index 0000000..b72653f --- /dev/null +++ b/plugin/plugin.go @@ -0,0 +1,234 @@ +// Copyright (c) 2023, the Drone Plugins project authors. +// Please see the AUTHORS file for details. All rights reserved. +// Use of this source code is governed by an Apache 2.0 license that can be +// found in the LICENSE file. + +package plugin + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os" + "strings" + + "github.com/drone-plugins/drone-manifest/tagging" + + "github.com/drone/drone-go/drone" + "github.com/drone/drone-template-lib/template" + "github.com/estesp/manifest-tool/v2/pkg/registry" + "github.com/estesp/manifest-tool/v2/pkg/types" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/sirupsen/logrus" + yaml "gopkg.in/yaml.v3" +) + +// Args provides plugin execution arguments. +type ( + Args struct { + Pipeline + + // Level defines the plugin log level. + Level string `envconfig:"PLUGIN_LOG_LEVEL"` + + // Skip verification of certificates + SkipVerify bool `envconfig:"PLUGIN_SKIP_VERIFY"` + + // Lint plugin + Lint bool `envconfig:"PLUGIN_LINT" default:"true"` + + // Plugin specific + Username string `envconfig:"PLUGIN_USERNAME"` + Password string `envconfig:"PLUGIN_PASSWORD"` + Platforms []string `envconfig:"PLUGIN_PLATFORMS"` + Target string `envconfig:"PLUGIN_TARGET"` + Template string `envconfig:"PLUGIN_TEMPLATE"` + Spec string `envconfig:"PLUGIN_SPEC"` + IgnoreMissing bool `envconfig:"PLUGIN_IGNORE_MISSING"` + Tags []string `envconfig:"PLUGIN_TAGS"` + AutoTag bool `envconfig:"PLUGIN_AUTO_TAG"` + } +) + +var errConfiguration = errors.New("configuration error") + +// Exec executes the plugin. +func Exec(ctx context.Context, args *Args) error { + linter := "" + + if args.Lint { + issues, warnings := lintArgs(args) + linter = fmt.Sprintf("lint: %d issue(s) found\n%s", issues, warnings) + logrus.Info(linter) + } + + err := verifyArgs(args) + if err != nil { + return fmt.Errorf("error in the configuration: %w", err) + } + + // Auto tag behavior + if args.AutoTag { + if tagging.UseDefaultTag(args.Commit.Ref, args.Repo.Branch) { + args.Tags = tagging.DefaultTags(args.Commit.Ref) + } else { + logrus.Infof("skipping automated tags for %s", args.Commit.Ref) + return nil + } + } + + // Get the yaml to push + var yamlFunc func(*Args) (types.YAMLInput, error) + if args.Spec != "" { + yamlFunc = yamlFromSpec + } else { + yamlFunc = yamlFromArgs + } + + yamlInput, err := yamlFunc(args) + if err != nil { + return fmt.Errorf("could not create manifest spec: %w", err) + } + + logrus.Info("pushing manifest") + + digest, length, err := registry.PushManifestList( + args.Username, // --username + args.Password, // --password + yamlInput, // --from-spec + args.IgnoreMissing, // --ignore-missing + args.SkipVerify, // --insecure + false, // --plain-http + types.Docker, // --type + "", // --docker-cfg + ) + if err != nil { + return fmt.Errorf("could not push manifest list: %w", err) + } + + logrus.Infof("manifest pushed: digest %s %d", digest, length) + + // Create the card data + cardData := struct { + Image string `json:"image"` + Digest string `json:"digest"` + Linter string `json:"linter"` + }{ + Image: yamlInput.Image, + Digest: digest, + Linter: linter, + } + + data, _ := json.Marshal(cardData) + card := drone.CardInput{ + Schema: "https://drone-plugins.github.io/drone-manifest/card.json", + Data: data, + } + writeCard(args.Card.Path, &card) + + return nil +} + +func lintArgs(args *Args) (issues int, warnings string) { + issues = 0 + var warningsBuilder strings.Builder + + if value, present := os.LookupEnv("PLUGIN_INSECURE"); present { + warningsBuilder.WriteString("remove insecure from config and use skip_verify instead") + args.SkipVerify = value == "true" + issues++ + } + + return issues, warningsBuilder.String() +} + +func verifyArgs(args *Args) error { + if args.Username == "" { + return fmt.Errorf("no username provided: %w", errConfiguration) + } + + if args.Password == "" { + return fmt.Errorf("no password provided: %w", errConfiguration) + } + + if args.Spec == "" { + if len(args.Platforms) == 0 { + return fmt.Errorf("no platforms provided: %w", errConfiguration) + } + + if args.Target == "" { + return fmt.Errorf("no target provided: %w", errConfiguration) + } + + if args.Template == "" { + return fmt.Errorf("no template provided: %w", errConfiguration) + } + } else if len(args.Platforms) != 0 || args.Target != "" || args.Template != "" { + return fmt.Errorf("both spec and arguments provided: %w", errConfiguration) + } + + return nil +} + +func yamlFromSpec(args *Args) (types.YAMLInput, error) { + var yamlInput types.YAMLInput + var raw []byte + + // if spec is not a valid file, assume inlining + if _, err := os.Stat(args.Spec); os.IsNotExist(err) { + raw = []byte(args.Spec) + } else { // otherwise read it + raw, err = os.ReadFile(args.Spec) + + if err != nil { + return yamlInput, fmt.Errorf("failed to read template: %w", errConfiguration) + } + } + + // Render using the old plugin format + p := toLegacyPlugin(args) + yamlFile, err := template.RenderTrim(string(raw), p) + if err != nil { + return yamlInput, fmt.Errorf("can't render template: %w", err) + } + + // Modified from https://github.com/estesp/manifest-tool/blob/main/v2/cmd/manifest-tool/push.go + err = yaml.Unmarshal([]byte(yamlFile), &yamlInput) + if err != nil { + return yamlInput, fmt.Errorf("can't unmarshal to yaml: %w", err) + } + + return yamlInput, nil +} + +func yamlFromArgs(args *Args) (types.YAMLInput, error) { + // Modified from https://github.com/estesp/manifest-tool/blob/main/v2/cmd/manifest-tool/push.go + srcImages := []types.ManifestEntry{} + + for _, platform := range args.Platforms { + osArchArr := strings.Split(platform, "/") + if len(osArchArr) != 2 && len(osArchArr) != 3 { + return types.YAMLInput{}, fmt.Errorf("platforms must be a string slice where one value is of the form 'os/arch': %w", errConfiguration) + } + variant := "" + os, arch := osArchArr[0], osArchArr[1] + if len(osArchArr) == 3 { + variant = osArchArr[2] + } + srcImages = append(srcImages, types.ManifestEntry{ + Image: strings.Replace(strings.Replace(strings.Replace(args.Template, "ARCH", arch, 1), "OS", os, 1), "VARIANT", variant, 1), + Platform: ocispec.Platform{ + OS: os, + Architecture: arch, + Variant: variant, + }, + }) + } + + return types.YAMLInput{ + Image: args.Target, + Tags: args.Tags, + Manifests: srcImages, + }, nil +} diff --git a/plugin/util.go b/plugin/util.go new file mode 100644 index 0000000..1851091 --- /dev/null +++ b/plugin/util.go @@ -0,0 +1,37 @@ +// Copyright (c) 2023, the Drone Plugins project authors. +// Please see the AUTHORS file for details. All rights reserved. +// Use of this source code is governed by an Apache 2.0 license that can be +// found in the LICENSE file. + +package plugin + +import ( + "encoding/base64" + "encoding/json" + "io" + "os" +) + +//nolint:errcheck +func writeCard(path string, card interface{}) { + data, _ := json.Marshal(card) + + switch { + case path == "/dev/stdout": + writeCardTo(os.Stdout, data) + case path == "/dev/stderr": + writeCardTo(os.Stderr, data) + case path != "": + os.WriteFile(path, data, 0o644) //nolint:gomnd,gosec + } +} + +//nolint:errcheck +func writeCardTo(out io.Writer, data []byte) { + encoded := base64.StdEncoding.EncodeToString(data) + + io.WriteString(out, "\u001B]1338;") + io.WriteString(out, encoded) + io.WriteString(out, "\u001B]0m") + io.WriteString(out, "\n") +} diff --git a/tagging/tagging.go b/tagging/tagging.go index 97dd4b6..18ccea6 100644 --- a/tagging/tagging.go +++ b/tagging/tagging.go @@ -26,7 +26,6 @@ func DefaultTags(ref string) []string { v := stripTagPrefix(ref) version, err := semver.NewVersion(v) - if err != nil { return []string{"latest"} } diff --git a/tagging/tagging_test.go b/tagging/tagging_test.go index 57bffbb..1139694 100644 --- a/tagging/tagging_test.go +++ b/tagging/tagging_test.go @@ -6,7 +6,7 @@ import ( ) func TestDefaultTags(t *testing.T) { - var tests = []struct { + tests := []struct { Before string After []string }{ @@ -102,7 +102,7 @@ func Test_stripHeadPrefix(t *testing.T) { } func Test_stripTagPrefix(t *testing.T) { - var tests = []struct { + tests := []struct { Before string After string }{