{"id":13760232,"url":"https://github.com/ItinerisLtd/composify","last_synced_at":"2025-05-10T10:31:55.055Z","repository":{"id":33788725,"uuid":"162269149","full_name":"ItinerisLtd/composify","owner":"ItinerisLtd","description":"Turn WordPress plugin zip files into git repositories, so that composer version constraints work properly.","archived":false,"fork":false,"pushed_at":"2024-11-04T17:52:53.000Z","size":2044,"stargazers_count":48,"open_issues_count":5,"forks_count":3,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-11-11T10:22:51.155Z","etag":null,"topics":["cli","composer","composify","wordpress","wordpress-development"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/ItinerisLtd.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}},"created_at":"2018-12-18T10:13:36.000Z","updated_at":"2024-11-04T17:52:54.000Z","dependencies_parsed_at":"2024-06-24T19:23:02.515Z","dependency_job_id":"f8995395-e3b0-475d-83fb-31c42635446a","html_url":"https://github.com/ItinerisLtd/composify","commit_stats":{"total_commits":514,"total_committers":6,"mean_commits":85.66666666666667,"dds":0.3949416342412452,"last_synced_commit":"a8cec8985b6348983639f79ef529b859ab45bfbb"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ItinerisLtd%2Fcomposify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ItinerisLtd%2Fcomposify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ItinerisLtd%2Fcomposify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ItinerisLtd%2Fcomposify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ItinerisLtd","download_url":"https://codeload.github.com/ItinerisLtd/composify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224718680,"owners_count":17358102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cli","composer","composify","wordpress","wordpress-development"],"created_at":"2024-08-03T13:01:05.747Z","updated_at":"2024-11-16T17:30:49.869Z","avatar_url":"https://github.com/ItinerisLtd.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# composify\n\nTurn WordPress plugin zip files into git repositories, so that composer version constraints work properly.\n\n[![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io)\n[![Version](https://img.shields.io/npm/v/@itinerisltd/composify.svg)](https://npmjs.org/package/@itinerisltd/composify)\n[![Downloads/week](https://img.shields.io/npm/dw/@itinerisltd/composify.svg)](https://npmjs.org/package/@itinerisltd/composify)\n[![License](https://img.shields.io/npm/l/@itinerisltd/composify.svg)](https://github.com/ItinerisLtd/composify/blob/master/package.json)\n[![Hire Itineris](https://img.shields.io/badge/Hire-Itineris-ff69b4.svg)](https://www.itineris.co.uk/contact/)\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Goal](#goal)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Examples](#examples)\n  - [Gravity Forms](#gravity-forms)\n  - [Advanced Custom Fields Pro](#advanced-custom-fields-pro)\n  - [Kinsta MU Plugins](#kinsta-mu-plugins)\n- [FAQ](#faq)\n  - [How to install the `composify`-ed plugin via `composer`?](#how-to-install-the-composify-ed-plugin-via-composer)\n  - [How to `composify` plugin zip URLs which are *password-protected*?](#how-to-composify-plugin-zip-urls-which-are-password-protected)\n  - [Can I change default flag values via environment variables?](#can-i-change-default-flag-values-via-environment-variables)\n  - [Can I install `composify` instead of using `$ npx`?](#can-i-install-composify-instead-of-using--npx)\n  - [How about plugins on wordpress.org?](#how-about-plugins-on-wordpressorg)\n  - [What to do when `fatal: Could not read from remote repository`?](#what-to-do-when-fatal-could-not-read-from-remote-repository)\n  - [Is it a must to use `composify` with Bedrock?](#is-it-a-must-to-use-composify-with-bedrock)\n  - [Any Alternatives?](#any-alternatives)\n  - [It looks awesome. Where can I find some more goodies like this?](#it-looks-awesome-where-can-i-find-some-more-goodies-like-this)\n  - [This isn't on wp.org. Where can I give a ⭐️⭐️⭐️⭐️⭐️ review?](#this-isnt-on-wporg-where-can-i-give-a-%EF%B8%8F%EF%B8%8F%EF%B8%8F%EF%B8%8F%EF%B8%8F-review)\n- [Feedback](#feedback)\n- [Security](#security)\n- [Change log](#change-log)\n- [Credits](#credits)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Goal\n\nSince plugin authors do not usually provide custom composer repositories (e.g: [Private Packagist](https://packagist.com/), [satis](https://getcomposer.org/doc/articles/handling-private-packages-with-satis.md#satis)), installing premium WordPress plugins via `composer` is not easy.\n\n[Lots](https://kinsta.com/blog/bedrock-trellis/) [of](https://gist.github.com/beaverbuilder/8ab6fd1f054582a1fe5ae053c3b75a55/e7ce9dd744255778583705b6da6cdce53a295506#file-composer-bb-theme-config-json) [tutorials](https://deliciousbrains.com/using-composer-manage-wordpress-themes-plugins/) teach you: open `composer.json` and add the following within the `repositories` array:\n```json\n// https://kinsta.com/blog/bedrock-trellis/\n{\n  \"type\": \"package\",\n  \"package\": {\n    \"name\": \"kinsta/kinsta-mu-plugins\",\n    \"type\": \"wordpress-muplugin\",\n    \"version\": \"2.0.15\",\n    \"dist\": {\n      \"url\": \"https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip\",\n      \"type\": \"zip\"\n    }\n  }\n}\n```\n\nThe problems:\n- if `package.dist.url` is *version-locked*, the `repositories` array has to be updated whenever a new plugin version is released\n- if `package.dist.url` is not *version-locked*,`$ composer install` is not deterministic (even with `composer.lock`)\n  * `package.dist.url` always points to the latest version\n  * `package.version` becomes meaningless because the downloaded zip could be a newer version\n  * running `$ composer install` (without changing anything) could break the site because a newer plugin version is installed\n  * when composer caching invoked, there is no way to know which plugin version will be installed\n\nThe solution / what `composify` does:\n1. download the plugin zip file\n2. unzip it\n3. generate `composer.json`\n4. commit plugins files and `composer.json`\n5. `$ git tag`\n5. `$ git push --follow-tags`\n\n## Requirements\n\n- NodeJS v10.0.0 or later\n\n## Installation\n\n`$ npx @itinerisltd/composify` just works! No installation required.\n\n## Usage\n\n```sh-session\n$ npx @itinerisltd/composify --help\nTurn WordPress plugin zip files into git repositories, so that composer version constraints work properly\n\nUSAGE\n  $ composify\n\nOPTIONS\n  -b, --branch=branch\n      the default branch of your remote repository [example: main]\n\n  -d, --directory=directory\n      directory name after unzip [example: kinsta-mu-plugins]\n\n  -f, --file=file\n      main plugin file which containing the plugin header comment [example:\n      kinsta-mu-plugins.php]\n\n  -h, --help\n      show CLI help\n\n  -n, --name=name\n      (required) package name [example: kinsta-mu-plugins]\n\n  -o, --vendor=vendor\n      (required) vendor / organization name [example: itinerisltd]\n\n  -r, --repo=repo\n      remote url or local path to the gti repository [example:\n      https://github.com/ItinerisLtd/kinsta-mu-plugins.git]\n\n  -t, --type=wordpress-plugin|wordpress-muplugin|wordpress-theme\n      (required) [default: wordpress-plugin] package type\n\n  -u, --[no-]unzip-subdir\n      unzip file into a sub-directory, only use when default options are breaking\n\n  -v, --version\n      show CLI version\n\n  -z, --zip=zip\n      (required) remote url or local path to the latest zip file [example:\n      https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip OR\n      /User/me/kinsta-mu-plugins.zip]\n```\n\n## Examples\n\n### Gravity Forms\n\n```sh-session\n$ npx @itinerisltd/composify --vendor=itinerisltd --name=gravityforms --zip=\u003cthe-signed-s3-url\u003e\n```\n\nNote the flags:\n```sh-session\n$ wget \u003cthe-signed-s3-url\u003e\n$ tree .\n.\n└── gravityforms_x.y.z.zip\n\n$ unzip -o ./gravityforms_2.4.5.zip\n$ tree .\n.\n├── gravityforms              \u003c-- `--directory`\n│   ├── gravityforms.php      \u003c-- `--file`\n│   ├── xxx\n│   └── yyy.php\n└── gravityforms_x.y.z.zip\n```\n\n* `--directory` is omitted because it defaults to `${name}`, i.e: `gravityforms`\n* `--file` is omitted because it defaults to `${name}.php`, i.e: `gravityforms.php`\n* `--repo` is omitted because it defaults to `https://github.com/${vendor}/${name}.git`\n* `--unzipDir` is omitted because main plugin file is inside `--directory`\n\n### Advanced Custom Fields Pro\n\n```sh-session\n$ npx @itinerisltd/composify --vendor=itinerisltd --name=advanced-custom-fields-pro --file=acf.php --zip=https://connect.advancedcustomfields.com/xxx\n```\n\nNote the flags:\n```sh-session\n$ wget https://connect.advancedcustomfields.com/xxx\n$ tree .\n.\n└── advanced-custom-fields-pro.zip\n\n$ unzip -o ./advanced-custom-fields-pro.zip\n$ tree .\n.\n├── advanced-custom-fields-pro        \u003c-- `--directory`\n│   ├── acf.php                       \u003c-- `--file`\n│   ├── readme.txt\n│   └── xxx\n└── advanced-custom-fields-pro.zip\n```\n\n* `--file` is set to `acf.php`\n\n### Kinsta MU Plugins\n\n```sh-session\n$ npx @itinerisltd/composify --vendor=itinerisltd --name=kinsta-mu-plugins --zip=https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip --unzip-subdir --type=wordpress-muplugin\n```\n\nNote the flags:\n```sh-session\n$ wget https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip\n$ tree .\n.\n└── kinsta-mu-plugins.zip\n$ unzip -o ./kinsta-mu-plugins.zip\n$ tree .\n.\n├── kinsta-mu-plugins\n│   ├── xxx\n│   └── yyy\n├── kinsta-mu-plugins.php    \u003c-- `--file`\n└── kinsta-mu-plugins.zip\n```\n\n* `--unzip-subdir` is set because the unzipped content is not *contained* inside a `--directory`\n\n## FAQ\n\n### How to install the `composify`-ed plugin via `composer`?\n\nOpen `composer.json` and add your git remote into `repositories`:\n```json\n{\n  \"repositories\": [\n    {\n      \"type\": \"git\",\n      \"url\": \"https://github.com/\u003cvendor\u003e/\u003cname\u003e\"\n    }\n  ]\n}\n```\n\n```sh-session\n$ composer require \u003cvendor\u003e/\u003cname\u003e\n```\n\nSee: https://getcomposer.org/doc/05-repositories.md#vcs\n\n### How to `composify` plugin zip URLs which are *password-protected*?\n\n1. Download the zip files to your computer first\n2. `$ composify/bin/run -z /path/to/the-plugin.zip -o itinerisltd -n the-plugin`\n\nNote: This is a v0.3 feature.\n\n### Can I change default flag values via environment variables?\n\nYes.\n\nThese 2 commands are equivalent:\n```sh-session\n$ COMPOSIFY_VENDOR=itinerisltd COMPOSIFY_NAME=gravityforms COMPOSIFY_ZIP=\u003cthe-signed-s3-url\u003e npx @itinerisltd/composify\n$ npx @itinerisltd/composify --vendor=itinerisltd --name=gravityforms --zip=\u003cthe-signed-s3-url\u003e\n```\n\n### Can I install `composify` instead of using `$ npx`?\n\nYes. However, you are responsible for updating it.\n\n```sh-session\n# yarn or npm doesn't matter\n$ yarn global add @itinerisltd/composify\n$ composify --vendor=itinerisltd --name=gravityforms --zip=\u003cthe-signed-s3-url\u003e\n```\n\n### How about plugins on wordpress.org?\n\nUse [WordPress Packagist](https://wpackagist.org/) instead.\n\n### What to do when `fatal: Could not read from remote repository`?\n\n```sh-session\nERROR: Repository not found.\nfatal: Could not read from remote repository.\n```\n\nMake sure you have:\n\n- created a git repository on remote server\n- [chosen remote url correctly](https://help.github.com/en/articles/which-remote-url-should-i-use)\n- [configure git authentication correctly](https://stackoverflow.com/questions/17659206/git-push-results-in-authentication-failed) on your computer or CI server\n- granted both read and write accesses to the remote repository for the git user on your computer or CI server\n\n### Is it a must to use `composify` with Bedrock?\n\nNo.\n\nAlthough we prefer and sponsor [Bedrock](https://github.com/roots/bedrock/#bedrock-sponsors) at [Itineris](https://www.itineris.co.uk/), you can `composify` any plugin zip files into git repositories, and install them via [composer](https://getcomposer.org/doc/05-repositories.md#vcs).\n\nBedrock alternatives:\n- [Composer in WordPress](https://composer.rarst.net/)\n- [WP Starter](https://wecodemore.github.io/wpstarter/)\n\n### Any Alternatives?\n\n- [Release Belt](https://github.com/Rarst/release-belt) - Composer repo for ZIPs\n- [Private Packagist Vendor](https://packagist.com/vendors) - Use JSON to make any ZIP file available through Composer.\n\n### It looks awesome. Where can I find some more goodies like this?\n\n- Articles on [Itineris' blog](https://www.itineris.co.uk/blog/)\n- More projects on [Itineris' GitHub profile](https://github.com/itinerisltd)\n- Follow [@itineris_ltd](https://twitter.com/itineris_ltd) and [@TangRufus](https://twitter.com/tangrufus) on Twitter\n- Hire [Itineris](https://www.itineris.co.uk/services/) to build your next awesome site\n\n### This isn't on wp.org. Where can I give a ⭐️⭐️⭐️⭐️⭐️ review?\n\nThanks! Glad you like it. It's important to make my boss know somebody is using this project. Instead of giving reviews on wp.org, consider:\n\n- tweet something good with mentioning [@itineris_ltd](https://twitter.com/itineris_ltd) and [@TangRufus](https://twitter.com/tangrufus)\n- star this [Github repo](https://github.com/ItinerisLtd/composify)\n- watch this [Github repo](https://github.com/ItinerisLtd/composify)\n- write blog posts\n- submit pull requests\n- [hire Itineris](https://www.itineris.co.uk/services/)\n\n## Feedback\n\n**Please provide feedback!** We want to make this library useful in as many projects as possible.\nPlease submit an [issue](https://github.com/ItinerisLtd/composify/issues/new) and point out what you do and don't like, or fork the project and make suggestions.\n**No issue is too small.**\n\n## Security\n\nIf you discover any security related issues, please email [hello@itineris.co.uk](mailto:hello@itineris.co.uk) instead of using the issue tracker.\n\n## Change log\n\nPlease see [CHANGELOG](./CHANGELOG.md) for more information on what has changed recently.\n\n## Credits\n\n[composify](https://github.com/ItinerisLtd/composify) is a [Itineris Limited](https://www.itineris.co.uk/) project created by [Tang Rufus](https://typist.tech).\n\nFull list of contributors can be found [here](https://github.com/ItinerisLtd/composify/graphs/contributors).\n\n## License\n\n[composify](https://github.com/ItinerisLtd/composify) is released under the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FItinerisLtd%2Fcomposify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FItinerisLtd%2Fcomposify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FItinerisLtd%2Fcomposify/lists"}