Build PHP Extension https://pecl.php.net/get/pdo_ibm, 1.7.0 #1272
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build PHP Extension From PECL | |
| run-name: Build PHP Extension ${{ inputs.extension-url }}, ${{ inputs.extension-ref }} | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| extension-url: | |
| description: 'Extension URL' | |
| required: true | |
| extension-ref: | |
| description: 'Extension ref' | |
| required: true | |
| php-version-list: | |
| description: 'PHP versions to build' | |
| required: false | |
| arch-list: | |
| type: choice | |
| options: ['x64', 'x86', 'x64,x86'] | |
| description: 'Architectures to build' | |
| required: false | |
| default: 'x64,x86' | |
| ts-list: | |
| type: choice | |
| options: ['nts', 'ts', 'nts,ts'] | |
| description: 'Thread safety to build' | |
| required: false | |
| default: 'nts,ts' | |
| args: | |
| description: 'Configure arguments' | |
| required: false | |
| libs: | |
| description: 'Libraries' | |
| required: false | |
| run-tests: | |
| type: choice | |
| options: ['true', 'false'] | |
| description: 'Run tests after building the extension' | |
| required: false | |
| default: 'false' | |
| test-runner: | |
| description: 'Test runner to use' | |
| required: false | |
| default: 'run-tests.php' | |
| test-runner-args: | |
| description: 'Arguments for the test runner' | |
| required: false | |
| repository_dispatch: | |
| types: [build_extension] | |
| permissions: | |
| contents: write | |
| jobs: | |
| prepare-release: | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: prepare-${{ inputs.extension-url }}-${{ inputs.extension-ref }} | |
| cancel-in-progress: false | |
| outputs: | |
| tag: ${{ steps.out.outputs.tag }} | |
| extension: ${{ steps.out.outputs.extension }} | |
| ref_clean: ${{ steps.out.outputs.ref_clean }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| # Важно: не создаём локальные теги. Релиз создаёт GitHub и тег будет Verified. | |
| - name: Compute names, ensure release with Verified tag | |
| id: prep | |
| shell: bash | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| extension_url="${{ inputs.extension-url }}" | |
| extension="$(basename "$extension_url" | tr '[:upper:]' '[:lower:]')" | |
| # Нормализуем имя расширения | |
| case "$extension" in | |
| "base58-php-ext") extension="base58" ;; | |
| "dd-trace-php") extension="ddtrace" ;; | |
| "msgpack-php") extension="msgpack" ;; | |
| "php-firebird") extension="interbase" ;; | |
| "php-ext-lz4") extension="lz4" ;; | |
| "php-memcached") extension="memcached" ;; | |
| "pecl-database-oci8") extension="oci8_19" ;; | |
| "pecl-database-pdo_oci") extension="pdo_oci" ;; | |
| "pecl-text-ssdeep") extension="ssdeep" ;; | |
| esac | |
| ref="${{ inputs.extension-ref }}" | |
| ref_clean="$(echo "$ref" | sed 's/^v//')" | |
| tag="${extension}-${ref_clean}" | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git fetch --tags --force || true | |
| target_sha="$(git rev-parse HEAD)" | |
| if gh release view "${tag}" -R ${{ github.repository }} >/dev/null 2>&1; then | |
| echo "Release ${tag} already exists" | |
| else | |
| # Если на origin уже есть тег (возможно не Verified) — удалим и пересоздадим через GitHub. | |
| # if git ls-remote --tags origin | grep -qE "refs/tags/${tag}$"; then | |
| # echo "Tag ${tag} exists on origin. Deleting to recreate it as Verified..." | |
| # gh api -X DELETE "repos/${{ github.repository }}/git/refs/tags/${tag}" || true | |
| # git fetch --tags --force || true | |
| # git push origin ":refs/tags/${tag}" || true | |
| # fi | |
| # Создаём релиз с target — GitHub создаст Verified тег | |
| gh release create "${tag}" \ | |
| -t "${extension} ${ref_clean}" \ | |
| -n "Release of PECL extension '${extension}' version ${ref_clean}" \ | |
| --target "${target_sha}" \ | |
| -R ${{ github.repository }} | |
| fi | |
| echo "extension=$extension" >> "$GITHUB_OUTPUT" | |
| echo "ref_clean=$ref_clean" >> "$GITHUB_OUTPUT" | |
| echo "tag=$tag" >> "$GITHUB_OUTPUT" | |
| - name: Expose outputs | |
| id: out | |
| run: | | |
| echo "extension=${{ steps.prep.outputs.extension }}" >> "$GITHUB_OUTPUT" | |
| echo "ref_clean=${{ steps.prep.outputs.ref_clean }}" >> "$GITHUB_OUTPUT" | |
| echo "tag=${{ steps.prep.outputs.tag }}" >> "$GITHUB_OUTPUT" | |
| get-extension-matrix: | |
| needs: prepare-release | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.extension-matrix.outputs.matrix }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Get the extension matrix | |
| id: extension-matrix | |
| uses: ./extension-matrix | |
| with: | |
| extension-url: ${{ inputs.extension-url }} | |
| extension-ref: ${{ inputs.extension-ref }} | |
| php-version-list: ${{ inputs.php-version-list }} | |
| arch-list: ${{ inputs.arch-list }} | |
| ts-list: ${{ inputs.ts-list }} | |
| extension: | |
| needs: [prepare-release, get-extension-matrix] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.get-extension-matrix.outputs.matrix) }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Build the extension | |
| uses: ./extension | |
| with: | |
| extension-url: ${{ inputs.extension-url }} | |
| extension-ref: ${{ inputs.extension-ref }} | |
| php-version: ${{ matrix.php-version }} | |
| arch: ${{ matrix.arch }} | |
| ts: ${{ matrix.ts }} | |
| args: ${{ inputs.args }} | |
| libs: ${{ inputs.libs }} | |
| run-tests: ${{ inputs.run-tests }} | |
| test-runner: ${{ inputs.test-runner }} | |
| test-runner-args: ${{ inputs.test-runner-args }} | |
| build-directory: C:\b | |
| env: | |
| artifact-naming-scheme: pecl | |
| auto-detect-args: true | |
| auto-detect-libs: true | |
| no-debug-symbols-ddtrace: true | |
| - name: Upload to release immediately | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $extensionUrl = "${{ inputs.extension-url }}" | |
| $extensionOriginal = (Split-Path $extensionUrl -Leaf).ToLower() | |
| $extension = $extensionOriginal | |
| switch ($extensionOriginal) { | |
| "base58-php-ext" { $extension = "base58" } | |
| "dd-trace-php" { $extension = "ddtrace" } | |
| "msgpack-php" { $extension = "msgpack" } | |
| "php-firebird" { $extension = "interbase" } | |
| "php-ext-lz4" { $extension = "lz4" } | |
| "php-memcached" { $extension = "memcached" } | |
| "pecl-database-oci8" { $extension = "oci8_19" } | |
| "pecl-database-pdo_oci" { $extension = "pdo_oci" } | |
| "pecl-text-ssdeep" { $extension = "ssdeep" } | |
| } | |
| $phpVersion = "${{ matrix.php-version }}" | |
| $arch = "${{ matrix.arch }}" | |
| $ts = "${{ matrix.ts }}" | |
| $ref = "${{ inputs.extension-ref }}" | |
| $refClean = $ref -replace '^v', '' | |
| $releaseTag = "${{ needs.prepare-release.outputs.tag }}" | |
| $vsVersion = switch ($phpVersion) { | |
| { $_ -in @("7.2", "7.3", "7.4") } { "vc15" } | |
| { $_ -in @("8.0", "8.1", "8.2", "8.3") } { "vs16" } | |
| { $_ -in @("8.4", "8.5") } { "vs17" } | |
| default { "vs16" } | |
| } | |
| $artifactName = "php_${extensionOriginal}-${ref}-${phpVersion}-${ts}-${vsVersion}-${arch}.zip" | |
| $artifactNameModern = "php_${extension}-${ref}-${phpVersion}-${ts}-${vsVersion}-${arch}.zip" | |
| $releaseAssetName = "php_${extension}-${refClean}-${phpVersion}-${ts}-${vsVersion}-${arch}.zip" | |
| $searchPaths = @(".", "C:\b", ".\artifacts", ".\build") | |
| $builtFile = $null | |
| $finalName = $artifactName | |
| foreach ($searchPath in $searchPaths) { | |
| if (Test-Path $searchPath) { | |
| $foundFile = Get-ChildItem -Path $searchPath -Filter $artifactName -File -ErrorAction SilentlyContinue | Select-Object -First 1 | |
| if ($foundFile) { $builtFile = $foundFile.FullName; $finalName = $artifactName; break } | |
| $foundFile = Get-ChildItem -Path $searchPath -Filter $artifactNameModern -File -ErrorAction SilentlyContinue | Select-Object -First 1 | |
| if ($foundFile) { $builtFile = $foundFile.FullName; $finalName = $artifactNameModern; break } | |
| } | |
| } | |
| if (-not $builtFile -or -not (Test-Path $builtFile)) { | |
| Write-Host "No built ZIP file found! Searched for: $artifactName, $artifactNameModern" | |
| Write-Host "Current directory contents:" | |
| Get-ChildItem -Recurse -Filter "*.zip" -ErrorAction SilentlyContinue | ForEach-Object { Write-Host $_.FullName } | |
| exit 1 | |
| } | |
| Write-Host "Found built file: $builtFile" | |
| if ($finalName -ne $releaseAssetName) { | |
| Copy-Item $builtFile $releaseAssetName -Force | |
| $artifactPathToUpload = (Resolve-Path $releaseAssetName).Path | |
| } else { | |
| $artifactPathToUpload = $builtFile | |
| } | |
| $tempDir = Join-Path $env:TEMP "repack_$(Get-Random)" | |
| New-Item -ItemType Directory -Path $tempDir -Force | Out-Null | |
| try { | |
| Write-Host "Extracting and repacking archive: $artifactPathToUpload" | |
| Expand-Archive -Path $artifactPathToUpload -DestinationPath $tempDir -Force | |
| Remove-Item $artifactPathToUpload -Force | |
| $extDir = Join-Path $tempDir "ext" | |
| $thirdPartyDir = Join-Path $tempDir "3rd-party\$extension" | |
| New-Item -ItemType Directory -Path $extDir -Force | Out-Null | |
| New-Item -ItemType Directory -Path $thirdPartyDir -Force | Out-Null | |
| $rootDll = Join-Path $tempDir "php_${extension}.dll" | |
| if (Test-Path $rootDll) { | |
| Move-Item $rootDll (Join-Path $extDir "php_${extension}.dll") -Force | |
| } | |
| $binDir = Join-Path $tempDir "bin" | |
| if (Test-Path $binDir) { | |
| $saslPlugin = Join-Path $binDir "sasl2\plugin_sasldb.dll" | |
| if (Test-Path $saslPlugin) { | |
| $sasl2Dir = Join-Path $tempDir "sasl2" | |
| New-Item -ItemType Directory -Path $sasl2Dir -Force | Out-Null | |
| if (-not (Test-Path (Join-Path $sasl2Dir "plugin_sasldb.dll"))) { | |
| Move-Item $saslPlugin (Join-Path $sasl2Dir "plugin_sasldb.dll") -Force | |
| } | |
| } | |
| Remove-Item $binDir -Recurse -Force | |
| } | |
| Get-ChildItem -Path $tempDir -Include @("*.lib", "*.pdb") -Recurse | Remove-Item -Force | |
| Get-ChildItem -Path $tempDir | Where-Object { | |
| $_.Name -ne 'ext' -and | |
| $_.Name -ne '3rd-party' -and | |
| $_.Name -ne 'sasl2' -and | |
| ( $_.PSIsContainer -or ($_.Extension -notin @('.dll')) ) -and | |
| -not ( $extension -eq 'imagick' -and $_.PSIsContainer -and $_.Name -eq 'config' ) | |
| } | ForEach-Object { | |
| Move-Item -Path $_.FullName -Destination (Join-Path $thirdPartyDir $_.Name) -Force | |
| } | |
| Compress-Archive -Path "$tempDir\*" -DestinationPath $releaseAssetName -Force | |
| } | |
| finally { | |
| if (Test-Path $tempDir) { Remove-Item $tempDir -Recurse -Force } | |
| } | |
| Write-Host "Uploading $releaseAssetName to release $releaseTag" | |
| gh release upload $releaseTag $releaseAssetName -R ${{ github.repository }} --clobber | |
| # cleanup-release: | |
| # runs-on: ubuntu-latest | |
| # if: failure() | |
| # needs: [prepare-release, get-extension-matrix, extension] | |
| # steps: | |
| # - name: Checkout repository | |
| # uses: actions/checkout@v4 | |
| # with: | |
| # fetch-depth: 0 | |
| # token: ${{ secrets.GITHUB_TOKEN }} | |
| # | |
| # - name: Cleanup Release in Case of Failure | |
| # continue-on-error: true | |
| # env: | |
| # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # run: | | |
| # set -e | |
| # release_tag="${{ needs.prepare-release.outputs.tag }}" | |
| # if gh release view "$release_tag" -R ${{ github.repository }} >/dev/null 2>&1; then | |
| # assets=$(gh release view "$release_tag" -R ${{ github.repository }} --json assets --jq '.assets[].name' 2>/dev/null || echo "") | |
| # if [ -n "$assets" ]; then | |
| # for asset in $assets; do | |
| # gh release delete-asset "$release_tag" "$asset" -R ${{ github.repository }} -y || true | |
| # done | |
| # fi | |
| # gh release delete "$release_tag" -R ${{ github.repository }} -y || true | |
| # fi | |
| # gh api -X DELETE "repos/${{ github.repository }}/git/refs/tags/$release_tag" || true |