0
0
mirror of https://github.com/thegeeklab/wp-s3-action.git synced 2024-11-21 04:40:39 +00:00

refactor: initial commit after rewrite to woodpecker

This commit is contained in:
Robert Kaussow 2023-08-19 16:00:02 +02:00
parent 5b8ed49203
commit 2932153f5d
Signed by: xoxys
GPG Key ID: 4E692A2EAECC03C0
25 changed files with 517 additions and 702 deletions

View File

@ -2,7 +2,7 @@ style: github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/thegeeklab/drone-s3-sync
repository_url: https://github.com/thegeeklab/wp-s3-action
options:
commit_groups:
title_maps:

View File

@ -2,7 +2,7 @@ api
github
url
gh
drone-s3-sync
wp-s3-action
(s|S)3
cloudfront
Minio

View File

@ -1,297 +0,0 @@
---
kind: pipeline
name: test
platform:
os: linux
arch: amd64
steps:
- name: deps
image: golang:1.20
commands:
- make deps
volumes:
- name: godeps
path: /go
- name: lint
image: golang:1.20
commands:
- make lint
volumes:
- name: godeps
path: /go
- name: test
image: golang:1.20
commands:
- make test
volumes:
- name: godeps
path: /go
volumes:
- name: godeps
temp: {}
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
---
kind: pipeline
name: build-binaries
platform:
os: linux
arch: amd64
steps:
- name: build
image: techknowlogick/xgo:go-1.20.x
commands:
- ln -s /drone/src /source
- make release
- name: executable
image: alpine
commands:
- $(find dist/ -executable -type f -iname ${DRONE_REPO_NAME}-linux-amd64) --help
- name: changelog-generate
image: thegeeklab/git-chglog
commands:
- git fetch -tq
- git-chglog --no-color --no-emoji -o CHANGELOG.md ${DRONE_TAG:---next-tag unreleased unreleased}
- name: changelog-format
image: thegeeklab/alpine-tools
commands:
- prettier CHANGELOG.md
- prettier -w CHANGELOG.md
- name: publish
image: plugins/github-release
settings:
api_key:
from_secret: github_token
files:
- dist/*
note: CHANGELOG.md
overwrite: true
title: ${DRONE_TAG}
when:
ref:
- refs/tags/**
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- test
---
kind: pipeline
name: build-container
platform:
os: linux
arch: amd64
steps:
- name: dryrun
image: thegeeklab/drone-docker-buildx:23
settings:
dockerfile: Dockerfile.multiarch
dry_run: true
platforms:
- linux/amd64
- linux/arm64
- linux/arm/v7
- linux/arm/v6
provenance: false
repo: thegeeklab/${DRONE_REPO_NAME}
when:
ref:
- refs/pull/**
- name: publish-dockerhub
image: thegeeklab/drone-docker-buildx:23
settings:
auto_tag: true
dockerfile: Dockerfile.multiarch
password:
from_secret: docker_password
platforms:
- linux/amd64
- linux/arm64
- linux/arm/v7
- linux/arm/v6
provenance: false
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
- name: publish-quay
image: thegeeklab/drone-docker-buildx:23
settings:
auto_tag: true
dockerfile: Dockerfile.multiarch
password:
from_secret: quay_password
platforms:
- linux/amd64
- linux/arm64
- linux/arm/v7
- linux/arm/v6
provenance: false
registry: quay.io
repo: quay.io/thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: quay_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- test
---
kind: pipeline
name: docs
platform:
os: linux
arch: amd64
concurrency:
limit: 1
steps:
- name: markdownlint
image: thegeeklab/markdownlint-cli
commands:
- markdownlint 'docs/content/**/*.md' 'README.md' 'CONTRIBUTING.md'
- name: spellcheck
image: thegeeklab/alpine-tools
commands:
- spellchecker --files '_docs/**/*.md' 'README.md' 'CONTRIBUTING.md' -d .dictionary -p spell indefinite-article syntax-urls --no-suggestions
environment:
FORCE_COLOR: true
NPM_CONFIG_LOGLEVEL: error
- name: publish
image: thegeeklab/drone-git-action
settings:
action:
- pages
author_email: bot@thegeeklab.de
author_name: thegeeklab-bot
branch: docs
message: auto-update documentation
netrc_password:
from_secret: github_token
pages_directory: _docs/
when:
ref:
- refs/heads/main
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- build-binaries
- build-container
---
kind: pipeline
name: notifications
platform:
os: linux
arch: amd64
steps:
- name: pushrm-dockerhub
image: chko/docker-pushrm:1
environment:
DOCKER_PASS:
from_secret: docker_password
DOCKER_USER:
from_secret: docker_username
PUSHRM_FILE: README.md
PUSHRM_SHORT: Drone plugin to synchronize a directory with an S3 bucket
PUSHRM_TARGET: thegeeklab/${DRONE_REPO_NAME}
when:
status:
- success
- name: pushrm-quay
image: chko/docker-pushrm:1
environment:
APIKEY__QUAY_IO:
from_secret: quay_token
PUSHRM_FILE: README.md
PUSHRM_TARGET: quay.io/thegeeklab/${DRONE_REPO_NAME}
when:
status:
- success
- name: matrix
image: thegeeklab/drone-matrix
settings:
homeserver:
from_secret: matrix_homeserver
password:
from_secret: matrix_password
roomid:
from_secret: matrix_roomid
template: "Status: **{{ .Build.Status }}**<br/> Build: [{{ .Repo.Owner }}/{{ .Repo.Name }}]({{ .Build.Link }}){{ if .Build.Branch }} ({{ .Build.Branch }}){{ end }} by {{ .Commit.Author }}<br/> Message: {{ .Commit.Message.Title }}"
username:
from_secret: matrix_username
when:
status:
- success
- failure
trigger:
ref:
- refs/heads/main
- refs/tags/**
status:
- success
- failure
depends_on:
- docs
---
kind: signature
hmac: dfc2eb36a2e743dc5a698a1721eac2e1e2f2702e3c53dde73e44a297c0e40744
...

15
.github/settings.yml vendored
View File

@ -1,8 +1,8 @@
repository:
name: drone-s3-sync
description: Drone plugin to synchronize a directory with an S3 bucket
homepage: https://drone-plugin-index.geekdocs.de/plugins/drone-s3-sync
topics: drone, drone-plugin
name: wp-s3-action
description: Woodpecker CI plugin to perform S3 actions
homepage: https://wp-plugin-index.geekdocs.de/plugins/wp-s3-action
topics: woodpecker-ci, woodpecker, woodpecker-plugin
private: false
has_issues: true
@ -51,8 +51,11 @@ branches:
required_status_checks:
strict: false
contexts:
- continuous-integration/drone/pr
enforce_admins: true
- ci/woodpecker/pr/test
- ci/woodpecker/pr/build-binary
- ci/woodpecker/pr/build-container
- ci/woodpecker/pr/docs
enforce_admins: false
required_linear_history: true
restrictions: null
- name: docs

2
.gitignore vendored
View File

@ -1,6 +1,6 @@
/dist/
/release/
/drone-s3-sync*
/wp-s3-action*
coverage.out
CHANGELOG.md

View File

@ -94,4 +94,4 @@ run:
linters-settings:
gofumpt:
extra-rules: true
lang-version: "1.20"
lang-version: "1.21"

View File

@ -1,3 +1,2 @@
.drone.yml
*.tpl.md
LICENSE

View File

@ -0,0 +1,44 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
build:
image: docker.io/techknowlogick/xgo:go-1.21.x
commands:
- ln -s $(pwd) /source
- make release
executable:
image: docker.io/library/alpine
commands:
- $(find dist/ -executable -type f -iname ${CI_REPO_NAME}-linux-amd64) --help
changelog-generate:
image: quay.io/thegeeklab/git-chglog
commands:
- git fetch -tq
- git-chglog --no-color --no-emoji -o CHANGELOG.md ${CI_COMMIT_TAG:---next-tag unreleased unreleased}
changelog-format:
image: quay.io/thegeeklab/alpine-tools
commands:
- prettier CHANGELOG.md
- prettier -w CHANGELOG.md
publish-github:
image: docker.io/plugins/github-release
settings:
api_key:
from_secret: github_token
note: CHANGELOG.md
overwrite: true
title: ${CI_COMMIT_TAG}
when:
- event: [tag]
depends_on:
- test

View File

@ -0,0 +1,66 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
dryrun:
image: quay.io/thegeeklab/wp-docker-buildx
settings:
containerfile: Containerfile.multiarch
dry_run: true
platforms:
- linux/amd64
- linux/arm64
provenance: false
repo: ${CI_REPO}
when:
- event: [pull_request]
publish-dockerhub:
group: container
image: quay.io/thegeeklab/wp-docker-buildx
settings:
auto_tag: true
containerfile: Containerfile.multiarch
password:
from_secret: docker_password
platforms:
- linux/amd64
- linux/arm64
provenance: false
repo: ${CI_REPO}
username:
from_secret: docker_username
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
publish-quay:
group: container
image: quay.io/thegeeklab/wp-docker-buildx
settings:
auto_tag: true
containerfile: Containerfile.multiarch
password:
from_secret: quay_password
platforms:
- linux/amd64
- linux/arm64
provenance: false
registry: quay.io
repo: quay.io/${CI_REPO}
username:
from_secret: quay_username
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
depends_on:
- test

72
.woodpecker/docs.yml Normal file
View File

@ -0,0 +1,72 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
markdownlint:
image: quay.io/thegeeklab/markdownlint-cli
commands:
- markdownlint 'README.md' 'CONTRIBUTING.md'
spellcheck:
image: quay.io/thegeeklab/alpine-tools
commands:
- spellchecker --files '_docs/**/*.md' 'README.md' 'CONTRIBUTING.md' -d .dictionary -p spell indefinite-article syntax-urls --no-suggestions
environment:
FORCE_COLOR: "true"
NPM_CONFIG_LOGLEVEL: "error"
publish:
image: quay.io/thegeeklab/wp-git-action
settings:
action:
- pages
author_email: bot@thegeeklab.de
author_name: thegeeklab-bot
branch: docs
message: "[skip ci] auto-update documentation"
netrc_password:
from_secret: github_token
pages_directory: _docs/
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
pushrm-dockerhub:
image: docker.io/chko/docker-pushrm:1
secrets:
- source: docker_password
target: DOCKER_PASS
- source: docker_username
target: DOCKER_USER
environment:
PUSHRM_FILE: README.md
PUSHRM_SHORT: Woodpecker CI plugin to perform S3 actions
PUSHRM_TARGET: ${CI_REPO}
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
status: [success]
pushrm-quay:
image: docker.io/chko/docker-pushrm:1
secrets:
- source: quay_token
target: APIKEY__QUAY_IO
environment:
PUSHRM_FILE: README.md
PUSHRM_TARGET: quay.io/${CI_REPO}
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
status: [success]
depends_on:
- build-binary
- build-container

