Compare commits

..
Author SHA1 Message Date
Shivam Mathur 084302964f Add thin PIE CLI extension installation helpers 2026-11-08 04:13:55 +05:30
Shivam Mathur 272385f548 Bump package version
Update Node.js dependencies
2026-11-05 15:04:39 +05:30
Shivam Mathur 9a96576163 Use published deepmerge fork for npm 12 compatibility 2026-11-03 17:35:37 +05:30
Shivam Mathur 75cc97469e Rebuild distribution for Deployer GitHub downloads 2026-11-03 17:24:47 +05:30
Miriam MüllerandClaude Opus 5.5 7456d5cfaf Deployer GitHub releases (#1149)
* Download Deployer from GitHub releases

Resolve the Deployer phar URL from the deployphp/deployer GitHub
releases instead of fetching the deployer.org manifest, keeping
deployer.org as a fallback for versions not published on GitHub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Use real Deployer version in checksum test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:24:25 +05:30
Shivam Mathur 0b3aa3e956 Fix PECL extension minimum stability resolution 2026-11-02 03:40:24 +05:30
Shivam Mathur 73aede52cb Fix npm audit vulnerabilities 2026-11-01 06:05:46 +05:30
IvanCraft623 7542bc9e62 Fix building extensions from git without a sub directory on bash 5.3 2026-11-01 05:34:44 +05:30
dependabot[bot] 0825094f51 Bump the github-actions group with 4 updates
Bumps the github-actions group with 4 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [shivammathur/cache-extensions](https://github.com/shivammathur/cache-extensions).


Updates `github/codeql-action/init` from 4.39.0 to 4.39.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee...9b3254085494b55a0f7c4c2b3d2d52cc712ce370)

Updates `github/codeql-action/autobuild` from 4.39.0 to 4.39.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee...9b3254085494b55a0f7c4c2b3d2d52cc712ce370)

Updates `github/codeql-action/analyze` from 4.39.0 to 4.39.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee...9b3254085494b55a0f7c4c2b3d2d52cc712ce370)

Updates `shivammathur/cache-extensions` from 1.15.4 to 1.15.6
- [Release notes](https://github.com/shivammathur/cache-extensions/releases)
- [Commits](https://github.com/shivammathur/cache-extensions/compare/82e72d795771d15c7a99152ca91ea5a95b1a9fdb...d894929efeece5f8d386bd667369b321947064ad)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: shivammathur/cache-extensions
  dependency-version: 1.15.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-31 16:33:47 +05:30
dependabot[bot] c1d501696e Bump the github-actions group with 4 updates
Bumps the github-actions group with 4 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [shivammathur/cache-extensions](https://github.com/shivammathur/cache-extensions).


Updates `github/codeql-action/init` from 4.38.3 to 4.39.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/24c54180a607b1449ed407dd24f251e4e9147c8d...6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee)

Updates `github/codeql-action/autobuild` from 4.38.3 to 4.39.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/24c54180a607b1449ed407dd24f251e4e9147c8d...6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee)

Updates `github/codeql-action/analyze` from 4.38.3 to 4.39.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/24c54180a607b1449ed407dd24f251e4e9147c8d...6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee)

