From 105d425ea643fe6abdc6885ba42cab9ab389082b Mon Sep 17 00:00:00 2001 From: Arnold Daniels Date: Thu, 13 Nov 2025 12:19:15 +0100 Subject: [PATCH 1/9] Switch CI from Travis to GitHub Actions --- .github/workflows/ci.yml | 53 ++++++++++++++++++++++++++++++++++++++++ .travis.yml | 53 ---------------------------------------- 2 files changed, 53 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7b1912e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +name: CI + +on: + push: + branches: + - master + tags: + - 'v*.*.*' + pull_request: + branches: + - master + +jobs: + build: + name: PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-version: + - '7.2' + - '7.3' + - '7.4' + - '8.0' + - 'nightly' + continue-on-error: ${{ matrix.php-version == 'nightly' }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: none + + - name: Install dependencies + run: | + phpize + ./configure + make + + - name: Install extension + run: sudo make install + + - name: Run tests + run: make test + + - name: Upload test diffs on failure + if: failure() + run: | + find tests -name '*.diff' -print -exec cat {} + diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4df8c9b..0000000 --- a/.travis.yml +++ /dev/null @@ -1,53 +0,0 @@ -env: - EXTNAME: skeleton - -language: php -php: - - 7.2 - - 7.3 - - 7.4 - - 8.0 - -matrix: - allow_failures: - - php: nightly - -branches: - only: - - master - - travis - - /^v\d+\.\d+\.\d+$/ - -install: - - phpize - - ./configure - - make - -before_script: - make install - -script: - make test - -after_failure: - - | - for FILE in $(find tests -name '*.diff'); do - echo $FILE - cat FILE - echo - done - -before_deploy: - - pecl package - - export RELEASE_PACKAGE=$(ls "$EXTNAME"-*.tgz) - -deploy: - provider: releases - auth_token: - secure: - file: "$RELEASE_PACKAGE" - skip_cleanup: true - name: "$TRAVIS_TAG" - prerelease: true - on: - tags: true From ba1126bb9c0d65141c695ed433d477cd81602efa Mon Sep 17 00:00:00 2001 From: Arnold Daniels Date: Thu, 13 Nov 2025 13:07:34 +0100 Subject: [PATCH 2/9] Update CI matrix to supported PHP versions --- .github/workflows/ci.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b1912e..236855f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,10 +18,9 @@ jobs: fail-fast: false matrix: php-version: - - '7.2' - - '7.3' - - '7.4' - - '8.0' + - '8.1' + - '8.2' + - '8.3' - 'nightly' continue-on-error: ${{ matrix.php-version == 'nightly' }} From 96aca896766e318bebc0002cf47623c9c3b0e24a Mon Sep 17 00:00:00 2001 From: Arnold Daniels Date: Thu, 13 Nov 2025 13:07:40 +0100 Subject: [PATCH 3/9] Update CI workflow and README --- README.md | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index feaa33c..9f66afe 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Skeleton PHP extension -[![Build Status](https://travis-ci.org/improved-php-library/skeleton-php-ext.svg?branch=master)](https://travis-ci.org/improved-php-library/skeleton-php-ext) +[![CI Status](https://github.com/improved-php-library/skeleton-php-ext/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/improved-php-library/skeleton-php-ext/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/7rof1vr8mv4kam17/branch/master?svg=true)](https://ci.appveyor.com/project/jasny/skeleton-php-ext/branch/master) Skeleton project for PHP C-extension. @@ -12,8 +12,7 @@ Skeleton project for PHP C-extension. Includes; -* Travis (Linux) and AppVeyor (Windows) configuration for continuous integration / platform tests. - * Automatic deployment of package to GitHub releases +* GitHub Actions (Linux) and AppVeyor (Windows) configuration for continuous integration / platform tests. * CMake config for editing in [CLion](https://www.jetbrains.com/clion/). (See [this article](https://dev.to/jasny/developing-a-php-extension-in-clion-3oo1)) * Supported for pecl dependencies. @@ -84,7 +83,7 @@ To customize this skeleton for your own extension (e.g. `foo_bar`), edit the fol 4. Change the `zend_module_entry` from `skeleton_module_entry` to `foo_bar_module_entry` 5. In `ZEND_GET_MODULE` replace `skeleton` to `foo_bar`. -### .appveyor.yml and .travis.yml +### .appveyor.yml and GitHub Actions workflow Change `skeleton` with your extension name for the `EXTNAME` env var. @@ -93,18 +92,9 @@ env: EXTNAME: foo_bar ``` -#### Deployment - -Both Travis and AppVeyor are configured to automatically deploy the generated packages to -[GitHub releases](https://help.github.com/en/articles/creating-releases). In order to do so, you need to specify a -GitHub API key. - -1. Create a new [Personal access token](https://github.com/settings/tokens) on GitHub via developer settings with the - `public_repo` privilege. -2. For AppVeyor, encrypt the token using the online [Encrypt Yaml](https://ci.appveyor.com/tools/encrypt) tool. Replace - `` for the encrypted value in `.appveyor.yml`. -3. For Travis, install the Travis CLI (`gem install travis`) and use `travis encrypt` to encrypt the token. Replace - `` for the encrypted value in `.travis.yml`. +Update `.github/workflows/ci.yml` so that it references your extension name where needed. When you are ready to publish +artifacts through GitHub Actions, store any required secrets (like a GitHub token) as encrypted repository secrets and +consume them from the workflow instead of committing sensitive values. ### LICENSE From 256ce0bdd85996db2fa9aba8d9b3817dec53e7fb Mon Sep 17 00:00:00 2001 From: Arnold Daniels Date: Thu, 13 Nov 2025 13:07:46 +0100 Subject: [PATCH 4/9] Add Windows GitHub Actions workflow --- .appveyor.yml | 144 --------------------------------------- .github/workflows/ci.yml | 71 ++++++++++++++++++- README.md | 13 ++-- 3 files changed, 75 insertions(+), 153 deletions(-) delete mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 4aef5e6..0000000 --- a/.appveyor.yml +++ /dev/null @@ -1,144 +0,0 @@ -# See https://github.com/sergeyklay/php-appveyor - -branches: - only: - - master - - appveyor - - w32 - - /^v\d+\.\d+\.\d+$/ - -environment: - EXTNAME: skeleton - - matrix: - - PHP_VERSION: 7.2 - BUILD_TYPE: Win32 - VC_VERSION: vc15 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - - - PHP_VERSION: 7.2 - BUILD_TYPE: nts-Win32 - VC_VERSION: vc15 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - - - PHP_VERSION: 7.3 - BUILD_TYPE: Win32 - VC_VERSION: vc15 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - - - PHP_VERSION: 7.3 - BUILD_TYPE: nts-Win32 - VC_VERSION: vc15 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - - - PHP_VERSION: 7.4 - BUILD_TYPE: Win32 - VC_VERSION: vc15 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - - - PHP_VERSION: 7.4 - BUILD_TYPE: nts-Win32 - VC_VERSION: vc15 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - - - PHP_VERSION: 8.0 - BUILD_TYPE: Win32 - VC_VERSION: vs16 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - - - PHP_VERSION: 8.0 - BUILD_TYPE: nts-Win32 - VC_VERSION: vs16 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - - PHP_SDK_VERSION: 2.2.0 - TEST_PHP_EXECUTABLE: C:\php\php.exe - NO_INTERACTION: 1 - REPORT_EXIT_STATUS: 1 - -matrix: - fast_finish: true - -cache: - - 'C:\Downloads -> .appveyor.yml' - -platform: - - x86 - - x64 - -init: - - ps: $DebugPreference = 'SilentlyContinue' # Continue - - ps: >- - if ($env:APPVEYOR_REPO_TAG -eq "true") { - Update-AppveyorBuild -Version "$($Env:APPVEYOR_REPO_TAG_NAME.TrimStart("v"))" - } else { - Update-AppveyorBuild -Version "${Env:APPVEYOR_REPO_BRANCH}-$($Env:APPVEYOR_REPO_COMMIT.Substring(0, 7))" - } - -install: - - ps: Import-Module .\.ci\php-appveyor.psm1 - - - ps: InstallPhpSdk $Env:PHP_SDK_VERSION $Env:VC_VERSION $Env:PLATFORM - - ps: InstallPhp $Env:PHP_VERSION $Env:BUILD_TYPE $Env:VC_VERSION $Env:PLATFORM - - ps: InstallPhpDevPack $Env:PHP_VERSION $Env:BUILD_TYPE $Env:VC_VERSION $Env:PLATFORM - -build_script: - - ps: Import-Module .\.ci\appveyor.psm1 - - ps: InitializeBuildVars - - cmd: '"%VSDEVCMD%" -arch=%PLATFORM%' - - cmd: '"%VCVARSALL%" %ARCH%' - - cmd: C:\php-sdk\bin\phpsdk_setvars - - cmd: C:\php-devpack\phpize - - cmd: configure.bat --with-prefix=C:\php --with-php-build=C:\php-devpack --disable-all %ENABLE_EXT% - - cmd: nmake 2> compile-errors.log 1> compile.log - - ps: InitializeReleaseVars - -test_script: - - cmd: nmake test - -after_build: - - ps: Set-Location "${Env:APPVEYOR_BUILD_FOLDER}" - - ps: >- - PrepareReleasePackage ` - -PhpVersion $Env:PHP_VERSION ` - -BuildType $Env:BUILD_TYPE ` - -Platform $Env:PLATFORM ` - -ConverMdToHtml $true ` - -ReleaseFiles "${Env:RELEASE_FOLDER}\php_${Env:EXTNAME}.dll",` - "${Env:APPVEYOR_BUILD_FOLDER}\CREDITS",` - "${Env:APPVEYOR_BUILD_FOLDER}\LICENSE" - -on_failure : - - ps: >- - If (Test-Path -Path "${Env:APPVEYOR_BUILD_FOLDER}\compile-errors.log") { - Get-Content -Path "${Env:APPVEYOR_BUILD_FOLDER}\compile-errors.log" - } - - If (Test-Path -Path "${Env:APPVEYOR_BUILD_FOLDER}\compile.log") { - Get-Content -Path "${Env:APPVEYOR_BUILD_FOLDER}\compile.log" - } - - Get-ChildItem "${Env:APPVEYOR_BUILD_FOLDER}\tests" -Recurse -Filter *.diff | Foreach-Object { - [Environment]::NewLine - Write-Output $_.FullName - Get-Content -Path $_.FullName - } - -artifacts: - - path: '.\$(RELEASE_ZIPBALL).zip' - name: '$(EXTNAME)' - type: zip - -deploy: - release: v$(appveyor_build_version) - description: 'v$(appveyor_build_version)' - provider: GitHub - auth_token: - secure: - artifact: '$(RELEASE_ZIPBALL).zip' - draft: false - prerelease: true - force_update: true - on: - branch: master - APPVEYOR_REPO_TAG: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 236855f..4a3d37b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,8 +11,8 @@ on: - master jobs: - build: - name: PHP ${{ matrix.php-version }} + linux: + name: Linux PHP ${{ matrix.php-version }} runs-on: ubuntu-latest strategy: fail-fast: false @@ -50,3 +50,70 @@ jobs: if: failure() run: | find tests -name '*.diff' -print -exec cat {} + + + windows: + name: Windows PHP ${{ matrix.php-version }} (${{ matrix.build-type }}) + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + php-version: + - '8.1' + - '8.2' + - '8.3' + build-type: + - 'nts-Win32' + - 'Win32' + env: + EXTNAME: skeleton + VC_VERSION: vs16 + PLATFORM: x64 + PHP_SDK_VERSION: 2.2.0 + PHP_VERSION: ${{ matrix.php-version }} + BUILD_TYPE: ${{ matrix.build-type }} + APPVEYOR_BUILD_FOLDER: ${{ github.workspace }} + TEST_PHP_EXECUTABLE: C:\php\php.exe + NO_INTERACTION: 1 + REPORT_EXIT_STATUS: 1 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install PHP SDK and toolchain + shell: pwsh + run: | + Import-Module "$env:GITHUB_WORKSPACE\.ci\php-appveyor.psm1" + InstallPhpSdk $Env:PHP_SDK_VERSION $Env:VC_VERSION $Env:PLATFORM + InstallPhp $Env:PHP_VERSION $Env:BUILD_TYPE $Env:VC_VERSION $Env:PLATFORM + InstallPhpDevPack $Env:PHP_VERSION $Env:BUILD_TYPE $Env:VC_VERSION $Env:PLATFORM + + - name: Build and test + shell: pwsh + run: | + Import-Module "$env:GITHUB_WORKSPACE\.ci\appveyor.psm1" + InitializeBuildVars + $commands = @( + "call `"$env:VSDEVCMD`" -arch=$env:PLATFORM", + "call `"$env:VCVARSALL`" $env:ARCH", + "call C:\php-sdk\bin\phpsdk_setvars.bat", + "call C:\php-devpack\phpize.bat", + "call configure.bat --with-prefix=C:\php --with-php-build=C:\php-devpack --disable-all $env:ENABLE_EXT", + "call nmake", + "call nmake test" + ) + cmd /c ($commands -join " && ") + + - name: Upload logs on failure + if: failure() + shell: pwsh + run: | + Get-ChildItem -Path . -Filter 'compile*.log' -File | ForEach-Object { + Write-Host "--- $($_.FullName)"; Get-Content $_ + } + Get-ChildItem -Path . -Filter 'config*.log' -File | ForEach-Object { + Write-Host "--- $($_.FullName)"; Get-Content $_ + } + Get-ChildItem -Path tests -Recurse -Filter '*.diff' -File | ForEach-Object { + Write-Host "--- $($_.FullName)"; Get-Content $_ + } diff --git a/README.md b/README.md index 9f66afe..bae000d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ # Skeleton PHP extension [![CI Status](https://github.com/improved-php-library/skeleton-php-ext/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/improved-php-library/skeleton-php-ext/actions/workflows/ci.yml) -[![Build status](https://ci.appveyor.com/api/projects/status/7rof1vr8mv4kam17/branch/master?svg=true)](https://ci.appveyor.com/project/jasny/skeleton-php-ext/branch/master) Skeleton project for PHP C-extension. @@ -12,7 +11,7 @@ Skeleton project for PHP C-extension. Includes; -* GitHub Actions (Linux) and AppVeyor (Windows) configuration for continuous integration / platform tests. +* GitHub Actions configuration for Linux and Windows continuous integration / platform tests. * CMake config for editing in [CLion](https://www.jetbrains.com/clion/). (See [this article](https://dev.to/jasny/developing-a-php-extension-in-clion-3oo1)) * Supported for pecl dependencies. @@ -83,18 +82,18 @@ To customize this skeleton for your own extension (e.g. `foo_bar`), edit the fol 4. Change the `zend_module_entry` from `skeleton_module_entry` to `foo_bar_module_entry` 5. In `ZEND_GET_MODULE` replace `skeleton` to `foo_bar`. -### .appveyor.yml and GitHub Actions workflow +### GitHub Actions workflow -Change `skeleton` with your extension name for the `EXTNAME` env var. +Change `skeleton` with your extension name for the `EXTNAME` env var in the Windows job. ``` env: EXTNAME: foo_bar ``` -Update `.github/workflows/ci.yml` so that it references your extension name where needed. When you are ready to publish -artifacts through GitHub Actions, store any required secrets (like a GitHub token) as encrypted repository secrets and -consume them from the workflow instead of committing sensitive values. +Update `.github/workflows/ci.yml` so that both the Linux and Windows jobs reference your extension name where needed. +When you are ready to publish artifacts through GitHub Actions, store any required secrets (like a GitHub token) as +encrypted repository secrets and consume them from the workflow instead of committing sensitive values. ### LICENSE From 8f3a97c57f12f05a2c1cf353a9bb3ce9df97f87f Mon Sep 17 00:00:00 2001 From: Arnold Daniels Date: Thu, 13 Nov 2025 14:15:21 +0100 Subject: [PATCH 5/9] Fix Windows CI Visual Studio detection --- .ci/appveyor.psm1 | 57 --------- .ci/windows-build.psm1 | 121 ++++++++++++++++++++ .ci/{php-appveyor.psm1 => windows-php.psm1} | 53 +++++++-- .github/workflows/ci.yml | 4 +- 4 files changed, 168 insertions(+), 67 deletions(-) delete mode 100644 .ci/appveyor.psm1 create mode 100644 .ci/windows-build.psm1 rename .ci/{php-appveyor.psm1 => windows-php.psm1} (91%) diff --git a/.ci/appveyor.psm1 b/.ci/appveyor.psm1 deleted file mode 100644 index e22786b..0000000 --- a/.ci/appveyor.psm1 +++ /dev/null @@ -1,57 +0,0 @@ -Function InitializeBuildVars { - switch ($Env:VC_VERSION) { - 'vc14' { - If (-not (Test-Path $Env:VS120COMNTOOLS)) { - Throw'The VS120COMNTOOLS environment variable is not set. Check your VS installation' - } - - $Env:VSDEVCMD = ($Env:VS120COMNTOOLS -replace '\\$', '') + '\VsDevCmd.bat' - Break - } - 'vc15' { - If (-not (Test-Path $Env:VS140COMNTOOLS)) { - Throw'The VS140COMNTOOLS environment variable is not set. Check your VS installation' - } - - $Env:VSDEVCMD = ($Env:VS140COMNTOOLS -replace '\\$', '') + '\VsDevCmd.bat' - Break - } - default { - $Env:VSDEVCMD = Get-ChildItem -Path "${Env:ProgramFiles(x86)}" -Filter "VsDevCmd.bat" -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName } - - If ("$Env:VSDEVCMD" -eq "") { - Throw 'Unable to find VsDevCmd. Check your VS installation' - } - } - } - - If ($Env:PLATFORM -eq 'x64') { - $Env:ARCH = 'x86_amd64' - } Else { - $Env:ARCH = 'x86' - } - - $Env:ENABLE_EXT = "--enable-{0}" -f ("${Env:EXTNAME}" -replace "_","-") - - $SearchInFolder = (Get-Item $Env:VSDEVCMD).Directory.Parent.Parent.FullName - $Env:VCVARSALL = Get-ChildItem -Path "$SearchInFolder" -Filter "vcvarsall.bat" -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName } -} - -Function InitializeReleaseVars { - If ($Env:PLATFORM -eq 'x86') { - If ($Env:BUILD_TYPE -Match "nts-Win32") { - $Env:RELEASE_SUBFOLDER = "Release" - } Else { - $Env:RELEASE_SUBFOLDER = "Release_TS" - } - } Else { - If ($Env:BUILD_TYPE -Match "nts-Win32") { - $Env:RELEASE_SUBFOLDER = "${Env:PLATFORM}\Release" - } Else { - $Env:RELEASE_SUBFOLDER = "${Env:PLATFORM}\Release_TS" - } - } - - $Env:RELEASE_FOLDER = "${Env:APPVEYOR_BUILD_FOLDER}\${Env:RELEASE_SUBFOLDER}" - $Env:RELEASE_ZIPBALL = "${Env:EXTNAME}_${Env:PLATFORM}_${Env:VC_VERSION}_php${Env:PHP_VERSION}_${Env:APPVEYOR_BUILD_VERSION}" -} diff --git a/.ci/windows-build.psm1 b/.ci/windows-build.psm1 new file mode 100644 index 0000000..a7bd57e --- /dev/null +++ b/.ci/windows-build.psm1 @@ -0,0 +1,121 @@ +Function Get-VsInstallPath { + param ( + [Parameter(Mandatory=$false)] [System.String] $VersionRange + ) + + $ProgramFilesX86 = ${Env:ProgramFiles(x86)} + $VsWhere = [System.IO.Path]::Combine($ProgramFilesX86, 'Microsoft Visual Studio', 'Installer', 'vswhere.exe') + + if (Test-Path $VsWhere) { + $Arguments = @( + '-latest', + '-requires', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64', + '-property', 'installationPath' + ) + + if ($VersionRange) { + $Arguments += @('-version', $VersionRange) + } + + $InstallPath = & $VsWhere @Arguments + + if ($LASTEXITCODE -eq 0 -and $InstallPath) { + return $InstallPath.Trim() + } + } + + return $null +} + +Function InitializeBuildVars { + $InstallPath = $null + + switch ($Env:VC_VERSION) { + 'vc14' { + If (-not (Test-Path $Env:VS120COMNTOOLS)) { + Throw 'The VS120COMNTOOLS environment variable is not set. Check your VS installation' + } + + $Env:VSDEVCMD = ($Env:VS120COMNTOOLS -replace '\\$', '') + '\\VsDevCmd.bat' + Break + } + 'vc15' { + If (-not (Test-Path $Env:VS140COMNTOOLS)) { + Throw 'The VS140COMNTOOLS environment variable is not set. Check your VS installation' + } + + $Env:VSDEVCMD = ($Env:VS140COMNTOOLS -replace '\\$', '') + '\\VsDevCmd.bat' + Break + } + default { + $VersionRange = $null + $ProgramFilesX86 = ${Env:ProgramFiles(x86)} + + if ($Env:VC_VERSION -match '^vs([0-9]+)$') { + $VsMajor = [int]$Matches[1] + $NextMajor = $VsMajor + 1 + $VersionRange = "[${VsMajor}.0,${NextMajor}.0)" + } + + $InstallPath = Get-VsInstallPath -VersionRange $VersionRange + + if (-not $InstallPath) { + $Env:VSDEVCMD = Get-ChildItem -Path $ProgramFilesX86 -Filter "VsDevCmd.bat" -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName } | Select-Object -First 1 + } else { + $Env:VSDEVCMD = Join-Path $InstallPath "Common7\Tools\VsDevCmd.bat" + } + + If (-not $Env:VSDEVCMD -or -not (Test-Path $Env:VSDEVCMD)) { + Throw 'Unable to find VsDevCmd. Check your VS installation' + } + } + } + + If ($Env:PLATFORM -eq 'x64') { + $Env:ARCH = 'x86_amd64' + } Else { + $Env:ARCH = 'x86' + } + + $Env:ENABLE_EXT = "--enable-{0}" -f ("${Env:EXTNAME}" -replace "_", "-") + + if (-not $InstallPath) { + $InstallPath = (Get-Item $Env:VSDEVCMD).Directory.Parent.Parent.FullName + } + + $Env:VCVARSALL = Get-ChildItem -Path $InstallPath -Filter "vcvarsall.bat" -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName } | Select-Object -First 1 + + if (-not $Env:VCVARSALL -or -not (Test-Path $Env:VCVARSALL)) { + Throw 'Unable to find vcvarsall.bat. Check your VS installation' + } +} + +Function InitializeReleaseVars { + If ($Env:PLATFORM -eq 'x86') { + If ($Env:BUILD_TYPE -Match "nts-Win32") { + $Env:RELEASE_SUBFOLDER = "Release" + } Else { + $Env:RELEASE_SUBFOLDER = "Release_TS" + } + } Else { + If ($Env:BUILD_TYPE -Match "nts-Win32") { + $Env:RELEASE_SUBFOLDER = "${Env:PLATFORM}\Release" + } Else { + $Env:RELEASE_SUBFOLDER = "${Env:PLATFORM}\Release_TS" + } + } + + $Workspace = $Env:GITHUB_WORKSPACE + if (-not $Workspace) { + $Workspace = $Env:APPVEYOR_BUILD_FOLDER + } + + $Env:RELEASE_FOLDER = "${Workspace}\${Env:RELEASE_SUBFOLDER}" + + $BuildVersion = $Env:GITHUB_RUN_NUMBER + if (-not $BuildVersion) { + $BuildVersion = $Env:APPVEYOR_BUILD_VERSION + } + + $Env:RELEASE_ZIPBALL = "${Env:EXTNAME}_${Env:PLATFORM}_${Env:VC_VERSION}_php${Env:PHP_VERSION}_${BuildVersion}" +} diff --git a/.ci/php-appveyor.psm1 b/.ci/windows-php.psm1 similarity index 91% rename from .ci/php-appveyor.psm1 rename to .ci/windows-php.psm1 index de0c921..560bccc 100644 --- a/.ci/php-appveyor.psm1 +++ b/.ci/windows-php.psm1 @@ -1,4 +1,4 @@ -# This file is part of the php-appveyor.psm1 project. +# This file is part of the windows-php.psm1 helpers for CI builds. # # (c) Serghei Iakovlev # @@ -297,10 +297,28 @@ function PrepareReleaseNote { $ReleaseFile = "${Destination}\${ReleaseFile}" $ReleaseDate = Get-Date -Format o - $Image = $Env:APPVEYOR_BUILD_WORKER_IMAGE - $Version = $Env:APPVEYOR_BUILD_VERSION - $Commit = $Env:APPVEYOR_REPO_COMMIT - $CommitDate = $Env:APPVEYOR_REPO_COMMIT_TIMESTAMP + $Image = $Env:GITHUB_RUNNER_OS + if (-not $Image) { + $Image = $Env:APPVEYOR_BUILD_WORKER_IMAGE + } + + $Version = $Env:GITHUB_RUN_NUMBER + if (-not $Version) { + $Version = $Env:APPVEYOR_BUILD_VERSION + } + + $Commit = $Env:GITHUB_SHA + if (-not $Commit) { + $Commit = $Env:APPVEYOR_REPO_COMMIT + } + + $CommitDate = $Env:GITHUB_EVENT_HEAD_COMMIT_TIMESTAMP + if (-not $CommitDate) { + $CommitDate = $Env:APPVEYOR_REPO_COMMIT_TIMESTAMP + } + if (-not $CommitDate) { + $CommitDate = Get-Date -Format o + } Write-Output "Release date: ${ReleaseDate}" | Out-File -Encoding "ASCII" -Append "${ReleaseFile}" Write-Output "Release version: ${Version}" | Out-File -Encoding "ASCII" -Append "${ReleaseFile}" @@ -325,7 +343,26 @@ function PrepareReleasePackage { ) $BasePath = Resolve-Path $BasePath - $ReleaseDirectory = "${Env:APPVEYOR_PROJECT_NAME}-${Env:APPVEYOR_BUILD_ID}-${Env:APPVEYOR_JOB_ID}-${Env:APPVEYOR_JOB_NUMBER}" + if ($Env:APPVEYOR_PROJECT_NAME) { + $ReleaseDirectory = "${Env:APPVEYOR_PROJECT_NAME}-${Env:APPVEYOR_BUILD_ID}-${Env:APPVEYOR_JOB_ID}-${Env:APPVEYOR_JOB_NUMBER}" + } else { + $Repository = $Env:GITHUB_REPOSITORY + if (-not $Repository) { + $Repository = 'project' + } + + $RunId = $Env:GITHUB_RUN_ID + if (-not $RunId) { + $RunId = 'local' + } + + $RunAttempt = $Env:GITHUB_RUN_ATTEMPT + if (-not $RunAttempt) { + $RunAttempt = '1' + } + + $ReleaseDirectory = "${Repository}-${RunId}-${RunAttempt}" + } PrepareReleaseNote ` -PhpVersion $PhpVersion ` @@ -508,8 +545,8 @@ function DownloadFile { $RetryCount = 0 $Completed = $false - $WebClient = New-Object System.Net.WebClient - $WebClient.Headers.Add('User-Agent', 'AppVeyor PowerShell Script') + $WebClient = New-Object System.Net.WebClient + $WebClient.Headers.Add('User-Agent', 'GitHubActions PowerShell Script') Write-Debug "Downloading: '${RemoteUrl}' => '${Destination}' ..." diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a3d37b..91d9345 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,7 +83,7 @@ jobs: - name: Install PHP SDK and toolchain shell: pwsh run: | - Import-Module "$env:GITHUB_WORKSPACE\.ci\php-appveyor.psm1" + Import-Module "$env:GITHUB_WORKSPACE\.ci\windows-php.psm1" InstallPhpSdk $Env:PHP_SDK_VERSION $Env:VC_VERSION $Env:PLATFORM InstallPhp $Env:PHP_VERSION $Env:BUILD_TYPE $Env:VC_VERSION $Env:PLATFORM InstallPhpDevPack $Env:PHP_VERSION $Env:BUILD_TYPE $Env:VC_VERSION $Env:PLATFORM @@ -91,7 +91,7 @@ jobs: - name: Build and test shell: pwsh run: | - Import-Module "$env:GITHUB_WORKSPACE\.ci\appveyor.psm1" + Import-Module "$env:GITHUB_WORKSPACE\.ci\windows-build.psm1" InitializeBuildVars $commands = @( "call `"$env:VSDEVCMD`" -arch=$env:PLATFORM", From db1359a2df37caf2cec5236d96d2de514b31920a Mon Sep 17 00:00:00 2001 From: Arnold Daniels Date: Thu, 13 Nov 2025 14:43:53 +0100 Subject: [PATCH 6/9] Use msvc-dev-cmd action for Windows builds --- .ci/windows-build.psm1 | 85 +++++++++++++++++++++------------------- .github/workflows/ci.yml | 20 ++++++++-- 2 files changed, 60 insertions(+), 45 deletions(-) diff --git a/.ci/windows-build.psm1 b/.ci/windows-build.psm1 index a7bd57e..1e86036 100644 --- a/.ci/windows-build.psm1 +++ b/.ci/windows-build.psm1 @@ -29,45 +29,58 @@ Function Get-VsInstallPath { Function InitializeBuildVars { $InstallPath = $null + $DevEnvPreconfigured = [bool]$Env:VSCMD_VER - switch ($Env:VC_VERSION) { - 'vc14' { - If (-not (Test-Path $Env:VS120COMNTOOLS)) { - Throw 'The VS120COMNTOOLS environment variable is not set. Check your VS installation' - } + if (-not $DevEnvPreconfigured) { + switch ($Env:VC_VERSION) { + 'vc14' { + If (-not (Test-Path $Env:VS120COMNTOOLS)) { + Throw 'The VS120COMNTOOLS environment variable is not set. Check your VS installation' + } - $Env:VSDEVCMD = ($Env:VS120COMNTOOLS -replace '\\$', '') + '\\VsDevCmd.bat' - Break - } - 'vc15' { - If (-not (Test-Path $Env:VS140COMNTOOLS)) { - Throw 'The VS140COMNTOOLS environment variable is not set. Check your VS installation' + $Env:VSDEVCMD = ($Env:VS120COMNTOOLS -replace '\\$', '') + '\\VsDevCmd.bat' + Break } + 'vc15' { + If (-not (Test-Path $Env:VS140COMNTOOLS)) { + Throw 'The VS140COMNTOOLS environment variable is not set. Check your VS installation' + } - $Env:VSDEVCMD = ($Env:VS140COMNTOOLS -replace '\\$', '') + '\\VsDevCmd.bat' - Break - } - default { - $VersionRange = $null - $ProgramFilesX86 = ${Env:ProgramFiles(x86)} - - if ($Env:VC_VERSION -match '^vs([0-9]+)$') { - $VsMajor = [int]$Matches[1] - $NextMajor = $VsMajor + 1 - $VersionRange = "[${VsMajor}.0,${NextMajor}.0)" + $Env:VSDEVCMD = ($Env:VS140COMNTOOLS -replace '\\$', '') + '\\VsDevCmd.bat' + Break + } + default { + $VersionRange = $null + $ProgramFilesX86 = ${Env:ProgramFiles(x86)} + + if ($Env:VC_VERSION -match '^vs([0-9]+)$') { + $VsMajor = [int]$Matches[1] + $NextMajor = $VsMajor + 1 + $VersionRange = "[${VsMajor}.0,${NextMajor}.0)" + } + + $InstallPath = Get-VsInstallPath -VersionRange $VersionRange + + if (-not $InstallPath) { + $Env:VSDEVCMD = Get-ChildItem -Path $ProgramFilesX86 -Filter "VsDevCmd.bat" -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName } | Select-Object -First 1 + } else { + $Env:VSDEVCMD = Join-Path $InstallPath "Common7\Tools\VsDevCmd.bat" + } + + If (-not $Env:VSDEVCMD -or -not (Test-Path $Env:VSDEVCMD)) { + Throw 'Unable to find VsDevCmd. Check your VS installation' + } } + } - $InstallPath = Get-VsInstallPath -VersionRange $VersionRange + if (-not $InstallPath) { + $InstallPath = (Get-Item $Env:VSDEVCMD).Directory.Parent.Parent.FullName + } - if (-not $InstallPath) { - $Env:VSDEVCMD = Get-ChildItem -Path $ProgramFilesX86 -Filter "VsDevCmd.bat" -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName } | Select-Object -First 1 - } else { - $Env:VSDEVCMD = Join-Path $InstallPath "Common7\Tools\VsDevCmd.bat" - } + $Env:VCVARSALL = Get-ChildItem -Path $InstallPath -Filter "vcvarsall.bat" -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName } | Select-Object -First 1 - If (-not $Env:VSDEVCMD -or -not (Test-Path $Env:VSDEVCMD)) { - Throw 'Unable to find VsDevCmd. Check your VS installation' - } + if (-not $Env:VCVARSALL -or -not (Test-Path $Env:VCVARSALL)) { + Throw 'Unable to find vcvarsall.bat. Check your VS installation' } } @@ -78,16 +91,6 @@ Function InitializeBuildVars { } $Env:ENABLE_EXT = "--enable-{0}" -f ("${Env:EXTNAME}" -replace "_", "-") - - if (-not $InstallPath) { - $InstallPath = (Get-Item $Env:VSDEVCMD).Directory.Parent.Parent.FullName - } - - $Env:VCVARSALL = Get-ChildItem -Path $InstallPath -Filter "vcvarsall.bat" -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName } | Select-Object -First 1 - - if (-not $Env:VCVARSALL -or -not (Test-Path $Env:VCVARSALL)) { - Throw 'Unable to find vcvarsall.bat. Check your VS installation' - } } Function InitializeReleaseVars { diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91d9345..1cf10fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,6 +80,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Setup MSVC environment + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + - name: Install PHP SDK and toolchain shell: pwsh run: | @@ -93,10 +98,17 @@ jobs: run: | Import-Module "$env:GITHUB_WORKSPACE\.ci\windows-build.psm1" InitializeBuildVars - $commands = @( - "call `"$env:VSDEVCMD`" -arch=$env:PLATFORM", - "call `"$env:VCVARSALL`" $env:ARCH", - "call C:\php-sdk\bin\phpsdk_setvars.bat", + $commands = @() + + if ($env:VSDEVCMD) { + $commands += "call `"$env:VSDEVCMD`" -arch=$env:PLATFORM" + } + + if ($env:VCVARSALL) { + $commands += "call `"$env:VCVARSALL`" $env:ARCH" + } + + $commands += @("call C:\php-sdk\bin\phpsdk_setvars.bat", "call C:\php-devpack\phpize.bat", "call configure.bat --with-prefix=C:\php --with-php-build=C:\php-devpack --disable-all $env:ENABLE_EXT", "call nmake", From de99ac05bd1b6d5f033e2ba3d6cbe86710f44b84 Mon Sep 17 00:00:00 2001 From: Arnold Daniels Date: Sat, 15 Nov 2025 01:34:54 +0100 Subject: [PATCH 7/9] Align Windows CI with VS 2022 toolchain --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cf10fa..ea0c403 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,7 +66,7 @@ jobs: - 'Win32' env: EXTNAME: skeleton - VC_VERSION: vs16 + VC_VERSION: vs17 PLATFORM: x64 PHP_SDK_VERSION: 2.2.0 PHP_VERSION: ${{ matrix.php-version }} @@ -84,6 +84,7 @@ jobs: uses: ilammy/msvc-dev-cmd@v1 with: arch: x64 + vsversion: '2022' - name: Install PHP SDK and toolchain shell: pwsh From 5518f36a83ef3522b3287018a14e99bd5948013a Mon Sep 17 00:00:00 2001 From: Arnold Daniels Date: Sat, 15 Nov 2025 22:54:49 +0100 Subject: [PATCH 8/9] Adjust Windows CI VC mapping --- .ci/windows-php.psm1 | 6 +++--- .github/workflows/ci.yml | 36 +++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/.ci/windows-php.psm1 b/.ci/windows-php.psm1 index 560bccc..bbdea64 100644 --- a/.ci/windows-php.psm1 +++ b/.ci/windows-php.psm1 @@ -59,7 +59,7 @@ function InstallPhp { $ReleasesPart = "releases/archives" } - $RemoteUrl = "http://windows.php.net/downloads/{0}/php-{1}-{2}-{3}-{4}.zip" -f + $RemoteUrl = "https://windows.php.net/downloads/{0}/php-{1}-{2}-{3}-{4}.zip" -f $ReleasesPart, $FullVersion, $BuildType, $VC, $Platform $Archive = "C:\Downloads\php-${FullVersion}-${BuildType}-${VC}-${Platform}.zip" @@ -96,7 +96,7 @@ function InstallPhpDevPack { $ReleasesPart = "releases/archives" } - $RemoteUrl = "http://windows.php.net/downloads/{0}/php-devel-pack-{1}-{2}-{3}-{4}.zip" -f + $RemoteUrl = "https://windows.php.net/downloads/{0}/php-devel-pack-{1}-{2}-{3}-{4}.zip" -f $ReleasesPart, $Version, $BuildType, $VC, $Platform $Archive = "C:\Downloads\php-devel-pack-${Version}-${BuildType}-${VC}-${Platform}.zip" @@ -441,7 +441,7 @@ function SetupPhpVersionString { [Parameter(Mandatory=$true)] [String] $Pattern ) - $RemoteUrl = 'http://windows.php.net/downloads/releases/sha256sum.txt' + $RemoteUrl = 'https://windows.php.net/downloads/releases/sha256sum.txt' $Destination = "${Env:Temp}\php-sha256sum.txt" if (-not (Test-Path $Destination)) { diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea0c403..baac949 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,16 +57,34 @@ jobs: strategy: fail-fast: false matrix: - php-version: - - '8.1' - - '8.2' - - '8.3' - build-type: - - 'nts-Win32' - - 'Win32' + include: + - php-version: '8.1' + build-type: 'nts-Win32' + vc-version: vs16 + vs-version: '2019' + - php-version: '8.1' + build-type: 'Win32' + vc-version: vs16 + vs-version: '2019' + - php-version: '8.2' + build-type: 'nts-Win32' + vc-version: vs17 + vs-version: '2022' + - php-version: '8.2' + build-type: 'Win32' + vc-version: vs17 + vs-version: '2022' + - php-version: '8.3' + build-type: 'nts-Win32' + vc-version: vs17 + vs-version: '2022' + - php-version: '8.3' + build-type: 'Win32' + vc-version: vs17 + vs-version: '2022' env: EXTNAME: skeleton - VC_VERSION: vs17 + VC_VERSION: ${{ matrix.vc-version }} PLATFORM: x64 PHP_SDK_VERSION: 2.2.0 PHP_VERSION: ${{ matrix.php-version }} @@ -84,7 +102,7 @@ jobs: uses: ilammy/msvc-dev-cmd@v1 with: arch: x64 - vsversion: '2022' + vsversion: ${{ matrix.vs-version }} - name: Install PHP SDK and toolchain shell: pwsh From 84cce12e7c4ba9cb8c175ac1a3a74e8fb650c30a Mon Sep 17 00:00:00 2001 From: Arnold Daniels Date: Sat, 15 Nov 2025 22:54:57 +0100 Subject: [PATCH 9/9] Resolve PHP toolchain automatically on Windows CI --- .ci/windows-php.psm1 | 59 +++++++++++++++++++++++++++++++++++----- .github/workflows/ci.yml | 28 +++++++++---------- 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/.ci/windows-php.psm1 b/.ci/windows-php.psm1 index bbdea64..7aacaa7 100644 --- a/.ci/windows-php.psm1 +++ b/.ci/windows-php.psm1 @@ -49,8 +49,12 @@ function InstallPhp { [Parameter(Mandatory=$false)] [System.String] $InstallPath = "C:\php" ) - SetupPrerequisites - $FullVersion = SetupPhpVersionString -Pattern $Version + SetupPrerequisites + $FullVersion = $Env:PHP_FULL_VERSION + + if (-not $FullVersion) { + $FullVersion = SetupPhpVersionString -Pattern $Version + } Write-Debug "Install PHP v${FullVersion}" @@ -86,8 +90,12 @@ function InstallPhpDevPack { [Parameter(Mandatory=$false)] [System.String] $InstallPath = "C:\php-devpack" ) - SetupPrerequisites - $Version = SetupPhpVersionString -Pattern $PhpVersion + SetupPrerequisites + $Version = $Env:PHP_FULL_VERSION + + if (-not $Version) { + $Version = SetupPhpVersionString -Pattern $PhpVersion + } Write-Debug "Install PHP Dev for PHP v${Version}" @@ -436,10 +444,47 @@ function FormatReleaseFiles { Set-Location "${CurrentPath}" } +function ResolvePhpToolset { + param ( + [Parameter(Mandatory=$true)] [String] $PhpVersion + ) + + $FullVersion = SetupPhpVersionString -Pattern $PhpVersion + $ParsedVersion = [Version]$FullVersion + + $VcVersion = 'vs16' + $VsVersion = '2019' + + if ($ParsedVersion.Major -gt 8) { + $VcVersion = 'vs17' + $VsVersion = '2022' + } elseif ($ParsedVersion.Major -eq 8) { + if ($ParsedVersion.Minor -ge 2) { + $VcVersion = 'vs17' + $VsVersion = '2022' + } else { + $VcVersion = 'vs16' + $VsVersion = '2019' + } + } elseif ($ParsedVersion.Major -eq 7 -and $ParsedVersion.Minor -ge 4) { + $VcVersion = 'vc15' + $VsVersion = '2017' + } elseif ($ParsedVersion.Major -eq 7 -and $ParsedVersion.Minor -ge 0) { + $VcVersion = 'vc14' + $VsVersion = '2015' + } + + return [PSCustomObject]@{ + FullVersion = $FullVersion + VcVersion = $VcVersion + VsVersion = $VsVersion + } +} + function SetupPhpVersionString { - param ( - [Parameter(Mandatory=$true)] [String] $Pattern - ) + param ( + [Parameter(Mandatory=$true)] [String] $Pattern + ) $RemoteUrl = 'https://windows.php.net/downloads/releases/sha256sum.txt' $Destination = "${Env:Temp}\php-sha256sum.txt" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index baac949..5a08536 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,31 +60,18 @@ jobs: include: - php-version: '8.1' build-type: 'nts-Win32' - vc-version: vs16 - vs-version: '2019' - php-version: '8.1' build-type: 'Win32' - vc-version: vs16 - vs-version: '2019' - php-version: '8.2' build-type: 'nts-Win32' - vc-version: vs17 - vs-version: '2022' - php-version: '8.2' build-type: 'Win32' - vc-version: vs17 - vs-version: '2022' - php-version: '8.3' build-type: 'nts-Win32' - vc-version: vs17 - vs-version: '2022' - php-version: '8.3' build-type: 'Win32' - vc-version: vs17 - vs-version: '2022' env: EXTNAME: skeleton - VC_VERSION: ${{ matrix.vc-version }} PLATFORM: x64 PHP_SDK_VERSION: 2.2.0 PHP_VERSION: ${{ matrix.php-version }} @@ -98,11 +85,24 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Resolve PHP toolset + id: php-toolset + shell: pwsh + run: | + Import-Module "$env:GITHUB_WORKSPACE\.ci\windows-php.psm1" + $toolset = ResolvePhpToolset -PhpVersion $env:PHP_VERSION + Add-Content -Path $env:GITHUB_ENV -Value "PHP_FULL_VERSION=$($toolset.FullVersion)" + Add-Content -Path $env:GITHUB_ENV -Value "VC_VERSION=$($toolset.VcVersion)" + Add-Content -Path $env:GITHUB_ENV -Value "VS_VERSION=$($toolset.VsVersion)" + Add-Content -Path $env:GITHUB_OUTPUT -Value "full-version=$($toolset.FullVersion)" + Add-Content -Path $env:GITHUB_OUTPUT -Value "vc-version=$($toolset.VcVersion)" + Add-Content -Path $env:GITHUB_OUTPUT -Value "vs-version=$($toolset.VsVersion)" + - name: Setup MSVC environment uses: ilammy/msvc-dev-cmd@v1 with: arch: x64 - vsversion: ${{ matrix.vs-version }} + vsversion: ${{ steps.php-toolset.outputs.vs-version }} - name: Install PHP SDK and toolchain shell: pwsh