30
.woodpecker/notify.yml Normal file
View File

@ -0,0 +1,30 @@
---
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
runs_on: [success, failure]
steps:
matrix:
image: quay.io/thegeeklab/drone-matrix
settings:
homeserver:
from_secret: matrix_homeserver
password:
from_secret: matrix_password
roomid:
from_secret: matrix_roomid
template: >-
Status: **{{ .Build.Status }}**<br/>
Build: [{{ .Repo.Owner }}/{{ .Repo.Name }}]({{ .Build.Link }}){{ if .Build.Branch }} ({{ .Build.Branch }}){{ end }} by {{ .Commit.Author }}<br/>
Message: {{ .Commit.Message.Title }}
username:
from_secret: matrix_username
when:
- status: [success, failure]
depends_on:
- docs

22
.woodpecker/test.yml Normal file
View File

@ -0,0 +1,22 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
deps:
image: docker.io/library/golang:1.21
commands:
- make deps
lint:
image: docker.io/library/golang:1.21
commands:
- make lint
test:
image: docker.io/library/golang:1.21
commands:
- make test

View File

@ -1,4 +1,4 @@
FROM --platform=$BUILDPLATFORM golang:1.20@sha256:839ba88412b5d3e12d66ed4774a85fc6e6c644dce8074ab82c798e5db27d4a09 as build
FROM --platform=$BUILDPLATFORM golang:1.21 as build
ARG TARGETOS
ARG TARGETARCH
@ -12,10 +12,10 @@ FROM alpine:3.18@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4
LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.title="drone-s3-sync"
LABEL org.opencontainers.image.url="https://github.com/thegeeklab/drone-s3-sync"
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/drone-s3-sync"
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/drone-s3-sync"
LABEL org.opencontainers.image.title="wp-s3-action"
LABEL org.opencontainers.image.url="https://github.com/thegeeklab/wp-s3-action"
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/wp-s3-action"
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/wp-s3-action"
COPY --from=build /src/dist/drone-s3-sync /bin/drone-s3-sync
ENTRYPOINT ["/bin/drone-s3-sync"]
COPY --from=build /src/dist/wp-s3-action /bin/wp-s3-action
ENTRYPOINT ["/bin/wp-s3-action"]

