Skip to content

Commit

Permalink
Merge branch 'release/1.0.0-rc.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
msudgh committed Aug 19, 2024
2 parents a977d24 + be0aea6 commit 6d88be7
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 42 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
node: [18, 20]
os: ['ubuntu-latest']
node: [18, lts/*]
fail-fast: false
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: pnpm/[email protected]
with:
version: 8
Expand Down
56 changes: 31 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
[![Codecov Status](https://codecov.io/gh/msudgh/sync-cloud-storage/branch/main/graph/badge.svg?token=2BY6063VOY)](https://codecov.io/gh/msudgh/sync-cloud-storage)
[![License](https://img.shields.io/github/license/msudgh/sync-cloud-storage)](LICENSE)

Synchronize files and directories between a remote machine and a cloud storage via cloud frameworks and stacks consisting of [AWS SAM (Serverless)](https://www.serverless.com/) and [AWS Cloud Development Kit (CDK)](https://aws.amazon.com/cdk/). This package supports the following cloud storage providers: [AWS S3](https://aws.amazon.com/s3/).
sync-cloud-storage is a Node.js package designed to seamlessly synchronize files and directories between local environments and cloud storage providers like [AWS S3](https://aws.amazon.com/s3/). It leverages [AWS SAM (Serverless)](https://www.serverless.com/) and [AWS Cloud Development Kit (CDK)](https://aws.amazon.com/cdk/) for powerful, modern, and flexible integrations.

## Features

- Sync multiple storages at once and flexible file matching (single or multiple file/dir sync) by defining patterns of [`glob`](<https://en.wikipedia.org/wiki/Glob_(programming)>) to include or exclude
- Supports a set of options as following for each file based on storage: `Prefix`, `Access Control List (ACL)`, `Tags`, `Metadata`
- Select a list of specific sync actions for each storage: `uploading`, `deleting`
- Sync multiple storage at once
- Use pattern matching on finding files (single or multiple file/dir sync) by defining patterns of [`glob`](<https://en.wikipedia.org/wiki/Glob_(programming)>) to include or exclude
- Supports a set of options as following for each file based on storage features: `Prefix`, `Access Control List (ACL)`, `Tags`, `Metadata`
- Modern and uses the latest official cloud provider's SDK
- AWS S3: [`[email protected]`](https://www.npmjs.com/package/@aws-sdk/client-s3)

Expand All @@ -28,7 +28,17 @@ Synchronize files and directories between a remote machine and a cloud storage v

#### Serverless

Sync storages action as a pre-deploy hook in the `serverless.yml`:
The integration is powered by Serverless hooks and In below, the default configured hooks are listed:

- scs:storages -> As a CLI command for serverless
- scs:tags -> As a CLI command for serverless
- scs:metadata -> As a CLI command for serverless
- before:offline:start:init -> Sync storages (scs:storages)
- before:deploy:deploy -> Sync storages (scs:storages)

##### Example

This setup uses `before:deploy:deploy` hook to sync storages before deploying the stack:

```yaml
plugins:
Expand All @@ -47,11 +57,14 @@ custom:
metadata:
foo: bar
bar: foo
tags:
foo: bar
bar: foo
```
#### CDK
Call sync storages action after setting up a CDK App:
Call `storages` action to sync after setting up a CDK App and Stack:

```typescript
import { Stack, App } from '@aws-cdk/core'
Expand All @@ -75,14 +88,7 @@ const syncCloudStorage = new SyncCloudStorage(stack, {
],
})
// Sync storages
syncCloudStorage.storages()

// Sync tags
syncCloudStorage.tags()

// Sync metadata
syncCloudStorage.metadata()
```

## Options
Expand All @@ -100,18 +106,18 @@ syncCloudStorage.metadata()

### Storage

| Option | Notes | Type | Required | Default |
| ----------- | ----------------------------------------------------------------------------------------------------------- | ------------------- | -------- | ------------------ |
| name | Name of storage (AWS S3 Bucket), Minimum length: 1 | `string` | true | undefined |
| patterns | Patterns of [`glob`][glob] paths to include or exclude on sync action, Minimum items: 1 | `array` of `string` | true | undefined |
| actions | Sync actions, Valid values: `upload`, `delete` | `array` of `string` | false | `upload`, `delete` |
| prefix | Prefix for the storage files and folders | `string` | false | `''` |
| enabled | Enable or disable the storage on sync action | `boolean` | false | `true` |
| acl | [AWS S3 Canned ACL][acl], Valid values: `private`, `public-read`, `public-read-write`, `authenticated-read` | `string` | false | undefined |
| metadata | A set of metadata key/value pair to be set or unset on the object | `object` | false | undefined |
| tags | A set of tag key/value pair to be set or unset on the object | `object` | false | `{}` |
| gitignore | Use .gitignore file to exclude files and directories | `boolean` | false | false |
| ignoreFiles | Ignore files and directories to exclude from sync action | `array` of `string` | false | undefined |
| Option | Notes | Type | Required | Default |
| ----------- | ----------------------------------------------------------------------------------------------------------- | ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| name | Name of storage (AWS S3 Bucket), Minimum length: 1 | `string` | true | undefined |
| patterns | Patterns of [`glob`][glob] paths to include or exclude on sync action, Minimum items: 1 | `array` of `string` | true | undefined |
| actions | Sync actions, Valid values: `upload`, `delete` | `array` of `string` | false | `upload`: Only upload new or modified file, `delete`: Only delete files that are not in the local environment from the storage |
| prefix | Prefix for the storage files and folders | `string` | false | `''` |
| enabled | Enable or disable the storage on sync action | `boolean` | false | `true` |
| acl | [AWS S3 Canned ACL][acl], Valid values: `private`, `public-read`, `public-read-write`, `authenticated-read` | `string` | false | undefined |
| metadata | A set of metadata key/value pair to be set or unset on the object | `object` | false | undefined |
| tags | A set of tag key/value pair to be set or unset on the object | `object` | false | undefined |
| gitignore | Use .gitignore file to exclude files and directories | `boolean` | false | false |
| ignoreFiles | Ignore files and directories to exclude from sync action | `array` of `string` | false | undefined |

[glob]: https://en.wikipedia.org/wiki/Glob_(programming)
[acl]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl
2 changes: 1 addition & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ coverage:
status:
project:
default:
target: 90%
target: 35%
threshold: 20%
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sync-cloud-storage",
"version": "1.0.0-rc.4",
"version": "1.0.0-rc.5",
"license": "MIT",
"type": "module",
"main": "dist/esm/index.js",
Expand All @@ -16,7 +16,9 @@
"bucket",
"serverless",
"aws",
"s3"
"s3",
"cdk",
"cloudformation"
],
"engines": {
"node": ">=18.x"
Expand Down Expand Up @@ -80,7 +82,7 @@
"dependencies": {
"@aws-sdk/client-s3": "3.511.0",
"@aws-sdk/lib-storage": "3.511.0",
"globby": "^14.0.1",
"globby": "^14.0.2",
"mrmime": "2.0.0",
"winston": "^3.11.0",
"zod": "3.23.8"
Expand Down
16 changes: 8 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/providers/serverless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export class SyncCloudStorageServerless extends BaseProvider {
return {
'scs:storages': () => this.storages(),
'scs:tags': () => this.tags(),
'scs:metadata': () => this.metadata(),
'before:offline:start:init': () => this.storages(),
'before:deploy:deploy': () => this.storages(),
}
Expand Down
2 changes: 1 addition & 1 deletion src/schemas/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const storage = z.object({
),
tags: z
.record(z.string(), z.string())
.default({})
.optional()
.describe('A set of tag key/value pair to be set or unset on the object'),
gitignore: z
.boolean()
Expand Down
14 changes: 12 additions & 2 deletions src/storages/s3/buckets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ export const storageExists = async (
}

/**
* Syncs storage with upload and delete actions by comparing local file and storage's object `${Key}-${ETag}`.
* Syncs storage with upload and delete actions
* by comparing local file and storage's object `${Key}-${ETag}`.
*
* In case of defining metadata and tags, it will be synced.
* @memberof S3
* @param {S3Client} client
* @param {Storage} storage
Expand Down Expand Up @@ -92,6 +95,11 @@ export const sync = async (
deleted = await deleteObjects(client, storage, objectsToDelete)
}

const metadataResult =
storage.metadata && (await syncMetadata(client, storage))

const tagsResult = storage.tags && (await syncTags(client, storage))

const result: StoragesSyncResult = {
storage,
files,
Expand All @@ -102,6 +110,8 @@ export const sync = async (
filesToDelete,
uploaded,
deleted,
metadata: metadataResult,
tags: tagsResult,
}

return result
Expand Down Expand Up @@ -203,7 +213,7 @@ export const syncTags = async (
}
}

const mergedTagSet = mergeTags(existingTagSet.TagSet, storage.tags)
const mergedTagSet = mergeTags(existingTagSet.TagSet, storage.tags ?? {})

await client.send(
new PutBucketTaggingCommand({
Expand Down
3 changes: 2 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ export type StoragesSyncResult = {
uploaded: UploadedObject[]
deleted: DeletedObject[]
error?: string | Error
metadata?: Record<string, string>
metadata?: SyncMetadataReturn
tags?: TagsSyncResult
}

export interface MethodReturn<T = undefined> {
Expand Down

0 comments on commit 6d88be7

Please sign in to comment.