├── action.yml ├── Dockerfile ├── LICENSE.md ├── entrypoint.sh └── README.md /action.yml: -------------------------------------------------------------------------------- 1 | name: "S3 Sync" 2 | description: "Sync a directory to an AWS S3 repository" 3 | author: jakejarvis 4 | runs: 5 | using: docker 6 | image: Dockerfile 7 | branding: 8 | icon: refresh-cw 9 | color: green 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-alpine 2 | 3 | LABEL "com.github.actions.name"="S3 Sync" 4 | LABEL "com.github.actions.description"="Sync a directory to an AWS S3 repository" 5 | LABEL "com.github.actions.icon"="refresh-cw" 6 | LABEL "com.github.actions.color"="green" 7 | 8 | LABEL version="0.5.1" 9 | LABEL repository="https://github.com/jakejarvis/s3-sync-action" 10 | LABEL homepage="https://jarv.is/" 11 | LABEL maintainer="Jake Jarvis " 12 | 13 | # https://github.com/aws/aws-cli/blob/master/CHANGELOG.rst 14 | ENV AWSCLI_VERSION='1.18.14' 15 | 16 | RUN pip install --quiet --no-cache-dir awscli==${AWSCLI_VERSION} 17 | 18 | ADD entrypoint.sh /entrypoint.sh 19 | ENTRYPOINT ["/entrypoint.sh"] 20 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-present Jake Jarvis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -z "$AWS_S3_BUCKET" ]; then 6 | echo "AWS_S3_BUCKET is not set. Quitting." 7 | exit 1 8 | fi 9 | 10 | if [ -z "$AWS_ACCESS_KEY_ID" ]; then 11 | echo "AWS_ACCESS_KEY_ID is not set. Quitting." 12 | exit 1 13 | fi 14 | 15 | if [ -z "$AWS_SECRET_ACCESS_KEY" ]; then 16 | echo "AWS_SECRET_ACCESS_KEY is not set. Quitting." 17 | exit 1 18 | fi 19 | 20 | # Default to us-east-1 if AWS_REGION not set. 21 | if [ -z "$AWS_REGION" ]; then 22 | AWS_REGION="us-east-1" 23 | fi 24 | 25 | # Override default AWS endpoint if user sets AWS_S3_ENDPOINT. 26 | if [ -n "$AWS_S3_ENDPOINT" ]; then 27 | ENDPOINT_APPEND="--endpoint-url $AWS_S3_ENDPOINT" 28 | fi 29 | 30 | # Create a dedicated profile for this action to avoid conflicts 31 | # with past/future actions. 32 | # https://github.com/jakejarvis/s3-sync-action/issues/1 33 | aws configure --profile s3-sync-action <<-EOF > /dev/null 2>&1 34 | ${AWS_ACCESS_KEY_ID} 35 | ${AWS_SECRET_ACCESS_KEY} 36 | ${AWS_REGION} 37 | text 38 | EOF 39 | 40 | # Sync using our dedicated profile and suppress verbose messages. 41 | # All other flags are optional via the `args:` directive. 42 | sh -c "aws s3 sync ${SOURCE_DIR:-.} s3://${AWS_S3_BUCKET}/${DEST_DIR} \ 43 | --profile s3-sync-action \ 44 | --no-progress \ 45 | ${ENDPOINT_APPEND} $*" 46 | 47 | # Clear out credentials after we're done. 48 | # We need to re-run `aws configure` with bogus input instead of 49 | # deleting ~/.aws in case there are other credentials living there. 50 | # https://forums.aws.amazon.com/thread.jspa?threadID=148833 51 | aws configure --profile s3-sync-action <<-EOF > /dev/null 2>&1 52 | null 53 | null 54 | null 55 | text 56 | EOF 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitHub Action to Sync S3 Bucket 🔄 2 | 3 | This simple action uses the [vanilla AWS CLI](https://docs.aws.amazon.com/cli/index.html) to sync a directory (either from your repository or generated during your workflow) with a remote S3 bucket. 4 | 5 | 6 | ## Usage 7 | 8 | ### `workflow.yml` Example 9 | 10 | Place in a `.yml` file such as this one in your `.github/workflows` folder. [Refer to the documentation on workflow YAML syntax here.](https://help.github.com/en/articles/workflow-syntax-for-github-actions) 11 | 12 | As of v0.3.0, all [`aws s3 sync` flags](https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html) are optional to allow for maximum customizability (that's a word, I promise) and must be provided by you via `args:`. 13 | 14 | #### The following example includes optimal defaults for a public static website: 15 | 16 | - `--acl public-read` makes your files publicly readable (make sure your [bucket settings are also set to public](https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteAccessPermissionsReqd.html)). 17 | - `--follow-symlinks` won't hurt and fixes some weird symbolic link problems that may come up. 18 | - Most importantly, `--delete` **permanently deletes** files in the S3 bucket that are **not** present in the latest version of your repository/build. 19 | - **Optional tip:** If you're uploading the root of your repository, adding `--exclude '.git/*'` prevents your `.git` folder from syncing, which would expose your source code history if your project is closed-source. (To exclude more than one pattern, you must have one `--exclude` flag per exclusion. The single quotes are also important!) 20 | 21 | ```yaml 22 | name: Upload Website 23 | 24 | on: 25 | push: 26 | branches: 27 | - master 28 | 29 | jobs: 30 | deploy: 31 | runs-on: ubuntu-latest 32 | steps: 33 | - uses: actions/checkout@master 34 | - uses: jakejarvis/s3-sync-action@master 35 | with: 36 | args: --acl public-read --follow-symlinks --delete 37 | env: 38 | AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} 39 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 40 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 41 | AWS_REGION: 'us-west-1' # optional: defaults to us-east-1 42 | SOURCE_DIR: 'public' # optional: defaults to entire repository 43 | ``` 44 | 45 | 46 | ### Configuration 47 | 48 | The following settings must be passed as environment variables as shown in the example. Sensitive information, especially `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`, should be [set as encrypted secrets](https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables) — otherwise, they'll be public to anyone browsing your repository's source code and CI logs. 49 | 50 | | Key | Value | Suggested Type | Required | Default | 51 | | ------------- | ------------- | ------------- | ------------- | ------------- | 52 | | `AWS_ACCESS_KEY_ID` | Your AWS Access Key. [More info here.](https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html) | `secret env` | **Yes** | N/A | 53 | | `AWS_SECRET_ACCESS_KEY` | Your AWS Secret Access Key. [More info here.](https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html) | `secret env` | **Yes** | N/A | 54 | | `AWS_S3_BUCKET` | The name of the bucket you're syncing to. For example, `jarv.is` or `my-app-releases`. | `secret env` | **Yes** | N/A | 55 | | `AWS_REGION` | The region where you created your bucket. Set to `us-east-1` by default. [Full list of regions here.](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions) | `env` | No | `us-east-1` | 56 | | `AWS_S3_ENDPOINT` | The endpoint URL of the bucket you're syncing to. Can be used for [VPC scenarios](https://aws.amazon.com/blogs/aws/new-vpc-endpoint-for-amazon-s3/) or for non-AWS services using the S3 API, like [DigitalOcean Spaces](https://www.digitalocean.com/community/tools/adapting-an-existing-aws-s3-application-to-digitalocean-spaces). | `env` | No | Automatic (`s3.amazonaws.com` or AWS's region-specific equivalent) | 57 | | `SOURCE_DIR` | The local directory (or file) you wish to sync/upload to S3. For example, `public`. Defaults to your entire repository. | `env` | No | `./` (root of cloned repository) | 58 | | `DEST_DIR` | The directory inside of the S3 bucket you wish to sync/upload to. For example, `my_project/assets`. Defaults to the root of the bucket. | `env` | No | `/` (root of bucket) | 59 | 60 | 61 | ## License 62 | 63 | This project is distributed under the [MIT license](LICENSE.md). 64 | --------------------------------------------------------------------------------