Skip to content

Commit e53dd81

Browse files
packageVersion for PHP builds
1 parent 8b86b9b commit e53dd81

14 files changed

Lines changed: 325 additions & 68 deletions

.github/workflows/build-php-cli-binaries.yml

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Build PHP CLI Binaries
2-
run-name: Build PHP ${{ inputs.php_version }} with Xdebug ${{ inputs.xdebug_version }}
2+
run-name: Build PHP ${{ inputs.php_version }} package ${{ inputs.package_version }} with Xdebug ${{ inputs.xdebug_version }}
33

44
on:
55
workflow_dispatch:
@@ -8,6 +8,10 @@ on:
88
description: PHP patch version to build
99
required: true
1010
default: 8.4.20
11+
package_version:
12+
description: Required immutable package identifier; choose a new value when rebuilding a PHP version
13+
required: true
14+
default: studio-1
1115
xdebug_version:
1216
description: Xdebug version to package
1317
required: true
@@ -84,6 +88,7 @@ jobs:
8488
extensions: apcu,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,ftp,gd,iconv,igbinary,intl,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pdo,pdo_mysql,pdo_sqlite,phar,redis,session,shmop,simplexml,sockets,sodium,sqlite3,ssh2,tokenizer,xdebug,xml,xmlreader,xmlwriter,yaml,zip,zlib
8589
env:
8690
PHP_VERSION: ${{ inputs.php_version }}
91+
PHP_PACKAGE_VERSION: ${{ inputs.package_version }}
8792
XDEBUG_VERSION: ${{ inputs.xdebug_version }}
8893
SPC_REF: ${{ inputs.spc_ref }}
8994
PHP_CLI_EXTENSIONS: ${{ matrix.extensions }}
@@ -113,8 +118,14 @@ jobs:
113118
exit 1
114119
fi
115120
121+
if [[ ! "$PHP_PACKAGE_VERSION" =~ ^[a-z0-9][a-z0-9._-]{0,63}$ ]]; then
122+
echo "Unsupported package version: $PHP_PACKAGE_VERSION (use 1-64 lowercase letters, numbers, dots, underscores, or dashes)" >&2
123+
exit 1
124+
fi
125+
116126
php_minor="${PHP_VERSION%.*}"
117127
echo "PHP_MINOR=$php_minor" >> "$GITHUB_ENV"
128+
echo "PHP_PACKAGE_ID=$PHP_VERSION-$PHP_PACKAGE_VERSION" >> "$GITHUB_ENV"
118129
119130
- name: Setup PHP for static-php-cli
120131
# Linux runs SPC inside the spc-gnu-docker container, which ships
@@ -255,6 +266,8 @@ jobs:
255266
cat > "$staging_dir/runtime.json" <<JSON
256267
{
257268
"phpVersion": "$PHP_VERSION",
269+
"packageVersion": "$PHP_PACKAGE_VERSION",
270+
"packageId": "$PHP_PACKAGE_ID",
258271
"phpMinor": "$PHP_MINOR",
259272
"threadSafety": "nts",
260273
"platform": "$PHP_CLI_ARTIFACT_PLATFORM",
@@ -320,6 +333,8 @@ jobs:
320333
cat > "$staging_dir/runtime.json" <<JSON
321334
{
322335
"phpVersion": "$PHP_VERSION",
336+
"packageVersion": "$PHP_PACKAGE_VERSION",
337+
"packageId": "$PHP_PACKAGE_ID",
323338
"phpMinor": "$PHP_MINOR",
324339
"threadSafety": "nts",
325340
"platform": "$PHP_CLI_ARTIFACT_PLATFORM",
@@ -496,6 +511,8 @@ jobs:
496511
497512
$runtimeJson = @{
498513
phpVersion = $env:PHP_VERSION
514+
packageVersion = $env:PHP_PACKAGE_VERSION
515+
packageId = $env:PHP_PACKAGE_ID
499516
phpMinor = $env:PHP_MINOR
500517
threadSafety = 'nts'
501518
platform = $env:PHP_CLI_ARTIFACT_PLATFORM
@@ -575,6 +592,7 @@ jobs:
575592
pull-requests: write
576593
env:
577594
PHP_VERSION: ${{ inputs.php_version }}
595+
PHP_PACKAGE_VERSION: ${{ inputs.package_version }}
578596
PHP_CLI_VISIBILITY: ${{ inputs.apps_cdn_visibility }}
579597
WPCOM_API_TOKEN: ${{ secrets.WPCOM_API_TOKEN }}
580598
steps:
@@ -606,13 +624,14 @@ jobs:
606624
607625
bundle exec fastlane publish_php_cli_binaries \
608626
version:"${PHP_VERSION}" \
627+
package_version:"${PHP_PACKAGE_VERSION}" \
609628
artifacts_dir:"${PWD}/out/php-binaries" \
610629
visibility:"${PHP_CLI_VISIBILITY}" \
611630
output_file:"${upload_results_file}"
612631
613632
echo "### Apps CDN PHP CLI upload" >> "$GITHUB_STEP_SUMMARY"
614633
echo "" >> "$GITHUB_STEP_SUMMARY"
615-
echo "Uploaded or updated PHP ${PHP_VERSION} CLI artifacts with ${PHP_CLI_VISIBILITY} visibility." >> "$GITHUB_STEP_SUMMARY"
634+
echo "Uploaded PHP ${PHP_VERSION} package ${PHP_PACKAGE_VERSION} CLI artifacts with ${PHP_CLI_VISIBILITY} visibility." >> "$GITHUB_STEP_SUMMARY"
616635
echo "" >> "$GITHUB_STEP_SUMMARY"
617636
618637
PHP_CLI_UPLOAD_RESULTS_FILE="$upload_results_file" ruby -rjson -e '
@@ -635,6 +654,7 @@ jobs:
635654
636655
node scripts/update-php-binary-cdn-metadata.mjs \
637656
--version "${PHP_VERSION}" \
657+
--package-version "${PHP_PACKAGE_VERSION}" \
638658
--upload-results "${PWD}/out/php-binaries/apps-cdn-upload-results.json"
639659
640660
if git diff --quiet -- packages/common/lib/php-binary-cdn-metadata.json; then
@@ -650,16 +670,16 @@ jobs:
650670
run: |
651671
set -euo pipefail
652672
653-
branch="update-php-cli-metadata-${PHP_VERSION}-${GITHUB_RUN_ID}"
673+
branch="update-php-cli-metadata-${PHP_VERSION}-${PHP_PACKAGE_VERSION}-${GITHUB_RUN_ID}"
654674
# Standard GitHub Actions bot noreply identity for workflow-created commits.
655675
git config user.name "github-actions[bot]"
656676
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
657677
git switch -c "$branch"
658678
git add packages/common/lib/php-binary-cdn-metadata.json
659-
git commit -m "Update PHP ${PHP_VERSION} binary metadata"
679+
git commit -m "Update PHP ${PHP_VERSION} package ${PHP_PACKAGE_VERSION} metadata"
660680
git push --set-upstream origin "$branch"
661681
gh pr create \
662682
--base "${GITHUB_REF_NAME}" \
663683
--head "$branch" \
664-
--title "Update PHP ${PHP_VERSION} binary metadata" \
665-
--body "Updates PHP CLI binary CDN metadata after a successful Apps CDN upload."
684+
--title "Update PHP ${PHP_VERSION} package ${PHP_PACKAGE_VERSION} metadata" \
685+
--body "Updates PHP CLI binary CDN metadata after a successful immutable Apps CDN upload."

apps/cli/lib/dependency-management/paths.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from 'path';
22
import {
3-
getConfiguredPhpBinaryVersion,
3+
getConfiguredPhpBinaryPackageId,
44
NativePhpSupportedVersions,
55
type NativePhpSupportedVersion,
66
} from '@studio/common/lib/php-binary-metadata';
@@ -20,15 +20,15 @@ function isNativePhpSupportedVersion( version: string ): version is NativePhpSup
2020
return ( NativePhpSupportedVersions as readonly string[] ).includes( version );
2121
}
2222

23-
// PHP binaries live in ~/.studio/php-bin/<patch>/. The default version also ships with
23+
// PHP binaries live in ~/.studio/php-bin/<package-id>/. The default version also ships with
2424
// Studio and is copied into this writable location by a CLI migration.
2525
export function getPhpBinaryPath( version: NativePhpSupportedVersion | string ): string {
2626
if ( ! isNativePhpSupportedVersion( version ) ) {
2727
return getExactPhpBinaryPath( version );
2828
}
2929

30-
const configuredVersion = getConfiguredPhpBinaryVersion( version );
31-
return getExactPhpBinaryPath( configuredVersion ?? version );
30+
const packageId = getConfiguredPhpBinaryPackageId( version );
31+
return getExactPhpBinaryPath( packageId ?? version );
3232
}
3333

3434
const WP_CLI_PHAR_FILENAME = 'wp-cli.phar';

apps/cli/lib/dependency-management/php-binary.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ async function downloadAndInstall(
6464
}
6565

6666
const downloadInfo = await resolvePhpBinaryDownloadInfo( version, platform, arch );
67-
const destPath = getPhpBinaryPath( downloadInfo.patchVersion );
67+
const destPath = getPhpBinaryPath( downloadInfo.packageId );
6868
const destDir = path.dirname( destPath );
6969
const phpBinRoot = path.dirname( destDir );
7070

@@ -90,7 +90,7 @@ async function downloadAndInstall(
9090
try {
9191
await downloadFile( downloadInfo.url, downloadPath, onProgress );
9292
await verifyHash( downloadPath, downloadInfo.sha, version, platform, arch );
93-
await extractAndInstall( downloadPath, destPath, downloadInfo.patchVersion, platform );
93+
await extractAndInstall( downloadPath, destPath, downloadInfo.packageId, platform );
9494
} catch ( err ) {
9595
fs.rmSync( destDir, { recursive: true, force: true } );
9696
throw err;
@@ -143,14 +143,14 @@ async function verifyHash(
143143
async function extractAndInstall(
144144
archivePath: string,
145145
destPath: string,
146-
patchVersion: string,
146+
packageId: string,
147147
platform: NodeJS.Platform
148148
): Promise< void > {
149149
const isWindows = platform === 'win32';
150150
const tmpDir = os.tmpdir();
151151
const fallbackBinaryName = isWindows ? 'php.exe' : 'php';
152152

153-
const extractDir = fs.mkdtempSync( path.join( tmpDir, `php-${ patchVersion }-` ) );
153+
const extractDir = fs.mkdtempSync( path.join( tmpDir, `php-${ packageId }-` ) );
154154
try {
155155
await extractZip( archivePath, extractDir );
156156
const binaryName = getRuntimeBinaryName( extractDir ) ?? fallbackBinaryName;

apps/cli/lib/dependency-management/tests/paths.test.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import fs from 'fs';
22
import os from 'os';
33
import path from 'path';
4-
import { getConfiguredPhpBinaryVersion } from '@studio/common/lib/php-binary-metadata';
4+
import { getConfiguredPhpBinaryPackageId } from '@studio/common/lib/php-binary-metadata';
55
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
66
import { getPhpBinaryPath } from 'cli/lib/dependency-management/paths';
77

@@ -30,19 +30,19 @@ describe( 'getPhpBinaryPath', () => {
3030
fs.rmSync( configDir, { recursive: true, force: true } );
3131
} );
3232

33-
it( 'uses the configured patch directory for a PHP minor', () => {
33+
it( 'uses the configured package directory for a PHP minor', () => {
3434
expect( getPhpBinaryPath( '8.4' ) ).toBe(
3535
path.join(
3636
configDir,
3737
'php-bin',
38-
getConfiguredPhpBinaryVersion( '8.4' )!,
38+
getConfiguredPhpBinaryPackageId( '8.4' )!,
3939
process.platform === 'win32' ? 'php.exe' : 'php'
4040
)
4141
);
4242
} );
4343

4444
it( 'does not let existing local patch folders override metadata', () => {
45-
const configuredVersion = getConfiguredPhpBinaryVersion( '8.4' )!;
45+
const configuredVersion = getConfiguredPhpBinaryPackageId( '8.4' )!;
4646
const localBinary = writePhpBinary( configuredVersion === '8.4.20' ? '8.4.21' : '8.4.20' );
4747

4848
expect( getPhpBinaryPath( '8.4' ) ).not.toBe( localBinary );
@@ -61,4 +61,15 @@ describe( 'getPhpBinaryPath', () => {
6161
path.join( configDir, 'php-bin', '8.4.21', process.platform === 'win32' ? 'php.exe' : 'php' )
6262
);
6363
} );
64+
65+
it( 'uses an exact package path when called with a Studio package ID', () => {
66+
expect( getPhpBinaryPath( '8.4.21-1.0.0' ) ).toBe(
67+
path.join(
68+
configDir,
69+
'php-bin',
70+
'8.4.21-1.0.0',
71+
process.platform === 'win32' ? 'php.exe' : 'php'
72+
)
73+
);
74+
} );
6475
} );

apps/cli/lib/dependency-management/tests/php-binary.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {
22
resolveNativePhpVersion,
3+
getConfiguredPhpBinaryPackageId,
4+
getConfiguredPhpBinaryPackageVersion,
35
getConfiguredPhpBinaryVersion,
46
getPhpBinaryDownloadInfo,
57
} from '@studio/common/lib/php-binary-metadata';
@@ -11,6 +13,8 @@ describe( 'getPhpBinaryDownloadInfo', () => {
1113
expect( getPhpBinaryDownloadInfo( '8.4', 'darwin', 'arm64' ) ).toEqual(
1214
expect.objectContaining( {
1315
patchVersion: getConfiguredPhpBinaryVersion( '8.4' ),
16+
packageId: getConfiguredPhpBinaryPackageId( '8.4' ),
17+
packageVersion: getConfiguredPhpBinaryPackageVersion( '8.4' ),
1418
url: expect.stringContaining( '/downloads/wordpress-com-studio-php-cli/mac-silicon/' ),
1519
sha: expect.stringMatching( /^[a-f0-9]{64}$/ ),
1620
} )
@@ -21,6 +25,8 @@ describe( 'getPhpBinaryDownloadInfo', () => {
2125
expect( getPhpBinaryDownloadInfo( '8.4', 'win32', 'arm64' ) ).toEqual(
2226
expect.objectContaining( {
2327
patchVersion: getConfiguredPhpBinaryVersion( '8.4' ),
28+
packageId: getConfiguredPhpBinaryPackageId( '8.4' ),
29+
packageVersion: getConfiguredPhpBinaryPackageVersion( '8.4' ),
2430
url: expect.stringContaining( '/downloads/wordpress-com-studio-php-cli/windows-x64/' ),
2531
sha: expect.stringMatching( /^[a-f0-9]{64}$/ ),
2632
} )
@@ -31,6 +37,15 @@ describe( 'getPhpBinaryDownloadInfo', () => {
3137
expect( getConfiguredPhpBinaryVersion( '8.4' ) ).toMatch( /^\d+\.\d+\.\d+$/ );
3238
} );
3339

40+
it( 'returns a package ID composed from the PHP patch and optional package version', () => {
41+
const patchVersion = getConfiguredPhpBinaryVersion( '8.4' );
42+
const packageVersion = getConfiguredPhpBinaryPackageVersion( '8.4' );
43+
44+
expect( getConfiguredPhpBinaryPackageId( '8.4' ) ).toBe(
45+
packageVersion ? `${ patchVersion }-${ packageVersion }` : patchVersion
46+
);
47+
} );
48+
3449
it( 'returns undefined when metadata is missing for the platform', () => {
3550
expect( getPhpBinaryDownloadInfo( '8.4', 'aix', 'x64' ) ).toBeUndefined();
3651
} );

apps/cli/migrations/06-install-bundled-default-php.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fs from 'node:fs';
22
import path from 'node:path';
33
import { DEFAULT_PHP_VERSION } from '@studio/common/constants';
44
import {
5-
getConfiguredPhpBinaryVersion,
5+
getConfiguredPhpBinaryPackageId,
66
resolveNativePhpVersion,
77
} from '@studio/common/lib/php-binary-metadata';
88
import { getPhpBinaryPath } from 'cli/lib/dependency-management/paths';
@@ -16,13 +16,13 @@ function getBundledPhpBinaryRoot(): string {
1616
);
1717
}
1818

19-
function getDefaultPhpPatchVersion(): string {
19+
function getDefaultPhpPackageId(): string {
2020
const nativeVersion = resolveNativePhpVersion( DEFAULT_PHP_VERSION );
21-
return getConfiguredPhpBinaryVersion( nativeVersion ) ?? nativeVersion;
21+
return getConfiguredPhpBinaryPackageId( nativeVersion ) ?? nativeVersion;
2222
}
2323

2424
function getBundledDefaultPhpDir(): string {
25-
return path.join( getBundledPhpBinaryRoot(), getDefaultPhpPatchVersion() );
25+
return path.join( getBundledPhpBinaryRoot(), getDefaultPhpPackageId() );
2626
}
2727

2828
function getBundledDefaultPhpPath(): string {

apps/cli/migrations/tests/06-install-bundled-default-php.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import os from 'os';
33
import path from 'path';
44
import { DEFAULT_PHP_VERSION } from '@studio/common/constants';
55
import {
6-
getConfiguredPhpBinaryVersion,
6+
getConfiguredPhpBinaryPackageId,
77
resolveNativePhpVersion,
88
} from '@studio/common/lib/php-binary-metadata';
99
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
@@ -16,16 +16,16 @@ function getBinaryName(): string {
1616
return process.platform === 'win32' ? 'php.exe' : 'php';
1717
}
1818

19-
function getDefaultPhpPatchVersion(): string {
20-
return getConfiguredPhpBinaryVersion( resolveNativePhpVersion( DEFAULT_PHP_VERSION ) )!;
19+
function getDefaultPhpPackageId(): string {
20+
return getConfiguredPhpBinaryPackageId( resolveNativePhpVersion( DEFAULT_PHP_VERSION ) )!;
2121
}
2222

2323
function getBundledDefaultPhpDir(): string {
24-
return path.join( bundledPhpDir, getDefaultPhpPatchVersion() );
24+
return path.join( bundledPhpDir, getDefaultPhpPackageId() );
2525
}
2626

2727
function getDefaultPhpDestinationDir(): string {
28-
return path.join( configDir, 'php-bin', getDefaultPhpPatchVersion() );
28+
return path.join( configDir, 'php-bin', getDefaultPhpPackageId() );
2929
}
3030

3131
function writeBundledDefaultPhp(): void {

0 commit comments

Comments
 (0)