[web-downloads] main: Add API documentation

From: Date: Wed, 24 Sep 2025 14:54:30 +0000
Subject: [web-downloads] main: Add API documentation
Groups: php.webmaster 
Request: Send a blank email to php-webmaster+get-33220@lists.php.net to get a copy of this message
Author: Shivam Mathur (shivammathur) Date: 2025-09-24T20:24:09+05:30 Commit: https://github.com/php/web-downloads/commit/acea0a817c271e764a3e4968fa81bf10a7534d76 Raw diff: https://github.com/php/web-downloads/commit/acea0a817c271e764a3e4968fa81bf10a7534d76.diff Add API documentation Changed paths: A API.md M README.md Diff: diff --git a/API.md b/API.md new file mode 100644 index 0000000..a4a865e --- /dev/null +++ b/API.md @@ -0,0 +1,148 @@ +## API + +### Base URL + +- All endpoints are routed via public/index.php. + +### Authentication + +- Endpoints marked with Auth: Required require a bearer token header: + - Header: Authorization: Bearer <AUTH_TOKEN> + +### Content type + +- For POST endpoints, send Content-Type: application/json and a valid JSON body. + - Invalid/malformed JSON will cause a decoding error (JSON exception) and the request will fail. + +### Errors + +- 200 OK: Successful request (body may be empty). +- 400 Bad Request: Validation failed. Response body starts with Invalid request: and includes per-field errors. +- 401 Unauthorized: Missing/invalid bearer token on protected endpoints. +- 404 Not Found: No route matches the requested path. +- 405 Method Not Allowed: Path exists but HTTP method is not allowed; response lists allowed methods. +- 500 Internal Server Error: Uncaught errors (e.g., download failure, malformed JSON, or other exceptions). + +--- + +### POST /api/php + +- Auth: Required +- Purpose: Upload PHP build artifact from a URL. +- Request body (JSON): + - url (string, required, URL): Direct download URL of the artifact. + - token (string, required): Used as a GitHub token if the URL points to api.github.com. +- Success: 200 OK. +- Errors: + - 400 with validation details if url or token are missing/invalid. + - 500 with Error: ... if the file could not be fetched or is not a ZIP. + +Example + +```bash +curl -i -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "url": "https://api.github.com/repos/org/repo/actions/artifacts/123/zip", + "token": "ghp_..." + }' \ + https://downloads.php.net/api/php +``` + +--- + +### POST /api/pecl + +- Auth: Required +- Purpose: Upload a PECL extension artifact. +- Request body (JSON): + - url (string, required, URL): Direct download URL of the artifact. + - extension (string, required): Extension name (used in filename). + - ref (string, required): Reference (e.g., tag/commit) used in filename. + - token (string, optional): Used as a GitHub token if the URL points to api.github.com. +- Success: 200 OK. +- Errors: + - 400 with validation details if required fields are missing/invalid. + - 500 with Error: ... if the file could not be fetched or is not a ZIP. + +Example + +```bash +curl -i -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "url": "https://api.github.com/repos/org/repo/actions/artifacts/456/zip", + "extension": "xdebug", + "ref": "3.3.2", + "token": "ghp_..." + }' \ + https://downloads.php.net/api/pecl +``` + +--- + +### POST /api/winlibs + +- Auth: Required +- Purpose: Record metadata and fetch all artifacts for a specific GitHub Actions workflow run of winlibs/winlib-builder. +- Request body (JSON): + - library (string, required) + - ref (string, required) + - workflow_run_id (string, required) + - php_versions (string, required): Comma-separated list matching ^(?:\d+\.\d+|master)(?:,\s*(?:\d+\.\d+|master))*$. + - vs_version_targets (string, required): Comma-separated list matching ^(v[c|s]\d{2})(,v[c|s]\d{2})*$. + - stability (string, required): stable, staging, or both (comma-separated) matching ^(stable|staging)(,(stable|staging))?$. + - token (string, required): GitHub token used to download artifacts. +- Success: 200 OK, empty body. +- Errors: + - 400 with validation details if input is invalid. + - Other failures are printed as cURL errors; HTTP status may still be 200 if not explicitly set. + +Example + +```bash +curl -i -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "library": "icu", + "ref": "main", + "workflow_run_id": "1234567890", + "php_versions": "8.1,8.2,8.3", + "vs_version_targets": "vc15,vs16", + "stability": "stable", + "token": "ghp_..." + }' \ + https://downloads.php.net/api/winlibs +``` + +--- + +### POST /api/series-init + +- Auth: Required +- Purpose: Initialize a series configuration by writing a JSON file into BUILDS_DIRECTORY/series. +- Request body (JSON): + - series (string, required) + - series_vs (string, required): Matches ^v[c|s]\d{2}$. + - target_vs (string, required): Matches ^v[c|s]\d{2}$. + - token (string, required) +- Success: 200 OK, empty body. +- Errors: 400 with validation details if input is invalid. + +Example + +```bash +curl -i -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "series": "8.4", + "series_vs": "vc15", + "target_vs": "vs16", + "token": "ghp_..." + }' \ + https://downloads.php.net/api/series-init +``` diff --git a/README.md b/README.md index 3759063..cb488a2 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,182 @@ It also has commands to process the downloaded files and update the relevant con Code must function on a vanilla PHP 8.2 installation. Please keep this in mind before filing a pull request. +## API + +### Base URL + +- All endpoints are served under your virtual host and routed via public/index.php. +- The API paths below are relative to the web root. + +### Authentication + +- Endpoints marked with Auth: Required require a bearer token header: + - Header: Authorization: Bearer <AUTH_TOKEN> + - The token is validated against the AUTH_TOKEN environment variable. + +### Content type + +- For POST endpoints, send Content-Type: application/json and a valid JSON body. + - Invalid/malformed JSON will cause a decoding error (JSON exception) and the request will fail. + +### Environment variables + +- AUTH_TOKEN (required for protected endpoints): Token expected in the Authorization header. +- BUILDS_DIRECTORY (required): Absolute path where downloaded artifacts and metadata are written. + +### Error model + +- 200 OK: Successful request (body may be empty). +- 400 Bad Request: Validation failed. Response body starts with Invalid request: and includes per-field errors. +- 401 Unauthorized: Missing/invalid bearer token on protected endpoints. +- 404 Not Found: No route matches the requested path. +- 405 Method Not Allowed: Path exists but HTTP method is not allowed; response lists allowed methods. +- 500 Internal Server Error: Uncaught errors (e.g., download failure, malformed JSON, or other exceptions). + +--- + +### GET /api + +- Auth: Not required +- Response: 200 OK, body: Welcome! + +Example + +```bash +curl -i \ + https://your.host/api +``` + +--- + +### POST /api/php + +- Auth: Required +- Purpose: Download a PHP build artifact from a URL into BUILDS_DIRECTORY/php. +- Request body (JSON): + - url (string, required, URL): Direct download URL of the artifact. + - token (string, required): Used as a GitHub token if the URL points to api.github.com. +- Success: 200 OK, empty body. File saved as php-{sha256(url)}{timestamp}.zip with permissions 0777. +- Errors: + - 400 with validation details if url or token are missing/invalid. + - 500 with Error: ... if the file could not be fetched or is not a ZIP. + +Example + +```bash +curl -i -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "url": "https://api.github.com/repos/org/repo/actions/artifacts/123/zip", + "token": "ghp_..." + }' \ + https://your.host/api/php +``` + +--- + +### POST /api/pecl + +- Auth: Required +- Purpose: Download a PECL extension artifact into BUILDS_DIRECTORY/pecl. +- Request body (JSON): + - url (string, required, URL): Direct download URL of the artifact. + - extension (string, required): Extension name (used in filename). + - ref (string, required): Reference (e.g., tag/commit) used in filename. + - token (string, optional): Used as a GitHub token if the URL points to api.github.com. +- Success: 200 OK, empty body. File saved as {extension}-{ref}-{sha256(url)}{timestamp}.zip with permissions 0777. +- Errors: + - 400 with validation details if required fields are missing/invalid. + - 500 with Error: ... if the file could not be fetched or is not a ZIP. + +Example + +```bash +curl -i -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "url": "https://api.github.com/repos/org/repo/actions/artifacts/456/zip", + "extension": "xdebug", + "ref": "3.3.2", + "token": "ghp_..." + }' \ + https://your.host/api/pecl +``` + +--- + +### POST /api/winlibs + +- Auth: Required +- Purpose: Record metadata and fetch all artifacts for a specific GitHub Actions workflow run of winlibs/winlib-builder into BUILDS_DIRECTORY/winlibs/{workflow_run_id}. +- Request body (JSON): + - library (string, required) + - ref (string, required) + - workflow_run_id (string, required) + - php_versions (string, required): Comma-separated list matching ^(?:\d+\.\d+|master)(?:,\s*(?:\d+\.\d+|master))*$. + - vs_version_targets (string, required): Comma-separated list matching ^(v[c|s]\d{2})(,v[c|s]\d{2})*$. + - stability (string, required): stable, staging, or both (comma-separated) matching ^(stable|staging)(,(stable|staging))?$. + - token (string, required): GitHub token used to download artifacts. +- Side effects: + - Downloads each artifact as {artifact_name}.zip into the workflow directory. + - Writes the entire request body to {workflow_dir}/data.json. +- Success: 200 OK, empty body. +- Errors: + - 400 with validation details if input is invalid. + - Other failures are printed as cURL errors; HTTP status may still be 200 if not explicitly set. + +Example + +```bash +curl -i -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "library": "icu", + "ref": "main", + "workflow_run_id": "1234567890", + "php_versions": "8.1,8.2,8.3", + "vs_version_targets": "vc15,vs16", + "stability": "stable", + "token": "ghp_..." + }' \ + https://your.host/api/winlibs +``` + +--- + +### POST /api/series-init + +- Auth: Required +- Purpose: Initialize a series configuration by writing a JSON file into BUILDS_DIRECTORY/series. +- Request body (JSON): + - series (string, required) + - series_vs (string, required): Matches ^v[c|s]\d{2}$. + - target_vs (string, required): Matches ^v[c|s]\d{2}$. + - token (string, required) +- Side effects: + + - Writes series-init-{sha256(series)}{timestamp}.json containing the request body. +- Success: 200 OK, empty body. +- Errors: 400 with validation details if input is invalid. + +Example + +```bash +curl -i -X POST \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "series": "8.4", + "series_vs": "vc15", + "target_vs": "vs16", + "token": "ghp_..." + }' \ + https://your.host/api/series-init +``` + ## License [MIT](LICENSE)

« previous php.webmaster (#33220) next »