Giter VIP home page Giter VIP logo

s3-plugin's Introduction

S3 Gradle Plugin

Build Status Install MIT License Flux Cap

Gradle plugin that uploads and downloads S3 objects.

Setup

New way:

plugins {
    id "com.github.mgk.gradle.s3" version "1.6.0"
}

Old way:

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "gradle.plugin.com.github.mgk.gradle:s3:1.6.0"
    }
}

apply plugin: "com.github.mgk.gradle.s3"

Versioning

This project uses semantic versioning

See gradle plugin page for other versions.

Usage

Authentication

The S3 plugin searches for credentials in the same order as the AWS default credentials provider chain. Additionally you can specify a credentials profile to use by setting the project s3.profile property:

s3 {
    profile = 'my-profile'
}

Setting the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY is one way to provide your S3 credentials. See the AWS Docs for details on credentials.

Tasks

The following Gradle tasks are provided. See the tests for examples.

S3Upload

Upload a file to S3. Properties:

  • bucket - S3 bucket to use (optional, defaults to the project s3 configured bucket)
  • file - path of file to be uploaded
  • key - key of S3 object to create.
  • overwrite - (optional, default is false), if true the S3 object is created or overwritten if it already exists.

By default S3Upload does not overwrite the S3 object if it already exists. Set overwrite to true to upload the file even if it exists.

S3Download

Downloads one or more S3 objects. This task has two modes of operation: single file download and recursive download. Properties that apply to both modes:

  • bucket - S3 bucket to use (optional, defaults to the project s3 configured bucket)

For a single file download:

  • key - key of S3 object to download
  • file - local path of file to save the download to

For a recursive download:

  • keyPrefix - S3 prefix of objects to download
  • destDir - local directory to download objects to

Nota Bene: recursive downloads create a sparse directory tree containing the full keyPrefix under destDir. So with an S3 bucket containing the object keys:

top/foo/bar
top/README

a recursive download:

task downloadRecursive(type: S3Download) {
  keyPrefix = "top/foo/"
  destDir = "local-dir"
}

results in this local tree:

local-dir/
└── foo
    └── bar

So only files under top/foo are downloaded, but their full S3 paths are appended to the destDir. This is different from the behavior of the aws cli aws s3 cp --recursive command which prunes the root of the downloaded objects. Use the flexible Gradle Copy task to prune the tree after downloading it. See example/build.gradle for an example.

Progress Reporting

Downloads report percentage progress at the gradle INFO level. Run gradle with the -i option to see download progress.

Development Notes

The example project pulls the build from Maven Local. Run ./gradlew publishToMavenLocal to deploy the plugin to the Maven Local repository. It also writes the current build to build/VERSION. The file example/build.gradle serves as tests and doc. The tests use the local build of the plugin.

The tests use a generated unique path in a test bucket to exercise all of the plugins features.

The test bucket has a AWS Object Expiration policy that removes objects older than one day automatically, so yay, no cleanup required.

The automated build uses an IAM access key that allows listBucket, getObject, and putObject on the test bucket only. The AWS credits configured as Travis environment variables. The access key id is not a secret so it is shown in the logs, while the secret access key is secret and not shown.

License

MIT License

s3-plugin's People

Contributors

deanrobertcook avatar kschults avatar luisgoncalves avatar mgk avatar peter-thomas avatar peter-thomas-mgd avatar sabdalla80 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

s3-plugin's Issues

Plugin does not appear to see all my project.s3 properties

I may very well have done something daft however, with my build.gradle (gradle 3.5), neither the region nor profile properties appear to be used by the plugin, bucket however is.

s3 {
  region = 'ap-southeast-2'
  profile = 'my-profile'
  bucket = 'myaccount-resources'
}

The profile property appears to be ignored, to get further I has to set the AWS environment variables.
Once that was done I then got the following error:

Unable to execute HTTP request: Connect to myaccount-resources.s3-us-west-1.amazonaws.com:443

So while it has picked up the bucket it has not used the region I defined.
So it seems that only bucket is readable by the plugin, profile and region appear to be ignored.

apache httpclient issue when used in a subproject

