{"id":44150391,"url":"https://github.com/artifact-keeper/artifact-keeper-example-plugin","last_synced_at":"2026-02-09T03:15:26.258Z","repository":{"id":335958253,"uuid":"1147623647","full_name":"artifact-keeper/artifact-keeper-example-plugin","owner":"artifact-keeper","description":"Example WASM plugin for Artifact Keeper — Unity .unitypackage format handler with CI/CD pipeline.","archived":false,"fork":false,"pushed_at":"2026-02-02T02:44:19.000Z","size":9,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-02T11:41:46.295Z","etag":null,"topics":["artifact-registry","example-project","plugin-system","rust","unity","wasm-plugin","webassembly"],"latest_commit_sha":null,"homepage":"https://artifactkeeper.com/docs/advanced/plugins","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/artifact-keeper.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,"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}},"created_at":"2026-02-02T02:23:59.000Z","updated_at":"2026-02-02T03:09:34.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/artifact-keeper/artifact-keeper-example-plugin","commit_stats":null,"previous_names":["artifact-keeper/artifact-keeper-example-plugin"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/artifact-keeper/artifact-keeper-example-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artifact-keeper%2Fartifact-keeper-example-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artifact-keeper%2Fartifact-keeper-example-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artifact-keeper%2Fartifact-keeper-example-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artifact-keeper%2Fartifact-keeper-example-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artifact-keeper","download_url":"https://codeload.github.com/artifact-keeper/artifact-keeper-example-plugin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artifact-keeper%2Fartifact-keeper-example-plugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29255594,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-09T03:07:45.136Z","status":"ssl_error","status_checked_at":"2026-02-09T03:07:24.123Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["artifact-registry","example-project","plugin-system","rust","unity","wasm-plugin","webassembly"],"created_at":"2026-02-09T03:15:25.605Z","updated_at":"2026-02-09T03:15:26.254Z","avatar_url":"https://github.com/artifact-keeper.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Artifact Keeper Example Plugin\n\nA fully working example of a custom format handler plugin for [Artifact Keeper](https://github.com/artifact-keeper/artifact-keeper). This plugin handles **Unity `.unitypackage`** files (gzipped tarballs), demonstrating real-world format validation, metadata extraction, and index generation.\n\nUse this repo as a starting point for building your own plugins. Fork it, change the format key, and implement your logic.\n\n## What this plugin does\n\n| Capability | Description |\n|------------|-------------|\n| **Validate** | Checks gzip magic bytes and correct file extension |\n| **Parse metadata** | Extracts version from path/filename, detects content type |\n| **Generate index** | Creates a `unity-index.json` listing all packages in a repository |\n\n## Prerequisites\n\n- [Rust](https://rustup.rs/) (stable)\n- The `wasm32-wasip1` target (installed automatically via `rust-toolchain.toml`)\n\n## Build\n\n```bash\n# Clone this repo\ngit clone https://github.com/artifact-keeper/artifact-keeper-example-plugin.git\ncd artifact-keeper-example-plugin\n\n# Build the WASM component\ncargo build --release\n\n# Output: target/wasm32-wasip1/release/unity_format_plugin.wasm\n```\n\n## Test\n\nUnit tests run on the host target (not WASM):\n\n```bash\ncargo test --target $(rustc -vV | grep host | awk '{print $2}')\n```\n\n## Install into Artifact Keeper\n\n### From Git URL\n\n```bash\ncurl -X POST https://your-registry/api/v1/plugins/install/git \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://github.com/artifact-keeper/artifact-keeper-example-plugin.git\",\n    \"ref\": \"v0.1.0\"\n  }'\n```\n\n### From ZIP (release artifact)\n\nDownload the ZIP from the [Releases](https://github.com/artifact-keeper/artifact-keeper-example-plugin/releases) page, then:\n\n```bash\ncurl -X POST https://your-registry/api/v1/plugins/install/zip \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -F \"file=@unity-format-plugin-v0.1.0.zip\"\n```\n\n### From local path\n\n```bash\ncurl -X POST https://your-registry/api/v1/plugins/install/local \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"path\": \"/path/to/artifact-keeper-example-plugin\"}'\n```\n\n## Create your own plugin\n\n1. **Fork this repo** or use it as a template\n2. Update `plugin.toml` with your format key, extensions, and description\n3. Implement the four functions in `src/lib.rs`:\n   - `format_key()` -- return your unique format identifier\n   - `parse_metadata()` -- extract metadata from uploaded artifacts\n   - `validate()` -- reject invalid artifacts before storage\n   - `generate_index()` -- create repository index files (or return `None`)\n4. The WIT contract in `wit/format-plugin.wit` defines the interface -- don't modify it\n5. Push a tag to trigger the release workflow\n\n## Project structure\n\n```\n.\n├── .cargo/config.toml      # Default WASM target\n├── .github/workflows/\n│   ├── ci.yml              # Lint + test + build on push/PR\n│   └── release.yml         # Build + package + GitHub Release on tag\n├── src/lib.rs              # Plugin implementation\n├── wit/format-plugin.wit   # WIT contract (from Artifact Keeper)\n├── plugin.toml             # Plugin manifest\n├── Cargo.toml              # Rust project config\n└── rust-toolchain.toml     # Rust toolchain + WASM target\n```\n\n## WIT Interface\n\nPlugins implement the `artifact-keeper:format@1.0.0` interface:\n\n```wit\ninterface handler {\n    record metadata {\n        path: string,\n        version: option\u003cstring\u003e,\n        content-type: string,\n        size-bytes: u64,\n        checksum-sha256: option\u003cstring\u003e,\n    }\n\n    format-key: func() -\u003e string;\n    parse-metadata: func(path: string, data: list\u003cu8\u003e) -\u003e result\u003cmetadata, string\u003e;\n    validate: func(path: string, data: list\u003cu8\u003e) -\u003e result\u003c_, string\u003e;\n    generate-index: func(artifacts: list\u003cmetadata\u003e) -\u003e result\u003coption\u003clist\u003ctuple\u003cstring, list\u003cu8\u003e\u003e\u003e\u003e, string\u003e;\n}\n```\n\n## Resources\n\n- [Plugin System Documentation](https://artifactkeeper.com/docs/advanced/plugins/)\n- [Artifact Keeper](https://github.com/artifact-keeper/artifact-keeper)\n- [WIT Specification](https://component-model.bytecodealliance.org/design/wit.html)\n- [wit-bindgen](https://github.com/bytecodealliance/wit-bindgen)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartifact-keeper%2Fartifact-keeper-example-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartifact-keeper%2Fartifact-keeper-example-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartifact-keeper%2Fartifact-keeper-example-plugin/lists"}