Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for intermediary URLs such as EDD #49

Open
wants to merge 20 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ on: [push, pull_request]

jobs:
test:
name: "CI"
name: "CI (${{ matrix.php-version }}, ${{ matrix.composer-version }}, ${{ matrix.phpdotenv-version }})"
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}

strategy:
matrix:
Expand All @@ -15,18 +16,29 @@ jobs:
- "7.3"
- "7.4"
- "8.0"
- "8.1"
- "8.2"
- "8.3"
composer-version: ["v2"]
phpdotenv-version: ["^4.1", "^5.2"]
experimental: [false]
include:
- php-version: "7.1"
composer-version: "v1"
phpdotenv-version: "^4.1"
experimental: false
- php-version: "7.1"
composer-version: "v1"
phpdotenv-version: "^5.2"
experimental: false
- php-version: "7.4"
composer-version: "v1"
phpdotenv-version: "^5.2"
experimental: false
- php-version: "8.4"
composer-version: "v2"
phpdotenv-version: "^5.2"
experimental: true

steps:
- name: "Checkout"
Expand Down Expand Up @@ -64,21 +76,12 @@ jobs:
max_attempts: 5
command: composer require "vlucas/phpdotenv:${{ matrix.phpdotenv-version }}" --no-update --no-interaction

- name: Install PHP 7 dependencies
- name: Install PHP dependencies
uses: nick-invision/retry@v1
with:
timeout_minutes: 5
max_attempts: 5
command: composer update --prefer-dist --no-interaction --no-progress
if: "matrix.php-version < 8"

- name: Install PHP 8 dependencies
uses: nick-invision/retry@v1
with:
timeout_minutes: 5
max_attempts: 5
command: composer update --prefer-dist --no-interaction --no-progress --ignore-platform-req=php
if: "matrix.php-version >= 8"

- name: "Run PHP_CodeSniffer"
run: "composer cs-check"
Expand Down
115 changes: 107 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,29 +91,126 @@ composer require "advanced-custom-fields/advanced-custom-fields-pro:*"

The configuration options listed below may be added to the root configuration in `composer.json` like so:

```json
```jsonc
{
"name": "...",
"description": "...",
"require": {
},
"name": "…",
"description": "…",
"require": {/* … */},
"extra": {
"private-composer-installer": {
"dotenv-path": ".",
"dotenv-name": ".env"
"dotenv-name": ".env",
"presets": {/* … */}
}
}
}
```

### dotenv-path
### dotenv-path[^1]

Dotenv file directory relative to the root package (where `composer.json` is located). By default dotenv files are expected to be in the root package folder or in any of the parent folders.

### dotenv-name
### dotenv-name[^1]

Dotenv file name. Defaults to `.env`.

### indirection

> [!NOTE]
> This feature is only supported with Composer 2 (latest).

Indirection provides support for downloading a package from a temporary URL that is provided through the response from the dist URL (the intermediary). By default this plugin expects the dist URL to be the package's download URL.

For example, certain WordPress plugins such as Gravity Forms, and managers such Easy Digital Downloads (EDD), usually serve their downloads from a temporary signed URL that is provided through an API endpoint as a JSON response.

The indirection property can contain the following options:

* `http` and `ssl` objects, as defined by [Composer's `CurlDownloader`](https://github.com/composer/composer/blob/2.2/src/Composer/Util/Http/CurlDownloader.php), to customize the request to the intermediary URL.
* `method`: Optional. The HTTP method for the request to the intermediary URL. Defaults to `GET`.
* `parse` object which expects:
* `format`: Required. A string indicating the kind of response expected from the intermediary's HTTP response. Either `json` or `serialize`. The latter expects data serialized with PHP's `serialize()` function and will use `unserialize()` to deserialize the data.
* `download_key`: Required. A string for specifying the key or key path ("dot" notation) to extract the package download URL from. Wildcards are not supported.
* `version_key`: Optional. A string for specifying the key or key path ("dot" notation) to extract the download's version number from. Wildcards are not supported. If specified, it ensures the intermediary's download matches the package's required version constraint. This is necessary for Gravity Forms and plugins that use EDD.

```jsonc
"indirection": {
"http": {
"method": "POST"
},
"ssl": {
"passphrase": "{%PACKAGE_SSL_PW}"
},
"parse": {
"format": "json",
"download_key": "data.0.download_url",
"version_key": "data.0.version"
}
}
```

The indirection can be defined from a [preset](#presets) or from the private package's inline extra data:

```jsonc
{
"repositories": [
{
"type": "package",
"package": {
"name": "package-name/package-name",
"version": "1.0.0",
"dist": {
"type": "zip",
"url": "https://example.com/api/download?name=foobar&key={%PACKAGE_KEY}&version={%VERSION}"
},
"require": {
"ffraenz/private-composer-installer": "^5.0"
},
"extra": {
"private-composer-installer": {
"indirection": {/* … */}
}
}
}
}
]
}
```

### presets[^1]

Presets are sets of configuration options to modify how a private package is processed.

Each private package can only reference one preset. A preset can be applied to a package by appending its identifier as a URI fragment:

```jsonc
{
"repositories": [
{
"type": "package",
"package": {
"name": "package-name/package-name",
"version": "1.0.0",
"dist": {
"type": "zip",
"url": "https://example.com/api/download?name=foobar&key={%PACKAGE_KEY}&version={%VERSION}#preset-1"
},
"require": {
"ffraenz/private-composer-installer": "^5.0"
}
}
}
],
"extra": {
"private-composer-installer": {
"presets": {
"preset-1": {/* … */},
"preset-2": {/* … */}
}
}
}
}
```

## Dependencies

This package heavily depends on [vlucas/phpdotenv](https://github.com/vlucas/phpdotenv) to load environment variables "automagically". This may cause version conflicts if your project already depends on it. Refer to this table to set the version of `private-composer-installer` accordingly or consider upgrading.
Expand Down Expand Up @@ -142,3 +239,5 @@ docker-compose run --rm composer composer test
---

This is a project by [Fränz Friederes](https://fraenz.frieder.es/) and [contributors](https://github.com/ffraenz/private-composer-installer/graphs/contributors)

[^1]: Only the [root package](https://getcomposer.org/doc/04-schema.md#root-package) can define this setting.
11 changes: 11 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"require": {
"php": "^7.1 || ^8.0",
"composer-plugin-api": "^1.0 || ^2.0",
"composer/semver": "^1.0 || ^2.0 || ^3.0",
"vlucas/phpdotenv": "^4.1 || ^5.2"
},
"require-dev": {
Expand All @@ -46,8 +47,18 @@
"FFraenz\\PrivateComposerInstaller\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"FFraenz\\PrivateComposerInstaller\\Test\\": "test/mocks"
}
},
"extra": {
"class": "FFraenz\\PrivateComposerInstaller\\Plugin",
"plugin-modifies-downloads": true
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
---
version: "3.1"

services:

composer:
Expand Down
Loading
Loading