When this plugin is added as a buildscript dependency to a subproject and the the plugin is applied to that subproject, the following error occurs. It works if the buildscript dependency is added to the root project while still applying the plugin to the subproject.

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':aws-spring-boot-sample-rest:s3Upload'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
        at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: java.lang.NoSuchMethodError: org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>(Ljavax/net/ssl/SSLContext;Ljavax/net/ssl/HostnameVerifier;)V
        at com.amazonaws.http.conn.ssl.SdkTLSSocketFactory.<init>(SdkTLSSocketFactory.java:56)
        at com.amazonaws.http.apache.client.impl.ApacheConnectionManagerFactory.getPreferredSocketFactory(ApacheConnectionManagerFactory.java:91)
        at com.amazonaws.http.apache.client.impl.ApacheConnectionManagerFactory.create(ApacheConnectionManagerFactory.java:65)
        at com.amazonaws.http.apache.client.impl.ApacheConnectionManagerFactory.create(ApacheConnectionManagerFactory.java:58)
        at com.amazonaws.http.apache.client.impl.ApacheHttpClientFactory.create(ApacheHttpClientFactory.java:51)
        at com.amazonaws.http.apache.client.impl.ApacheHttpClientFactory.create(ApacheHttpClientFactory.java:39)
        at com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:319)
        at com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:303)
        at com.amazonaws.AmazonWebServiceClient.<init>(AmazonWebServiceClient.java:164)
        at com.amazonaws.services.s3.AmazonS3Client.<init>(AmazonS3Client.java:564)
        at com.amazonaws.services.s3.AmazonS3Client.<init>(AmazonS3Client.java:544)
        at com.amazonaws.services.s3.AmazonS3Client.<init>(AmazonS3Client.java:526)
        at com.amazonaws.services.s3.AmazonS3Client.<init>(AmazonS3Client.java:510)
        at com.github.mgk.gradle.S3Task.getS3Client(S3Plugin.groovy:54)
        at com.github.mgk.gradle.S3Upload_Decorated.getS3Client(Unknown Source)
        at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.getProperty(BeanDynamicObject.java:228)
        at org.gradle.internal.metaobject.BeanDynamicObject.tryGetProperty(BeanDynamicObject.java:171)
        at org.gradle.internal.metaobject.CompositeDynamicObject.tryGetProperty(CompositeDynamicObject.java:55)
        at org.gradle.internal.metaobject.AbstractDynamicObject.getProperty(AbstractDynamicObject.java:59)
        at com.github.mgk.gradle.S3Upload_Decorated.getProperty(Unknown Source)
        at com.github.mgk.gradle.S3Upload.task(S3Plugin.groovy:76)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:46)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:780)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:747)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
        ... 29 more

Missing Gradle task annotations on S3Download

We have been using this plugin for a few of our projects for several months and are quite happy with it. We recently upgraded to Gradle v6.0.1 and are now seeing these warnings in our projects:

Property 'destDir' is not annotated with an input or output annotation. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Property 'file' is not annotated with an input or output annotation. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Property 'key' is not annotated with an input or output annotation. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Property 'keyPrefix' is not annotated with an input or output annotation. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.
Property 's3Client' is not annotated with an input or output annotation. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.

It appears that the plugin is missing the appropriate @Input annotations on the properties defined for the S3Download class in the plugin (lines 93-97). They are present in the S3Upload class, but seem to have been missed here.

Is this something that can be fixed? Thanks!

How to compile this plugin to configure its tasks

I wanted to do something like this:
dependencies { compile 'com.github.mgk.gradle:s3:1.4.0' }

And import the tasks into my plugin to configure them from my .groovy files. I can do that with other plugins like this one: https://github.com/classmethod/gradle-aws-plugin/tree/develop/src/main/java/jp/classmethod/aws/gradle/s3

by doing:

compile "jp.classmethod.aws:gradle-aws-plugin:0.30"

With this plugin I just get "Couldn't resolve..". Is there a way to do this?

Support recursive download

The aws cli supports a --recursive flag on the cp task for getting all objects under a specified prefix and putting them into a directory. What would it take to support that functionality with this gradle plugin?

The maven repo address seems to be wrong

Trying to use this plugin, I get:

> Could not find gradle.plugin.com.github.mgk.gradle:s3:1.5.0.
                 Searched in the following locations:
                     https://plugins.gradle.org/m2/gradle/plugin/com/github/mgk/gradle/s3/1.5.0/s3-1.5.0.pom
                     https://plugins.gradle.org/m2/gradle/plugin/com/github/mgk/gradle/s3/1.5.0/s3-1.5.0.jar

Upgrade gradle from v3 -> v8

The project is using a very old gradle setup. In order to be published again it needs to use a more recent gradle config.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.