diff --git a/__tests__/tools.test.ts b/__tests__/tools.test.ts index 5b1f04e5..a81e6bc8 100644 --- a/__tests__/tools.test.ts +++ b/__tests__/tools.test.ts @@ -402,9 +402,20 @@ describe('Tools tests', () => { expect(script).toContain('Platform fedora is not supported'); }); + it('checking addCustomTool', async () => { + let script: string = await tools.addCustomTool('tool', '1.2.3', 'linux'); + expect(script).toContain('tool.sh\nadd_tool 1.2.3'); + + script = await tools.addCustomTool('tool', '1.2.3', 'darwin'); + expect(script).toContain('tool.sh\nadd_tool 1.2.3'); + + script = await tools.addCustomTool('tool', '1.2.3', 'win32'); + expect(script).toContain('tool.ps1\nAdd-Tool 1.2.3'); + }); + it('checking addTools on linux', async () => { const script: string = await tools.addTools( - 'blackfire, blackfire-player, cs2pr, flex, php-cs-fixer, phplint, phpstan, phpunit, pecl, phinx, phinx:1.2.3, phive, php-config, phpize, symfony, wp-cli', + 'blackfire, blackfire-player, cs2pr, flex, grpc_php_plugin, php-cs-fixer, phplint, phpstan, phpunit, pecl, phinx, phinx:1.2.3, phive, php-config, phpize, protoc, symfony, wp-cli', '7.4', 'linux' ); @@ -436,6 +447,8 @@ describe('Tools tests', () => { expect(script).toContain( 'add_tool https://github.com/wp-cli/builds/blob/gh-pages/phar/wp-cli.phar?raw=true wp-cli' ); + expect(script).toContain('add_protoc latest'); + expect(script).toContain('add_grpc_php_plugin latest'); expect(script).toContain('add_pecl'); expect(script).toContain('add_composertool flex flex symfony/'); expect(script).toContain('add_composertool phinx phinx robmorgan/'); @@ -455,6 +468,7 @@ describe('Tools tests', () => { 'composer-unused', 'cs2pr:1.2.3', 'flex', + 'grpc_php_plugin:1.2.3', 'infection', 'phan', 'phan:2.7.2', @@ -466,6 +480,7 @@ describe('Tools tests', () => { 'phpcs', 'phpize', 'phpmd', + 'protoc:v1.2.3', 'psalm', 'symfony', 'symfony:1.2.3', @@ -519,6 +534,8 @@ describe('Tools tests', () => { expect(script).toContain( 'https://github.com/vimeo/psalm/releases/latest/download/psalm.phar psalm' ); + expect(script).toContain('add_grpc_php_plugin 1.2.3'); + expect(script).toContain('add_protoc 1.2.3'); expect(script).toContain('add_composertool vapor-cli vapor-cli laravel/'); expect(script).toContain('add_composertool flex flex symfony/'); expect(script).toContain('add_composertool phinx phinx robmorgan/'); diff --git a/__tests__/utils.test.ts b/__tests__/utils.test.ts index 58d55c28..d137f9b5 100644 --- a/__tests__/utils.test.ts +++ b/__tests__/utils.test.ts @@ -177,4 +177,13 @@ describe('Utils tests', () => { it('checking joins', async () => { expect(await utils.joins('a', 'b', 'c')).toBe('a b c'); }); + + it('checking scriptExtension', async () => { + expect(await utils.scriptExtension('linux')).toBe('.sh'); + expect(await utils.scriptExtension('darwin')).toBe('.sh'); + expect(await utils.scriptExtension('win32')).toBe('.ps1'); + expect(await utils.scriptExtension('fedora')).toContain( + 'Platform fedora is not supported' + ); + }); }); diff --git a/dist/index.js b/dist/index.js index c87b6a4a..8ac13c4e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1314,7 +1314,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.joins = exports.getUnsupportedLog = exports.suppressOutput = exports.getExtensionPrefix = exports.CSVArray = exports.extensionArray = exports.writeScript = exports.readScript = exports.addLog = exports.stepLog = exports.log = exports.color = exports.asyncForEach = exports.getInput = void 0; +exports.scriptExtension = exports.joins = exports.getUnsupportedLog = exports.suppressOutput = exports.getExtensionPrefix = exports.CSVArray = exports.extensionArray = exports.writeScript = exports.readScript = exports.addLog = exports.stepLog = exports.log = exports.color = exports.asyncForEach = exports.getInput = void 0; const fs = __importStar(__webpack_require__(747)); const path = __importStar(__webpack_require__(622)); const core = __importStar(__webpack_require__(470)); @@ -1551,6 +1551,23 @@ async function joins(...str) { return [...str].join(' '); } exports.joins = joins; +/** + * Function to get script extensions + * + * @param os_version + */ +async function scriptExtension(os_version) { + switch (os_version) { + case 'win32': + return '.ps1'; + case 'linux': + case 'darwin': + return '.sh'; + default: + return await log('Platform ' + os_version + ' is not supported', os_version, 'error'); + } +} +exports.scriptExtension = scriptExtension; /***/ }), @@ -1930,9 +1947,10 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.addTools = exports.addPackage = exports.addDevTools = exports.addArchive = exports.getCleanedToolsList = exports.getComposerUrl = exports.addComposer = exports.getWpCliUrl = exports.getSymfonyUri = exports.getDeployerUrl = exports.getPharUrl = exports.addPhive = exports.getCodeceptionUri = exports.getCodeceptionUriBuilder = exports.getUri = exports.parseTool = exports.getToolVersion = exports.getCommand = void 0; +exports.addTools = exports.addCustomTool = exports.addPackage = exports.addDevTools = exports.addArchive = exports.getCleanedToolsList = exports.getComposerUrl = exports.addComposer = exports.getWpCliUrl = exports.getSymfonyUri = exports.getDeployerUrl = exports.getPharUrl = exports.addPhive = exports.getCodeceptionUri = exports.getCodeceptionUriBuilder = exports.getUri = exports.parseTool = exports.getToolVersion = exports.getCommand = void 0; const utils = __importStar(__webpack_require__(163)); const httpm = __importStar(__webpack_require__(539)); +const path = __importStar(__webpack_require__(622)); /** * Function to get command to setup tools * @@ -1962,6 +1980,8 @@ async function getToolVersion(version) { const composer_regex = /^stable$|^preview$|^snapshot$|^v?[1|2]$/; version = version.replace(/[><=^]*/, ''); switch (true) { + case version.charAt(0) == 'v': + return version.replace('v', ''); case composer_regex.test(version): case semver_regex.test(version): return version; @@ -2291,6 +2311,20 @@ async function addPackage(tool, release, prefix, os_version) { return tool_command + tool + ' ' + release + ' ' + prefix; } exports.addPackage = addPackage; +/** + * Function to get script to add tools with custom support. + * + * @param tool + * @param version + * @param os_version + */ +async function addCustomTool(tool, version, os_version) { + const script_extension = await utils.scriptExtension(os_version); + const script = path.join(__dirname, '../src/scripts/tools/' + tool + script_extension); + const command = await getCommand(os_version, tool); + return '. ' + script + '\n' + command + version; +} +exports.addCustomTool = addCustomTool; /** * Setup tools * @@ -2358,6 +2392,10 @@ async function addTools(tools_csv, php_version, os_version) { case 'flex': script += await addPackage(tool, release, 'symfony/', os_version); break; + case 'grpc_php_plugin': + case 'protoc': + script += await addCustomTool(tool, version, os_version); + break; case 'infection': url = github + 'infection/infection/' + uri; script += await addArchive(tool, version, url, os_version); diff --git a/src/scripts/tools/grpc_php_plugin.ps1 b/src/scripts/tools/grpc_php_plugin.ps1 new file mode 100644 index 00000000..103b2f61 --- /dev/null +++ b/src/scripts/tools/grpc_php_plugin.ps1 @@ -0,0 +1,20 @@ +Function Add-Msys2() { + $msys_location = 'C:\msys64' + if (-not(Test-Path $msys_location)) { + choco install msys2 -y >$null 2>&1 + $msys_location = 'C:\tools\msys64' + } + return $msys_location +} + +Function Add-Grpc_php_plugin() { + $msys_location = Add-Msys2 + . $msys_location\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-x86_64-grpc" >$null 2>&1 + Write-Output "::add-path::$msys_location\mingw64\bin" + Write-Output "::set-output name=grpc_php_plugin_path::$msys_location\mingw64\bin\grpc_php_plugin.exe" + Add-ToProfile $current_profile 'grpc_php_plugin' "New-Alias grpc_php_plugin $msys_location\mingw64\bin\grpc_php_plugin.exe" + Add-Log $tick "grpc_php_plugin" "Added" + printf "::group::\033[34;1m%s \033[0m\033[90;1m%s \033[0m\n" "grpc_php_plugin" "Click to read the grpc_php_plugin related license information" + Write-Output (Invoke-WebRequest https://raw.githubusercontent.com/grpc/grpc/master/LICENSE).Content + Write-Output "::endgroup::" +} diff --git a/src/scripts/tools/grpc_php_plugin.sh b/src/scripts/tools/grpc_php_plugin.sh new file mode 100644 index 00000000..a209a4ab --- /dev/null +++ b/src/scripts/tools/grpc_php_plugin.sh @@ -0,0 +1,51 @@ +add_bazel() { + if [ ! "$(command -v bazel)" ]; then + os=$(uname -s) + if [ "$os" = "Linux" ]; then + ${apt_install:?} curl gnupg + curl "${curl_opts[@]:?}" https://bazel.build/bazel-release.pub.gpg | sudo apt-key add - + echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list + sudo "${debconf_fix:?}" apt-get update -y + ${apt_install:?} bazel + elif [ "$os" = "Darwin" ]; then + brew install bazel + fi + fi +} + +get_grpc_tag() { + if [ "$grpc_tag" = "latest" ]; then + grpc_tag=$(curl "${curl_opts[@]:?}" https://grpc.io/release) + else + status_code=$(sudo curl -s -w "%{http_code}" -o /tmp/grpc.tmp "${curl_opts[@]:?}" "https://github.com/grpc/grpc/releases/tag/v$grpc_tag") + if [ "$status_code" = "200" ]; then + grpc_tag="v$grpc_tag" + else + grpc_tag=$(curl "${curl_opts[@]:?}" https://grpc.io/release) + fi + fi +} + +add_grpc_php_plugin() { + grpc_tag=$1 + get_grpc_tag + ( + curl "${curl_opts[@]:?}" "https://github.com/grpc/grpc/archive/$grpc_tag.tar.gz" | tar -xz -C /tmp + cd "/tmp/grpc-${grpc_tag:1}" || exit + add_bazel + echo "os: $os" + echo "release: $DISTRIB_RELEASE" + if [ "$DISTRIB_RELEASE" = "16.04" ]; then + CC="$(command -v gcc)" CXX="$(command -v g++)" ./tools/bazel build src/compiler:grpc_php_plugin + else + ./tools/bazel build src/compiler:grpc_php_plugin + fi + sudo mv ./bazel-bin/src/compiler/grpc_php_plugin /usr/local/bin/grpc_php_plugin + sudo chmod a+x /usr/local/bin/grpc_php_plugin + ) >/dev/null 2>&1 + echo "::set-output name=grpc_php_plugin_path::/usr/local/bin/grpc_php_plugin" + add_log "${tick:?}" "grpc_php_plugin" "Added" + printf "::group::\033[34;1m%s \033[0m\033[90;1m%s \033[0m\n" "grpc_php_plugin" "Click to read the grpc_php_plugin related license information" + cat "/tmp/grpc-${grpc_tag:1}/LICENSE" + echo "::endgroup::" +} diff --git a/src/scripts/tools/protoc.ps1 b/src/scripts/tools/protoc.ps1 new file mode 100644 index 00000000..48680f86 --- /dev/null +++ b/src/scripts/tools/protoc.ps1 @@ -0,0 +1,38 @@ +Function Get-ProtobufTag() { + if("$protobuf_tag" -eq "latest") { + $protobuf_tag = (Invoke-RestMethod https://api.github.com/repos/protocolbuffers/protobuf/tags).Name | Where-Object { $_ -match "v\d+.\d+.\d+$" } | Select-Object -First 1 + } else { + try { + [net.httpWebRequest] $request = [net.webRequest]::create("https://github.com/protocolbuffers/protobuf/releases/tag/v$protobuf_tag") + $req.Method = "HEAD" + [net.httpWebResponse] $response = $request.getResponse() + $response.Close() + $protobuf_tag = "v$protobuf_tag" + } catch { + $protobuf_tag = (Invoke-RestMethod https://api.github.com/repos/protocolbuffers/protobuf/tags).Name | Where-Object { $_ -match "v\d+.\d+.\d+$" } | Select-Object -First 1 + } + } + return $protobuf_tag +} + +Function Add-Protoc() { + param( + [Parameter(Mandatory = $true, Position = 0, HelpMessage = 'The PHP version to be installed')] + [ValidatePattern('^latest$|^(v?)\d+\.\d+\.\d+$')] + [string] $protobuf_tag + ) + $protobuf_tag = Get-ProtobufTag + $arch_num = '64' + if(-not([Environment]::Is64BitOperatingSystem)) { + $arch_num = '32' + } + $url = "https://github.com/protocolbuffers/protobuf/releases/download/$protobuf_tag/protoc-$($protobuf_tag -replace 'v', '')-win$arch_num.zip" + Invoke-WebRequest -UseBasicParsing -Uri $url -OutFile $bin_dir\protoc.zip >$null 2>&1 + Expand-Archive -Path $bin_dir\protoc.zip -DestinationPath $bin_dir\protoc -Force >$null 2>&1 + Move-Item -Path $bin_dir\protoc\bin\protoc.exe -Destination $bin_dir\protoc.exe + Add-ToProfile $current_profile 'protoc' "New-Alias protoc $bin_dir\protoc.exe" + Add-Log $tick "protoc" "Added" + printf "::group::\033[34;1m%s \033[0m\033[90;1m%s \033[0m\n" "protoc" "Click to read the protoc related license information" + Write-Output (Invoke-WebRequest https://raw.githubusercontent.com/protocolbuffers/protobuf/master/LICENSE).Content + Write-Output "::endgroup::" +} diff --git a/src/scripts/tools/protoc.sh b/src/scripts/tools/protoc.sh new file mode 100644 index 00000000..545077e6 --- /dev/null +++ b/src/scripts/tools/protoc.sh @@ -0,0 +1,28 @@ +get_protobuf_tag() { + if [ "$protobuf_tag" = "latest" ]; then + protobuf_tag=$(curl "${curl_opts[@]:?}" https://github.com/protocolbuffers/protobuf/releases/latest 2<&1 | grep -m 1 -Eo "(v[0-9]+.[0-9]+.[0-9]+)" | head -n 1) + else + status_code=$(sudo curl -s -w "%{http_code}" -o /tmp/protobuf.tmp "${curl_opts[@]:?}" "https://github.com/protocolbuffers/protobuf/releases/tag/v$protobuf_tag") + if [ "$status_code" = "200" ]; then + protobuf_tag="v$protobuf_tag" + else + protobuf_tag=$(curl "${curl_opts[@]:?}" https://github.com/protocolbuffers/protobuf/releases/latest 2<&1 | grep -m 1 -Eo "(v[0-9]+.[0-9]+.[0-9]+)" | head -n 1) + fi + fi +} + +add_protoc() { + protobuf_tag=$1 + get_protobuf_tag + ( + platform='linux' + [ "$(uname -s)" = "Darwin" ] && platform='osx' + curl -o /tmp/protobuf.zip "${curl_opts[@]:?}" "https://github.com/protocolbuffers/protobuf/releases/download/$protobuf_tag/protoc-${protobuf_tag:1}-$platform-x86_64.zip" + sudo unzip /tmp/protobuf.zip -d /usr/local/ + sudo chmod a+x /usr/local/bin/protoc + ) >/dev/null 2>&1 + add_log "${tick:?}" "protoc" "Added" + printf "::group::\033[34;1m%s \033[0m\033[90;1m%s \033[0m\n" "protoc" "Click to read the protoc related license information" + curl "${curl_opts[@]:?}" https://raw.githubusercontent.com/protocolbuffers/protobuf/master/LICENSE + echo "::endgroup::" +} diff --git a/src/tools.ts b/src/tools.ts index c5ed8a56..ffb3f599 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -1,6 +1,7 @@ import * as utils from './utils'; import * as httpm from '@actions/http-client'; import {IHttpClientResponse as hcr} from '@actions/http-client/interfaces'; +import * as path from 'path'; /** * Function to get command to setup tools @@ -38,6 +39,8 @@ export async function getToolVersion(version: string): Promise { const composer_regex = /^stable$|^preview$|^snapshot$|^v?[1|2]$/; version = version.replace(/[><=^]*/, ''); switch (true) { + case version.charAt(0) == 'v': + return version.replace('v', ''); case composer_regex.test(version): case semver_regex.test(version): return version; @@ -439,6 +442,27 @@ export async function addPackage( return tool_command + tool + ' ' + release + ' ' + prefix; } +/** + * Function to get script to add tools with custom support. + * + * @param tool + * @param version + * @param os_version + */ +export async function addCustomTool( + tool: string, + version: string, + os_version: string +): Promise { + const script_extension: string = await utils.scriptExtension(os_version); + const script: string = path.join( + __dirname, + '../src/scripts/tools/' + tool + script_extension + ); + const command: string = await getCommand(os_version, tool); + return '. ' + script + '\n' + command + version; +} + /** * Setup tools * @@ -522,6 +546,10 @@ export async function addTools( case 'flex': script += await addPackage(tool, release, 'symfony/', os_version); break; + case 'grpc_php_plugin': + case 'protoc': + script += await addCustomTool(tool, version, os_version); + break; case 'infection': url = github + 'infection/infection/' + uri; script += await addArchive(tool, version, url, os_version); diff --git a/src/utils.ts b/src/utils.ts index bd77dc0f..20c37350 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -292,3 +292,24 @@ export async function getUnsupportedLog( export async function joins(...str: string[]): Promise { return [...str].join(' '); } + +/** + * Function to get script extensions + * + * @param os_version + */ +export async function scriptExtension(os_version: string): Promise { + switch (os_version) { + case 'win32': + return '.ps1'; + case 'linux': + case 'darwin': + return '.sh'; + default: + return await log( + 'Platform ' + os_version + ' is not supported', + os_version, + 'error' + ); + } +}