From f42065d568787cf88e422ab92da46407de347402 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Thu, 21 Jan 2021 11:37:11 +0100 Subject: [PATCH 1/4] Allow extensions to be compiled from GitHub sources --- README.md | 16 ++++++++++++-- __tests__/extensions.test.ts | 27 ++++++++++++++++++++++++ dist/index.js | 19 +++++++++++++++++ src/extensions.ts | 41 ++++++++++++++++++++++++++++++++++++ src/scripts/darwin.sh | 18 ++++++++++++++++ src/scripts/linux.sh | 19 ++++++++--------- 6 files changed, 128 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 8b32e045..7b3a05c4 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ On all supported OS/Platforms the following PHP versions are supported as per th PHP extensions can be setup using the `extensions` input. It accepts a `string` in csv-format. -- On `Ubuntu`, extensions which are available as a package or available on `PECL` can be setup. +- On `Ubuntu`, extensions which are available as a package, available on `PECL`, or hosted on GitHub can be setup. ```yaml - name: Setup PHP with PECL extension @@ -129,7 +129,7 @@ PHP extensions can be setup using the `extensions` input. It accepts a `string` - On `Windows`, extensions available on `PECL` which have the `DLL` binary can be setup. -- On `macOS`, extensions available on `PECL` can be installed. +- On `macOS`, extensions available on `PECL` or hosted on GitHub can be installed. - Extensions installed along with PHP if specified are enabled. @@ -192,6 +192,18 @@ PHP extensions can be setup using the `extensions` input. It accepts a `string` fail-fast: true ``` +- Extensions can be compiled from source if they are hosted on GitHub. In this case, the version specification contains the repository and branch/tag to clone: + +```yaml +- name: Setup PHP and remove shared extension + uses: shivammathur/setup-php@v2 + with: + php-version: '7.4' + extensions: mongodb-mongodb/mongo-php-driver@v1.9 +``` + +The version can be a branch name or tag as supported by `git clone -b `. The clone is performed recursively, i.e. submodules will be cloned as well. + ## :wrench: Tools Support These tools can be setup globally using the `tools` input. It accepts a string in csv-format. diff --git a/__tests__/extensions.test.ts b/__tests__/extensions.test.ts index bca5600f..8c0e5c85 100644 --- a/__tests__/extensions.test.ts +++ b/__tests__/extensions.test.ts @@ -58,6 +58,15 @@ describe('Extension tests', () => { win32 = await extensions.addExtension('blackfire-1.31.0', '7.3', 'win32'); expect(win32).toContain('Add-Blackfire blackfire-1.31.0'); + + win32 = await extensions.addExtension( + 'mongodb-mongodb/mongo-php-driver@master', + '7.3', + 'win32' + ); + expect(win32).toContain( + 'Add-Log "$cross" "mongodb-mongodb/mongo-php-driver@master" "mongodb-mongodb/mongo-php-driver@master is not supported on PHP 7.3"' + ); }); it('checking addExtensionOnLinux', async () => { @@ -131,6 +140,15 @@ describe('Extension tests', () => { linux = await extensions.addExtension('intl-68.2', '8.0', 'linux'); expect(linux).toContain('add_intl intl-68.2'); + + linux = await extensions.addExtension( + 'mongodb-mongodb/mongo-php-driver@master', + '7.3', + 'linux' + ); + expect(linux).toContain( + 'add_extension_from_github mongodb mongodb mongo-php-driver master' + ); }); it('checking addExtensionOnDarwin', async () => { @@ -220,5 +238,14 @@ describe('Extension tests', () => { darwin = await extensions.addExtension('xdebug', '7.2', 'openbsd'); expect(darwin).toContain('Platform openbsd is not supported'); + + darwin = await extensions.addExtension( + 'mongodb-mongodb/mongo-php-driver@master', + '7.3', + 'darwin' + ); + expect(darwin).toContain( + 'add_extension_from_github mongodb mongodb mongo-php-driver master' + ); }); }); diff --git a/dist/index.js b/dist/index.js index 18b3c42a..1aba8c63 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2901,6 +2901,13 @@ async function addExtensionDarwin(extension_csv, version) { const version_extension = version + extension; const [ext_name, ext_version] = extension.split('-'); const ext_prefix = await utils.getExtensionPrefix(ext_name); + // Install extensions from a GitHub tarball. This needs to be checked first + // as the version may also match the semver check below. + const urlMatches = extension.match(/.*-(.*)\/(.*)@(.*)/); + if (urlMatches != null) { + add_script += await utils.joins('\nadd_extension_from_github', ext_name, urlMatches[1], urlMatches[2], urlMatches[3], ext_prefix); + return; + } switch (true) { // match :extension case /^:/.test(ext_name): @@ -2987,6 +2994,11 @@ async function addExtensionWindows(extension_csv, version) { case /.*-(stable|beta|alpha|devel|snapshot)/.test(version_extension): add_script += await utils.joins('\nAdd-Extension', ext_name, ext_version.replace('stable', '')); break; + // match extensions from GitHub. Do this before checking for semver as + // the version may match that as well + case /.*-(.*)\/(.*)@(.*)/.test(extension): + add_script += await utils.getUnsupportedLog(extension, version, 'win32'); + break; // match semver without state case /.*-\d+\.\d+\.\d+$/.test(version_extension): add_script += await utils.joins('\nAdd-Extension', ext_name, 'stable', ext_version); @@ -3044,6 +3056,13 @@ async function addExtensionLinux(extension_csv, version) { const version_extension = version + extension; const [ext_name, ext_version] = extension.split('-'); const ext_prefix = await utils.getExtensionPrefix(ext_name); + // Install extensions from a GitHub tarball. This needs to be checked first + // as the version may also match the semver check below. + const urlMatches = extension.match(/.*-(.*)\/(.*)@(.*)/); + if (urlMatches != null) { + add_script += await utils.joins('\nadd_extension_from_github', ext_name, urlMatches[1], urlMatches[2], urlMatches[3], ext_prefix); + return; + } switch (true) { // Match :extension case /^:/.test(ext_name): diff --git a/src/extensions.ts b/src/extensions.ts index 904c30a0..40a950b8 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -17,6 +17,22 @@ export async function addExtensionDarwin( const version_extension: string = version + extension; const [ext_name, ext_version]: string[] = extension.split('-'); const ext_prefix = await utils.getExtensionPrefix(ext_name); + + // Install extensions from a GitHub tarball. This needs to be checked first + // as the version may also match the semver check below. + const urlMatches = extension.match(/.*-(.*)\/(.*)@(.*)/); + if (urlMatches != null) { + add_script += await utils.joins( + '\nadd_extension_from_github', + ext_name, + urlMatches[1], + urlMatches[2], + urlMatches[3], + ext_prefix + ); + return; + } + switch (true) { // match :extension case /^:/.test(ext_name): @@ -142,6 +158,15 @@ export async function addExtensionWindows( ext_version.replace('stable', '') ); break; + // match extensions from GitHub. Do this before checking for semver as + // the version may match that as well + case /.*-(.*)\/(.*)@(.*)/.test(extension): + add_script += await utils.getUnsupportedLog( + extension, + version, + 'win32' + ); + break; // match semver without state case /.*-\d+\.\d+\.\d+$/.test(version_extension): add_script += await utils.joins( @@ -214,6 +239,22 @@ export async function addExtensionLinux( const version_extension: string = version + extension; const [ext_name, ext_version]: string[] = extension.split('-'); const ext_prefix = await utils.getExtensionPrefix(ext_name); + + // Install extensions from a GitHub tarball. This needs to be checked first + // as the version may also match the semver check below. + const urlMatches = extension.match(/.*-(.*)\/(.*)@(.*)/); + if (urlMatches != null) { + add_script += await utils.joins( + '\nadd_extension_from_github', + ext_name, + urlMatches[1], + urlMatches[2], + urlMatches[3], + ext_prefix + ); + return; + } + switch (true) { // Match :extension case /^:/.test(ext_name): diff --git a/src/scripts/darwin.sh b/src/scripts/darwin.sh index 7fd28f07..08c9fce6 100644 --- a/src/scripts/darwin.sh +++ b/src/scripts/darwin.sh @@ -39,6 +39,24 @@ add_pecl_extension() { fi } +# Function to install extension from a GitHub repository +add_extension_from_github() { + extension=$1 + org=$2 + repo=$3 + release=$4 + prefix=$5 + ( + add_devtools phpize + delete_extension "$extension" + git clone --recurse-submodules -b "$release" https://github.com/"$org"/"$repo" /tmp/"$repo-$release" || exit 1 + cd /tmp/"$repo-$release" || exit 1 + phpize && ./configure && make -j"$(nproc)" && sudo make install + enable_extension "$extension" "$prefix" + ) >/dev/null 2>&1 + add_extension_log "$extension-$org/$repo@$release" "Installed and enabled" +} + # Function to fetch a brew tap fetch_brew_tap() { tap=$1 diff --git a/src/scripts/linux.sh b/src/scripts/linux.sh index 4e0e3682..f022bbb8 100644 --- a/src/scripts/linux.sh +++ b/src/scripts/linux.sh @@ -148,23 +148,22 @@ add_pecl_extension() { fi } -# Function to install extension from source -add_extension_from_source() { +# Function to install extension from a GitHub repository +add_extension_from_github() { extension=$1 - repo=$2 - release=$3 - args=$4 + org=$2 + repo=$3 + release=$4 prefix=$5 ( add_devtools phpize delete_extension "$extension" - get -q -n "/tmp/$extension.tar.gz" "https://github.com/$repo/archive/$release.tar.gz" - tar xf /tmp/"$extension".tar.gz -C /tmp - cd /tmp/"$extension-$release" || exit 1 - phpize && ./configure "$args" && make -j"$(nproc)" && sudo make install + git clone --recurse-submodules -b "$release" https://github.com/"$org"/"$repo" /tmp/"$repo-$release" || exit 1 + cd /tmp/"$repo-$release" || exit 1 + phpize && ./configure && make -j"$(nproc)" && sudo make install enable_extension "$extension" "$prefix" ) >/dev/null 2>&1 - add_extension_log "$extension-$release" "Installed and enabled" + add_extension_log "$extension-$org/$repo@$release" "Installed and enabled" } # Function to setup phpize and php-config. From 26791e8412bbb5058007418b97f9517f911384cd Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Mon, 25 Jan 2021 13:39:13 +0100 Subject: [PATCH 2/4] Address code review feedback --- dist/index.js | 38 ++++++++++++++-------- src/extensions.ts | 76 ++++++++++++++++++++++++++----------------- src/scripts/common.sh | 20 +++++++++++- src/scripts/darwin.sh | 18 ---------- src/scripts/linux.sh | 18 ---------- 5 files changed, 89 insertions(+), 81 deletions(-) diff --git a/dist/index.js b/dist/index.js index 1aba8c63..1384c87e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2901,13 +2901,7 @@ async function addExtensionDarwin(extension_csv, version) { const version_extension = version + extension; const [ext_name, ext_version] = extension.split('-'); const ext_prefix = await utils.getExtensionPrefix(ext_name); - // Install extensions from a GitHub tarball. This needs to be checked first - // as the version may also match the semver check below. - const urlMatches = extension.match(/.*-(.*)\/(.*)@(.*)/); - if (urlMatches != null) { - add_script += await utils.joins('\nadd_extension_from_github', ext_name, urlMatches[1], urlMatches[2], urlMatches[3], ext_prefix); - return; - } + let matches; switch (true) { // match :extension case /^:/.test(ext_name): @@ -2930,6 +2924,17 @@ async function addExtensionDarwin(extension_csv, version) { case /.*-(stable|beta|alpha|devel|snapshot|rc|preview)/.test(version_extension): add_script += await utils.joins('\nadd_unstable_extension', ext_name, ext_version, ext_prefix); return; + // match extensions from GitHub. Do this before checking for semver as + // the version may match that as well + case /.*-(.*)\/(.*)@(.*)/.test(extension): + matches = /.*-(.*)\/(.*)@(.*)/.exec(extension); + if (matches == null) { + // Shouldn't happen + add_script += await utils.getUnsupportedLog(extension, version, 'darwin'); + return; + } + add_script += await utils.joins('\nadd_extension_from_github', ext_name, matches[1], matches[2], matches[3], ext_prefix); + return; // match semver case /.*-\d+\.\d+\.\d+.*/.test(version_extension): add_script += await utils.joins('\nadd_pecl_extension', ext_name, ext_version, ext_prefix); @@ -3056,13 +3061,7 @@ async function addExtensionLinux(extension_csv, version) { const version_extension = version + extension; const [ext_name, ext_version] = extension.split('-'); const ext_prefix = await utils.getExtensionPrefix(ext_name); - // Install extensions from a GitHub tarball. This needs to be checked first - // as the version may also match the semver check below. - const urlMatches = extension.match(/.*-(.*)\/(.*)@(.*)/); - if (urlMatches != null) { - add_script += await utils.joins('\nadd_extension_from_github', ext_name, urlMatches[1], urlMatches[2], urlMatches[3], ext_prefix); - return; - } + let matches; switch (true) { // Match :extension case /^:/.test(ext_name): @@ -3088,6 +3087,17 @@ async function addExtensionLinux(extension_csv, version) { case /.*-(stable|beta|alpha|devel|snapshot|rc|preview)/.test(version_extension): add_script += await utils.joins('\nadd_unstable_extension', ext_name, ext_version, ext_prefix); return; + // match extensions from GitHub. Do this before checking for semver as + // the version may match that as well + case /.*-(.*)\/(.*)@(.*)/.test(extension): + matches = /.*-(.*)\/(.*)@(.*)/.exec(extension); + if (matches == null) { + // Shouldn't happen + add_script += await utils.getUnsupportedLog(extension, version, 'linux'); + return; + } + add_script += await utils.joins('\nadd_extension_from_github', ext_name, matches[1], matches[2], matches[3], ext_prefix); + return; // match semver versions case /.*-\d+\.\d+\.\d+.*/.test(version_extension): add_script += await utils.joins('\nadd_pecl_extension', ext_name, ext_version, ext_prefix); diff --git a/src/extensions.ts b/src/extensions.ts index 40a950b8..916b4806 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -17,21 +17,7 @@ export async function addExtensionDarwin( const version_extension: string = version + extension; const [ext_name, ext_version]: string[] = extension.split('-'); const ext_prefix = await utils.getExtensionPrefix(ext_name); - - // Install extensions from a GitHub tarball. This needs to be checked first - // as the version may also match the semver check below. - const urlMatches = extension.match(/.*-(.*)\/(.*)@(.*)/); - if (urlMatches != null) { - add_script += await utils.joins( - '\nadd_extension_from_github', - ext_name, - urlMatches[1], - urlMatches[2], - urlMatches[3], - ext_prefix - ); - return; - } + let matches: RegExpExecArray; switch (true) { // match :extension @@ -69,6 +55,28 @@ export async function addExtensionDarwin( ext_prefix ); return; + // match extensions from GitHub. Do this before checking for semver as + // the version may match that as well + case /.*-(.*)\/(.*)@(.*)/.test(extension): + matches = /.*-(.*)\/(.*)@(.*)/.exec(extension) as RegExpExecArray; + if (matches == null) { + // Shouldn't happen + add_script += await utils.getUnsupportedLog( + extension, + version, + 'darwin' + ); + return; + } + add_script += await utils.joins( + '\nadd_extension_from_github', + ext_name, + matches[1], + matches[2], + matches[3], + ext_prefix + ); + return; // match semver case /.*-\d+\.\d+\.\d+.*/.test(version_extension): add_script += await utils.joins( @@ -239,21 +247,7 @@ export async function addExtensionLinux( const version_extension: string = version + extension; const [ext_name, ext_version]: string[] = extension.split('-'); const ext_prefix = await utils.getExtensionPrefix(ext_name); - - // Install extensions from a GitHub tarball. This needs to be checked first - // as the version may also match the semver check below. - const urlMatches = extension.match(/.*-(.*)\/(.*)@(.*)/); - if (urlMatches != null) { - add_script += await utils.joins( - '\nadd_extension_from_github', - ext_name, - urlMatches[1], - urlMatches[2], - urlMatches[3], - ext_prefix - ); - return; - } + let matches: RegExpExecArray; switch (true) { // Match :extension @@ -296,6 +290,28 @@ export async function addExtensionLinux( ext_prefix ); return; + // match extensions from GitHub. Do this before checking for semver as + // the version may match that as well + case /.*-(.*)\/(.*)@(.*)/.test(extension): + matches = /.*-(.*)\/(.*)@(.*)/.exec(extension) as RegExpExecArray; + if (matches == null) { + // Shouldn't happen + add_script += await utils.getUnsupportedLog( + extension, + version, + 'linux' + ); + return; + } + add_script += await utils.joins( + '\nadd_extension_from_github', + ext_name, + matches[1], + matches[2], + matches[3], + ext_prefix + ); + return; // match semver versions case /.*-\d+\.\d+\.\d+.*/.test(version_extension): add_script += await utils.joins( diff --git a/src/scripts/common.sh b/src/scripts/common.sh index c4804ba7..1cc7c571 100644 --- a/src/scripts/common.sh +++ b/src/scripts/common.sh @@ -267,4 +267,22 @@ add_composertool() { # Function to get PHP version in semver format. php_semver() { php"$version" -v | grep -Eo -m 1 "[0-9]+\.[0-9]+\.[0-9]+" | head -n 1 -} \ No newline at end of file +} + +# Function to install extension from a GitHub repository +add_extension_from_github() { + extension=$1 + org=$2 + repo=$3 + release=$4 + prefix=$5 + ( + add_devtools phpize + delete_extension "$extension" + git clone --recurse-submodules -b "$release" https://github.com/"$org"/"$repo" /tmp/"$repo-$release" || exit 1 + cd /tmp/"$repo-$release" || exit 1 + phpize && ./configure && make -j"$(nproc)" && sudo make install + enable_extension "$extension" "$prefix" + ) >/dev/null 2>&1 + add_extension_log "$extension-$org/$repo@$release" "Installed and enabled" +} diff --git a/src/scripts/darwin.sh b/src/scripts/darwin.sh index 08c9fce6..7fd28f07 100644 --- a/src/scripts/darwin.sh +++ b/src/scripts/darwin.sh @@ -39,24 +39,6 @@ add_pecl_extension() { fi } -# Function to install extension from a GitHub repository -add_extension_from_github() { - extension=$1 - org=$2 - repo=$3 - release=$4 - prefix=$5 - ( - add_devtools phpize - delete_extension "$extension" - git clone --recurse-submodules -b "$release" https://github.com/"$org"/"$repo" /tmp/"$repo-$release" || exit 1 - cd /tmp/"$repo-$release" || exit 1 - phpize && ./configure && make -j"$(nproc)" && sudo make install - enable_extension "$extension" "$prefix" - ) >/dev/null 2>&1 - add_extension_log "$extension-$org/$repo@$release" "Installed and enabled" -} - # Function to fetch a brew tap fetch_brew_tap() { tap=$1 diff --git a/src/scripts/linux.sh b/src/scripts/linux.sh index f022bbb8..d1c1a994 100644 --- a/src/scripts/linux.sh +++ b/src/scripts/linux.sh @@ -148,24 +148,6 @@ add_pecl_extension() { fi } -# Function to install extension from a GitHub repository -add_extension_from_github() { - extension=$1 - org=$2 - repo=$3 - release=$4 - prefix=$5 - ( - add_devtools phpize - delete_extension "$extension" - git clone --recurse-submodules -b "$release" https://github.com/"$org"/"$repo" /tmp/"$repo-$release" || exit 1 - cd /tmp/"$repo-$release" || exit 1 - phpize && ./configure && make -j"$(nproc)" && sudo make install - enable_extension "$extension" "$prefix" - ) >/dev/null 2>&1 - add_extension_log "$extension-$org/$repo@$release" "Installed and enabled" -} - # Function to setup phpize and php-config. add_devtools() { tool=$1 From fd62612e9e1f111ea00cd5a9a08e6074508d4bba Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Mon, 25 Jan 2021 13:46:50 +0100 Subject: [PATCH 3/4] Allow building specific commits --- src/scripts/common.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/scripts/common.sh b/src/scripts/common.sh index 1cc7c571..76ef244d 100644 --- a/src/scripts/common.sh +++ b/src/scripts/common.sh @@ -279,8 +279,10 @@ add_extension_from_github() { ( add_devtools phpize delete_extension "$extension" - git clone --recurse-submodules -b "$release" https://github.com/"$org"/"$repo" /tmp/"$repo-$release" || exit 1 + git clone -n https://github.com/"$org"/"$repo" /tmp/"$repo-$release" || exit 1 cd /tmp/"$repo-$release" || exit 1 + git checkout "$release" || exit 1 + git submodule update --init --recursive || exit 1 phpize && ./configure && make -j"$(nproc)" && sudo make install enable_extension "$extension" "$prefix" ) >/dev/null 2>&1 From 3f466981fc6d87d77b8cc6d81218b1526413e872 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Mon, 8 Feb 2021 13:35:32 +0100 Subject: [PATCH 4/4] Address review feedback --- src/extensions.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/extensions.ts b/src/extensions.ts index 916b4806..9281ca6a 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -59,15 +59,6 @@ export async function addExtensionDarwin( // the version may match that as well case /.*-(.*)\/(.*)@(.*)/.test(extension): matches = /.*-(.*)\/(.*)@(.*)/.exec(extension) as RegExpExecArray; - if (matches == null) { - // Shouldn't happen - add_script += await utils.getUnsupportedLog( - extension, - version, - 'darwin' - ); - return; - } add_script += await utils.joins( '\nadd_extension_from_github', ext_name, @@ -294,15 +285,6 @@ export async function addExtensionLinux( // the version may match that as well case /.*-(.*)\/(.*)@(.*)/.test(extension): matches = /.*-(.*)\/(.*)@(.*)/.exec(extension) as RegExpExecArray; - if (matches == null) { - // Shouldn't happen - add_script += await utils.getUnsupportedLog( - extension, - version, - 'linux' - ); - return; - } add_script += await utils.joins( '\nadd_extension_from_github', ext_name,