{"id":33405323,"url":"https://github.com/s3m/s3m","last_synced_at":"2026-04-18T07:03:26.025Z","repository":{"id":57666137,"uuid":"179674750","full_name":"s3m/s3m","owner":"s3m","description":"CLI for streams of data in S3 buckets","archived":false,"fork":false,"pushed_at":"2026-02-05T14:56:54.000Z","size":1037,"stargazers_count":48,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-06T01:18:02.292Z","etag":null,"topics":["aws-s3","s3","stream","upload"],"latest_commit_sha":null,"homepage":"https://s3m.stream","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/s3m.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"nbari"}},"created_at":"2019-04-05T12:09:52.000Z","updated_at":"2026-02-05T14:45:08.000Z","dependencies_parsed_at":"2023-02-18T12:45:57.091Z","dependency_job_id":"40240776-2bc8-4b16-a2dd-5ef0a2509c7b","html_url":"https://github.com/s3m/s3m","commit_stats":{"total_commits":214,"total_committers":1,"mean_commits":214.0,"dds":0.0,"last_synced_commit":"b47f528278305d52986a4217219bffb11a013b7f"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"purl":"pkg:github/s3m/s3m","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s3m%2Fs3m","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s3m%2Fs3m/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s3m%2Fs3m/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s3m%2Fs3m/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/s3m","download_url":"https://codeload.github.com/s3m/s3m/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s3m%2Fs3m/sbom","scorecard":{"id":587392,"data":{"date":"2025-08-11","repo":{"name":"github.com/s3m/s3m","commit":"140075e9169836570fcc9b9fd5b321aaea9b2263"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.6,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":10,"reason":"20 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: topLevel 'contents' permission set to 'write': .github/workflows/build.yml:11","Warn: no topLevel permission defined: .github/workflows/coverage.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/deploy.yml:11","Warn: no topLevel permission defined: .github/workflows/packagecloud.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/coverage.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/coverage.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/coverage.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/coverage.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/coverage.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/coverage.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/coverage.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/coverage.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy.yml:120: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/deploy.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy.yml:123: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/deploy.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/deploy.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/deploy.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/deploy.yml:107: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/deploy.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/packagecloud.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/packagecloud.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/packagecloud.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/packagecloud.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/packagecloud.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/packagecloud.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:59: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:60: update your workflow using https://app.stepsecurity.io/secureworkflow/s3m/s3m/test.yml/main?enable=pin","Warn: containerImage not pinned by hash: .devcontainer/Dockerfile:1: pin your Docker image by updating rust to rust@sha256:e090f7b4adf86191313dba91260351d7f5e15cac0fe34f26706a805c0cb9641f","Warn: chocoCommand not pinned by hash: .github/workflows/build.yml:60","Warn: chocoCommand not pinned by hash: .github/workflows/deploy.yml:57","Info:   0 out of   9 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of  13 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned","Info:   0 out of   2 chocoCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/deploy.yml:113"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 0.13.1 not signed: https://api.github.com/repos/s3m/s3m/releases/225255329","Warn: release artifact 0.13.0 not signed: https://api.github.com/repos/s3m/s3m/releases/222242020","Warn: release artifact 0.12.0 not signed: https://api.github.com/repos/s3m/s3m/releases/220808096","Warn: release artifact 0.11.2 not signed: https://api.github.com/repos/s3m/s3m/releases/196976068","Warn: release artifact 0.11.1 not signed: https://api.github.com/repos/s3m/s3m/releases/196832414","Warn: release artifact 0.13.1 does not have provenance: https://api.github.com/repos/s3m/s3m/releases/225255329","Warn: release artifact 0.13.0 does not have provenance: https://api.github.com/repos/s3m/s3m/releases/222242020","Warn: release artifact 0.12.0 does not have provenance: https://api.github.com/repos/s3m/s3m/releases/220808096","Warn: release artifact 0.11.2 does not have provenance: https://api.github.com/repos/s3m/s3m/releases/196976068","Warn: release artifact 0.11.1 does not have provenance: https://api.github.com/repos/s3m/s3m/releases/196832414"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: RUSTSEC-2024-0384"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T20:55:25.072Z","repository_id":57666137,"created_at":"2025-08-20T20:55:25.072Z","updated_at":"2025-08-20T20:55:25.072Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30475639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T20:45:58.186Z","status":"ssl_error","status_checked_at":"2026-03-13T20:45:20.133Z","response_time":60,"last_error":"SSL_read: 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-s3","s3","stream","upload"],"created_at":"2025-11-23T16:17:15.334Z","updated_at":"2026-04-18T07:03:26.004Z","avatar_url":"https://github.com/s3m.png","language":"Rust","funding_links":["https://github.com/sponsors/nbari"],"categories":["Development","Open Source Repos","General Purpose Tools"],"sub_categories":["Devops","S3"],"readme":"# s3m\n\n[![Deploy](https://github.com/s3m/s3m/actions/workflows/deploy.yml/badge.svg)](https://github.com/s3m/s3m/actions/workflows/deploy.yml)\n[![Test \u0026 Build](https://github.com/s3m/s3m/actions/workflows/build.yml/badge.svg)](https://github.com/s3m/s3m/actions/workflows/build.yml)\n[![codecov](https://codecov.io/gh/s3m/s3m/graph/badge.svg?token=Y2BQJUGPJ5)](https://codecov.io/gh/s3m/s3m)\n[![crates.io](https://img.shields.io/crates/v/s3m.svg)](https://crates.io/crates/s3m)\n\n**s3m** a command-line tool for storing streams of data in s3 buckets.\n\n## Problem trying to solve\n\nThere are streams of data that can not be lost besides that when created,\nthey degrade the performance of running systems, for example, if the stream\nis a backup of a database, every time the stream is produced it may lock the\nentire cluster (depends on the options and tools used mysqldump/xtrabackup for\nexample), however, the effort to create the stream is proportional to the size\nof the database, in most cases the bigger the database is the more time\nand CPU and Memory are required.\n\nIn the case of backups, normally the streams are piped to a compression tool\nand later put in the disk, in some cases writing to the existing disk where\nthe database is or to a remote mount endpoint, is not possible due to size\nconstraints and the compressed backup should be streamed to am s3 bucket (X\nprovider), therefore if for some reason the connection gets lost while streaming\nalmost before finishing, the whole backup procedure could be corrupted and in\nworst scenario everything should start all over again.\n\nThe aim of **s3m** apart from trying to consume fewer resources is to make as\nmuch as possible \"fault-tolerant\" the storage procedure of the incoming stream\nso that even if the server lost network connectivity, the stream can be resumed\nand continue the upload process where it was left without the need to start all\nover again (no when input is from STDIN/pipe).\n\nhttps://s3m.stream\n\n## System Requirements\n\n**s3m** is designed to run in very constrained environments with minimal resource usage:\n\n- **Disk Space**: 512MB when streaming from STDIN (for buffering multipart uploads)\n- **Memory**: Minimal - uses streaming to avoid loading data into RAM\n- **Network**: Internet connection for S3 uploads (supports resumable uploads on disconnection)\n\n## Configuration\n\nCreate `~/.config/s3m/config.yml`:\n\n```yaml\nhosts:\n  s3:\n    endpoint: s3.us-west-2.amazonaws.com\n    access_key: YOUR_ACCESS_KEY\n    secret_key: YOUR_SECRET_KEY\n    bucket: my-bucket  # optional default bucket\n```\n\n### Multiple Providers\n\n```yaml\nhosts:\n  aws:\n    region: us-west-1\n    access_key: AWS_KEY\n    secret_key: AWS_SECRET\n\n  backblaze:\n    endpoint: s3.us-west-000.backblazeb2.com\n    access_key: B2_KEY\n    secret_key: B2_SECRET\n```\n\n## Usage\n\ns3m uses the format: `/host/bucket/file`\n\n### Upload a file\n\n```bash\n# Upload file\ns3m file.dat /s3/my-bucket/\n\n# Upload with different name\ns3m local-file.dat /s3/my-bucket/remote-name.dat\n\n# Stream from STDIN\nmariadb-dump database | s3m --pipe /s3/backups/db-backup.sql\n```\n\n### Download a file\n\n```bash\ns3m get /s3/my-bucket/file.dat\n```\n\n### List buckets and objects\n\n```bash\n# List all buckets\ns3m ls s3\n\n# List objects in bucket\ns3m ls s3/my-bucket\n\n# List with prefix\ns3m ls s3/my-bucket/path/\n```\n\n### Usage summary\n\n```bash\n# Bucket summary\ns3m du s3/my-bucket\n\n# Prefix summary grouped by UTC day\ns3m du s3/my-bucket/backups/ --group-by day\n```\n\n### Stream state\n\n```bash\n# List resumable multipart state\ns3m streams\n\n# Show one entry\ns3m streams show \u003cid\u003e\n\n# Clean broken/completed entries\ns3m streams clean\n```\n\n### Delete multiple objects\n\n```bash\n# One object uses DeleteObject\ns3m rm s3/my-bucket/file.dat\n\n# Multiple objects use DeleteObjects grouped by bucket\ns3m rm s3/my-bucket/a.txt s3/my-bucket/b.txt\ns3m rm s3/bucket-a/a.txt s3/bucket-b/b.txt\n```\n\n### Recursive bucket delete\n\n```bash\n# Delete all objects in the bucket, then delete the bucket\ns3m rm -b --recursive s3/my-bucket\n```\n\n### JSON output for automation\n\n```bash\n# List objects as JSON\ns3m ls s3/my-bucket --json\n\n# Get object metadata as JSON\ns3m get -m s3/my-bucket/file.dat --json\n\n# Usage summary as JSON\ns3m du s3/my-bucket --json\n\n# Stream state as JSON\ns3m streams ls --json\n```\n\n### Create bucket\n\n```bash\ns3m cb s3/new-bucket\n```\n\n### Delete\n\n```bash\n# Delete object\ns3m rm s3/my-bucket/file.dat\n\n# Delete multiple objects\ns3m rm s3/my-bucket/a.txt s3/my-bucket/b.txt\n\n# Delete bucket\ns3m rm -b s3/empty-bucket\n\n# Recursively delete bucket contents, then the bucket\ns3m rm -b --recursive s3/my-bucket\n```\n\n## Compression \u0026 Encryption\n\n### Compression\n\n```bash\n# Compress before upload (uses Zstandard)\ns3m --compress mysqldump.sql s3/backups/db.sql.zst\n```\n\n### Encryption\n\n```bash\n# Generate secure encryption key (32 characters)\nopenssl rand -hex 16 \u003e encryption.key\n```\n\n```yaml\n# ~/.config/s3m/config.yml\nhosts:\n  secure:\n    endpoint: s3.us-west-2.amazonaws.com\n    access_key: YOUR_ACCESS_KEY\n    secret_key: YOUR_SECRET_KEY\n    bucket: my-bucket\n    enc_key: 0123456789abcdef0123456789abcdef\n```\n\n```bash\n# Encrypt during upload using the host config key\ns3m file.dat /secure/my-bucket/file.dat.enc\n\n# Download and decrypt using the same host config key\ns3m get /secure/my-bucket/file.dat.enc\n\n# Decrypt a local encrypted file manually\ns3m --decrypt file.dat.enc 0123456789abcdef0123456789abcdef\n```\n\nUploads and downloads do not accept `--encrypt` or `--enc-key` flags. Encryption is enabled by setting `enc_key` on the selected host in `config.yml`.\n\n## Advanced Options\n\n### Buffer size\n\n```bash\n# Adjust part size for multipart uploads (in MB)\ns3m --buffer 50 big-file.dat s3/large/huge-file.dat\n```\n\n### Bandwidth throttling\n\n```bash\n# Limit upload speed (in KB/s)\ns3m --throttle 10240 file.dat s3/backups/file.dat  # 10MB/s\n```\n\n### Retries\n\n```bash\n# Configure retry attempts for failed parts\ns3m --retries 5 file.dat s3/bucket/file.dat\n```\n\n## Notes for streaming and transformed uploads\n\n- Regular file multipart uploads can be resumed.\n- `STDIN` / `--pipe` uploads are not resumable after interruption because the original input stream cannot be replayed safely.\n- When the input size is unknown, `s3m` uses a fixed multipart buffer of `512 MiB` per part.\n- Streaming and transformed upload paths (for example `STDIN`, compression, and encryption) use a two-line progress display: the top line shows local buffering progress for the current `512 MiB` part, and the bottom line shows either `confirmed ...` bytes or `sending part N ... | confirmed ...` during the active part upload.\n- For interrupted or failed multipart uploads from streaming paths, configure bucket lifecycle rules to clean up incomplete multipart uploads automatically.\n\n## Development\n\n### Running Tests\n\n```bash\n# Unit + integration tests\ncargo test\n\n# Integration tests with MinIO (Podman)\njust container            # start MinIO (idempotent)\njust test-integration     # run MinIO-backed e2e tests against that MinIO\n# or in one go\njust container test-integration\n# full suite (fmt + clippy + unit + integration)\njust test\n# stop/clean the container\npodman rm -f s3m-test-minio\n```\n\nExample `config.yml` for the default MinIO container:\n\n```yaml\n---\nhosts:\n  minio:\n    endpoint: http://localhost:9000\n    access_key: minioadmin\n    secret_key: minioadmin\n```\n\n### Test Coverage\n\n```bash\ncargo install cargo-llvm-cov\ncargo llvm-cov --all-features --workspace\n```\n\nCoverage: **80%+**\n\n### Contributing\n\n1. Write tests for new features\n2. Run: `just test` (to run the containerized integration tests)\n3. Run: `cargo clippy --all-targets --all-features`\n4. Run: `cargo fmt`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs3m%2Fs3m","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fs3m%2Fs3m","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs3m%2Fs3m/lists"}