{"id":32195814,"url":"https://github.com/confetti-clj/s3-deploy","last_synced_at":"2026-03-09T19:47:52.178Z","repository":{"id":62432152,"uuid":"46858236","full_name":"confetti-clj/s3-deploy","owner":"confetti-clj","description":"Simple utility functions to diff and sync local files with S3 buckets ","archived":false,"fork":false,"pushed_at":"2020-05-10T10:30:55.000Z","size":44,"stargazers_count":10,"open_issues_count":6,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-22T02:48:26.750Z","etag":null,"topics":["aws","deployment","s3","static-site"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/confetti-clj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-25T11:43:54.000Z","updated_at":"2020-05-24T22:20:00.000Z","dependencies_parsed_at":"2022-11-01T21:01:02.455Z","dependency_job_id":null,"html_url":"https://github.com/confetti-clj/s3-deploy","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/confetti-clj/s3-deploy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/confetti-clj%2Fs3-deploy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/confetti-clj%2Fs3-deploy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/confetti-clj%2Fs3-deploy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/confetti-clj%2Fs3-deploy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/confetti-clj","download_url":"https://codeload.github.com/confetti-clj/s3-deploy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/confetti-clj%2Fs3-deploy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30309922,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T17:35:44.120Z","status":"ssl_error","status_checked_at":"2026-03-09T17:35:43.707Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","deployment","s3","static-site"],"created_at":"2025-10-22T02:21:22.606Z","updated_at":"2026-03-09T19:47:52.130Z","avatar_url":"https://github.com/confetti-clj.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://cloud.githubusercontent.com/assets/97496/11431670/0ef1bb58-949d-11e5-83f7-d07cf1dd89c7.png\" alt=\"confetti logo\" align=\"right\" /\u003e\n\n# confetti/s3-deploy [![cljdoc badge](https://cljdoc.org/badge/confetti/s3-deploy)](https://cljdoc.org/d/confetti/s3-deploy)\n\n[goals](#goals) | [usage](#usage) | [changes](#changes)\n\nSimple utility functions to diff and sync local files with S3 buckets.\n\n[](dependency)\n```clojure\n[confetti/s3-deploy \"0.1.4\"] ;; latest release\n```\n[](/dependency)\n\n## Goals\n\n- a simple data-driven API to sync local files to an S3 bucket\n- useful reporting capabilities to inform users about the sync process\n- allow some ordering of uploads to get \"fake-transactionality\"\n- allow specification of custom metadata\n- [easy to script](#cli-tools) with Clojure's command line tools\n\n## Usage\n\nMost functions that are part of the public API of this library operate\non simple maps like the following, furthermore called `file-maps`:\n```clojure\n{:s3-key   \"desired/destination/file.txt\"\n :file     #object[java.io.File \"file.txt.gz\"]\n :metadata {:content-encoding \"gzip\"}}\n```\nBy using `file-maps` we decouple the structure of the filesystem from\nthe structure we ultimately want to achieve in our target S3 bucket.\n\n\u003e By default the `:content-type` metadata is derived from the extension\n\u003e of the value you provided as `:s3-key`.\n\nSyncing is possible via `confetti.s3-deploy/sync!`:\n```clojure\n(confetti.s3-deploy/sync! creds bucket-name file-maps)\n```\nTo generate `file-maps` from a directory this library ships a tiny\nhelper `dir-\u003efile-maps` that will generate file-maps:\n```clojure\n(dir-\u003efile-maps (io/file \"src\"))\n;;=\u003e [{:s3-key \"confetti/s3_deploy.clj\",\n;;     :file   #object[java.io.File 0x4795c68f \"/Users/martin/code/confetti-s3-deploy/src/confetti/s3_deploy.clj\"]}]\n```\nDepending on your use case you will want to build your own `file-maps`\ngenerating function. Lower level functions are available as well:\n```clojure\n(confetti.s3-deploy/diff* bucket-objects file-maps)\n```\nCan be used to get a diff between a buckets objects and a given collection\nof `file-maps`.\n```clojure\n(confetti.s3-deploy/calculate-ops bucket-objects file-maps)\n```\nWill return a vector of operations needed to get the bucket in sync with\nthe supplied `file-maps`.\n\nFor more details check [the implementation](https://github.com/confetti-clj/s3-deploy/blob/master/src/confetti/s3_deploy.clj).\n\n## CLI Tools\n\n`s3-deploy` provides a high level API making it attractive for CLI jobs. Here is a minimal example:\n\n```clojure\n;; cat deploy.clj\n(require '[confetti.s3-deploy :as s3]\n         '[clojure.java.io :as io])\n\n(def dir-to-sync (io/file \"public\"))\n\n(s3/sync!\n  {:access-key (System/getenv \"AWS_ACCESS_KEY\")\n   :secret-key (System/getenv \"AWS_SECRET_KEY\")}\n  (System/getenv \"S3_BUCKET_NAME\")\n  (s3/dir-\u003efile-maps dir-to-sync)\n  {:dry-run? true\n   :report-fn (fn [{:keys [s3-key op]}]\n                (println op s3-key))})\n```\nWhich can be ran with:\n```\nclj -Sdeps '{:deps {confetti/s3-deploy {:mvn/version \"0.1.3\"}}}' deploy.clj\n```\n\n## Changes\n\n#### 0.1.4\n\n- Update prismatic schema dependency to avoid `Inst` warnings\n\n#### 0.1.3\n\n- relax schema around S3 metadata ([#19](https://github.com/confetti-clj/s3-deploy/issues/19))\n\n#### 0.1.2\n\n- improve implementation of `relative-path` function so that it works properly on Windows. ([#16](https://github.com/confetti-clj/s3-deploy/pull/16))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconfetti-clj%2Fs3-deploy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconfetti-clj%2Fs3-deploy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconfetti-clj%2Fs3-deploy/lists"}