View File

@ -3,7 +3,7 @@ GOFUMPT_PACKAGE_VERSION := v0.5.0
# renovate: datasource=github-releases depName=golangci/golangci-lint
GOLANGCI_LINT_PACKAGE_VERSION := v1.54.1
EXECUTABLE := drone-s3-sync
EXECUTABLE := wp-s3-action
DIST := dist
DIST_DIRS := $(DIST)
@ -19,7 +19,7 @@ GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(G
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
GENERATE ?=
XGO_VERSION := go-1.20.x
XGO_VERSION := go-1.21.x
XGO_TARGETS ?= linux/amd64,linux/arm-6,linux/arm-7,linux/arm64
TARGETOS ?= linux
@ -30,8 +30,8 @@ endif
TAGS ?= netgo,osusergo
ifndef VERSION
ifneq ($(DRONE_TAG),)
VERSION ?= $(subst v,,$(DRONE_TAG))
ifneq ($(CI_COMMIT_TAG),)
VERSION ?= $(subst v,,$(CI_COMMIT_TAG))
else
VERSION ?= $(shell git rev-parse --short HEAD)
endif

View File

@ -1,21 +1,21 @@
# drone-s3-sync
# wp-s3-action
Drone plugin to synchronize a directory with an S3 bucket
Woodpecker CI plugin to perform S3 actions
[![Build Status](https://img.shields.io/drone/build/thegeeklab/drone-s3-sync?logo=drone&server=https%3A%2F%2Fdrone.thegeeklab.de)](https://drone.thegeeklab.de/thegeeklab/drone-s3-sync)
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/drone-s3-sync)
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/drone-s3-sync)
[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/drone-s3-sync)](https://goreportcard.com/report/github.com/thegeeklab/drone-s3-sync)
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/drone-s3-sync)](https://github.com/thegeeklab/drone-s3-sync/graphs/contributors)
[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/drone-s3-sync)
[![License: MIT](https://img.shields.io/github/license/thegeeklab/drone-s3-sync)](https://github.com/thegeeklab/drone-s3-sync/blob/main/LICENSE)
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/wp-s3-action/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/wp-s3-action)
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/wp-s3-action)
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/wp-s3-action)
[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/wp-s3-action)](https://goreportcard.com/report/github.com/thegeeklab/wp-s3-action)
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/wp-s3-action)](https://github.com/thegeeklab/wp-s3-action/graphs/contributors)
[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/wp-s3-action)
[![License: MIT](https://img.shields.io/github/license/thegeeklab/wp-s3-action)](https://github.com/thegeeklab/wp-s3-action/blob/main/LICENSE)
Drone plugin to synchronize a directory with an S3 bucket. You can find the full documentation at [https://drone-plugin-index.geekdocs.de](https://drone-plugin-index.geekdocs.de/plugins/drone-s3-sync).
Woodpecker CI plugin to perform S3 actions. You can find the full documentation at [https://wp-plugin-index.geekdocs.de](https://wp-plugin-index.geekdocs.de/plugins/wp-s3-action).
## Contributors
Special thanks to all [contributors](https://github.com/thegeeklab/drone-s3-sync/graphs/contributors). If you would like to contribute, please see the [instructions](https://github.com/thegeeklab/drone-s3-sync/blob/main/CONTRIBUTING.md).
Special thanks to all [contributors](https://github.com/thegeeklab/wp-s3-action/graphs/contributors). If you would like to contribute, please see the [instructions](https://github.com/thegeeklab/wp-s3-action/blob/main/CONTRIBUTING.md).
## License
This project is licensed under the MIT License - see the [LICENSE](https://github.com/thegeeklab/drone-s3-sync/blob/main/LICENSE) file for details.
This project is licensed under the MIT License - see the [LICENSE](https://github.com/thegeeklab/wp-s3-action/blob/main/LICENSE) file for details.

View File

@ -1,15 +1,16 @@
---
title: drone-s3-sync
title: wp-s3-action
---
[![Build Status](https://img.shields.io/drone/build/thegeeklab/drone-s3-sync?logo=drone&server=https%3A%2F%2Fdrone.thegeeklab.de)](https://drone.thegeeklab.de/thegeeklab/drone-s3-sync)
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/drone-s3-sync)
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/drone-s3-sync)
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/drone-s3-sync)](https://github.com/thegeeklab/drone-s3-sync/graphs/contributors)
[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/drone-s3-sync)
[![License: MIT](https://img.shields.io/github/license/thegeeklab/drone-s3-sync)](https://github.com/thegeeklab/drone-s3-sync/blob/main/LICENSE)
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/wp-s3-action/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/wp-s3-action)
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/wp-s3-action)
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/wp-s3-action)
[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/wp-s3-action)](https://goreportcard.com/report/github.com/thegeeklab/wp-s3-action)
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/wp-s3-action)](https://github.com/thegeeklab/wp-s3-action/graphs/contributors)
[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/wp-s3-action)
[![License: MIT](https://img.shields.io/github/license/thegeeklab/wp-s3-action)](https://github.com/thegeeklab/wp-s3-action/blob/main/LICENSE)
Drone plugin to synchronize a directory with an S3 bucket.
Woodpecker CI plugin to perform S3 actions.
<!-- prettier-ignore-start -->
<!-- spellchecker-disable -->
@ -25,7 +26,7 @@ name: default
steps:
- name: sync
image: thegeeklab/drone-s3-sync
image: thegeeklab/wp-s3-action
settings:
access_key: a50d28f4dd477bc184fbd10b376de753
secret_key: bc5785d3ece6a9cdefa42eb99b58986f9095ff1c
@ -39,7 +40,7 @@ steps:
<!-- prettier-ignore-start -->
<!-- spellchecker-disable -->
{{< propertylist name=drone-s3-sync.data sort=name >}}
{{< propertylist name=wp-s3-action.data sort=name >}}
<!-- spellchecker-enable -->
<!-- prettier-ignore-end -->
@ -53,7 +54,7 @@ name: default
steps:
- name: sync
image: thegeeklab/drone-s3-sync
image: thegeeklab/wp-s3-action
settings:
access_key: a50d28f4dd477bc184fbd10b376de753
secret_key: bc5785d3ece6a9cdefa42eb99b58986f9095ff1c
@ -89,7 +90,7 @@ name: default
steps:
- name: sync
image: thegeeklab/drone-s3-sync
image: thegeeklab/wp-s3-action
settings:
endpoint: https://minio.example.com
access_key: a50d28f4dd477bc184fbd10b376de753
@ -105,18 +106,13 @@ steps:
Build the binary with the following command:
```Shell
export GOOS=linux
export GOARCH=amd64
export CGO_ENABLED=0
export GO111MODULE=on
make build
```
Build the Docker image with the following command:
Build the container image with the following command:
```Shell
docker build --file docker/Dockerfile.amd64 --tag thegeeklab/drone-s3-sync .
docker build --file Containerfile.multiarch --tag thegeeklab/wp-s3-action .
```
## Test
@ -126,7 +122,7 @@ docker run --rm \
-e PLUGIN_BUCKET=my_bucket \
-e AWS_ACCESS_KEY_ID=abc123 \
-e AWS_SECRET_ACCESS_KEY=xyc789 \
-v $(pwd):$(pwd) \
-w $(pwd) \
thegeeklab/drone-s3-sync
-v $(pwd):/build:z \
-w /build \
thegeeklab/wp-s3-action
```

View File

@ -1,104 +0,0 @@
package main
import (
"errors"
"fmt"
"os"
"github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"github.com/thegeeklab/drone-plugin-lib/v2/urfave"
"github.com/thegeeklab/drone-s3-sync/plugin"
"github.com/urfave/cli/v2"
)
//nolint:gochecknoglobals
var (
BuildVersion = "devel"
BuildDate = "00000000"
)
var ErrTypeAssertionFailed = errors.New("type assertion failed")
func main() {
settings := &plugin.Settings{}
if _, err := os.Stat("/run/drone/env"); err == nil {
_ = godotenv.Overload("/run/drone/env")
}
cli.VersionPrinter = func(c *cli.Context) {
fmt.Printf("%s version=%s date=%s\n", c.App.Name, c.App.Version, BuildDate)
}
app := &cli.App{
Name: "drone-s3-sync",
Usage: "synchronize a directory with an S3 bucket",
Version: BuildVersion,
Flags: append(settingsFlags(settings, urfave.FlagsPluginCategory), urfave.Flags()...),
Action: run(settings),
}
if err := app.Run(os.Args); err != nil {
logrus.Fatal(err)
}
}
func run(settings *plugin.Settings) cli.ActionFunc {
return func(ctx *cli.Context) error {
urfave.LoggingFromContext(ctx)
acl, ok := ctx.Generic("acl").(*StringMapFlag)
if !ok {
return fmt.Errorf("%w: failed to read acl input", ErrTypeAssertionFailed)
}
cacheControl, ok := ctx.Generic("cache-control").(*StringMapFlag)
if !ok {
return fmt.Errorf("%w: failed to read cache-control input", ErrTypeAssertionFailed)
}
contentType, ok := ctx.Generic("content-type").(*StringMapFlag)
if !ok {
return fmt.Errorf("%w: failed to read content-type input", ErrTypeAssertionFailed)
}
contentEncoding, ok := ctx.Generic("content-encoding").(*StringMapFlag)
if !ok {
return fmt.Errorf("%w: failed to read content-encoding input", ErrTypeAssertionFailed)
}
metadata, ok := ctx.Generic("metadata").(*DeepStringMapFlag)
if !ok {
return fmt.Errorf("%w: failed to read metadata input", ErrTypeAssertionFailed)
}
redirects, ok := ctx.Generic("redirects").(*MapFlag)
if !ok {
return fmt.Errorf("%w: failed to read redirects input", ErrTypeAssertionFailed)
}
settings.ACL = acl.Get()
settings.CacheControl = cacheControl.Get()
settings.ContentType = contentType.Get()
settings.ContentEncoding = contentEncoding.Get()
settings.Metadata = metadata.Get()
settings.Redirects = redirects.Get()
plugin := plugin.New(
*settings,
urfave.PipelineFromContext(ctx),
urfave.NetworkFromContext(ctx),
)
if err := plugin.Validate(); err != nil {
return fmt.Errorf("validation failed: %w", err)
}
if err := plugin.Execute(); err != nil {
return fmt.Errorf("execution failed: %w", err)
}
return nil
}
}

View File

@ -1,76 +0,0 @@
package main
import (
"encoding/json"
)
type DeepStringMapFlag struct {
parts map[string]map[string]string
}
func (d *DeepStringMapFlag) String() string {
return ""
}
func (d *DeepStringMapFlag) Get() map[string]map[string]string {
return d.parts
}
func (d *DeepStringMapFlag) Set(value string) error {
d.parts = map[string]map[string]string{}
err := json.Unmarshal([]byte(value), &d.parts)
if err != nil {
single := map[string]string{}
err := json.Unmarshal([]byte(value), &single)
if err != nil {
return err
}
d.parts["*"] = single
}
return nil
}
type StringMapFlag struct {
parts map[string]string
}
func (s *StringMapFlag) String() string {
return ""
}
func (s *StringMapFlag) Get() map[string]string {
return s.parts
}
func (s *StringMapFlag) Set(value string) error {
s.parts = map[string]string{}
err := json.Unmarshal([]byte(value), &s.parts)
if err != nil {
s.parts["*"] = value
}
return nil
}
type MapFlag struct {
parts map[string]string
}
func (m *MapFlag) String() string {
return ""
}
func (m *MapFlag) Get() map[string]string {
return m.parts
}
func (m *MapFlag) Set(value string) error {
m.parts = map[string]string{}
return json.Unmarshal([]byte(value), &m.parts)
}

View File

@ -1,7 +1,8 @@
package main
import (
"github.com/thegeeklab/drone-s3-sync/plugin"
"github.com/thegeeklab/wp-s3-action/plugin"
"github.com/urfave/cli/v2"
)
@ -81,42 +82,42 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
Name: "acl",
Usage: "access control list",
EnvVars: []string{"PLUGIN_ACL"},
Value: &StringMapFlag{},
Destination: &settings.ACL,
Category: category,
},
&cli.GenericFlag{
Name: "content-type",
Usage: "content-type settings for uploads",
EnvVars: []string{"PLUGIN_CONTENT_TYPE"},
Value: &StringMapFlag{},
Destination: &settings.ContentType,
Category: category,
},
&cli.GenericFlag{
Name: "content-encoding",
Usage: "content-encoding settings for uploads",
EnvVars: []string{"PLUGIN_CONTENT_ENCODING"},
Value: &StringMapFlag{},
Destination: &settings.ContentEncoding,
Category: category,
},
&cli.GenericFlag{
Name: "cache-control",
Usage: "cache-control settings for uploads",
EnvVars: []string{"PLUGIN_CACHE_CONTROL"},
Value: &StringMapFlag{},
Destination: &settings.CacheControl,
Category: category,
},
&cli.GenericFlag{
Name: "metadata",
Usage: "additional metadata for uploads",
EnvVars: []string{"PLUGIN_METADATA"},
Value: &DeepStringMapFlag{},
Destination: &settings.Metadata,
Category: category,
},
&cli.GenericFlag{
Name: "redirects",
Usage: "redirects to create",
EnvVars: []string{"PLUGIN_REDIRECTS"},
Value: &MapFlag{},
Destination: &settings.Redirects,
Category: category,
},
&cli.StringFlag{

28
cmd/wp-s3-action/main.go Normal file
View File

@ -0,0 +1,28 @@
package main
import (
"fmt"
"github.com/thegeeklab/wp-s3-action/plugin"
wp "github.com/thegeeklab/wp-plugin-go/plugin"
)
//nolint:gochecknoglobals
var (
BuildVersion = "devel"
BuildDate = "00000000"
)
func main() {
settings := &plugin.Settings{}
options := wp.Options{
Name: "wp-s3-action",
Description: "Perform S3 actions",
Version: BuildVersion,
VersionMetadata: fmt.Sprintf("date=%s", BuildDate),
Flags: settingsFlags(settings, wp.FlagsPluginCategory),
}
plugin.New(options, settings).Run()
}

16
go.mod
View File

@ -1,20 +1,24 @@
module github.com/thegeeklab/drone-s3-sync
module github.com/thegeeklab/wp-s3-action
go 1.20
go 1.21
require (
github.com/aws/aws-sdk-go v1.44.302
github.com/joho/godotenv v1.5.1
github.com/rs/zerolog v1.30.0
github.com/ryanuber/go-glob v1.0.0
github.com/sirupsen/logrus v1.9.3
github.com/thegeeklab/drone-plugin-lib/v2 v2.3.4
github.com/thegeeklab/wp-plugin-go v0.4.0
github.com/urfave/cli/v2 v2.25.7
)
require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/sys v0.2.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.11.0 // indirect
)

31
go.sum
View File

@ -1,30 +1,35 @@
github.com/aws/aws-sdk-go v1.44.302 h1:ST3ko6GrJKn3Xi+nAvxjG3uk/V1pW8KC52WLeIxqqNk=
github.com/aws/aws-sdk-go v1.44.302/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
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/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c=
github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w=
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/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/thegeeklab/drone-plugin-lib/v2 v2.3.4 h1:Quzrike/xRAR0izxQ0d+ocJyIUm4h1497Oyo9grcRzg=
github.com/thegeeklab/drone-plugin-lib/v2 v2.3.4/go.mod h1:qWVUZCmwL0Ntwa/hvyqM03EeIr1ReBR2XJsmIc7MGus=
github.com/thegeeklab/wp-plugin-go v0.4.0 h1:eTkRH04gAAsYgCUekk8RBmPrIXk+UG+EJtRkoUFllLs=
github.com/thegeeklab/wp-plugin-go v0.4.0/go.mod h1:y0k5zaKWjdGbgkaOHhEPFEL6p+yOLOjqHy0LWOrv0MM=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
@ -36,27 +41,29 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@ -64,5 +71,3 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -18,8 +18,8 @@ import (
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudfront"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/rs/zerolog/log"
"github.com/ryanuber/go-glob"
"github.com/sirupsen/logrus"
)
type AWS struct {
@ -32,18 +32,18 @@ type AWS struct {
func NewAWS(plugin *Plugin) AWS {
sessCfg := &aws.Config{
S3ForcePathStyle: aws.Bool(plugin.settings.PathStyle),
Region: aws.String(plugin.settings.Region),
S3ForcePathStyle: aws.Bool(plugin.Settings.PathStyle),
Region: aws.String(plugin.Settings.Region),
}
if plugin.settings.Endpoint != "" {
sessCfg.Endpoint = &plugin.settings.Endpoint
sessCfg.DisableSSL = aws.Bool(strings.HasPrefix(plugin.settings.Endpoint, "http://"))
if plugin.Settings.Endpoint != "" {
sessCfg.Endpoint = &plugin.Settings.Endpoint
sessCfg.DisableSSL = aws.Bool(strings.HasPrefix(plugin.Settings.Endpoint, "http://"))
}
// allowing to use the instance role or provide a key and secret
if plugin.settings.AccessKey != "" && plugin.settings.SecretKey != "" {
sessCfg.Credentials = credentials.NewStaticCredentials(plugin.settings.AccessKey, plugin.settings.SecretKey, "")
if plugin.Settings.AccessKey != "" && plugin.Settings.SecretKey != "" {
sessCfg.Credentials = credentials.NewStaticCredentials(plugin.Settings.AccessKey, plugin.Settings.SecretKey, "")
}
sess, _ := session.NewSession(sessCfg)
@ -73,9 +73,9 @@ func (a *AWS) Upload(local, remote string) error {
var acl string
for pattern := range plugin.settings.ACL {
for pattern := range plugin.Settings.ACL.Get() {
if match := glob.Glob(pattern, local); match {
acl = plugin.settings.ACL[pattern]
acl = plugin.Settings.ACL.Get()[pattern]
break
}
@ -89,9 +89,9 @@ func (a *AWS) Upload(local, remote string) error {
var contentType string
for patternExt := range plugin.settings.ContentType {
for patternExt := range plugin.Settings.ContentType.Get() {
if patternExt == fileExt {
contentType = plugin.settings.ContentType[patternExt]
contentType = plugin.Settings.ContentType.Get()[patternExt]
break
}
@ -103,9 +103,9 @@ func (a *AWS) Upload(local, remote string) error {
var contentEncoding string
for patternExt := range plugin.settings.ContentEncoding {
for patternExt := range plugin.Settings.ContentEncoding.Get() {
if patternExt == fileExt {
contentEncoding = plugin.settings.ContentEncoding[patternExt]
contentEncoding = plugin.Settings.ContentEncoding.Get()[patternExt]
break
}
@ -113,9 +113,9 @@ func (a *AWS) Upload(local, remote string) error {
var cacheControl string
for pattern := range plugin.settings.CacheControl {
for pattern := range plugin.Settings.CacheControl.Get() {
if match := glob.Glob(pattern, local); match {
cacheControl = plugin.settings.CacheControl[pattern]
cacheControl = plugin.Settings.CacheControl.Get()[pattern]
break
}
@ -123,9 +123,9 @@ func (a *AWS) Upload(local, remote string) error {
metadata := map[string]*string{}
for pattern := range plugin.settings.Metadata {
for pattern := range plugin.Settings.Metadata.Get() {
if match := glob.Glob(pattern, local); match {
for k, v := range plugin.settings.Metadata[pattern] {
for k, v := range plugin.Settings.Metadata.Get()[pattern] {
metadata[k] = aws.String(v)
}
@ -136,7 +136,7 @@ func (a *AWS) Upload(local, remote string) error {
var AWSErr awserr.Error
head, err := a.client.HeadObject(&s3.HeadObjectInput{
Bucket: aws.String(plugin.settings.Bucket),
Bucket: aws.String(plugin.Settings.Bucket),
Key: aws.String(remote),
})
if err != nil && errors.As(err, &AWSErr) {
@ -145,7 +145,7 @@ func (a *AWS) Upload(local, remote string) error {
return err
}
logrus.Debugf(
log.Debug().Msgf(
"'%s' not found in bucket, uploading with content-type '%s' and permissions '%s'",
local,
contentType,
@ -153,7 +153,7 @@ func (a *AWS) Upload(local, remote string) error {
)
putObject := &s3.PutObjectInput{
Bucket: aws.String(plugin.settings.Bucket),
Bucket: aws.String(plugin.Settings.Bucket),
Key: aws.String(remote),
Body: file,
ContentType: aws.String(contentType),
@ -170,7 +170,7 @@ func (a *AWS) Upload(local, remote string) error {
}
// skip upload during dry run
if a.plugin.settings.DryRun {
if a.plugin.Settings.DryRun {
return nil
}
@ -189,43 +189,43 @@ func (a *AWS) Upload(local, remote string) error {
shouldCopy := false
if head.ContentType == nil && contentType != "" {
logrus.Debugf("content-type has changed from unset to %s", contentType)
log.Debug().Msgf("content-type has changed from unset to %s", contentType)
shouldCopy = true
}
if !shouldCopy && head.ContentType != nil && contentType != *head.ContentType {
logrus.Debugf("content-type has changed from %s to %s", *head.ContentType, contentType)
log.Debug().Msgf("content-type has changed from %s to %s", *head.ContentType, contentType)
shouldCopy = true
}
if !shouldCopy && head.ContentEncoding == nil && contentEncoding != "" {
logrus.Debugf("Content-Encoding has changed from unset to %s", contentEncoding)
log.Debug().Msgf("Content-Encoding has changed from unset to %s", contentEncoding)
shouldCopy = true
}
if !shouldCopy && head.ContentEncoding != nil && contentEncoding != *head.ContentEncoding {
logrus.Debugf("Content-Encoding has changed from %s to %s", *head.ContentEncoding, contentEncoding)
log.Debug().Msgf("Content-Encoding has changed from %s to %s", *head.ContentEncoding, contentEncoding)
shouldCopy = true
}
if !shouldCopy && head.CacheControl == nil && cacheControl != "" {
logrus.Debugf("cache-control has changed from unset to %s", cacheControl)
log.Debug().Msgf("cache-control has changed from unset to %s", cacheControl)
shouldCopy = true
}
if !shouldCopy && head.CacheControl != nil && cacheControl != *head.CacheControl {
logrus.Debugf("cache-control has changed from %s to %s", *head.CacheControl, cacheControl)
log.Debug().Msgf("cache-control has changed from %s to %s", *head.CacheControl, cacheControl)
shouldCopy = true
}
if !shouldCopy && len(head.Metadata) != len(metadata) {
logrus.Debugf("count of metadata values has changed for %s", local)
log.Debug().Msgf("count of metadata values has changed for %s", local)
shouldCopy = true
}
@ -234,7 +234,7 @@ func (a *AWS) Upload(local, remote string) error {
for k, v := range metadata {
if hv, ok := head.Metadata[k]; ok {
if *v != *hv {
logrus.Debugf("metadata values have changed for %s", local)
log.Debug().Msgf("metadata values have changed for %s", local)
shouldCopy = true
@ -246,7 +246,7 @@ func (a *AWS) Upload(local, remote string) error {
if !shouldCopy {
grant, err := a.client.GetObjectAcl(&s3.GetObjectAclInput{
Bucket: aws.String(plugin.settings.Bucket),
Bucket: aws.String(plugin.Settings.Bucket),
Key: aws.String(remote),
})
if err != nil {
@ -275,24 +275,24 @@ func (a *AWS) Upload(local, remote string) error {
}
if previousACL != acl {
logrus.Debugf("permissions for '%s' have changed from '%s' to '%s'", remote, previousACL, acl)
log.Debug().Msgf("permissions for '%s' have changed from '%s' to '%s'", remote, previousACL, acl)
shouldCopy = true
}
}
if !shouldCopy {
logrus.Debugf("skipping '%s' because hashes and metadata match", local)
log.Debug().Msgf("skipping '%s' because hashes and metadata match", local)
return nil
}
logrus.Debugf("updating metadata for '%s' content-type: '%s', ACL: '%s'", local, contentType, acl)
log.Debug().Msgf("updating metadata for '%s' content-type: '%s', ACL: '%s'", local, contentType, acl)
copyObject := &s3.CopyObjectInput{
Bucket: aws.String(plugin.settings.Bucket),
Bucket: aws.String(plugin.Settings.Bucket),
Key: aws.String(remote),
CopySource: aws.String(fmt.Sprintf("%s/%s", plugin.settings.Bucket, remote)),
CopySource: aws.String(fmt.Sprintf("%s/%s", plugin.Settings.Bucket, remote)),
ACL: aws.String(acl),
ContentType: aws.String(contentType),
Metadata: metadata,
@ -308,7 +308,7 @@ func (a *AWS) Upload(local, remote string) error {
}
// skip update if dry run
if a.plugin.settings.DryRun {
if a.plugin.Settings.DryRun {
return nil
}
@ -322,10 +322,10 @@ func (a *AWS) Upload(local, remote string) error {
return err
}
logrus.Debugf("uploading '%s' with content-type '%s' and permissions '%s'", local, contentType, acl)
log.Debug().Msgf("uploading '%s' with content-type '%s' and permissions '%s'", local, contentType, acl)
putObject := &s3.PutObjectInput{
Bucket: aws.String(plugin.settings.Bucket),
Bucket: aws.String(plugin.Settings.Bucket),
Key: aws.String(remote),
Body: file,
ContentType: aws.String(contentType),
@ -342,7 +342,7 @@ func (a *AWS) Upload(local, remote string) error {
}
// skip upload if dry run
if a.plugin.settings.DryRun {
if a.plugin.Settings.DryRun {
return nil
}
@ -354,14 +354,14 @@ func (a *AWS) Upload(local, remote string) error {
func (a *AWS) Redirect(path, location string) error {
plugin := a.plugin
logrus.Debugf("adding redirect from '%s' to '%s'", path, location)
log.Debug().Msgf("adding redirect from '%s' to '%s'", path, location)
if a.plugin.settings.DryRun {
if a.plugin.Settings.DryRun {
return nil
}
_, err := a.client.PutObject(&s3.PutObjectInput{
Bucket: aws.String(plugin.settings.Bucket),
Bucket: aws.String(plugin.Settings.Bucket),
Key: aws.String(path),
ACL: aws.String("public-read"),
WebsiteRedirectLocation: aws.String(location),
@ -373,14 +373,14 @@ func (a *AWS) Redirect(path, location string) error {
func (a *AWS) Delete(remote string) error {
plugin := a.plugin
logrus.Debugf("removing remote file '%s'", remote)
log.Debug().Msgf("removing remote file '%s'", remote)
if a.plugin.settings.DryRun {
if a.plugin.Settings.DryRun {
return nil
}
_, err := a.client.DeleteObject(&s3.DeleteObjectInput{
Bucket: aws.String(plugin.settings.Bucket),
Bucket: aws.String(plugin.Settings.Bucket),
Key: aws.String(remote),
})
@ -393,7 +393,7 @@ func (a *AWS) List(path string) ([]string, error) {
remote := make([]string, 0)
resp, err := a.client.ListObjects(&s3.ListObjectsInput{
Bucket: aws.String(plugin.settings.Bucket),
Bucket: aws.String(plugin.Settings.Bucket),
Prefix: aws.String(path),
})
if err != nil {
@ -406,7 +406,7 @@ func (a *AWS) List(path string) ([]string, error) {
for *resp.IsTruncated {
resp, err = a.client.ListObjects(&s3.ListObjectsInput{
Bucket: aws.String(plugin.settings.Bucket),
Bucket: aws.String(plugin.Settings.Bucket),
Prefix: aws.String(path),
Marker: aws.String(remote[len(remote)-1]),
})
@ -426,10 +426,10 @@ func (a *AWS) List(path string) ([]string, error) {
func (a *AWS) Invalidate(invalidatePath string) error {
p := a.plugin
logrus.Debugf("invalidating '%s'", invalidatePath)
log.Debug().Msgf("invalidating '%s'", invalidatePath)
_, err := a.cfClient.CreateInvalidation(&cloudfront.CreateInvalidationInput{
DistributionId: aws.String(p.settings.CloudFrontDistribution),
DistributionId: aws.String(p.Settings.CloudFrontDistribution),
InvalidationBatch: &cloudfront.InvalidationBatch{
CallerReference: aws.String(time.Now().Format(time.RFC3339Nano)),
Paths: &cloudfront.Paths{

View File

@ -1,47 +1,32 @@
package plugin
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/sirupsen/logrus"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
)
// Settings for the Plugin.
type Settings struct {
Endpoint string
AccessKey string
SecretKey string
Bucket string
Region string
Source string
Target string
Delete bool
ACL map[string]string
CacheControl map[string]string
ContentType map[string]string
ContentEncoding map[string]string
Metadata map[string]map[string]string
Redirects map[string]string
CloudFrontDistribution string
DryRun bool
PathStyle bool
Client AWS
Jobs []Job
MaxConcurrency int
var ErrTypeAssertionFailed = errors.New("type assertion failed")
// Execute provides the implementation of the plugin.
//
//nolint:revive
func (p *Plugin) run(ctx context.Context, cCtx *cli.Context) error {
if err := p.Validate(); err != nil {
return fmt.Errorf("validation failed: %w", err)
}
type Job struct {
local string
remote string
action string
if err := p.Execute(); err != nil {
return fmt.Errorf("execution failed: %w", err)
}
type Result struct {
j Job
err error
return nil
}
// Validate handles the settings validation of the plugin.
@ -51,25 +36,25 @@ func (p *Plugin) Validate() error {
return fmt.Errorf("error while retrieving working directory: %w", err)
}
p.settings.Source = filepath.Join(wd, p.settings.Source)
p.settings.Target = strings.TrimPrefix(p.settings.Target, "/")
p.Settings.Source = filepath.Join(wd, p.Settings.Source)
p.Settings.Target = strings.TrimPrefix(p.Settings.Target, "/")
return nil
}
// Execute provides the implementation of the plugin.
func (p *Plugin) Execute() error {
p.settings.Jobs = make([]Job, 1)
p.settings.Client = NewAWS(p)
p.Settings.Jobs = make([]Job, 1)
p.Settings.Client = NewAWS(p)
if err := p.createSyncJobs(); err != nil {
return fmt.Errorf("error while creating sync job: %w", err)
}
if len(p.settings.CloudFrontDistribution) > 0 {
p.settings.Jobs = append(p.settings.Jobs, Job{
if len(p.Settings.CloudFrontDistribution) > 0 {
p.Settings.Jobs = append(p.Settings.Jobs, Job{
local: "",
remote: filepath.Join("/", p.settings.Target, "*"),
remote: filepath.Join("/", p.Settings.Target, "*"),
action: "invalidateCloudFront",
})
}
@ -82,27 +67,27 @@ func (p *Plugin) Execute() error {
}
func (p *Plugin) createSyncJobs() error {
remote, err := p.settings.Client.List(p.settings.Target)
remote, err := p.Settings.Client.List(p.Settings.Target)
if err != nil {
return err
}
local := make([]string, 0)
err = filepath.Walk(p.settings.Source, func(path string, info os.FileInfo, err error) error {
err = filepath.Walk(p.Settings.Source, func(path string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() {
return err
}
localPath := path
if p.settings.Source != "." {
localPath = strings.TrimPrefix(path, p.settings.Source)
if p.Settings.Source != "." {
localPath = strings.TrimPrefix(path, p.Settings.Source)
localPath = strings.TrimPrefix(localPath, "/")
}
local = append(local, localPath)
p.settings.Jobs = append(p.settings.Jobs, Job{
local: filepath.Join(p.settings.Source, localPath),
remote: filepath.Join(p.settings.Target, localPath),
p.Settings.Jobs = append(p.Settings.Jobs, Job{
local: filepath.Join(p.Settings.Source, localPath),
remote: filepath.Join(p.Settings.Target, localPath),
action: "upload",
})
@ -112,20 +97,20 @@ func (p *Plugin) createSyncJobs() error {
return err
}
for path, location := range p.settings.Redirects {
for path, location := range p.Settings.Redirects.Get() {
path = strings.TrimPrefix(path, "/")
local = append(local, path)
p.settings.Jobs = append(p.settings.Jobs, Job{
p.Settings.Jobs = append(p.Settings.Jobs, Job{
local: path,
remote: location,
action: "redirect",
})
}
if p.settings.Delete {
if p.Settings.Delete {
for _, remote := range remote {
found := false
remotePath := strings.TrimPrefix(remote, p.settings.Target+"/")
remotePath := strings.TrimPrefix(remote, p.Settings.Target+"/")
for _, l := range local {
if l == remotePath {
@ -136,7 +121,7 @@ func (p *Plugin) createSyncJobs() error {
}
if !found {
p.settings.Jobs = append(p.settings.Jobs, Job{
p.Settings.Jobs = append(p.Settings.Jobs, Job{
local: "",
remote: remote,
action: "delete",
@ -149,15 +134,15 @@ func (p *Plugin) createSyncJobs() error {
}
func (p *Plugin) runJobs() error {
client := p.settings.Client
jobChan := make(chan struct{}, p.settings.MaxConcurrency)
results := make(chan *Result, len(p.settings.Jobs))
client := p.Settings.Client
jobChan := make(chan struct{}, p.Settings.MaxConcurrency)
results := make(chan *Result, len(p.Settings.Jobs))
var invalidateJob *Job
logrus.Infof("Synchronizing with bucket '%s'", p.settings.Bucket)
log.Info().Msgf("Synchronizing with bucket '%s'", p.Settings.Bucket)
for _, job := range p.settings.Jobs {
for _, job := range p.Settings.Jobs {
jobChan <- struct{}{}
go func(job Job) {
@ -181,7 +166,7 @@ func (p *Plugin) runJobs() error {
}(job)
}
for range p.settings.Jobs {
for range p.Settings.Jobs {
r := <-results
if r.err != nil {
return fmt.Errorf("failed to %s %s to %s: %w", r.j.action, r.j.local, r.j.remote, r.err)

View File

@ -1,21 +1,58 @@
package plugin
import (
"github.com/thegeeklab/drone-plugin-lib/v2/drone"
wp "github.com/thegeeklab/wp-plugin-go/plugin"
"github.com/thegeeklab/wp-plugin-go/types"
)
// Plugin implements drone.Plugin to provide the plugin implementation.
// Plugin implements provide the plugin implementation.
type Plugin struct {
settings Settings
pipeline drone.Pipeline
network drone.Network
*wp.Plugin
Settings *Settings
}
// New initializes a plugin from the given Settings, Pipeline, and Network.
func New(settings Settings, pipeline drone.Pipeline, network drone.Network) *Plugin {
return &Plugin{
settings: settings,
pipeline: pipeline,
network: network,
// Settings for the Plugin.
type Settings struct {
Endpoint string
AccessKey string
SecretKey string
Bucket string
Region string
Source string
Target string
Delete bool
ACL types.StringMapFlag
CacheControl types.StringMapFlag
ContentType types.StringMapFlag
ContentEncoding types.StringMapFlag
Metadata types.DeepStringMapFlag
Redirects types.StringMapFlag
CloudFrontDistribution string
DryRun bool
PathStyle bool
Client AWS
Jobs []Job
MaxConcurrency int
}
type Job struct {
local string
remote string
action string
}
type Result struct {
j Job
err error
}
func New(options wp.Options, settings *Settings) *Plugin {
p := &Plugin{}
options.Execute = p.run
p.Plugin = wp.New(options)
p.Settings = settings
return p
}