Updates `shivammathur/cache-extensions` from 1.15.2 to 1.15.4
- [Release notes](https://github.com/shivammathur/cache-extensions/releases)
- [Commits](https://github.com/shivammathur/cache-extensions/compare/22e24453af1bf3851994136f122ce065ab828a74...82e72d795771d15c7a99152ca91ea5a95b1a9fdb)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: shivammathur/cache-extensions
  dependency-version: 1.15.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-24 18:43:14 +05:30
Shivam Mathur b430072a48 Allow two-component PECL extension versions 2026-10-23 12:44:42 +05:30
Shivam Mathur 3bdfe21000 Validate pinned PECL extension versions 2026-10-22 17:06:10 +05:30
Shivam Mathur ff0b532a6d Preserve PHPUnit diagnostics and native annotation levels 2026-10-22 16:48:57 +05:30
John Rayes fd2044be8d ci: Extend PHPUnit problem matcher to annotate more test outcomes
The matcher only annotated failures whose output matched a single
layout ("Failed asserting that..." followed by a blank line and
file:line). Extend it so more of the output PHPUnit produces is
surfaced as GitHub annotations:

- Failures with no blank line before file:line
- Failures with a custom assertion message ahead of "Failed asserting",
  with and without a blank line (e.g. BBCTest attribute breakout)
- Risky tests and skipped tests that have a reason, as warnings
- Skipped tests with no reason (header followed by file:line), as warnings
- Tests skipped through @depends, which print no file:line, as warnings

The warning-level matchers exclude "Failed asserting" lines so failures
are not annotated a second time.
2026-10-22 16:48:57 +05:30
dependabot[bot] 7769f838bc Bump the github-actions group with 7 updates
Bumps the github-actions group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [github/codeql-action/init](https://github.com/github/codeql-action) | `4.38.2` | `4.38.3` |
| [github/codeql-action/autobuild](https://github.com/github/codeql-action) | `4.38.2` | `4.38.3` |
| [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.38.2` | `4.38.3` |
| [shivammathur/setup-php](https://github.com/shivammathur/setup-php) | `2.37.2` | `2.40.0` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `7.0.1` | `7.0.2` |
| [actions/download-artifact](https://github.com/actions/download-artifact) | `8.0.1` | `8.0.2` |
| [actions/setup-node](https://github.com/actions/setup-node) | `7.0.0` | `7.1.0` |


Updates `github/codeql-action/init` from 4.38.2 to 4.38.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d)

Updates `github/codeql-action/autobuild` from 4.38.2 to 4.38.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d)

Updates `github/codeql-action/analyze` from 4.38.2 to 4.38.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d)

Updates `shivammathur/setup-php` from 2.37.2 to 2.40.0
- [Release notes](https://github.com/shivammathur/setup-php/releases)
- [Commits](https://github.com/shivammathur/setup-php/compare/2.37.2...eb7c497e18156a6bbabfef1d3a82760b9eda3962)

Updates `actions/upload-artifact` from 7.0.1 to 7.0.2
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/043fb46d1a93c77aae656e7c1c64a875d1fc6a0a...cf430e030ddbb5b0abf93d22962f4752f3646cd9)

Updates `actions/download-artifact` from 8.0.1 to 8.0.2
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c...9000827ccba6bdab643e8b6fd33ac0654aef8333)

Updates `actions/setup-node` from 7.0.0 to 7.1.0
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/820762786026740c76f36085b0efc47a31fe5020...949feb2413d6458794dcd2491c4babbbce0c15c1)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: shivammathur/setup-php
  dependency-version: 2.40.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/download-artifact
  dependency-version: 8.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/setup-node
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-17 17:05:56 +05:30
Shivam Mathur f7b8145ef0 Skip installing dependencies that are already installed 2026-10-17 16:57:09 +05:30
Shivam Mathur 19d3947a16 Fix fallback to latest release containing tool PHAR 2026-10-12 09:48:45 +05:30
Shivam Mathur 5a89ae6dd6 Update setup-php in docs workflow [skip ci] 2026-10-10 21:35:44 +05:30
dependabot[bot] b828e3206e Bump shivammathur/cache-extensions
Bumps the github-actions group with 1 update: [shivammathur/cache-extensions](https://github.com/shivammathur/cache-extensions).


Updates `shivammathur/cache-extensions` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/shivammathur/cache-extensions/releases)
- [Commits](https://github.com/shivammathur/cache-extensions/compare/de3c642a5fce0ef91581a1c9831e229f525196d6...22e24453af1bf3851994136f122ce065ab828a74)

---
updated-dependencies:
- dependency-name: shivammathur/cache-extensions
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-10 16:18:51 +05:30
Michael Lip c463b1d02f Keep a two digit minor in parseVersion (#1134)
Co-authored-by: Michael Lip <51033404+theluckystrike@users.noreply.github.com>
2026-10-10 15:23:58 +05:30
Shivam Mathur db75472672 Fall back to PHAR when Composer tool installation fails 2026-10-10 12:24:10 +05:30
Shivam Mathur 40d4c7a0d3 Modernize the tools manifest schema to Draft 2020-12 2026-10-10 12:24:10 +05:30
Shivam Mathur f5a207e3fa Use Homebrew API when the core tap is missing 2026-10-09 10:56:37 +05:30
Shivam Mathur 11b9f9a7f0 Migrate the action and tests to ES modules 2026-10-09 00:14:33 +05:30
Shivam Mathur f1477a078f Install PHPStan using scoped Composer 2026-10-08 22:36:54 +05:30
Shivam Mathur 0534f032be Bump Node.js dependencies and support ESM packages 2026-10-08 22:36:54 +05:30
42 changed files with 960 additions and 1665 deletions
+3 -3
View File
@@ -26,13 +26,13 @@ jobs:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4
uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4
with:
config-file: ./.github/codeql/codeql-configuration.yml
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4
uses: github/codeql-action/autobuild@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4
uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4
+4 -4
View File
@@ -23,7 +23,7 @@ jobs:
php-versions: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5', '8.6', '8.7']
steps:
- name: Setup PHP
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2
uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2
with:
php-version: ${{ matrix.php-versions }}
tools: none
@@ -42,7 +42,7 @@ jobs:
run: |
php -m | Out-File -FilePath "$env:file.all" -Append
- name: Setup PHP
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2
uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2
with:
php-version: ${{ matrix.php-versions }}
extensions: none
@@ -91,7 +91,7 @@ jobs:
Remove-Item "$env:file.all" -Force
Remove-Item "$env:file.builtin" -Force
- name: Upload artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
with:
name: lists-php${{ matrix.php-versions }}-${{ matrix.operating-system }}.md
path: php${{ matrix.php-versions }}-${{ matrix.operating-system }}.md
@@ -109,7 +109,7 @@ jobs:
repository: ${{ github.repository }}.wiki
persist-credentials: false
- name: Download artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8
with:
path: ${{ github.workspace }}/lists
pattern: lists-*
+1 -1
View File
@@ -39,7 +39,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js 24.x
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6
with:
node-version: 24.x
+1 -1
View File
@@ -48,7 +48,7 @@ jobs:
- name: Setup cache environment
id: cache-env
uses: shivammathur/cache-extensions@de3c642a5fce0ef91581a1c9831e229f525196d6 # v1
uses: shivammathur/cache-extensions@d894929efeece5f8d386bd667369b321947064ad # v1
with:
php-version: ${{ matrix.php-versions || env.default-php-version }}
extensions: ${{ env.extensions }}
+2 -2
View File
@@ -38,7 +38,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6
with:
node-version: '24.x'
registry-url: https://registry.npmjs.org
@@ -60,7 +60,7 @@ jobs:
run: npm publish --access public --tag "${{ steps.publish-tag.outputs.tag }}"
- name: Change to GitHub Packages registry
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6
with:
registry-url: https://npm.pkg.github.com
package-manager-cache: false
+2
View File
@@ -174,6 +174,8 @@ PHP extensions can be set up using the `extensions` input. It accepts a `string`
- Extensions with pre-release versions available on `PECL` can be set up by suffixing the extension's name with its state i.e `alpha`, `beta`, `devel` or `snapshot`.
This sets the minimum stability. The newest release with that stability or a more stable state is selected.
```yaml
- name: Setup PHP with pre-release PECL extension
uses: shivammathur/setup-php@v2
+1 -1
View File
@@ -1,4 +1,4 @@
import * as config from '../src/config';
import * as config from '../src/config.js';
describe('Config tests', () => {
it.each`
+2 -1
View File
@@ -1,4 +1,5 @@
import * as core from '../src/core';
import {jest} from '@jest/globals';
import * as core from '../src/core.js';
describe('Core tests', () => {
const originalEnv = process.env;
+1 -1
View File
@@ -1,4 +1,4 @@
import * as coverage from '../src/coverage';
import * as coverage from '../src/coverage.js';
describe('Config tests', () => {
it.each`
+2 -1
View File
@@ -1,5 +1,5 @@
import * as fs from 'fs';
import * as extensions from '../src/extensions';
import * as extensions from '../src/extensions.js';
describe('Extension tests', () => {
it.each`
@@ -7,6 +7,7 @@ describe('Extension tests', () => {
${'none'} | ${'7.4'} | ${'Disable-AllShared'}
${':intl'} | ${'7.4'} | ${'Disable-Extension intl'}
${'ast-beta'} | ${'7.4'} | ${'Add-Extension ast beta'}
${'ast-stable'} | ${'7.4'} | ${'Add-Extension ast stable'}
${'blackfire'} | ${'7.3'} | ${'Add-Blackfire blackfire'}
${'blackfire-1.31.0'} | ${'7.3'} | ${'Add-Blackfire blackfire-1.31.0'}
${'grpc-1.2.3'} | ${'7.4'} | ${'Add-Extension grpc stable 1.2.3'}
+1 -1
View File
@@ -1,4 +1,4 @@
import * as fetch from '../src/fetch';
import * as fetch from '../src/fetch.js';
import nock from 'nock';
beforeAll(() => nock.disableNetConnect());
+7 -5
View File
@@ -1,12 +1,11 @@
import * as install from '../src/install';
import * as utils from '../src/utils';
import {jest} from '@jest/globals';
/**
* Mock install.ts
*/
jest.mock('../src/install', () => ({
jest.unstable_mockModule('../src/install.js', () => ({
getScript: jest
.fn()
.fn<typeof import('../src/install.js').getScript>()
.mockImplementation(async (os: string): Promise<string> => {
const filename = os + (await utils.scriptExtension(os));
const version: string = await utils.parseVersion(
@@ -36,7 +35,7 @@ jest.mock('../src/install', () => ({
/**
* Mock fetch.ts
*/
jest.mock('../src/fetch', () => ({
jest.unstable_mockModule('../src/fetch.js', () => ({
fetch: jest.fn().mockImplementation(() => {
return {
data: '{ "latest": "8.3", "lowest": "8.1", "highest": "8.3", "nightly": "8.4", "5.x": "5.6" }'
@@ -44,6 +43,9 @@ jest.mock('../src/fetch', () => ({
})
}));
const utils = await import('../src/utils.js');
const install = await import('../src/install.js');
describe('Install', () => {
it.each`
version | os | extension_csv | ini_file | ini_values_csv | coverage_driver | tools | output
+1 -1
View File
@@ -1,4 +1,4 @@
import * as packagist from '../src/packagist';
import * as packagist from '../src/packagist.js';
import nock from 'nock';
beforeAll(() => nock.disableNetConnect());
+95 -73
View File
@@ -1,6 +1,6 @@
import * as fs from 'fs';
import * as tools from '../src/tools';
import {ToolData, ToolInput} from '../src/tools';
import {jest} from '@jest/globals';
import fs from 'fs';
import type {ToolData, ToolInput} from '../src/tools.js';
function getData(data: Partial<ToolData>): ToolData {
const tool = data.tool || 'tool';
@@ -40,16 +40,12 @@ function unsetComposerAuthEnv(): void {
/**
* Mock fetch.ts
*/
jest.mock('../src/fetch', () => ({
jest.unstable_mockModule('../src/fetch.js', () => ({
fetch: jest
.fn()
.fn<typeof import('../src/fetch.js').fetch>()
.mockImplementation(
async (url: string, token?: string): Promise<Record<string, string>> => {
if (url.includes('deployer')) {
return {
data: '[{"version": "1.2.3", "url": "https://deployer.org/releases/v1.2.3/deployer.phar"}]'
};
} else if (url.includes('atom') && !url.includes('no-')) {
if (url.includes('atom') && !url.includes('no-')) {
return {
data: '"releases/tag/1.2.3", "releases/tag/3.2.1", "releases/tag/2.3.1"'
};
@@ -86,9 +82,9 @@ jest.mock('../src/fetch', () => ({
)
}));
jest.mock('../src/packagist', () => ({
jest.unstable_mockModule('../src/packagist.js', () => ({
search: jest
.fn()
.fn<typeof import('../src/packagist.js').search>()
.mockImplementation(
async (
package_name: string,
@@ -102,6 +98,10 @@ jest.mock('../src/packagist', () => ({
)
}));
const tools = await import('../src/tools.js');
afterEach(() => jest.restoreAllMocks());
describe('Tools tests', () => {
it.each`
token | version
@@ -381,6 +381,56 @@ describe('Tools tests', () => {
}
);
it.each`
release | resolved
${'phpstan'} | ${'latest/download'}
${'phpstan:0.12.68'} | ${'download/0.12.68'}
${'phpstan:^0.12.68'} | ${'download/0.12.68'}
${'phpstan:0.12'} | ${'download/1.2.3'}
${'phpstan:0.12.x'} | ${'download/1.2.3'}
${'phpstan:0.12.*'} | ${'download/1.2.3'}
`(
'resolving PHPStan PHAR fallback for $release',
async ({release, resolved}) => {
unsetComposerAuthEnv();
for (const os of ['linux', 'darwin', 'win32']) {
const data = await tools.getData(release, '8.0', os);
const script = await tools.addPackage(data);
expect(script).toContain(
'scoped https://github.com/phpstan/phpstan/releases/' +
resolved +
'/phpstan.phar "-V"'
);
expect(data.type).toBe('composer');
expect(data.release).toContain('phpstan');
}
}
);
it('keeps Composer available when the fallback version lookup fails', async () => {
process.env['GITHUB_TOKEN'] = 'invalid_token';
const data = await tools.getData('phpstan:0.12', '8.0', 'linux');
expect(await tools.addPackage(data)).toBe(
'add_composer_tool phpstan "phpstan:0.12.*" phpstan/ scoped'
);
unsetComposerAuthEnv();
});
it('uses fallback settings independently of the Composer repository', async () => {
const data = await tools.getData('vendor/tool:1.2.3', '8.0', 'linux', {
fallback: {
type: 'phar',
repository: 'releases/tool',
domain: 'https://example.com',
extension: '.phar',
version_prefix: 'v'
}
});
expect(await tools.addPackage(data)).toBe(
'add_composer_tool tool tool:1.2.3 vendor/ global https://example.com/releases/tool/v1.2.3/tool.phar ""'
);
});
it.each`
version | php_version | os | script
${'latest'} | ${'8.0'} | ${'linux'} | ${'add_tool https://github.com/phar-io/phive/releases/download/3.2.1/phive-3.2.1.phar phive'}
@@ -431,13 +481,15 @@ describe('Tools tests', () => {
it.each`
version | url
${'latest'} | ${'https://deployer.org/deployer.phar'}
${'1.2.3'} | ${'https://deployer.org/releases/v1.2.3/deployer.phar'}
${'3.2.1'} | ${'Version missing in deployer manifest'}
${'latest'} | ${'https://github.com/deployphp/deployer/releases/latest/download/deployer.phar,https://deployer.org/deployer.phar deployer'}
${'7.5.12'} | ${'https://github.com/deployphp/deployer/releases/download/v7.5.12/deployer.phar,https://deployer.org/releases/v7.5.12/deployer.phar deployer'}
${'6.8.0'} | ${'https://github.com/deployphp/deployer/releases/download/v6.8.0/deployer.phar,https://deployer.org/releases/v6.8.0/deployer.phar deployer'}
`('checking addDeployer: $version', async ({version, url}) => {
const data = getData({
tool: 'deployer',
domain: 'https://deployer.org',
repository: 'deployphp/deployer',
version_prefix: 'v',
version: version
});
expect(await tools.addDeployer(data)).toContain(url);
@@ -527,30 +579,11 @@ describe('Tools tests', () => {
});
it('checking affected composer version with CRLF ranges', async () => {
let affected = false;
let fixed = true;
await jest.isolateModulesAsync(async () => {
jest.doMock('fs', () => ({
...jest.requireActual('fs'),
readFileSync: (
filePath: fs.PathOrFileDescriptor,
options?: unknown
) => {
if (String(filePath).includes('composer-gh-auth-no-op')) {
return '1.0.0-0 1.10.28\r\n2.0.0-0 2.2.28\r\n2.3.0-0 2.9.8';
}
return (jest.requireActual('fs') as typeof fs).readFileSync(
filePath,
options as fs.ObjectEncodingOptions & {flag?: string}
);
}
}));
const isolatedTools = jest.requireActual<typeof tools>('../src/tools');
affected = isolatedTools.skipGitHubAuthForComposerVersion('2.9.7');
fixed = isolatedTools.skipGitHubAuthForComposerVersion('2.9.8');
});
expect(affected).toBe(true);
expect(fixed).toBe(false);
jest
.spyOn(fs, 'readFileSync')
.mockReturnValue('1.0.0-0 1.10.28\r\n2.0.0-0 2.2.28\r\n2.3.0-0 2.9.8');
expect(tools.skipGitHubAuthForComposerVersion('2.9.7')).toBe(true);
expect(tools.skipGitHubAuthForComposerVersion('2.9.8')).toBe(false);
});
it.each`
@@ -655,7 +688,7 @@ describe('Tools tests', () => {
'add_tool https://github.com/humbug/php-scoper/releases/latest/download/php-scoper.phar php-scoper "--version"',
'add_tool https://github.com/phpDocumentor/phpDocumentor/releases/latest/download/phpDocumentor.phar phpDocumentor "--version"',
'add_composer_tool phplint phplint overtrue/',
'add_tool https://github.com/phpstan/phpstan/releases/latest/download/phpstan.phar phpstan "-V"',
'add_composer_tool phpstan phpstan phpstan/ scoped',
'add_tool https://phar.phpunit.de/phpunit-7.4.0.phar,https://phar.phpunit.de/phpunit-7.phar phpunit "--version"',
'add_pecl',
'add_tool https://www.phing.info/get/phing-latest.phar phing "-v"',
@@ -744,7 +777,7 @@ describe('Tools tests', () => {
'blackfire-player is not a windows tool',
'Add-Tool https://github.com/staabm/annotate-pull-request-from-checkstyle/releases/latest/download/cs2pr cs2pr "-V"',
'Add-Tool https://github.com/bmitch/churn-php/releases/latest/download/churn.phar churn "-V"',
'Add-Tool https://deployer.org/deployer.phar deployer "-V"',
'Add-Tool https://github.com/deployphp/deployer/releases/latest/download/deployer.phar,https://deployer.org/deployer.phar deployer "-V"',
'Tool does_not_exist is not supported',
'Add-ComposerTool flex flex symfony/ global',
'Add-Mago',
@@ -830,19 +863,20 @@ describe('Tools tests', () => {
});
it.each`
tools_csv | os | script
${'phpunit:9.5.0@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_tool https://phar.phpunit.de/phpunit-9.5.0.phar,https://phar.phpunit.de/phpunit-9.phar phpunit "--version" sha256:' + 'a'.repeat(64)}
${'phpunit:9.5.0@sha256:' + 'a'.repeat(64)} | ${'win32'} | ${'Add-Tool https://phar.phpunit.de/phpunit-9.5.0.phar,https://phar.phpunit.de/phpunit-9.phar phpunit "--version" sha256:' + 'a'.repeat(64)}
${'composer:2.9.8@sha256:' + 'b'.repeat(64)} | ${'linux'} | ${'composer 2.9.8 sha256:' + 'b'.repeat(64)}
${'cs2pr:1.2.3@sha256:' + 'd'.repeat(64)} | ${'linux'} | ${'add_tool https://github.com/staabm/annotate-pull-request-from-checkstyle/releases/download/1.2.3/cs2pr cs2pr "-V" sha256:' + 'd'.repeat(64)}
${'phive:0.15.3@sha512:' + 'c'.repeat(128)} | ${'darwin'} | ${'add_tool https://github.com/phar-io/phive/releases/download/0.15.3/phive-0.15.3.phar phive "status" sha512:' + 'c'.repeat(128)}
${'phinx:1.2.3@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "phinx" "Checksum verification is not supported for phinx"'}
${'pecl:1.2.3@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "pecl" "Checksum verification is not supported for pecl"'}
${'phpunit:9.5.0@sha256:invalid'} | ${'linux'} | ${'add_log "$cross" "phpunit" "Invalid sha256 checksum, expected 64 hexadecimal characters"'}
${'composer:2.9.8@SHA256:' + 'b'.repeat(64)} | ${'linux'} | ${'composer 2.9.8 sha256:' + 'b'.repeat(64)}
${'composer:2.9.8@sha384:' + 'b'.repeat(96)} | ${'linux'} | ${'add_log "$cross" "composer" "Unsupported checksum algorithm sha384, expected sha256 or sha512"'}
${'composer:2.9.8@md5:' + 'b'.repeat(32)} | ${'linux'} | ${'add_log "$cross" "composer" "Unsupported checksum algorithm md5, expected sha256 or sha512"'}
${'composer:2.9.8@sha256' + 'b'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "composer" "Invalid checksum syntax, expected @sha256:<hash> or @sha512:<hash>"'}
tools_csv | os | script
${'phpunit:9.5.0@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_tool https://phar.phpunit.de/phpunit-9.5.0.phar,https://phar.phpunit.de/phpunit-9.phar phpunit "--version" sha256:' + 'a'.repeat(64)}
${'phpunit:9.5.0@sha256:' + 'a'.repeat(64)} | ${'win32'} | ${'Add-Tool https://phar.phpunit.de/phpunit-9.5.0.phar,https://phar.phpunit.de/phpunit-9.phar phpunit "--version" sha256:' + 'a'.repeat(64)}
${'composer:2.9.8@sha256:' + 'b'.repeat(64)} | ${'linux'} | ${'composer 2.9.8 sha256:' + 'b'.repeat(64)}
${'cs2pr:1.2.3@sha256:' + 'd'.repeat(64)} | ${'linux'} | ${'add_tool https://github.com/staabm/annotate-pull-request-from-checkstyle/releases/download/1.2.3/cs2pr cs2pr "-V" sha256:' + 'd'.repeat(64)}
${'deployer:7.5.12@sha256:' + 'e'.repeat(64)} | ${'linux'} | ${'add_tool https://github.com/deployphp/deployer/releases/download/v7.5.12/deployer.phar,https://deployer.org/releases/v7.5.12/deployer.phar deployer "-V" sha256:' + 'e'.repeat(64)}
${'phive:0.15.3@sha512:' + 'c'.repeat(128)} | ${'darwin'} | ${'add_tool https://github.com/phar-io/phive/releases/download/0.15.3/phive-0.15.3.phar phive "status" sha512:' + 'c'.repeat(128)}
${'phinx:1.2.3@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "phinx" "Checksum verification is not supported for phinx"'}
${'pecl:1.2.3@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "pecl" "Checksum verification is not supported for pecl"'}
${'phpunit:9.5.0@sha256:invalid'} | ${'linux'} | ${'add_log "$cross" "phpunit" "Invalid sha256 checksum, expected 64 hexadecimal characters"'}
${'composer:2.9.8@SHA256:' + 'b'.repeat(64)} | ${'linux'} | ${'composer 2.9.8 sha256:' + 'b'.repeat(64)}
${'composer:2.9.8@sha384:' + 'b'.repeat(96)} | ${'linux'} | ${'add_log "$cross" "composer" "Unsupported checksum algorithm sha384, expected sha256 or sha512"'}
${'composer:2.9.8@md5:' + 'b'.repeat(32)} | ${'linux'} | ${'add_log "$cross" "composer" "Unsupported checksum algorithm md5, expected sha256 or sha512"'}
${'composer:2.9.8@sha256' + 'b'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "composer" "Invalid checksum syntax, expected @sha256:<hash> or @sha512:<hash>"'}
`(
'checking addTools with checksum: $tools_csv, $os',
async ({tools_csv, os, script}) => {
@@ -948,26 +982,14 @@ describe('Tools tests', () => {
}
});
let result: string = '';
await jest.isolateModulesAsync(async () => {
jest.doMock('fs', () => ({
...jest.requireActual('fs'),
readFileSync: (
filePath: fs.PathOrFileDescriptor,
options?: unknown
) => {
if (String(filePath).includes('tools.json')) {
return brokenToolsJson;
}
return (jest.requireActual('fs') as typeof fs).readFileSync(
filePath,
options as fs.ObjectEncodingOptions & {flag?: string}
);
}
}));
const isolatedTools = jest.requireActual<typeof tools>('../src/tools');
result = await isolatedTools.addTools('broken-tool', '7.4', 'linux');
const readFileSync = fs.readFileSync;
jest.spyOn(fs, 'readFileSync').mockImplementation((filePath, options) => {
if (String(filePath).includes('tools.json')) {
return brokenToolsJson;
}
return readFileSync(filePath, options);
});
const result = await tools.addTools('broken-tool', '7.4', 'linux');
expect(result).toContain(
'add_log "$cross" "broken-tool" "broken-tool has no function defined. Please report this issue."'
+16 -8
View File
@@ -1,8 +1,13 @@
import {fileURLToPath} from 'url';
import {jest} from '@jest/globals';
import fs from 'fs';
import os from 'os';
import * as path from 'path';
import * as utils from '../src/utils';
import * as fetchModule from '../src/fetch';
const fetchMock = jest.fn<typeof import('../src/fetch.js').fetch>();
jest.unstable_mockModule('../src/fetch.js', () => ({fetch: fetchMock}));
const utils = await import('../src/utils.js');
const dirname = path.dirname(fileURLToPath(import.meta.url));
describe('Utils tests', () => {
it('checking readEnv', async () => {
@@ -40,9 +45,9 @@ describe('Utils tests', () => {
});
it('checking parseVersion', async () => {
const fetchSpy = jest.spyOn(fetchModule, 'fetch').mockResolvedValue({
const fetchSpy = fetchMock.mockResolvedValue({
data: fs.readFileSync(
path.join(__dirname, '../src/configs/php-versions.json'),
path.join(dirname, '../src/configs/php-versions.json'),
'utf8'
)
});
@@ -53,6 +58,9 @@ describe('Utils tests', () => {
expect(await utils.parseVersion('8.7.0')).toBe('8.7');
expect(await utils.parseVersion('7')).toBe('7.0');
expect(await utils.parseVersion('7.4')).toBe('7.4');
expect(await utils.parseVersion('8.10')).toBe('8.10');
expect(await utils.parseVersion('10')).toBe('10.0');
expect(await utils.parseVersion('10.0')).toBe('10.0');
expect(await utils.parseVersion('5.x')).toBe('5.6');
expect(await utils.parseVersion('pre')).toBe('pre');
expect(await utils.parseVersion('pre-installed')).toBe('pre');
@@ -324,8 +332,8 @@ describe('Utils tests', () => {
"Could not find '.phpenv-version' file."
);
const existsSync = jest.spyOn(fs, 'existsSync').mockImplementation();
const readFileSync = jest.spyOn(fs, 'readFileSync').mockImplementation();
const existsSync = jest.spyOn(fs, 'existsSync').mockReturnValue(false);
const readFileSync = jest.spyOn(fs, 'readFileSync').mockReturnValue('');
existsSync.mockReturnValue(true);
readFileSync.mockReturnValue('8.1');
@@ -391,8 +399,8 @@ describe('Utils tests', () => {
});
it('readPHPVersion rejects unsupported values from each source', async () => {
const existsSync = jest.spyOn(fs, 'existsSync').mockImplementation();
const readFileSync = jest.spyOn(fs, 'readFileSync').mockImplementation();
const existsSync = jest.spyOn(fs, 'existsSync').mockReturnValue(false);
const readFileSync = jest.spyOn(fs, 'readFileSync').mockReturnValue('');
process.env['php-version'] = '$0';
await expect(utils.readPHPVersion()).rejects.toThrow('php-version input');
-1157
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
{
"type": "module"
}
+6 -1
View File
@@ -1,5 +1,5 @@
import {createRequire} from 'node:module';
import typescriptEslint from '@typescript-eslint/eslint-plugin';
import {importX} from 'eslint-plugin-import-x';
import jest from 'eslint-plugin-jest';
import prettierRecommended from 'eslint-plugin-prettier/recommended';
import eslintConfigPrettier from 'eslint-config-prettier';
@@ -7,6 +7,11 @@ import globals from 'globals';
import tsParser from '@typescript-eslint/parser';
import js from '@eslint/js';
// Until import-x supports minimatch 11, use its CommonJS entry point to avoid
// the removed makeRe import in no-internal-modules, unused by these presets.
// https://github.com/un-ts/eslint-plugin-import-x/pull/570
const {importX} = createRequire(import.meta.url)('eslint-plugin-import-x');
export default [
js.configs.recommended,
...typescriptEslint.configs['flat/recommended'],
+6 -2
View File
@@ -1,11 +1,15 @@
module.exports = {
export default {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
extensionsToTreatAsEsm: ['.ts'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1'
},
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.ts$': ['ts-jest', {tsconfig: 'tsconfig.test.json'}]
'^.+\\.ts$': ['ts-jest', {tsconfig: 'tsconfig.test.json', useESM: true}]
},
verbose: true,
collectCoverage: true
+192 -140
View File
@@ -1,12 +1,12 @@
{
"name": "setup-php",
"version": "2.40.0",
"version": "2.40.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "setup-php",
"version": "2.40.0",
"version": "2.40.1",
"license": "MIT",
"dependencies": {
"@actions/exec": "^3.0.0",
@@ -16,24 +16,24 @@
"@eslint/compat": "^2.1.1",
"@eslint/js": "^10.0.1",
"@types/jest": "^30.0.0",
"@types/node": "^26.6.4",
"@typescript-eslint/eslint-plugin": "^8.71.1",
"@typescript-eslint/parser": "^8.71.1",
"@types/node": "^26.6.6",
"@typescript-eslint/eslint-plugin": "^8.72.1",
"@typescript-eslint/parser": "^8.72.1",
"@typescript/native": "npm:typescript@^7.0.2",
"@vercel/ncc": "^0.45.0",
"eslint": "^10.12.0",
"eslint": "^10.14.0",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-import-x": "^4.17.1",
"eslint-plugin-jest": "^29.16.6",
"eslint-plugin-prettier": "^5.5.6",
"globals": "^17.13.0",
"eslint-plugin-jest": "^29.17.0",
"eslint-plugin-prettier": "^5.5.7",
"globals": "^17.14.0",
"jest": "^30.5.2",
"jest-circus": "^30.5.2",
"nock": "^15.0.1",
"prettier": "^3.9.9",
"nock": "^15.0.5",
"prettier": "^3.9.10",
"simple-git-hooks": "^2.14.0",
"ts-jest": "^29.4.14",
"ts-jest": "^29.4.15",
"typescript": "npm:@typescript/typescript6@^6.0.2"
}
},
@@ -592,6 +592,17 @@
"keyv": "^5.6.0"
}
},
"node_modules/@dual-bundle/import-meta-resolve": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.2.1.tgz",
"integrity": "sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==",
"dev": true,
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/JounQin"
}
},
"node_modules/@emnapi/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
@@ -828,6 +839,13 @@
"url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@isaacs/nonrecursive-glob-match": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@isaacs/nonrecursive-glob-match/-/nonrecursive-glob-match-1.0.3.tgz",
"integrity": "sha512-SI7kyKHq4XXDRozw+r9GlRZkia1ZkFrpLW98r2IC2Bpr8YkFGE3fvjzmxCG0x78A++69HmDNrDvSMYBZmHGpKA==",
"dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -845,6 +863,16 @@
"node": ">=8"
}
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"license": "MIT",
"dependencies": {
"sprintf-js": "~1.0.2"
}
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
@@ -859,6 +887,20 @@
"node": ">=8"
}
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
"version": "3.15.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz",
"integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==",
"dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -1871,9 +1913,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "26.6.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.4.tgz",
"integrity": "sha512-ldVPDCzj7fsaGZrLB0NuHuTvJcsNasysBAqMolr/cgxrLd1xbqxIr3XJiPnHHJUCxj5sNF1vnRj9aWnrVh5Jcg==",
"version": "26.6.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.6.tgz",
"integrity": "sha512-MzQj+8Kx3XI40OmUAE6Qoh58ZMNstNNMwn2nfd3qWsfe7nDNSqJNzes4njhz6AHwrSHOffSLwXU6yb474Q4aog==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1905,17 +1947,17 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.71.1.tgz",
"integrity": "sha512-nNlBf6HuotqMgZvSkWD5hNdemiBIxQ2NmrlgfcUIeZRs+BbakjscCQRq/Hb74EFVnFiSWWdL12JruqwBy3ERDw==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.72.1.tgz",
"integrity": "sha512-5CokTWXpmbylfFabsbvHC0CAw3XLaGnoa+nFJX5FR592h/LoZsENUE6p/rg5xvkKrFEXz6pYmgI29AgXc2N3BQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.71.1",
"@typescript-eslint/type-utils": "8.71.1",
"@typescript-eslint/utils": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1",
"@typescript-eslint/scope-manager": "8.72.1",
"@typescript-eslint/type-utils": "8.72.1",
"@typescript-eslint/utils": "8.72.1",
"@typescript-eslint/visitor-keys": "8.72.1",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
"ts-api-utils": "^2.5.0"
@@ -1928,22 +1970,22 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.71.1",
"@typescript-eslint/parser": "^8.72.1",
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.71.1.tgz",
"integrity": "sha512-oM/5sAqz/l1v/zYK1qTOPrn2+JIrBGC1V6uNYucRO5gh6eT9vWJ/RhPbGE59byvZEUQ4VP6XkLBaS5Jti5jpvw==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.72.1.tgz",
"integrity": "sha512-ZGwZP4OCfyA0AQTpEAMWz+rtX01DRhQWW5hB0ucKDEIX5U7jdmPSaMx94rQfaPAQzIYz2BimOgKOJtjfpRFQ9g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.71.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1",
"@typescript-eslint/scope-manager": "8.72.1",
"@typescript-eslint/types": "8.72.1",
"@typescript-eslint/typescript-estree": "8.72.1",
"@typescript-eslint/visitor-keys": "8.72.1",
"debug": "^4.4.3"
},
"engines": {
@@ -1959,14 +2001,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.71.1.tgz",
"integrity": "sha512-Oijc9RUsohHjncg6iGi7gCtjnEjYt9FWv9u6ygK8uKcHK5eLjLAkqERQ9BaytbpceOFdk6kifPCS/zAZE+A99g==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.72.1.tgz",
"integrity": "sha512-fAuVMkwdO/huI8nyo/WKnNKf6Gag93S56Rh3Ts5mGcavwSdaN8tRg1gCeIGX8PF+nzp1BjGfO4gHhGzW1J6jTg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.71.1",
"@typescript-eslint/types": "^8.71.1",
"@typescript-eslint/tsconfig-utils": "^8.72.1",
"@typescript-eslint/types": "^8.72.1",
"debug": "^4.4.3"
},
"engines": {
@@ -1981,14 +2023,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.71.1.tgz",
"integrity": "sha512-1YUDZXdTnXLlob03SFHBipdyMBsDVm7zoSz0ytTJ39dk5J1TgsTK03VlR/dLXG/RLLUrPcYbD4rp23BmHxHP0w==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.72.1.tgz",
"integrity": "sha512-lC/t6eMCZZQAAKZEYGL6RDVSuFehpdmMT6h+nJIjIa6oylN/PwDgDVtEIbB7O9xFfZYtZAYLoLlDNWKJhtF+uQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1"
"@typescript-eslint/types": "8.72.1",
"@typescript-eslint/visitor-keys": "8.72.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1999,9 +2041,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.71.1.tgz",
"integrity": "sha512-oTvkml5SxXhgg+WWKhod5qWQICDXtOB+/Hi9VdPKFAANJ2b7YOgMffgvzXuqog7R6A/JtrzRf128dsxummyWhg==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.72.1.tgz",
"integrity": "sha512-e4D5R5vpeAEPBxT2BAzsFQL3sbwyeeeo5+aczgNSRK1V734jE7pTqaGFU+fXapWEQwnZbpFaTn32+Z8DwS6OTg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2016,15 +2058,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.71.1.tgz",
"integrity": "sha512-kH3t3jZCYv2PZSBEWPKTariLrCaoF1CLoPitYFBJOhAGEwWnSRAtGEifrfrpBa4K9JlwWNZotgA5w3/wLSk/FQ==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.72.1.tgz",
"integrity": "sha512-iY2wlmyrXJmx4yxUGP3aYCFF3cA/6ShddOKmLU2dx7LnEykbAM8WThlxZEfd1NddqceF6eJmZUayxx9oKIYNlg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1",
"@typescript-eslint/utils": "8.71.1",
"@typescript-eslint/types": "8.72.1",
"@typescript-eslint/typescript-estree": "8.72.1",
"@typescript-eslint/utils": "8.72.1",
"debug": "^4.4.3",
"ts-api-utils": "^2.5.0"
},
@@ -2041,9 +2083,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.71.1.tgz",
"integrity": "sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.1.tgz",
"integrity": "sha512-LmE5IhQet1BWOWEXqBrVtBPsMAOQ6Nzk35d+WLh3mk4EUF33sqlfxjio1MdYeSvKSG5skactKKuixBIKXhL4Rw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2055,16 +2097,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.71.1.tgz",
"integrity": "sha512-pSKSEK1JJpHs6KiKVtABCE4iJK5d7FLFzDXQNBQ2oRY7LEd3UwOt3TZemTgu9syTIf56dJWlTn/pdmrO9oKUXQ==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.72.1.tgz",
"integrity": "sha512-DAlUoUV93hIvrtIQLwCbmZQYVZwOMhiHJrOVUUIWicFZaIYjTRqlY3I/NZevfkLmSqkNHRu2qYDcq9lrn16oOQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.71.1",
"@typescript-eslint/tsconfig-utils": "8.71.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1",
"@typescript-eslint/project-service": "8.72.1",
"@typescript-eslint/tsconfig-utils": "8.72.1",
"@typescript-eslint/types": "8.72.1",
"@typescript-eslint/visitor-keys": "8.72.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
@@ -2083,16 +2125,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.71.1.tgz",
"integrity": "sha512-CBjT6gfAz3DW2j9Q4moFnqt208Aq+506sVGXfpRcyAeqn0EpayL0mjdWoCO2t3RC7GewNrFxdeehuEaPg6DMzQ==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.72.1.tgz",
"integrity": "sha512-5v5liypurJBFHCBNqh/RjsymAD+VWcE0djuGY/BUqp5fC3Qn+luWDEksjuTtWjPn6i5zQlUtkZCRG/CYG0yCkA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.71.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1"
"@typescript-eslint/scope-manager": "8.72.1",
"@typescript-eslint/types": "8.72.1",
"@typescript-eslint/typescript-estree": "8.72.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2107,13 +2149,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.71.1.tgz",
"integrity": "sha512-0GxiUGqMU0qXJt58cBsiG3DP8lUmBaFo2vChtUX+CT7PnR3v/VGLLrzVP4K9r1lNiZXjHYefMBbPunplr09v6w==",
"version": "8.72.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.1.tgz",
"integrity": "sha512-SB8xqipSzZHUePCCLNeYxqnxq83X61/qzNhjQGbTfjxGZIeOEP7tBgWYX05Tcd6CgE02WdTJnh5b8kMZJ/+bnQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/types": "8.72.1",
"eslint-visitor-keys": "^5.0.0"
},
"engines": {
@@ -2997,13 +3039,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true,
"license": "Python-2.0"
},
"node_modules/babel-jest": {
"version": "30.5.2",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.5.2.tgz",
@@ -3433,9 +3468,10 @@
"license": "MIT"
},
"node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"name": "@shivammathur/deepmerge",
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/@shivammathur/deepmerge/-/deepmerge-4.3.2.tgz",
"integrity": "sha512-OBZnBsXwbBITC90wXf9Ph8W7OAUkhFdM+BGRYeIQwt5nILxy5wkk2plUoabi9Yp6xm0c/Yv9PuLiGBXnfizAMA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3530,9 +3566,9 @@
}
},
"node_modules/eslint": {
"version": "10.12.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.12.0.tgz",
"integrity": "sha512-npHjrHb2o4ehH3mE+YuxABR+0gyb0aVWCIolgJDArwCiHEIsonBm3ZKjel5b0U5+a+MbEvIyRCGCzD3eKKK2NA==",
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.14.0.tgz",
"integrity": "sha512-T0pNsxkb9IKmtQjhpK3d7nWOpFv+YHuMbTJnSVMoQblF0onvXfErrtp4V1jHtsQPan7dKaGVD0q1WCXnzMF31A==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -3545,7 +3581,7 @@
"@eslint/config-helpers": "^0.7.0",
"@eslint/core": "^1.2.1",
"@eslint/plugin-kit": "^0.7.3",
"@humanfs/node": "^0.16.6",
"@humanfs/node": "^0.16.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2",
"@types/estree": "^1.0.6",
@@ -3566,7 +3602,7 @@
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"minimatch": "^10.2.5",
"minimatch": "^10.2.6",
"natural-compare": "^1.4.0",
"optionator": "^0.9.3"
},
@@ -3702,9 +3738,9 @@
}
},
"node_modules/eslint-plugin-jest": {
"version": "29.16.6",
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.16.6.tgz",
"integrity": "sha512-q8TVr0rlNvUD0XnafGWkwtPeX+tTl2llP86EDl3sJtwWrQA/JT9SIu2hLLZbhhX6fT5SDE4O0gIKyZUujKnkYA==",
"version": "29.17.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.17.0.tgz",
"integrity": "sha512-6jtpU6MhYKbagkES02TupWAUUooJpZtKg94Ax0b8HhUorv3InSTBU8RRtlSBe0LocOcShXOpyec3PHzPDkJCSg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3732,14 +3768,14 @@
}
},
"node_modules/eslint-plugin-prettier": {
"version": "5.5.6",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.6.tgz",
"integrity": "sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==",
"version": "5.5.7",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.7.tgz",
"integrity": "sha512-WjHyn3GrFd+ZR0rzsLiM4zJZ35PZMOE0SUIxzGmnWNG0126yNfJKJzObmmkYDwHJfGlkz3PSlzyG9ez/LJntwg==",
"dev": true,
"license": "MIT",
"dependencies": {
"prettier-linter-helpers": "^1.0.1",
"synckit": "^0.11.13"
"synckit": "^0.12.3"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
@@ -3762,6 +3798,23 @@
}
}
},
"node_modules/eslint-plugin-prettier/node_modules/synckit": {
"version": "0.12.3",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.12.3.tgz",
"integrity": "sha512-U+/AXT6LWsxnj2vz9HeUuPWBNgdWxjyIEjEPdbJARC9txmgPzo2VEdqnFo4hHaNyMPtycyVJrSaQYeQv/PoyyA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@dual-bundle/import-meta-resolve": "^4.2.1",
"@pkgr/core": "^0.3.6"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/synckit"
}
},
"node_modules/eslint-scope": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz",
@@ -3848,6 +3901,20 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true,
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/esquery": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
@@ -4105,15 +4172,15 @@
}
},
"node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-14.0.3.tgz",
"integrity": "sha512-A1vjIwC3qpdCso45Iw127gnp7sPhqgY8lUQhDrArIs+GbmfaaVPFuoyy7WyLT9EPZCRZ7j7aLdwUhQmHWesEow==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"minimatch": "^10.2.2",
"minimatch": "^11.0.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
"path-scurry": "^3.0.0"
},
"engines": {
"node": "18 || 20 || >=22"
@@ -4136,9 +4203,9 @@
}
},
"node_modules/globals": {
"version": "17.13.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-17.13.0.tgz",
"integrity": "sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==",
"version": "17.14.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-17.14.0.tgz",
"integrity": "sha512-UtdkTVyAJePQv0J2M9Xe4L0ruNSDV314XiIJsADI2Zf40bcdAonE/D/OhAU8AT99oij9mhLByb+NvA3QWZYgCg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4991,29 +5058,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
"integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/nodeca"
}
],
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
@@ -5176,13 +5220,14 @@
}
},
"node_modules/minimatch": {
"version": "10.2.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
"integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-11.0.3.tgz",
"integrity": "sha512-iny/40PEGkNJQ5/Pv6z3nm6FbRAby32GeZRjCUJk2WnNDbgPSTcdI+DDvLqsgBdD4cD5sMtMheqPPnehCCa8Nw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"brace-expansion": "^5.0.8"
"@isaacs/nonrecursive-glob-match": "^1.0.3",
"brace-expansion": "^5.0.12"
},
"engines": {
"node": "18 || 20 || >=22"
@@ -5249,16 +5294,16 @@
"license": "MIT"
},
"node_modules/nock": {
"version": "15.0.1",
"resolved": "https://registry.npmjs.org/nock/-/nock-15.0.1.tgz",
"integrity": "sha512-Mjx5Xl4t9vP13eUZPWqwwpjjXNjvhUTo1qTdryVM3+7t6Z2w6WHZ9GVZk/zQ8Ym1vbmloWaglye3cloyHAJ8FA==",
"version": "15.0.5",
"resolved": "https://registry.npmjs.org/nock/-/nock-15.0.5.tgz",
"integrity": "sha512-nVeuZGS2we1PyvqbW082Qj0EB4bd//6pZk/zOPDlaTPU72qcWrqfHg3kx9JcBcH1fJxwJHjmsfuQ4mss42su4w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@mswjs/interceptors": "^0.44.0"
},
"engines": {
"node": ">=20.12.1"
"node": ">=22.20.0"
}
},
"node_modules/node-addon-api": {
@@ -5431,9 +5476,9 @@
}
},
"node_modules/path-scurry": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-3.0.0.tgz",
"integrity": "sha512-1pTbQqH1wIwMi/eleQ5leFTTCkzFsPcgXNjwOA8YGGW/W4/kHT3dssE7Z6NH+zuqNLOzOB0uaD61yl7cAcVhgg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
@@ -5567,9 +5612,9 @@
}
},
"node_modules/prettier": {
"version": "3.9.9",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.9.tgz",
"integrity": "sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==",
"version": "3.9.10",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.10.tgz",
"integrity": "sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==",
"dev": true,
"license": "MIT",
"bin": {
@@ -5795,6 +5840,13 @@
"node": ">=0.10.0"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/stable-hash-x": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz",
@@ -5978,15 +6030,15 @@
}
},
"node_modules/ts-jest": {
"version": "29.4.14",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.14.tgz",
"integrity": "sha512-+943G6wCX5E3VpzTQhBGBFntCmdT+QAkTvUlp03edTONFBvqskuXPhpyX16xdUotO4P5HQKyppldSWjocoltLQ==",
"version": "29.4.15",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.15.tgz",
"integrity": "sha512-s2qmEUYFRqbjz1wv0EmccNPVOb45HOFpFuhzQJLKShYVisuTbCFPIIAIV2EuK5rIxb4BejLDbH7dnBZfYjybUQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"bs-logger": "^0.2.6",
"fast-json-stable-stringify": "^2.1.0",
"handlebars": "^4.7.9",
"handlebars": "^4.7.10",
"json5": "^2.2.3",
"lodash.memoize": "^4.1.2",
"make-error": "^1.3.6",
+15 -16
View File
@@ -1,8 +1,9 @@
{
"name": "setup-php",
"version": "2.40.0",
"version": "2.40.1",
"private": false,
"description": "Setup PHP for use with GitHub Actions",
"type": "module",
"main": "lib/install.js",
"types": "lib/install.d.ts",
"directories": {
@@ -42,32 +43,30 @@
"@eslint/compat": "^2.1.1",
"@eslint/js": "^10.0.1",
"@types/jest": "^30.0.0",
"@types/node": "^26.6.4",
"@typescript-eslint/eslint-plugin": "^8.71.1",
"@typescript-eslint/parser": "^8.71.1",
"@types/node": "^26.6.6",
"@typescript-eslint/eslint-plugin": "^8.72.1",
"@typescript-eslint/parser": "^8.72.1",
"@typescript/native": "npm:typescript@^7.0.2",
"@vercel/ncc": "^0.45.0",
"eslint": "^10.12.0",
"eslint": "^10.14.0",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-import-x": "^4.17.1",
"eslint-plugin-jest": "^29.16.6",
"eslint-plugin-prettier": "^5.5.6",
"globals": "^17.13.0",
"eslint-plugin-jest": "^29.17.0",
"eslint-plugin-prettier": "^5.5.7",
"globals": "^17.14.0",
"jest": "^30.5.2",
"jest-circus": "^30.5.2",
"nock": "^15.0.1",
"prettier": "^3.9.9",
"nock": "^15.0.5",
"prettier": "^3.9.10",
"simple-git-hooks": "^2.14.0",
"ts-jest": "^29.4.14",
"ts-jest": "^29.4.15",
"typescript": "npm:@typescript/typescript6@^6.0.2"
},
"overrides": {
"@babel/core": "^7.29.7",
"js-yaml": "^4.2.0",
"test-exclude": "^7.0.1",
"glob": "^13.0.6",
"minimatch": "^10.2.1"
"deepmerge": "npm:@shivammathur/deepmerge@4.3.2",
"glob": "^14.0.3",
"minimatch": "^11.0.3"
},
"bugs": {
"url": "https://github.com/shivammathur/setup-php/issues"
+1 -1
View File
@@ -1,4 +1,4 @@
import * as utils from './utils';
import * as utils from './utils.js';
/**
* Add script to set custom ini values for unix
+71 -15
View File
@@ -3,21 +3,77 @@
{
"owner": "phpunit",
"pattern": [
{
"regexp": "^\\d+\\)\\s.*$"
},
{
"regexp": "^(.*Failed\\sasserting\\sthat.*)$",
"message": 1
},
{
"regexp": "^\\s*$"
},
{
"regexp": "^(.*):(\\d+)$",
"file": 1,
"line": 2
}
{ "regexp": "^\\d+\\)\\s.*$" },
{ "regexp": "^(.*Failed\\sasserting\\sthat.*)$", "message": 1 },
{ "regexp": "^\\s*$" },
{ "regexp": "^(.*):(\\d+)$", "file": 1, "line": 2 }
]
},
{
"owner": "phpunit-no-blank",
"pattern": [
{ "regexp": "^\\d+\\)\\s.*$" },
{ "regexp": "^(.*Failed\\sasserting\\sthat.*)$", "message": 1 },
{ "regexp": "^(.*):(\\d+)$", "file": 1, "line": 2 }
]
},
{
"owner": "phpunit-custom-message",
"pattern": [
{ "regexp": "^\\d+\\)\\s.*$" },
{ "regexp": "^(?!.*Failed\\sasserting)(.+)$", "message": 1 },
{ "regexp": "^.*Failed\\sasserting\\sthat.*$" },
{ "regexp": "^(.*):(\\d+)$", "file": 1, "line": 2 }
]
},
{
"owner": "phpunit-custom-message-blank",
"pattern": [
{ "regexp": "^\\d+\\)\\s.*$" },
{ "regexp": "^(?!.*Failed\\sasserting)(.+)$", "message": 1 },
{ "regexp": "^.*Failed\\sasserting\\sthat.*$" },
{ "regexp": "^\\s*$" },
{ "regexp": "^(.*):(\\d+)$", "file": 1, "line": 2 }
]
},
{
"owner": "phpunit-other-blank",
"pattern": [
{ "regexp": "^\\d+\\)\\s.*$" },
{ "regexp": "^(?!.*Failed\\sasserting)(.+)$", "message": 1 },
{ "regexp": "^(?:\\s*|[-+@ ].*)$" },
{ "regexp": "^(.*):(\\d+)$", "file": 1, "line": 2 }
]
},
{
"owner": "phpunit-other",
"pattern": [
{ "regexp": "^\\d+\\)\\s.*$" },
{ "regexp": "^(?!.*Failed\\sasserting)(.+)$", "message": 1 },
{ "regexp": "^(.*):(\\d+)$", "file": 1, "line": 2 }
]
},
{
"owner": "phpunit-warning",
"severity": "warning",
"pattern": [
{ "regexp": "^There (?:was|were) \\d+ (?:(?:risky|skipped) tests?(?: suites?)?|(?:PHPUnit(?: test runner)? )?warnings?):$" },
{ "regexp": "^(?:(\\s*(/.*|[A-Za-z]:[\\\\/].*):(\\d+)|(?!-+$|There (?:was|were) \\d+ .+:$|\\d+ tests? triggered \\d+ .+:$|OK(?: \\(\\d+ tests?, \\d+ assertions?\\)|, but (?:there were issues|some tests were skipped|incomplete, skipped, or risky tests)!)$|(?:FAILURES|ERRORS|WARNINGS)!$|Tests: \\d+(?:,|\\.?$)|PHPUnit \\d+\\.\\S+ by |Triggered by:$).*)|Triggered by:)$", "message": 1, "file": 2, "line": 3, "loop": true }
]
},
{
"owner": "phpunit-notice",
"severity": "notice",
"pattern": [
{ "regexp": "^There (?:was|were) \\d+ (?:incomplete tests?(?: suites?)?|(?:PHPUnit(?: test runner)? )?notices?):$" },
{ "regexp": "^(?:(\\s*(/.*|[A-Za-z]:[\\\\/].*):(\\d+)|(?!-+$|There (?:was|were) \\d+ .+:$|\\d+ tests? triggered \\d+ .+:$|OK(?: \\(\\d+ tests?, \\d+ assertions?\\)|, but (?:there were issues|some tests were skipped|incomplete, skipped, or risky tests)!)$|(?:FAILURES|ERRORS|WARNINGS)!$|Tests: \\d+(?:,|\\.?$)|PHPUnit \\d+\\.\\S+ by |Triggered by:$).*)|Triggered by:)$", "message": 1, "file": 2, "line": 3, "loop": true }
]
},
{
"owner": "phpunit-issue",
"pattern": [
{ "regexp": "^\\d+ tests? triggered \\d+ (?:PHP(?:Unit)? )?(error|warning|notice)s?:$", "severity": 1 },
{ "regexp": "^(?:\\d+\\)\\s)?(?:(\\s*(/.*|[A-Za-z]:[\\\\/].*):(\\d+)|(?!-+$|There (?:was|were) \\d+ .+:$|\\d+ tests? triggered \\d+ .+:$|OK(?: \\(\\d+ tests?, \\d+ assertions?\\)|, but (?:there were issues|some tests were skipped|incomplete, skipped, or risky tests)!)$|(?:FAILURES|ERRORS|WARNINGS)!$|Tests: \\d+(?:,|\\.?$)|PHPUnit \\d+\\.\\S+ by |Triggered by:$).*)|Triggered by:)$", "message": 1, "file": 2, "line": 3, "loop": true }
]
}
]
+10 -5
View File
@@ -153,12 +153,17 @@
"version_parameter": "-V"
},
"phpstan": {
"type": "phar",
"type": "composer",
"repository": "phpstan/phpstan",
"extension": ".phar",
"domain": "https://github.com",
"version_prefix": "",
"version_parameter": "-V"
"scope": "scoped",
"fallback": {
"type": "phar",
"repository": "phpstan/phpstan",
"extension": ".phar",
"domain": "https://github.com",
"version_prefix": "",
"version_parameter": "-V"
}
},
"pie": {
"type": "phar",
+152 -114
View File
@@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/shivammathur/setup-php/develop/src/configs/tools_schema.json",
"type": "object",
"title": "Tools",
@@ -14,123 +14,161 @@
"function": "function_name",
"repository": "user/tool",
"packagist": "user/tool",
"scope": "global, scoped",
"type": "phar, composer, custom-package or custom-function",
"scope": "scoped",
"type": "composer",
"version_parameter": "--version",
"version_prefix": "v"
"version_prefix": "v",
"fallback": {
"type": "phar",
"repository": "user/tool",
"domain": "https://github.com",
"extension": ".phar",
"version_prefix": "v",
"version_parameter": "--version"
}
}
}
],
"items": {
"properties": {
"alias": {
"$id": "#/items/properties/alias",
"type": "string",
"title": "The alias schema",
"description": "Alias for a tool.",
"examples": [
"tool_alias"
]
"additionalProperties": {
"$ref": "#/$defs/tool"
},
"$defs": {
"tool": {
"type": "object",
"properties": {
"alias": {
"type": "string",
"title": "The alias schema",
"description": "Alias for a tool.",
"examples": [
"tool_alias"
]
},
"domain": {
"type": "string",
"title": "The domain schema",
"description": "Domain URL of the tool.",
"examples": [
"https://example.com"
]
},
"extension": {
"type": "string",
"title": "The extension schema",
"description": "File extension of the tool.",
"examples": [
".ext"
]
},
"fetch_latest": {
"type": "string",
"title": "The fetch_latest schema",
"description": "Fetch the latest version from GitHub releases.",
"enum": [
"true",
"false"
]
},
"function": {
"type": "string",
"title": "The function schema",
"description": "Function name in tools.ts which returns the script to setup the tool.",
"examples": [
"function_name"
]
},
"repository": {
"type": "string",
"title": "The repository schema",
"description": "GitHub repository of the tool.",
"examples": [
"user/tool"
]
},
"packagist": {
"type": "string",
"title": "The repository schema",
"description": "Packagist repository of the tool in case different from repository.",
"examples": [
"user/tool"
]
},
"scope": {
"type": "string",
"title": "The scope schema",
"description": "Scope of tool installation: global or scoped",
"enum": [
"global",
"scoped"
]
},
"type": {
"type": "string",
"title": "The type schema",
"description": "Type of tool: phar, composer, custom-package or custom-function.",
"enum": [
"phar",
"composer",
"custom-package",
"custom-function"
]
},
"version_parameter": {
"type": "string",
"title": "The version_parameter schema",
"description": "Parameter to get the tool version.",
"examples": [
"--version"
]
},
"version_prefix": {
"type": "string",
"title": "The version_prefix schema",
"description": "Prefix of the version in the download URL.",
"examples": [
"v"
]
},
"fallback": {
"$ref": "#/$defs/pharFallback"
}
},
"domain": {
"$id": "#/items/properties/domain",
"type": "string",
"title": "The domain schema",
"description": "Domain URL of the tool.",
"examples": [
"https://example.com"
]
},
"extension": {
"$id": "#/items/properties/extension",
"type": "string",
"title": "The extension schema",
"description": "File extension of the tool.",
"examples": [
".ext"
]
},
"fetch_latest": {
"$id": "#/items/properties/fetch_latest",
"type": "string",
"title": "The fetch_latest schema",
"description": "Fetch the latest version from GitHub releases.",
"enum": [
"true",
"false"
]
},
"function": {
"$id": "#/items/properties/function",
"type": "string",
"title": "The function schema",
"description": "Function name in tools.ts which returns the script to setup the tool.",
"examples": [
"function_name"
]
},
"repository": {
"$id": "#/items/properties/repository",
"type": "string",
"title": "The repository schema",
"description": "GitHub repository of the tool.",
"examples": [
"user/tool"
]
},
"packagist": {
"$id": "#/items/properties/packagist",
"type": "string",
"title": "The repository schema",
"description": "Packagist repository of the tool in case different from repository.",
"examples": [
"user/tool"
]
},
"scope": {
"$id": "#/items/properties/scope",
"type": "string",
"title": "The scope schema",
"description": "Scope of tool installation: global or scoped",
"enum": [
"global",
"scoped"
]
},
"type": {
"$id": "#/items/properties/type",
"type": "string",
"title": "The type schema",
"description": "Type of tool: phar, composer, custom-package or custom-function.",
"enum": [
"phar",
"composer",
"custom-package",
"custom-function"
]
},
"version_parameter": {
"$id": "#/items/properties/version_parameter",
"type": "string",
"title": "The version_parameter schema",
"description": "Parameter to get the tool version.",
"examples": [
"--version"
]
},
"version_prefix": {
"$id": "#/items/properties/version_prefix",
"type": "string",
"title": "The version_prefix schema",
"description": "Prefix of the version in the download URL.",
"examples": [
"v"
]
}
"required": [
"type"
],
"additionalProperties": true
},
"required": [
"type"
],
"additionalProperties": true
"pharFallback": {
"type": "object",
"title": "The fallback schema",
"description": "PHAR installation settings used when Composer installation fails.",
"properties": {
"type": {
"const": "phar"
},
"repository": {
"$ref": "#/$defs/tool/properties/repository"
},
"domain": {
"$ref": "#/$defs/tool/properties/domain"
},
"extension": {
"$ref": "#/$defs/tool/properties/extension"
},
"fetch_latest": {
"$ref": "#/$defs/tool/properties/fetch_latest"
},
"version_parameter": {
"$ref": "#/$defs/tool/properties/version_parameter"
},
"version_prefix": {
"$ref": "#/$defs/tool/properties/version_prefix"
}
},
"required": [
"type"
],
"additionalProperties": false
}
}
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
import * as utils from './utils';
import * as extensions from './extensions';
import * as config from './config';
import * as utils from './utils.js';
import * as extensions from './extensions.js';
import * as config from './config.js';
export async function checkXdebugError(
extension: string,
+2 -2
View File
@@ -1,4 +1,4 @@
import * as utils from './utils';
import * as utils from './utils.js';
/**
* Install and enable extensions for darwin
@@ -180,7 +180,7 @@ export async function addExtensionWindows(
add_script += await utils.joins(
'\nAdd-Extension',
ext_name,
ext_version.replace('stable', '')
ext_version
);
break;
// match extensions for compiling from source
+11 -8
View File
@@ -1,11 +1,15 @@
import {fileURLToPath} from 'url';
import path from 'path';
import {exec} from '@actions/exec';
import fs from 'fs';
import * as config from './config';
import * as core from './core';
import * as coverage from './coverage';
import * as extensions from './extensions';
import * as tools from './tools';
import * as utils from './utils';
import * as config from './config.js';
import * as core from './core.js';
import * as coverage from './coverage.js';
import * as extensions from './extensions.js';
import * as tools from './tools.js';
import * as utils from './utils.js';
const dirname = path.dirname(fileURLToPath(import.meta.url));
/**
* Build the script
@@ -15,7 +19,7 @@ import * as utils from './utils';
export async function getScript(os: string): Promise<string> {
const url = 'https://setup-php.com/sponsor';
const filename = os + (await utils.scriptExtension(os));
const script_path = path.join(__dirname, '../src/scripts', filename);
const script_path = path.join(dirname, '../src/scripts', filename);
const run_path = script_path.replace(os, 'run');
const extension_csv: string = utils.sanitizeShellInput(
await utils.getInput('extensions', false),
@@ -65,7 +69,6 @@ export async function run(): Promise<void> {
const os: string = process.platform;
const tool = await utils.scriptTool(os);
const run_path = await getScript(os);
const {exec} = await import('@actions/exec');
await exec(tool + run_path);
}
+1 -1
View File
@@ -1,5 +1,5 @@
import * as cv from 'compare-versions';
import * as fetch from './fetch';
import * as fetch from './fetch.js';
type RS = Record<string, string>;
type RSRS = Record<string, RS>;
+6 -3
View File
@@ -168,8 +168,12 @@ patch_brew() {
# Function to update dependencies.
update_dependencies() {
if ! [ -e /tmp/update_dependencies ]; then
for repo in "$brew_repo" "${core_repo:?}"; do
if [ -e "$repo" ]; then
local repos=("$brew_repo")
if [ -n "${HOMEBREW_NO_INSTALL_FROM_API:-}" ]; then
repos+=("${core_repo:?}")
fi
for repo in "${repos[@]}"; do
if [ -d "$repo" ]; then
git_retry -C "$repo" fetch origin main && git -C "$repo" reset --hard origin/main || return $?
fi
done
@@ -341,7 +345,6 @@ export HOMEBREW_NO_AUTO_UPDATE=1
export HOMEBREW_NO_ENV_HINTS=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
export HOMEBREW_NO_INSTALL_FROM_API=1
# shellcheck source=.
. "${scripts:?}"/unix.sh
+66 -3
View File
@@ -85,6 +85,67 @@ Function Add-ExtensionFromGithub {
}
}
# Function to install a PIE package or mapped version. Windows uses prebuilt DLLs.
Function Add-PieExtension {
Param (
[Parameter(Position = 0, Mandatory = $true)]
[ValidateNotNull()]
[string]
$extension,
[Parameter(Position = 1, Mandatory = $false)]
[string]
$package = '',
[Parameter(Position = 2, Mandatory = $false)]
[Alias('AllowSourceBuild')]
[bool]
$allow_source = $false
)
$requested = ($package -split ':', 2)[-1]
if ($package -notmatch '/') {
$mapping = Get-Content "$src\configs\pie-extensions.json" -Raw | ConvertFrom-Json
$package = $mapping.$extension
if (-not $package) { throw "No PIE package mapping for $extension" }
if ($requested -in @('', 'latest', 'stable')) { $requested = '' } else { $package += ":$requested" }
} elseif ($package -notmatch ':') {
$requested = ''
}
& "$php_dir\php.exe" -r 'exit(extension_loaded($argv[1]) && ($argv[2] === "" || phpversion($argv[1]) === $argv[2]) ? 0 : 1);' -- $extension "$requested" >$null 2>&1
if ($LASTEXITCODE -eq 0) {
Add-Log $tick $extension 'Enabled'
return
}
$pie_args = @('install', $package, '--no-interaction', '--skip-enable-extension', '--no-build-tools-check', '--no-system-dependencies-check', "--with-php-path=$php_dir\php.exe")
if (-not $allow_source) {
# Skip CPU detection when compilation is disabled.
$pie_args += @('--suppress-download-url-method=composer-default', '--suppress-download-url-method=pre-packaged-source', '--make-parallel-jobs=1')
}
New-Item -ItemType Directory -Path $composer_home -Force >$null
Set-ComposerAuth
$pie_log = Join-Path ([System.IO.Path]::GetTempPath()) "pie-$extension.log"
$pie_path = Join-Path $bin_dir 'pie'
if ([version]$installed.MajorMinorVersion -lt [version]'8.1') {
$pie_path = Join-Path $bin_dir 'pie-cli.exe'
if (-not (Test-Path $pie_path -PathType Leaf)) {
Get-File -Url https://github.com/php/pie/releases/latest/download/pie-Windows-X64.exe -OutFile $pie_path
}
& $pie_path @pie_args >$pie_log 2>&1
} else {
if (-not (Test-Path $pie_path -PathType Leaf)) {
Add-Tool https://github.com/php/pie/releases/latest/download/pie.phar pie '-V' >$null 2>&1
}
& "$php_dir\php.exe" $pie_path @pie_args >$pie_log 2>&1
}
if ($LASTEXITCODE -ne 0) {
Get-Content $pie_log | ForEach-Object { Write-Host $_ }
throw "Could not install $package using PIE (exit code $LASTEXITCODE)"
}
Enable-ExtensionDependencies $extension
Enable-PhpExtension -Extension $extension -Path $php_dir
& "$php_dir\php.exe" -r 'exit(extension_loaded($argv[1]) ? 0 : 1);' -- $extension >$null 2>&1
if ($LASTEXITCODE -ne 0) { throw "Could not load $extension after installing $package using PIE" }
Add-Log $tick $extension 'Installed and enabled'
}
# Function to add PHP extensions.
Function Add-Extension {
Param (
@@ -104,6 +165,7 @@ Function Add-Extension {
[string]
$extension_version = ''
)
$minimum_stability_requested = $PSBoundParameters.ContainsKey('stability') -and $extension_version -eq ''
$extension_backup = ''
$restore_startup_errors = $false
try {
@@ -115,7 +177,7 @@ Function Add-Extension {
$extension_info = Get-PhpExtension -Path $php_dir | Where-Object { $_.Name -eq $extension -or $_.Handle -eq $extension }
}
# Only suppress startup errors while probing a cached DLL or replacing an installed DLL.
if($cached -or ($extension_version -ne '' -and $extension_info.Version -ne $extension_version -and (Test-Path "$ext_dir\php_$extension.dll"))) {
if($cached -or (($minimum_stability_requested -or ($extension_version -ne '' -and $extension_info.Version -ne $extension_version)) -and (Test-Path "$ext_dir\php_$extension.dll"))) {
$startup_errors = Get-PhpIniKey -Key display_startup_errors -Path "$php_dir\php.ini"
if($startup_errors -notmatch '^(0|off|false|no)$') {
$restore_startup_errors = $true
@@ -147,7 +209,7 @@ Function Add-Extension {
Remove-Item "$ext_dir\php_$extension.dll" -Force
$extension_info = $null
}
if ($null -ne $extension_info -and ($extension_version -eq '' -or $extension_info.Version -eq $extension_version)) {
if ($null -ne $extension_info -and ($extension_info.State -eq 'Builtin' -or (-not $minimum_stability_requested -and ($extension_version -eq '' -or $extension_info.Version -eq $extension_version)))) {
switch ($extension_info.State) {
'Builtin' {
Add-Log $tick $extension "Enabled"
@@ -169,8 +231,9 @@ Function Add-Extension {
if ($version -match '8.[1-4]' -and $stability -eq 'stable') {
$minimumStability = 'snapshot'
}
$maximumStability = if ($extension_version -eq '') { 'stable' } else { $stability }
$params = @{ Extension = $extension; MinimumStability = $minimumStability; MaximumStability = $stability; Path = $php_dir; AdditionalFilesPath = $deps_dir; NoDependencies = $true }
$params = @{ Extension = $extension; MinimumStability = $minimumStability; MaximumStability = $maximumStability; Path = $php_dir; AdditionalFilesPath = $deps_dir; NoDependencies = $true }
if ($extension_version -ne '')
{
$params["Version"] = $extension_version
+89 -17
View File
@@ -165,19 +165,75 @@ add_extension() {
# Function to get the PECL version of an extension.
get_pecl_version() {
local extension=$1
states=("stable" "rc" "preview" "beta" "alpha" "snapshot")
stability="$(echo "$2" | grep -m 1 -Eio "($(IFS='|' ; echo "${states[*]}"))")"
IFS=' ' read -r -a states <<< "$(echo "${states[@]}" | grep -Eo "$stability.*")"
local requested=${2:-stable}
local states=("stable" "rc" "preview" "beta" "alpha" "devel" "snapshot")
local stability major_version response pecl_version pattern
response=$(get -s -n "" "https://pecl.php.net/rest/r/$extension/allreleases.xml")
if [[ "$requested" =~ ^[0-9] ]]; then
# Preserve exact pins and PECL's case-sensitive archive directory names.
pecl_version=$(echo "$response" | grep -Fio "<v>$requested</v>" | head -n 1 | cut -d '>' -f 2 | cut -d '<' -f 1)
echo "${pecl_version:-$requested}"
return
fi
requested="$(echo "$requested" | tr '[:upper:]' '[:lower:]')"
[[ " ${states[*]} " = *" $requested "* ]] || return 0
IFS=' ' read -r -a states <<< "$(echo "${states[@]}" | grep -Eo ".*$requested")"
stability="$(IFS='|' ; echo "${states[*]}")"
major_version=${3:-'[0-9]+'}
pecl_rest='https://pecl.php.net/rest/r/'
response=$(get -s -n "" "$pecl_rest$extension"/allreleases.xml)
for state in "${states[@]}"; do
pecl_version=$(echo "$response" | grep -m 1 -Eio "($major_version\.[0-9]+\.[0-9]+${state}[0-9]+<)" | cut -d '<' -f 1)
[ -z "$pecl_version" ] && pecl_version=$(echo "$response" | grep -m 1 -Eio "v>(.*)<\/v>.*$state<" | grep -m 1 -Eo "($major_version\.[0-9]+\.[0-9]+.*)<" | cut -d '<' -f 1)
[ -n "$pecl_version" ] && break;
done
[ -z "$pecl_version" ] && pecl_version=$(echo "$response" | grep -m 1 -Eo "($major_version\.[0-9]+\.[0-9]+)<" | cut -d '<' -f 1)
echo "$pecl_version"
pattern="v>($major_version\.[0-9]+(\.[0-9]+)?)[^<]*</v>[[:space:]]*<s>($stability)<"
if [[ "$requested" = rc || "$requested" = preview ]]; then
pattern="$pattern|v>($major_version\.[0-9]+(\.[0-9]+)?)($stability)[0-9]*<"
fi
# PECL orders releases by version, so select the first acceptable state.
echo "$response" | grep -Eio "$pattern" | head -n 1 | cut -d '>' -f 2 | cut -d '<' -f 1
}
# Install a PIE package or mapped version: extension, package, allow_source=false, prefix.
pie_install() {
local extension=$1 package=${2:-} allow_source=${3:-false}
local prefix=${4:-$(get_extension_prefix "$extension")} requested pie_path php_config asset arch
requested=${package##*:}
if [[ "$package" != */* ]]; then
package=$(jq -er --arg extension "$extension" '.[$extension]' "${src:?}/configs/pie-extensions.json") || return 1
case "$requested" in ''|latest|stable) requested= ;; *) package="$package:$requested" ;; esac
elif [[ "$package" != *:* ]]; then
requested=
fi
if php -d display_errors=0 -r 'exit(extension_loaded($argv[1]) && ($argv[2] === "" || phpversion($argv[1]) === $argv[2]) ? 0 : 1);' -- "$extension" "$requested"; then
return 0
fi
local pie_args=(install "$package" --no-interaction --skip-enable-extension --no-build-tools-check --no-system-dependencies-check)
php_config=$(command -v php-config) || return 1
pie_args+=("--with-php-config=$php_config")
if [ "$allow_source" != true ]; then
# Skip CPU detection when compilation is disabled.
pie_args+=(--suppress-download-url-method=composer-default --suppress-download-url-method=pre-packaged-source --make-parallel-jobs=1)
fi
if php -r 'exit(PHP_VERSION_ID >= 80100 ? 0 : 1);'; then
if ! command -v pie >/dev/null 2>&1; then
add_tool https://github.com/php/pie/releases/latest/download/pie.phar pie '-V' >/dev/null 2>&1 || return 1
fi
pie_path=$(command -v pie) || return 1
else
arch=$(uname -m)
case "$arch" in x86_64|amd64) arch=X64 ;; arm64|aarch64) arch=ARM64 ;; *) return 1 ;; esac
asset="pie-$(uname -s)-$arch"
[ "$(uname -s)" != Darwin ] || asset="pie-macOS-$arch"
pie_path="${tool_path_dir:?}/pie-cli"
if [ ! -x "$pie_path" ]; then
[ "$(get -v -e "$pie_path" "https://github.com/php/pie/releases/latest/download/$asset")" = 200 ] || return 1
fi
fi
mkdir -p "${composer_home:?}"
set_composer_auth
sudo -E "$pie_path" "${pie_args[@]}" >"/tmp/pie-$extension.log" 2>&1 || {
local status=$?
cat "/tmp/pie-$extension.log" >&2
return "$status"
}
sudo rm -f /tmp/php"${version:?}"_extensions
enable_extension "$extension" "$prefix" || return 1
check_extension "$extension"
}
# Function to install PECL extensions and accept default options
@@ -190,7 +246,10 @@ pecl_install() {
# Install using the source interface as it allows for patching.
if [[ $(printf "%s\n%s" "${version:?}" "8.3" | sort -V | head -n1) != "$version" ]]; then
extension_version=${extension##*-};
[ "$extension_version" = "${extension%-*}" ] && extension_version=$(get_pecl_version "$extension" "stable")
if [ "$extension_version" = "${extension%-*}" ]; then
extension_version=$(get_pecl_version "$extension" "stable")
[ -n "$extension_version" ] || return 1
fi
add_extension_from_source "${extension%-*}" https://pecl.php.net "${extension%-*}" "${extension%-*}" "$extension_version" "$prefix" pecl
check_extension "${extension%-*}" && return 0 || return 1;
else
@@ -217,7 +276,7 @@ add_pecl_extension() {
local extension=$1
local pecl_version=$2
local prefix=$3
if [[ $pecl_version =~ .*(alpha|beta|rc|snapshot|preview).* ]]; then
if [[ $pecl_version =~ (alpha|beta|rc|snapshot|preview|devel) ]]; then
pecl_version=$(get_pecl_version "$extension" "$pecl_version")
fi
# Cache versioned extensions using suffixless copies in extension_dir.
@@ -234,12 +293,21 @@ add_pecl_extension() {
[ -n "$pecl_version" ] && sudo rm -f "${ext_dir:?}/$extension-$pecl_version"
[ -n "$pecl_version" ] && pecl_version="-$pecl_version"
pecl_install "$extension$pecl_version" || ( [ "${fail_fast:?}" = "false" ] && add_extension "$extension" "$(get_extension_prefix "$extension")" >/dev/null 2>&1)
extension_version="$(php -r "echo phpversion('$extension');")"
if ! extension_version="$(php -d display_errors=0 -d display_startup_errors=0 -r "echo phpversion('$extension'); exit(extension_loaded('$extension') ? 0 : 1);" 2>/dev/null)"; then
add_log "${cross:?}" "$extension" "Could not install $extension on PHP ${semver:?}"
return
fi
if [ -n "$pecl_version" ] && [ "${extension_version/-/}" != "${pecl_version#-}" ]; then
[ "${fail_fast:?}" = "true" ] && add_log "${cross:?}" "$extension-$extension_version" "Installed and enabled, but $extension$pecl_version was requested"
add_log "!" "$extension-$extension_version" "Installed and enabled, but $extension$pecl_version was requested"
echo "::warning::Installed $extension-$extension_version, but $extension$pecl_version was requested"
return
fi
if [ -n "$pecl_version" ] && [ "${extension_version/-/}" = "${pecl_version#-}" ]; then
sudo cp "${ext_dir:?}/$extension.so" "${ext_dir:?}/$extension-$extension_version" 2>/dev/null || true
sudo cp "${ext_dir:?}/$extension.so" "${ext_dir:?}/$extension$pecl_version" 2>/dev/null || true
fi
[ -n "$extension_version" ] && extension_version="-$extension_version"
add_extension_log "$extension$extension_version" "Installed and enabled"
add_log "${tick:?}" "$extension$extension_version" "Installed and enabled"
fi
}
@@ -249,6 +317,10 @@ add_unstable_extension() {
local stability=$2
local prefix=$3
pecl_version=$(get_pecl_version "$extension" "$stability")
if [ -z "$pecl_version" ]; then
add_log "${cross:?}" "$extension-$stability" "No release found with minimum stability $stability"
return
fi
add_pecl_extension "$extension" "$pecl_version" "$prefix"
}
+1 -1
View File
@@ -126,7 +126,7 @@ fetch_extension() {
run_group "git clone -nv $url/$org/$repo /tmp/$repo-$release" "git clone"
cd /tmp/"$repo-$release" || exit 1
git checkout -q "$release"
cd "$sub_dir" || exit 1
cd "${sub_dir:-.}" || exit 1
if [ -e .gitmodules ]; then
jobs="$(grep -c "\[submodule" .gitmodules)"
run_group "git submodule update --jobs $jobs --init --recursive" "git submodule"
+20 -1
View File
@@ -21,7 +21,11 @@ self_hosted_helper() {
trap "sudo rm -f /usr/bin/apt-fast 2>/dev/null" exit
fi
sudo mkdir -p /opt/hostedtoolcache >/dev/null 2>&1 || true
install_packages apt-transport-https ca-certificates curl file make jq unzip autoconf automake gcc g++ gnupg
local packages=()
mapfile -t packages < <(filter_packages apt-transport-https ca-certificates curl file make jq unzip autoconf automake gcc g++ gnupg)
if [ "${#packages[@]}" -gt 0 ]; then
install_packages "${packages[@]}"
fi
}
# Function to fix broken packages.
@@ -90,6 +94,21 @@ check_package() {
apt-cache policy "$1" 2>/dev/null | grep -q 'Candidate'
}
# Function to filter out installed packages
filter_packages() {
[ "$#" -gt 0 ] || return 0
local package architecture status
local -A installed=()
while IFS=$'\t' read -r package architecture status; do
[[ "$status" = [ih]'i ' ]] && status=1 || status=0
installed["$package"]=$(( ${installed["$package"]:-1} && status ))
installed["$package:$architecture"]=$status
done < <(dpkg-query -W -f='${Package}\t${Architecture}\t${db:Status-Abbrev}\n' -- "$@" 2>/dev/null)
for package in "$@"; do
[ "${installed[$package]:-0}" -eq 1 ] || printf '%s\n' "$package"
done
}
# Helper function to add an extension.
add_extension_helper() {
local extension=$1
+50 -9
View File
@@ -237,6 +237,26 @@ Function Add-ToolsHelper() {
}
}
# Function to find the newest stable release containing a tool asset.
Function Get-LastRelease($url) {
$releases_url = $url.Split('/latest/download/')[0]
$asset = $url.Split('/')[-1]
$page = 1
do {
$releases = (Get-File -Url "${releases_url}?page=$page&q=prerelease%3Afalse").Content
foreach ($match in [regex]::Matches($releases, 'src="([^"]+/releases/expanded_assets/[^"]+)"')) {
$assets_url = $match.Groups[1].Value
if (-not $assets_url.StartsWith("$releases_url/expanded_assets/")) { continue }
$download_path = $assets_url.Substring('https://github.com'.Length).Replace('/expanded_assets/', '/download/') + "/$asset"
$assets = (Get-File -Url $assets_url).Content
if ($assets.Contains("href=`"$download_path`"")) {
return "https://github.com$download_path"
}
}
$page++
} while ($releases.Contains('class="next_page"'))
}
# Function to add tools.
Function Add-Tool() {
Param (
@@ -288,15 +308,17 @@ Function Add-Tool() {
try {
$status_code = (Invoke-WebRequest -Passthru -Uri $url -OutFile $tool_path).StatusCode
} catch {
if($url -match '.*github.com.*releases.*latest.*') {
$status_code = 0
if($url -match '^https://github\.com/[^/]+/[^/]+/releases/latest/download/[^/?#]+$') {
try {
$url = $url.replace("releases/latest/download", "releases/download/" + ([regex]::match((Get-File -Url ($url.split('/release')[0] + "/releases")).Content, "([0-9]+\.[0-9]+\.[0-9]+)/" + ($url.Substring($url.LastIndexOf("/") + 1))).Groups[0].Value).split('/')[0])
$status_code = (Invoke-WebRequest -Passthru -Uri $url -OutFile $tool_path).StatusCode
$release_url = Get-LastRelease $url
if ($release_url) {
$url = $release_url
$status_code = (Invoke-WebRequest -Passthru -Uri $url -OutFile $tool_path).StatusCode
}
} catch {
$status_code = 0
}
} else {
$status_code = 0
}
}
if($status_code -eq 200 -and (Test-Path $tool_path)) {
@@ -375,23 +397,33 @@ Function Add-ComposerToolHelper() {
composer global config --no-plugins allow-plugins."$prefix$tool" true >$null 2>&1
}
composer global require $prefix$release $composer_args >$null 2>&1
if($LASTEXITCODE -ne 0) {
return
}
return composer global show $prefix$tool 2>&1 | findstr '^versions'
} else {
$release_stream = [System.IO.MemoryStream]::New([System.Text.Encoding]::ASCII.GetBytes($release))
$scoped_dir_suffix = (Get-FileHash -InputStream $release_stream -Algorithm sha256).Hash
$scoped_dir = "$composer_bin\_tools\$tool-$scoped_dir_suffix"
$unix_scoped_dir = $scoped_dir.replace('\', '/')
if(-not(Test-Path $scoped_dir)) {
if(-not(Test-Path $scoped_dir\vendor\autoload.php)) {
New-Item -ItemType Directory -Force -Path $scoped_dir > $null 2>&1
Set-Content -Path $scoped_dir\composer.json -Value "{}"
if((composer show $prefix$tool $tool_version -d $unix_scoped_dir -a 2>&1 | findstr '^type *: *composer-plugin') -and ($composer_args -ne '')) {
composer config -d $unix_scoped_dir --no-plugins allow-plugins."$prefix$tool" true >$null 2>&1
}
composer require $prefix$release -d $unix_scoped_dir $composer_args >$null 2>&1
if($LASTEXITCODE -ne 0) {
return
}
}
$log = composer show $prefix$tool -d $unix_scoped_dir 2>&1 | findstr '^versions'
if(-not $log) {
return
}
[System.Environment]::SetEnvironmentVariable(($tool.replace('-', '_') + '_bin'), "$scoped_dir\vendor\bin")
Add-Path $scoped_dir\vendor\bin
return composer show $prefix$tool -d $unix_scoped_dir 2>&1 | findstr '^versions'
return $log
}
}
@@ -417,7 +449,13 @@ Function Add-ComposerTool() {
[ValidateNotNull()]
[ValidateLength(1, [int]::MaxValue)]
[string]
$scope
$scope,
[Parameter(Position = 4, Mandatory = $false)]
[string]
$fallback_url,
[Parameter(Position = 5, Mandatory = $false)]
[string]
$fallback_version_parameter
)
$composer_args = ""
if($composer_version.split('.')[0] -ne "1") {
@@ -433,10 +471,13 @@ Function Add-ComposerTool() {
if(Test-Path $composer_bin\composer) {
Copy-Item -Path "$bin_dir\composer" -Destination "$composer_bin\composer" -Force
}
Add-ToolsHelper $tool
if($log) {
$tool_version = Get-ToolVersion "Write-Output" "$log"
Add-ToolsHelper $tool
Add-Log $tick $tool "Added $tool $tool_version"
} elseif($fallback_url) {
Add-Log "!" $tool "Could not setup $tool using Composer. Falling back to PHAR."
Add-Tool $fallback_url $tool $fallback_version_parameter
} else {
Add-Log $cross $tool "Could not setup $tool"
}
+44 -12
View File
@@ -203,6 +203,27 @@ add_tools_helper() {
done
}
# Function to find the newest stable release containing a tool asset.
get_last_release() {
local releases_url="${1%/latest/download/*}"
local asset="${1##*/}"
local page=1 releases assets_url tag download_path
while true; do
releases=$(get -s -n "" "$releases_url?page=$page&q=prerelease%3Afalse") || return 1
while IFS= read -r assets_url; do
[[ "$assets_url" = "$releases_url/expanded_assets/"* ]] || continue
tag="${assets_url#"$releases_url/expanded_assets/"}"
download_path="${releases_url#https://github.com}/download/$tag/$asset"
if get -s -n "" "$assets_url" | grep -Fq "href=\"$download_path\""; then
printf 'https://github.com%s\n' "$download_path"
return 0
fi
done <<< "$(printf '%s' "$releases" | grep -Eo 'src="[^"]+/releases/expanded_assets/[^"]+"' | cut -d '"' -f 2)"
[[ "$releases" = *'class="next_page"'* ]] || return 1
page=$((page + 1))
done
}
# Function to setup a remote tool.
add_tool() {
url=$1
@@ -243,9 +264,12 @@ add_tool() {
else
[ -f "$tool_path" ] && sudo cp -a "$tool_path" "$tool_path.bak"
status_code=$(get -v -e "$tool_path" "${url[@]}")
if [ "$status_code" != "200" ] && [[ "${url[0]}" =~ .*github.com.*releases.*latest.* ]]; then
url[0]="${url[0]//releases\/latest\/download/releases/download/$(get -s -n "" "$(echo "${url[0]}" | cut -d '/' -f '1-5')/releases" | grep -Eo -m 1 "([0-9]+\.[0-9]+\.[0-9]+)/$(echo "${url[0]}" | sed -e "s/.*\///")" | cut -d '/' -f 1)}"
status_code=$(get -v -e "$tool_path" "${url[0]}")
if [ "$status_code" != "200" ] && [[ "${url[0]}" =~ ^https://github\.com/[^/]+/[^/]+/releases/latest/download/[^/?#]+$ ]]; then
local release_url
if release_url=$(get_last_release "${url[0]}"); then
url[0]="$release_url"
status_code=$(get -v -e "$tool_path" "${url[0]}")
fi
fi
if [ "$status_code" = "200" ]; then
if [ -n "$checksum" ] && ! verify_checksum "$tool_path" "$checksum"; then
@@ -293,19 +317,20 @@ add_composer_tool_helper() {
if composer global show "$prefix$tool" "$tool_version" -a 2>&1 | grep -qE '^type *: *composer-plugin' && [ -n "$composer_args" ]; then
composer global config --no-plugins allow-plugins."$prefix$tool" true >/dev/null 2>&1
fi
composer global require "$prefix$release" "$composer_args" >/dev/null 2>&1
composer global require "$prefix$release" "$composer_args" >/dev/null 2>&1 || return 1
composer global show "$prefix$tool" 2>&1 | grep -E ^versions | sudo tee /tmp/composer.log >/dev/null 2>&1
else
scoped_dir="$composer_bin/_tools/$tool-$(echo -n "$release" | shasum -a 256 | cut -d ' ' -f 1)"
if ! [ -d "$scoped_dir" ]; then
if ! [ -f "$scoped_dir/vendor/autoload.php" ]; then
mkdir -p "$scoped_dir"
echo '{}' | tee "$scoped_dir/composer.json" >/dev/null
if composer show "$prefix$tool" "$tool_version" -d "$scoped_dir" -a 2>&1 | grep -qE '^type *: *composer-plugin' && [ -n "$composer_args" ]; then
composer config -d "$scoped_dir" --no-plugins allow-plugins."$prefix$tool" true >/dev/null 2>&1
fi
composer require "$prefix$release" -d "$scoped_dir" "$composer_args" >/dev/null 2>&1
composer show "$prefix$tool" -d "$scoped_dir" 2>&1 | grep -E ^versions | sudo tee /tmp/composer.log >/dev/null 2>&1
composer require "$prefix$release" -d "$scoped_dir" "$composer_args" >/dev/null 2>&1 || return 1
fi
composer show "$prefix$tool" -d "$scoped_dir" 2>&1 | grep -E ^versions | sudo tee /tmp/composer.log >/dev/null 2>&1
[ -s /tmp/composer.log ] || return 1
add_path "$scoped_dir"/vendor/bin
fi
}
@@ -316,6 +341,7 @@ add_composer_tool() {
release=$2
prefix=$3
scope=$4
local fallback_url=${5:-} fallback_version_parameter=${6:-}
composer_args=
composer_major_version=$(cut -d'.' -f 1 /tmp/composer_version)
if [ "$composer_major_version" != "1" ]; then
@@ -326,11 +352,17 @@ add_composer_tool() {
return
fi
fi
add_composer_tool_helper "$tool" "$release" "$prefix" "$scope" "$composer_args"
tool_version=$(get_tool_version cat /tmp/composer.log)
([ -s /tmp/composer.log ] && add_log "$tick" "$tool" "Added $tool $tool_version"
) || add_log "$cross" "$tool" "Could not setup $tool"
add_tools_helper "$tool"
sudo rm -f /tmp/composer.log
if add_composer_tool_helper "$tool" "$release" "$prefix" "$scope" "$composer_args" && [ -s /tmp/composer.log ]; then
tool_version=$(get_tool_version cat /tmp/composer.log)
add_tools_helper "$tool"
add_log "$tick" "$tool" "Added $tool $tool_version"
elif [ -n "$fallback_url" ]; then
add_log "!" "$tool" "Could not setup $tool using Composer. Falling back to PHAR."
add_tool "$fallback_url" "$tool" "$fallback_version_parameter"
else
add_log "$cross" "$tool" "Could not setup $tool"
fi
if [ -e "$composer_bin/composer" ]; then
sudo cp -a "$tool_path_dir/composer" "$composer_bin"
fi
+5
View File
@@ -225,6 +225,11 @@ configure_brew() {
tap_dir="$brew_repo"/Library/Taps
core_repo="$tap_dir"/homebrew/homebrew-core
if [ -d "$core_repo" ]; then
export HOMEBREW_NO_INSTALL_FROM_API=1
else
unset HOMEBREW_NO_INSTALL_FROM_API
fi
export HOMEBREW_CHANGE_ARCH_TO_ARM=1
export HOMEBREW_NO_AUTO_UPDATE=1
export HOMEBREW_NO_ENV_HINTS=1
+2
View File
@@ -20,6 +20,8 @@ Function Step-Log($message) {
Function Add-Log($mark, $subject, $message) {
if ($mark -eq $tick) {
printf "\033[32;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s \033[0m\n" $mark $subject $message
} elseif ($mark -eq "!") {
printf "\033[33;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s \033[0m\n" $mark $subject $message
} else {
printf "\033[31;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s \033[0m\n" $mark $subject $message
if($env:fail_fast -eq 'true') {
+53 -39
View File
@@ -1,9 +1,12 @@
import {fileURLToPath} from 'url';
import path from 'path';
import fs from 'fs';
import * as cv from 'compare-versions';
import * as fetch from './fetch';
import * as packagist from './packagist';
import * as utils from './utils';
import * as fetch from './fetch.js';
import * as packagist from './packagist.js';
import * as utils from './utils.js';
const dirname = path.dirname(fileURLToPath(import.meta.url));
/**
* Valid function names for custom tool handlers
@@ -48,6 +51,7 @@ export interface ToolData {
url: string;
uri?: string;
error?: string;
fallback?: ToolFallback;
}
/**
@@ -72,8 +76,19 @@ interface ToolConfig {
version_parameter?: string;
version_prefix?: string;
packagist?: string;
fallback?: ToolFallback;
}
type ToolFallback = Pick<
ToolConfig,
| 'repository'
| 'domain'
| 'extension'
| 'fetch_latest'
| 'version_parameter'
| 'version_prefix'
> & {type: 'phar'};
/**
* Regex to match a checksum suffix in a tool release - tool:version@sha256:<hash>
*/
@@ -141,21 +156,13 @@ interface GitHubRef {
};
}
/**
* Deployer manifest entry
*/
interface DeployerManifestEntry {
version: string;
url: string;
}
export function skipGitHubAuthForComposerVersion(version: string): boolean {
if (!/^\d+\.\d+\.\d+(?:-[\w-]+)?$/.test(version)) {
return false;
}
return fs
.readFileSync(
path.join(__dirname, '../src/configs/composer-gh-auth-no-op'),
path.join(dirname, '../src/configs/composer-gh-auth-no-op'),
'utf8'
)
.trim()
@@ -414,7 +421,23 @@ export async function addPackage(data: ToolData): Promise<string> {
const args = [parts[1], data.release, parts[0] + '/', data.scope]
.map(a => utils.safeArg(a, data.os))
.join(' ');
return command + args;
if (!data.fallback) return command + args;
const fallback = await getData(
data.release.replace(/\.\*$/, ''),
data.php_version,
data.os,
data.fallback
);
// A failed version lookup must not prevent a successful Composer install.
if (fallback.error) return command + args;
return (
command +
args +
' ' +
utils.safeArg(fallback.url, data.os) +
' ' +
(fallback.version_parameter || '""')
);
}
/**
@@ -514,29 +537,17 @@ export async function addComposer(data: ToolData): Promise<string> {
* @param data
*/
export async function addDeployer(data: ToolData): Promise<string> {
if (data.version === 'latest') {
data.url = data.domain + '/deployer.phar';
} else {
const manifest = await fetch.fetch('https://deployer.org/manifest.json');
const version_data: Record<string, DeployerManifestEntry> = JSON.parse(
manifest.data
);
const version_key: string | undefined = Object.keys(version_data).find(
(key: string) => {
return version_data[key].version === data.version;
}
);
if (version_key) {
data.url = version_data[version_key].url;
} else {
return await utils.addLog(
'$cross',
'deployer',
'Version missing in deployer manifest',
data.os
);
}
}
const github_url = await getUrl({
...data,
domain: data.github,
prefix: 'releases',
verb: 'download'
});
const source_url =
data.version === 'latest'
? `${data.domain}/deployer.phar`
: `${data.domain}/releases/v${data.version}/deployer.phar`;
data.url = `${github_url},${source_url}`;
return await addArchive(data);
}
@@ -670,9 +681,10 @@ export async function addWPCLI(data: ToolData): Promise<string> {
export async function getData(
release: string,
php_version: string,
os: string
os: string,
overrides: ToolConfig = {}
): Promise<ToolData> {
const json_file_path = path.join(__dirname, '../src/configs/tools.json');
const json_file_path = path.join(dirname, '../src/configs/tools.json');
const json_file: string = fs.readFileSync(json_file_path, 'utf8');
const json_objects: Record<string, ToolConfig> = JSON.parse(json_file);
release = release.replace(/\s+/g, '');
@@ -702,6 +714,7 @@ export async function getData(
config = {tool};
}
}
config = {...config, ...overrides};
const github = 'https://github.com';
const domain = config.domain ?? github;
const data: ToolData = {
@@ -727,7 +740,8 @@ export async function getData(
packagist: config.packagist ?? config.repository ?? '',
type: config.type,
function: config.function,
alias: config.alias
alias: config.alias,
fallback: config.fallback
};
data.checksum = checksum_data.checksum;
data.error = checksum_data.error;
+9 -9
View File
@@ -1,7 +1,10 @@
import {fileURLToPath} from 'url';
import fs from 'fs';
import * as path from 'path';
import * as core from './core';
import * as fetch from './fetch';
import * as core from './core.js';
import * as fetch from './fetch.js';
const dirname = path.dirname(fileURLToPath(import.meta.url));
/**
* Function to read environment variable and return a string value.
@@ -88,12 +91,9 @@ export async function parseVersion(version: string): Promise<string> {
if (!/^\d+(\.\d+){0,2}$/.test(version)) {
throw new Error(`Invalid PHP version: ${version.slice(0, 20)}`);
}
switch (true) {
case version.length > 1:
return version.slice(0, 3);
default:
return version + '.0';
}
return version.includes('.')
? version.split('.').slice(0, 2).join('.')
: version + '.0';
}
}
@@ -480,7 +480,7 @@ export async function customPackage(
const pkg_name: string = pkg.replace(/\d+|(pdo|pecl)[_-]|[_-]db2/, '');
const script_extension: string = await scriptExtension(os);
const script: string = path.join(
__dirname,
dirname,
'../src/scripts/' + type + '/' + pkg_name + script_extension
);
const command: string = await getCommand(os, pkg_name);
+2 -2
View File
@@ -5,8 +5,8 @@
"lib": [
"ES2025"
],
"module": "Node20",
"moduleResolution": "Node16",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"noImplicitAny": true,
"outDir": "./lib",
"removeComments": true,