mirror of
https://github.com/thegeeklab/drone-s3-sync.git
synced 2024-11-16 02:50:40 +00:00
Compare commits
89 Commits
Author | SHA1 | Date | |
---|---|---|---|
dc9499494d | |||
|
5b8ed49203 | ||
|
1b81d9b309 | ||
|
ad0e5c20a7 | ||
|
6c3b703a75 | ||
|
9c4cd6f4d8 | ||
|
32fbf9a234 | ||
|
ae961b4cff | ||
|
0490fb3b83 | ||
|
6ff0115c36 | ||
|
29f45437b6 | ||
|
22a176322a | ||
|
50fb140f66 | ||
|
23e861b95f | ||
|
98a0e95bfe | ||
|
91abeb92c8 | ||
|
997a6a16b5 | ||
|
e2ec69973b | ||
|
32ac157677 | ||
|
5f06938198 | ||
|
7b855d26fd | ||
|
46f45b8494 | ||
|
97e5ae30e3 | ||
|
25fd54bbcb | ||
|
89e06548b5 | ||
|
ab492e5f01 | ||
|
0027757cc6 | ||
|
d93d5bf935 | ||
|
769df02e4e | ||
|
24be32e9b8 | ||
|
5cb382dc18 | ||
|
bc1574b319 | ||
|
1ae37a2627 | ||
|
37d3738266 | ||
|
115764f40a | ||
|
338ce66c98 | ||
|
26b6178a16 | ||
|
5c4da224c5 | ||
|
3bd9d1df75 | ||
|
5b4a0b74ee | ||
|
f39bb55202 | ||
|
cc8fed3fce | ||
|
cb03a3d203 | ||
236085b2f0 | |||
|
54b4ee8562 | ||
|
0940f4a5b5 | ||
|
189386db93 | ||
|
343b6e7234 | ||
|
122c6a8c64 | ||
|
8330677c1c | ||
|
4d88de0025 | ||
|
0b1f2de73a | ||
|
c5d7f1fb9d | ||
|
73b066bbc1 | ||
|
d8603a6354 | ||
|
88b40b546e | ||
|
3f6b05e178 | ||
|
fb067ec1a0 | ||
|
3755380e29 | ||
|
ce55cbda96 | ||
|
d744ce5174 | ||
|
c2efcd9335 | ||
|
2837e59a35 | ||
|
509f35ee9d | ||
|
4d4bf1db12 | ||
|
f607610f44 | ||
|
3406d0d903 | ||
|
e5f58105e6 | ||
|
f45f5f02c7 | ||
|
e597746c33 | ||
|
ebe1ce6eed | ||
|
c063220478 | ||
|
b745b8daec | ||
|
25b0714282 | ||
2234e5d8f7 | |||
|
d147fea1c4 | ||
|
559085f54c | ||
2aa7584420 | |||
|
b409f87689 | ||
|
c13939c820 | ||
d2730125d8 | |||
|
8f561ae1a0 | ||
|
2917bf9b57 | ||
|
4d98876594 | ||
|
a77ef85b99 | ||
|
b5e5d32d69 | ||
|
7b56fc2372 | ||
|
c706deee99 | ||
|
6cb88f2bba |
297
.drone.yml
297
.drone.yml
@ -1,297 +0,0 @@
|
||||
---
|
||||
kind: pipeline
|
||||
name: test
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: deps
|
||||
image: golang:1.19
|
||||
commands:
|
||||
- make deps
|
||||
volumes:
|
||||
- name: godeps
|
||||
path: /go
|
||||
|
||||
- name: lint
|
||||
image: golang:1.19
|
||||
commands:
|
||||
- make lint
|
||||
volumes:
|
||||
- name: godeps
|
||||
path: /go
|
||||
|
||||
- name: test
|
||||
image: golang:1.19
|
||||
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.19.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:20
|
||||
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:20
|
||||
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:20
|
||||
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 }}){{/if}} 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: 944cf1fa4e35a0f1a4634335ec63ed97dd0f9059d05311fd2211595a7f7626b7
|
||||
|
||||
...
|
106
.golangci.yml
106
.golangci.yml
@ -1,25 +1,91 @@
|
||||
linters:
|
||||
enable:
|
||||
- gosimple
|
||||
- deadcode
|
||||
- typecheck
|
||||
- govet
|
||||
- errcheck
|
||||
- staticcheck
|
||||
- unused
|
||||
- structcheck
|
||||
- varcheck
|
||||
- dupl
|
||||
- gofmt
|
||||
- misspell
|
||||
- gocritic
|
||||
- bidichk
|
||||
- ineffassign
|
||||
- revive
|
||||
- gofumpt
|
||||
- depguard
|
||||
enable-all: false
|
||||
disable-all: true
|
||||
enable:
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- typecheck
|
||||
- unused
|
||||
- asasalint
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- bodyclose
|
||||
- containedctx
|
||||
- contextcheck
|
||||
- decorder
|
||||
- dogsled
|
||||
- dupl
|
||||
- dupword
|
||||
- durationcheck
|
||||
- errchkjson
|
||||
- errname
|
||||
- errorlint
|
||||
- execinquery
|
||||
- exhaustive
|
||||
- exportloopref
|
||||
- forcetypeassert
|
||||
- ginkgolinter
|
||||
- gocheckcompilerdirectives
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- godot
|
||||
- godox
|
||||
- goerr113
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goheader
|
||||
- goimports
|
||||
- gomnd
|
||||
- gomoddirectives
|
||||
- gomodguard
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- grouper
|
||||
- importas
|
||||
- interfacebloat
|
||||
- ireturn
|
||||
- lll
|
||||
- loggercheck
|
||||
- maintidx
|
||||
- makezero
|
||||
- misspell
|
||||
- musttag
|
||||
- nakedret
|
||||
- nestif
|
||||
- nilerr
|
||||
- nilnil
|
||||
- nlreturn
|
||||
- noctx
|
||||
- nolintlint
|
||||
- nonamedreturns
|
||||
- nosprintfhostport
|
||||
- prealloc
|
||||
- predeclared
|
||||
- promlinter
|
||||
- reassign
|
||||
- revive
|
||||
# - rowserrcheck
|
||||
# - sqlclosecheck
|
||||
# - structcheck
|
||||
- stylecheck
|
||||
- tagliatelle
|
||||
- tenv
|
||||
- testableexamples
|
||||
- thelper
|
||||
- tparallel
|
||||
- unconvert
|
||||
- unparam
|
||||
- usestdlibvars
|
||||
# - wastedassign
|
||||
- whitespace
|
||||
- wsl
|
||||
fast: false
|
||||
|
||||
run:
|
||||
@ -28,4 +94,4 @@ run:
|
||||
linters-settings:
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
lang-version: "1.18"
|
||||
lang-version: "1.20"
|
||||
|
@ -3,7 +3,7 @@
|
||||
## Security
|
||||
|
||||
If you think you have found a **security issue**, please do not mention it in this repository.
|
||||
Instead, send an email to security@thegeeklab.de with as many details as possible so it can be handled confidential.
|
||||
Instead, send an email to `security@thegeeklab.de` with as many details as possible so it can be handled confidential.
|
||||
|
||||
## Bug Reports and Feature Requests
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM --platform=$BUILDPLATFORM golang:1.19@sha256:bb9811fad43a7d6fd2173248d8331b2dcf5ac9af20976b1937ecd214c5b8c383 as build
|
||||
FROM --platform=$BUILDPLATFORM golang:1.20@sha256:839ba88412b5d3e12d66ed4774a85fc6e6c644dce8074ab82c798e5db27d4a09 as build
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
@ -8,7 +8,7 @@ WORKDIR /src
|
||||
|
||||
RUN make build
|
||||
|
||||
FROM alpine:3.17@sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a
|
||||
FROM alpine:3.18@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a
|
||||
|
||||
LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>"
|
||||
LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>"
|
||||
|
6
Makefile
6
Makefile
@ -1,7 +1,7 @@
|
||||
# renovate: datasource=github-releases depName=mvdan/gofumpt
|
||||
GOFUMPT_PACKAGE_VERSION := v0.4.0
|
||||
GOFUMPT_PACKAGE_VERSION := v0.5.0
|
||||
# renovate: datasource=github-releases depName=golangci/golangci-lint
|
||||
GOLANGCI_LINT_PACKAGE_VERSION := v1.50.1
|
||||
GOLANGCI_LINT_PACKAGE_VERSION := v1.54.1
|
||||
|
||||
EXECUTABLE := drone-s3-sync
|
||||
|
||||
@ -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.19.x
|
||||
XGO_VERSION := go-1.20.x
|
||||
XGO_TARGETS ?= linux/amd64,linux/arm-6,linux/arm-7,linux/arm64
|
||||
|
||||
TARGETOS ?= linux
|
||||
|
@ -1,6 +1,6 @@
|
||||
# drone-s3-sync
|
||||
|
||||
Drone plugin to synchronize a directory with an S3 bucket
|
||||
DISCONTINUED: Drone plugin to synchronize a directory with an S3 bucket
|
||||
|
||||
[![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)
|
||||
@ -10,6 +10,8 @@ Drone plugin to synchronize a directory with an S3 bucket
|
||||
[![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)
|
||||
|
||||
> **DISCONTINUED:** As I don't use Drone CI anymore, this project is unmaintained. If you are interested in a free and open source CI system check out [Woodpecker CI](https://woodpecker-ci.org/).
|
||||
|
||||
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).
|
||||
|
||||
## Contributors
|
||||
|
@ -136,6 +136,7 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
|
||||
&cli.IntFlag{
|
||||
Name: "max-concurrency",
|
||||
Usage: "customize number concurrent files to process",
|
||||
//nolint:gomnd
|
||||
Value: 100,
|
||||
EnvVars: []string{"PLUGIN_MAX_CONCURRENCY"},
|
||||
Destination: &settings.MaxConcurrency,
|
||||
|
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
@ -11,11 +12,14 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var (
|
||||
BuildVersion = "devel"
|
||||
BuildDate = "00000000"
|
||||
)
|
||||
|
||||
var ErrTypeAssertionFailed = errors.New("type assertion failed")
|
||||
|
||||
func main() {
|
||||
settings := &plugin.Settings{}
|
||||
|
||||
@ -44,12 +48,42 @@ func run(settings *plugin.Settings) cli.ActionFunc {
|
||||
return func(ctx *cli.Context) error {
|
||||
urfave.LoggingFromContext(ctx)
|
||||
|
||||
settings.ACL = ctx.Generic("acl").(*StringMapFlag).Get()
|
||||
settings.CacheControl = ctx.Generic("cache-control").(*StringMapFlag).Get()
|
||||
settings.ContentType = ctx.Generic("content-type").(*StringMapFlag).Get()
|
||||
settings.ContentEncoding = ctx.Generic("content-encoding").(*StringMapFlag).Get()
|
||||
settings.Metadata = ctx.Generic("metadata").(*DeepStringMapFlag).Get()
|
||||
settings.Redirects = ctx.Generic("redirects").(*MapFlag).Get()
|
||||
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,
|
||||
|
@ -18,9 +18,11 @@ func (d *DeepStringMapFlag) Get() map[string]map[string]string {
|
||||
|
||||
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
|
||||
@ -46,10 +48,12 @@ func (s *StringMapFlag) Get() map[string]string {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -67,5 +71,6 @@ func (m *MapFlag) Get() map[string]string {
|
||||
|
||||
func (m *MapFlag) Set(value string) error {
|
||||
m.parts = map[string]string{}
|
||||
|
||||
return json.Unmarshal([]byte(value), &m.parts)
|
||||
}
|
||||
|
14
go.mod
14
go.mod
@ -1,14 +1,14 @@
|
||||
module github.com/thegeeklab/drone-s3-sync
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.44.180
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/aws/aws-sdk-go v1.44.302
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/ryanuber/go-glob v1.0.0
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/thegeeklab/drone-plugin-lib/v2 v2.2.1
|
||||
github.com/urfave/cli/v2 v2.23.7
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/thegeeklab/drone-plugin-lib/v2 v2.3.4
|
||||
github.com/urfave/cli/v2 v2.25.7
|
||||
)
|
||||
|
||||
require (
|
||||
@ -16,5 +16,5 @@ require (
|
||||
github.com/jmespath/go-jmespath v0.4.0 // 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.1.0 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
)
|
||||
|
23
go.sum
23
go.sum
@ -1,5 +1,5 @@
|
||||
github.com/aws/aws-sdk-go v1.44.180 h1:VLZuAHI9fa/3WME5JjpVjcPCNfpGHVMiHx8sLHWhMgI=
|
||||
github.com/aws/aws-sdk-go v1.44.180/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
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/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=
|
||||
@ -9,8 +9,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
||||
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.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
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=
|
||||
@ -18,15 +18,15 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
||||
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.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
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.2.1 h1:fta32M+y6aHG/BX+Kwxo9DQAcYpTyCBHn7sAm2qjfL0=
|
||||
github.com/thegeeklab/drone-plugin-lib/v2 v2.2.1/go.mod h1:Bu++VS6GXEWCHQdzR65dPsGtBGOMuqAQPiRVBaa+HrY=
|
||||
github.com/urfave/cli/v2 v2.23.7 h1:YHDQ46s3VghFHFf1DdF+Sh7H4RqhcM+t0TmZRJx4oJY=
|
||||
github.com/urfave/cli/v2 v2.23.7/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
|
||||
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/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=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
@ -46,8 +46,9 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
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 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||
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/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=
|
||||
|
140
plugin/aws.go
140
plugin/aws.go
@ -1,7 +1,9 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
//nolint:gosec
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
@ -28,20 +30,20 @@ type AWS struct {
|
||||
plugin *Plugin
|
||||
}
|
||||
|
||||
func NewAWS(p *Plugin) AWS {
|
||||
func NewAWS(plugin *Plugin) AWS {
|
||||
sessCfg := &aws.Config{
|
||||
S3ForcePathStyle: aws.Bool(p.settings.PathStyle),
|
||||
Region: aws.String(p.settings.Region),
|
||||
S3ForcePathStyle: aws.Bool(plugin.settings.PathStyle),
|
||||
Region: aws.String(plugin.settings.Region),
|
||||
}
|
||||
|
||||
if p.settings.Endpoint != "" {
|
||||
sessCfg.Endpoint = &p.settings.Endpoint
|
||||
sessCfg.DisableSSL = aws.Bool(strings.HasPrefix(p.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 p.settings.AccessKey != "" && p.settings.SecretKey != "" {
|
||||
sessCfg.Credentials = credentials.NewStaticCredentials(p.settings.AccessKey, p.settings.SecretKey, "")
|
||||
if plugin.settings.AccessKey != "" && plugin.settings.SecretKey != "" {
|
||||
sessCfg.Credentials = credentials.NewStaticCredentials(plugin.settings.AccessKey, plugin.settings.SecretKey, "")
|
||||
}
|
||||
|
||||
sess, _ := session.NewSession(sessCfg)
|
||||
@ -51,11 +53,13 @@ func NewAWS(p *Plugin) AWS {
|
||||
r := make([]string, 1)
|
||||
l := make([]string, 1)
|
||||
|
||||
return AWS{c, cf, r, l, p}
|
||||
return AWS{c, cf, r, l, plugin}
|
||||
}
|
||||
|
||||
//nolint:gocognit,gocyclo,maintidx
|
||||
func (a *AWS) Upload(local, remote string) error {
|
||||
p := a.plugin
|
||||
plugin := a.plugin
|
||||
|
||||
if local == "" {
|
||||
return nil
|
||||
}
|
||||
@ -68,9 +72,11 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
defer file.Close()
|
||||
|
||||
var acl string
|
||||
for pattern := range p.settings.ACL {
|
||||
|
||||
for pattern := range plugin.settings.ACL {
|
||||
if match := glob.Glob(pattern, local); match {
|
||||
acl = p.settings.ACL[pattern]
|
||||
acl = plugin.settings.ACL[pattern]
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -82,9 +88,11 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
fileExt := filepath.Ext(local)
|
||||
|
||||
var contentType string
|
||||
for patternExt := range p.settings.ContentType {
|
||||
|
||||
for patternExt := range plugin.settings.ContentType {
|
||||
if patternExt == fileExt {
|
||||
contentType = p.settings.ContentType[patternExt]
|
||||
contentType = plugin.settings.ContentType[patternExt]
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -94,43 +102,58 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
}
|
||||
|
||||
var contentEncoding string
|
||||
for patternExt := range p.settings.ContentEncoding {
|
||||
|
||||
for patternExt := range plugin.settings.ContentEncoding {
|
||||
if patternExt == fileExt {
|
||||
contentEncoding = p.settings.ContentEncoding[patternExt]
|
||||
contentEncoding = plugin.settings.ContentEncoding[patternExt]
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var cacheControl string
|
||||
for pattern := range p.settings.CacheControl {
|
||||
|
||||
for pattern := range plugin.settings.CacheControl {
|
||||
if match := glob.Glob(pattern, local); match {
|
||||
cacheControl = p.settings.CacheControl[pattern]
|
||||
cacheControl = plugin.settings.CacheControl[pattern]
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
metadata := map[string]*string{}
|
||||
for pattern := range p.settings.Metadata {
|
||||
|
||||
for pattern := range plugin.settings.Metadata {
|
||||
if match := glob.Glob(pattern, local); match {
|
||||
for k, v := range p.settings.Metadata[pattern] {
|
||||
for k, v := range plugin.settings.Metadata[pattern] {
|
||||
metadata[k] = aws.String(v)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var AWSErr awserr.Error
|
||||
|
||||
head, err := a.client.HeadObject(&s3.HeadObjectInput{
|
||||
Bucket: aws.String(p.settings.Bucket),
|
||||
Bucket: aws.String(plugin.settings.Bucket),
|
||||
Key: aws.String(remote),
|
||||
})
|
||||
if err != nil && err.(awserr.Error).Code() != "404" {
|
||||
if err != nil && errors.As(err, &AWSErr) {
|
||||
//nolint:errorlint,forcetypeassert
|
||||
if err.(awserr.Error).Code() == "404" {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debugf("'%s' not found in bucket, uploading with content-type '%s' and permissions '%s'", local, contentType, acl)
|
||||
logrus.Debugf(
|
||||
"'%s' not found in bucket, uploading with content-type '%s' and permissions '%s'",
|
||||
local,
|
||||
contentType,
|
||||
acl,
|
||||
)
|
||||
|
||||
putObject := &s3.PutObjectInput{
|
||||
Bucket: aws.String(p.settings.Bucket),
|
||||
Bucket: aws.String(plugin.settings.Bucket),
|
||||
Key: aws.String(remote),
|
||||
Body: file,
|
||||
ContentType: aws.String(contentType),
|
||||
@ -152,48 +175,58 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
}
|
||||
|
||||
_, err = a.client.PutObject(putObject)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
//nolint:gosec
|
||||
hash := md5.New()
|
||||
_, _ = io.Copy(hash, file)
|
||||
sum := fmt.Sprintf("'%x'", hash.Sum(nil))
|
||||
|
||||
//nolint:nestif
|
||||
if sum == *head.ETag {
|
||||
shouldCopy := false
|
||||
|
||||
if head.ContentType == nil && contentType != "" {
|
||||
logrus.Debugf("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)
|
||||
|
||||
shouldCopy = true
|
||||
}
|
||||
|
||||
if !shouldCopy && head.ContentEncoding == nil && contentEncoding != "" {
|
||||
logrus.Debugf("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)
|
||||
|
||||
shouldCopy = true
|
||||
}
|
||||
|
||||
if !shouldCopy && head.CacheControl == nil && cacheControl != "" {
|
||||
logrus.Debugf("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)
|
||||
|
||||
shouldCopy = true
|
||||
}
|
||||
|
||||
if !shouldCopy && len(head.Metadata) != len(metadata) {
|
||||
logrus.Debugf("count of metadata values has changed for %s", local)
|
||||
|
||||
shouldCopy = true
|
||||
}
|
||||
|
||||
@ -202,7 +235,9 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
if hv, ok := head.Metadata[k]; ok {
|
||||
if *v != *hv {
|
||||
logrus.Debugf("metadata values have changed for %s", local)
|
||||
|
||||
shouldCopy = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -211,7 +246,7 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
|
||||
if !shouldCopy {
|
||||
grant, err := a.client.GetObjectAcl(&s3.GetObjectAclInput{
|
||||
Bucket: aws.String(p.settings.Bucket),
|
||||
Bucket: aws.String(plugin.settings.Bucket),
|
||||
Key: aws.String(remote),
|
||||
})
|
||||
if err != nil {
|
||||
@ -219,18 +254,20 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
}
|
||||
|
||||
previousACL := "private"
|
||||
for _, g := range grant.Grants {
|
||||
gt := *g.Grantee
|
||||
if gt.URI != nil {
|
||||
if *gt.URI == "http://acs.amazonaws.com/groups/global/AllUsers" {
|
||||
if *g.Permission == "READ" {
|
||||
|
||||
for _, grant := range grant.Grants {
|
||||
grantee := *grant.Grantee
|
||||
if grantee.URI != nil {
|
||||
if *grantee.URI == "http://acs.amazonaws.com/groups/global/AllUsers" {
|
||||
if *grant.Permission == "READ" {
|
||||
previousACL = "public-read"
|
||||
} else if *g.Permission == "WRITE" {
|
||||
} else if *grant.Permission == "WRITE" {
|
||||
previousACL = "public-read-write"
|
||||
}
|
||||
}
|
||||
if *gt.URI == "http://acs.amazonaws.com/groups/global/AuthenticatedUsers" {
|
||||
if *g.Permission == "READ" {
|
||||
|
||||
if *grantee.URI == "http://acs.amazonaws.com/groups/global/AuthenticatedUsers" {
|
||||
if *grant.Permission == "READ" {
|
||||
previousACL = "authenticated-read"
|
||||
}
|
||||
}
|
||||
@ -239,20 +276,23 @@ 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)
|
||||
|
||||
shouldCopy = true
|
||||
}
|
||||
}
|
||||
|
||||
if !shouldCopy {
|
||||
logrus.Debugf("skipping '%s' because hashes and metadata match", local)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
logrus.Debugf("updating metadata for '%s' content-type: '%s', ACL: '%s'", local, contentType, acl)
|
||||
|
||||
copyObject := &s3.CopyObjectInput{
|
||||
Bucket: aws.String(p.settings.Bucket),
|
||||
Bucket: aws.String(plugin.settings.Bucket),
|
||||
Key: aws.String(remote),
|
||||
CopySource: aws.String(fmt.Sprintf("%s/%s", p.settings.Bucket, remote)),
|
||||
CopySource: aws.String(fmt.Sprintf("%s/%s", plugin.settings.Bucket, remote)),
|
||||
ACL: aws.String(acl),
|
||||
ContentType: aws.String(contentType),
|
||||
Metadata: metadata,
|
||||
@ -273,6 +313,7 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
}
|
||||
|
||||
_, err = a.client.CopyObject(copyObject)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -282,8 +323,9 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
}
|
||||
|
||||
logrus.Debugf("uploading '%s' with content-type '%s' and permissions '%s'", local, contentType, acl)
|
||||
|
||||
putObject := &s3.PutObjectInput{
|
||||
Bucket: aws.String(p.settings.Bucket),
|
||||
Bucket: aws.String(plugin.settings.Bucket),
|
||||
Key: aws.String(remote),
|
||||
Body: file,
|
||||
ContentType: aws.String(contentType),
|
||||
@ -305,11 +347,13 @@ func (a *AWS) Upload(local, remote string) error {
|
||||
}
|
||||
|
||||
_, err = a.client.PutObject(putObject)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *AWS) Redirect(path, location string) error {
|
||||
p := a.plugin
|
||||
plugin := a.plugin
|
||||
|
||||
logrus.Debugf("adding redirect from '%s' to '%s'", path, location)
|
||||
|
||||
if a.plugin.settings.DryRun {
|
||||
@ -317,16 +361,18 @@ func (a *AWS) Redirect(path, location string) error {
|
||||
}
|
||||
|
||||
_, err := a.client.PutObject(&s3.PutObjectInput{
|
||||
Bucket: aws.String(p.settings.Bucket),
|
||||
Bucket: aws.String(plugin.settings.Bucket),
|
||||
Key: aws.String(path),
|
||||
ACL: aws.String("public-read"),
|
||||
WebsiteRedirectLocation: aws.String(location),
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *AWS) Delete(remote string) error {
|
||||
p := a.plugin
|
||||
plugin := a.plugin
|
||||
|
||||
logrus.Debugf("removing remote file '%s'", remote)
|
||||
|
||||
if a.plugin.settings.DryRun {
|
||||
@ -334,17 +380,20 @@ func (a *AWS) Delete(remote string) error {
|
||||
}
|
||||
|
||||
_, err := a.client.DeleteObject(&s3.DeleteObjectInput{
|
||||
Bucket: aws.String(p.settings.Bucket),
|
||||
Bucket: aws.String(plugin.settings.Bucket),
|
||||
Key: aws.String(remote),
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *AWS) List(path string) ([]string, error) {
|
||||
p := a.plugin
|
||||
remote := make([]string, 1)
|
||||
plugin := a.plugin
|
||||
|
||||
remote := make([]string, 0)
|
||||
|
||||
resp, err := a.client.ListObjects(&s3.ListObjectsInput{
|
||||
Bucket: aws.String(p.settings.Bucket),
|
||||
Bucket: aws.String(plugin.settings.Bucket),
|
||||
Prefix: aws.String(path),
|
||||
})
|
||||
if err != nil {
|
||||
@ -357,7 +406,7 @@ func (a *AWS) List(path string) ([]string, error) {
|
||||
|
||||
for *resp.IsTruncated {
|
||||
resp, err = a.client.ListObjects(&s3.ListObjectsInput{
|
||||
Bucket: aws.String(p.settings.Bucket),
|
||||
Bucket: aws.String(plugin.settings.Bucket),
|
||||
Prefix: aws.String(path),
|
||||
Marker: aws.String(remote[len(remote)-1]),
|
||||
})
|
||||
@ -376,7 +425,9 @@ func (a *AWS) List(path string) ([]string, error) {
|
||||
|
||||
func (a *AWS) Invalidate(invalidatePath string) error {
|
||||
p := a.plugin
|
||||
|
||||
logrus.Debugf("invalidating '%s'", invalidatePath)
|
||||
|
||||
_, err := a.cfClient.CreateInvalidation(&cloudfront.CreateInvalidationInput{
|
||||
DistributionId: aws.String(p.settings.CloudFrontDistribution),
|
||||
InvalidationBatch: &cloudfront.InvalidationBatch{
|
||||
@ -389,5 +440,6 @@ func (a *AWS) Invalidate(invalidatePath string) error {
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -44,14 +44,13 @@ type Result struct {
|
||||
err error
|
||||
}
|
||||
|
||||
var MissingAwsValuesMessage = "Must set 'bucket'"
|
||||
|
||||
// Validate handles the settings validation of the plugin.
|
||||
func (p *Plugin) Validate() error {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
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, "/")
|
||||
|
||||
@ -88,7 +87,7 @@ func (p *Plugin) createSyncJobs() error {
|
||||
return err
|
||||
}
|
||||
|
||||
local := make([]string, 1)
|
||||
local := make([]string, 0)
|
||||
|
||||
err = filepath.Walk(p.settings.Source, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil || info.IsDir() {
|
||||
@ -122,13 +121,16 @@ func (p *Plugin) createSyncJobs() error {
|
||||
action: "redirect",
|
||||
})
|
||||
}
|
||||
|
||||
if p.settings.Delete {
|
||||
for _, r := range remote {
|
||||
for _, remote := range remote {
|
||||
found := false
|
||||
rPath := strings.TrimPrefix(r, p.settings.Target+"/")
|
||||
remotePath := strings.TrimPrefix(remote, p.settings.Target+"/")
|
||||
|
||||
for _, l := range local {
|
||||
if l == rPath {
|
||||
if l == remotePath {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -136,7 +138,7 @@ func (p *Plugin) createSyncJobs() error {
|
||||
if !found {
|
||||
p.settings.Jobs = append(p.settings.Jobs, Job{
|
||||
local: "",
|
||||
remote: r,
|
||||
remote: remote,
|
||||
action: "delete",
|
||||
})
|
||||
}
|
||||
@ -150,41 +152,46 @@ func (p *Plugin) runJobs() error {
|
||||
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)
|
||||
for _, j := range p.settings.Jobs {
|
||||
|
||||
for _, job := range p.settings.Jobs {
|
||||
jobChan <- struct{}{}
|
||||
go func(j Job) {
|
||||
|
||||
go func(job Job) {
|
||||
var err error
|
||||
switch j.action {
|
||||
|
||||
switch job.action {
|
||||
case "upload":
|
||||
err = client.Upload(j.local, j.remote)
|
||||
err = client.Upload(job.local, job.remote)
|
||||
case "redirect":
|
||||
err = client.Redirect(j.local, j.remote)
|
||||
err = client.Redirect(job.local, job.remote)
|
||||
case "delete":
|
||||
err = client.Delete(j.remote)
|
||||
err = client.Delete(job.remote)
|
||||
case "invalidateCloudFront":
|
||||
invalidateJob = &j
|
||||
invalidateJob = &job
|
||||
default:
|
||||
err = nil
|
||||
}
|
||||
results <- &Result{j, err}
|
||||
results <- &Result{job, err}
|
||||
|
||||
<-jobChan
|
||||
}(j)
|
||||
}(job)
|
||||
}
|
||||
|
||||
for range p.settings.Jobs {
|
||||
r := <-results
|
||||
if r.err != nil {
|
||||
return fmt.Errorf("failed to %s %s to %s: %+v", r.j.action, r.j.local, r.j.remote, r.err)
|
||||
return fmt.Errorf("failed to %s %s to %s: %w", r.j.action, r.j.local, r.j.remote, r.err)
|
||||
}
|
||||
}
|
||||
|
||||
if invalidateJob != nil {
|
||||
err := client.Invalidate(invalidateJob.remote)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to %s %s to %s: %+v", invalidateJob.action, invalidateJob.local, invalidateJob.remote, err)
|
||||
return fmt.Errorf("failed to %s %s to %s: %w", invalidateJob.action, invalidateJob.local, invalidateJob.remote, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ type Plugin struct {
|
||||
}
|
||||
|
||||
// New initializes a plugin from the given Settings, Pipeline, and Network.
|
||||
func New(settings Settings, pipeline drone.Pipeline, network drone.Network) drone.Plugin {
|
||||
func New(settings Settings, pipeline drone.Pipeline, network drone.Network) *Plugin {
|
||||
return &Plugin{
|
||||
settings: settings,
|
||||
pipeline: pipeline,
|
||||
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["github>thegeeklab/renovate-presets:golang"]
|
||||
}
|
Loading…
Reference in New Issue
Block a user