Add extension dependency support for Darwin

Refactor extension.sh to 3 scripts

Update dependencies

Minor fixes in cache.ts and tests

Improve get_api_version in cache.sh

Improve logs

Use @actions/cache to cache dependencies

Refactor linux.sh

Refactor Node.js code

Do not setup dependencies for old PHP

Remove duplicate dependency extensions in linux

Bump version to 1.6.0
This commit is contained in:
Shivam Mathur
2021-07-01 09:32:36 +05:30
parent b9734e30e3
commit 65ea75914e
13 changed files with 60512 additions and 1962 deletions

View File

@@ -12,12 +12,5 @@
"plugin:prettier/recommended", "plugin:prettier/recommended",
"prettier" "prettier"
], ],
"plugins": ["@typescript-eslint", "jest"], "plugins": ["@typescript-eslint", "jest"]
"rules": {
"camelcase": "off",
"require-atomic-updates": "off",
"@typescript-eslint/ban-ts-ignore": "off",
"@typescript-eslint/camelcase": "off",
"@typescript-eslint/no-unused-vars": "off"
}
} }

View File

@@ -1,3 +1,4 @@
import path from 'path';
import * as cache from '../src/cache'; import * as cache from '../src/cache';
import * as utils from '../src/utils'; import * as utils from '../src/utils';
@@ -6,17 +7,14 @@ import * as utils from '../src/utils';
*/ */
jest.mock('../src/cache', () => ({ jest.mock('../src/cache', () => ({
run: jest.fn().mockImplementation(async (): Promise<string> => { run: jest.fn().mockImplementation(async (): Promise<string> => {
let version: string = process.env['php-version'] || ''; const version: string = await utils.parseVersion(
version = version.length > 1 ? version.slice(0, 3) : version + '.0'; process.env['php-version'] || ''
);
const extensions = await utils.filterExtensions( const extensions = await utils.filterExtensions(
process.env['extensions'] || '' process.env['extensions'] || ''
); );
const key: string = process.env['key'] || ''; const key: string = process.env['key'] || '';
const script_path = 'extensions.sh'; return await utils.scriptCall('test', extensions, key, version);
return (
'bash ' + script_path + ' "' + extensions + '" ' + key + ' ' + version
);
}) })
})); }));
@@ -38,21 +36,22 @@ function setEnv(
} }
describe('Install', () => { describe('Install', () => {
const spath: string = path.join(__dirname, '../src/scripts/cache.sh');
it('Test Run', async () => { it('Test Run', async () => {
setEnv('7.0', 'xdebug, pcov', 'cache-v1'); setEnv('7.0', 'xdebug, pcov', 'cache-v1');
const script: string = '' + (await cache.run()); const script: string = '' + (await cache.run());
expect(script).toContain('bash extensions.sh "xdebug, pcov" cache-v1 7.0'); expect(script).toContain(`bash ${spath} test "xdebug, pcov" cache-v1 7.0`);
}); });
it('Test Run', async () => { it('Test Run', async () => {
setEnv('7.4', 'xdebug, zip', 'cache-v2'); setEnv('7.4', 'xdebug, zip', 'cache-v2');
const script: string = '' + (await cache.run()); const script: string = '' + (await cache.run());
expect(script).toContain('bash extensions.sh "xdebug, zip" cache-v2 7.4'); expect(script).toContain(`bash ${spath} test "xdebug, zip" cache-v2 7.4`);
}); });
it('Test Run', async () => { it('Test Run', async () => {
setEnv('7.4', 'xdebug, :zip', 'cache-v2'); setEnv('7.4', 'xdebug, :zip', 'cache-v2');
const script: string = '' + (await cache.run()); const script: string = '' + (await cache.run());
expect(script).toContain('bash extensions.sh "xdebug" cache-v2 7.4'); expect(script).toContain(`bash ${spath} test "xdebug" cache-v2 7.4`);
}); });
}); });

View File

@@ -1,3 +1,5 @@
import * as fs from 'fs';
import * as path from 'path';
import * as utils from '../src/utils'; import * as utils from '../src/utils';
jest.mock('@actions/core', () => ({ jest.mock('@actions/core', () => ({
@@ -6,6 +8,14 @@ jest.mock('@actions/core', () => ({
}) })
})); }));
async function cleanup(path: string): Promise<void> {
fs.unlink(path, error => {
if (error) {
console.log(error);
}
});
}
describe('Utils tests', () => { describe('Utils tests', () => {
it('checking readEnv', async () => { it('checking readEnv', async () => {
process.env['test'] = 'setup-php'; process.env['test'] = 'setup-php';
@@ -20,11 +30,19 @@ describe('Utils tests', () => {
'cache-extensions' 'cache-extensions'
); );
expect(await utils.getInput('DoesNotExist', false)).toBe(''); expect(await utils.getInput('DoesNotExist', false)).toBe('');
expect(async () => { await expect(async () => {
await utils.getInput('DoesNotExist', true); await utils.getInput('DoesNotExist', true);
}).rejects.toThrow('Input required and not supplied: DoesNotExist'); }).rejects.toThrow('Input required and not supplied: DoesNotExist');
}); });
it('checking getOutput', async () => {
const temp_dir: string = process.env['RUNNER_TEMP'] || '';
const file_path: string = path.join(temp_dir, 'test');
fs.writeFileSync(file_path, 'test', {mode: 0o755});
expect(await utils.getOutput('test')).toBe('test');
await cleanup(file_path);
});
it('checking parseVersion', async () => { it('checking parseVersion', async () => {
expect(await utils.parseVersion('7')).toBe('7.0'); expect(await utils.parseVersion('7')).toBe('7.0');
expect(await utils.parseVersion('7.4')).toBe('7.4'); expect(await utils.parseVersion('7.4')).toBe('7.4');
@@ -32,7 +50,7 @@ describe('Utils tests', () => {
}); });
it('checking filterExtensions', async () => { it('checking filterExtensions', async () => {
expect(await utils.filterExtensions('a,:b,c')).toBe('a,c'); expect(await utils.filterExtensions('a,:b,c')).toBe('"a,c"');
expect(await utils.filterExtensions('a, :b, c')).toBe('a, c'); expect(await utils.filterExtensions('a, :b, c')).toBe('"a, c"');
}); });
}); });

57747
dist/index.js vendored

File diff suppressed because one or more lines are too long

3984
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
{ {
"name": "cache-extensions", "name": "cache-extensions",
"version": "1.5.1", "version": "1.6.0",
"private": false, "private": false,
"description": "Cache extensions in GitHub Actions", "description": "Cache PHP extensions in GitHub Actions",
"main": "lib/cache.js", "main": "lib/cache.js",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
@@ -19,31 +19,33 @@
"keywords": [ "keywords": [
"actions", "actions",
"php", "php",
"setup" "extension",
"cache"
], ],
"author": "shivammathur", "author": "shivammathur",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.3.0", "@actions/cache": "^1.0.7",
"@actions/exec": "^1.0.4" "@actions/core": "^1.4.0",
"@actions/exec": "^1.1.0"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^26.0.23", "@types/jest": "^26.0.23",
"@types/node": "^15.6.1", "@types/node": "^15.14.0",
"@typescript-eslint/eslint-plugin": "^4.25.0", "@typescript-eslint/eslint-plugin": "^4.28.1",
"@typescript-eslint/parser": "^4.25.0", "@typescript-eslint/parser": "^4.28.1",
"@vercel/ncc": "^0.28.6", "@vercel/ncc": "^0.28.6",
"eslint": "^7.27.0", "eslint": "^7.29.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4", "eslint-plugin-import": "^2.23.4",
"eslint-plugin-jest": "^24.3.6", "eslint-plugin-jest": "^24.3.6",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.0",
"husky": "^4.3.8", "husky": "^4.3.8",
"jest": "^27.0.3", "jest": "^27.0.6",
"jest-circus": "^27.0.3", "jest-circus": "^27.0.6",
"prettier": "^2.3.0", "prettier": "^2.3.2",
"ts-jest": "^27.0.1", "ts-jest": "^27.0.3",
"typescript": "^4.3.2" "typescript": "^4.3.5"
}, },
"husky": { "husky": {
"skipCI": true, "skipCI": true,

View File

@@ -1,8 +1,37 @@
import {exec} from '@actions/exec'; import {exec} from '@actions/exec';
import * as cache from '@actions/cache';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as path from 'path'; import * as path from 'path';
import * as utils from './utils'; import * as utils from './utils';
/**
* Handle dependencies
*
* @param extensions
* @param version
*/
export async function handleDependencies(
extensions: string,
version: string
): Promise<void> {
if (!/^5.[3-5]$/.test(version) && /linux|darwin/.test(process.platform)) {
const cache_key: string = (await utils.getOutput('key')) + '-deps';
const cache_dir: string = path.join(
await utils.readEnv('RUNNER_TOOL_CACHE'),
'deps'
);
const cache_hit: string | undefined = await cache.restoreCache(
[cache_dir],
cache_key,
[cache_key]
);
await exec(await utils.scriptCall('dependencies', extensions, version));
if (!cache_hit) {
await cache.saveCache([cache_dir], cache_key);
}
}
}
/** /**
* Run the script * Run the script
*/ */
@@ -15,14 +44,16 @@ export async function run(): Promise<void> {
await utils.getInput('extensions', true) await utils.getInput('extensions', true)
); );
const key: string = await utils.getInput('key', true); const key: string = await utils.getInput('key', true);
const script_path: string = path.join(__dirname, '../src/extensions.sh'); await exec(await utils.scriptCall('data', extensions, version, key));
await exec( await handleDependencies(extensions, version);
'bash ' + script_path + ' "' + extensions + '" ' + key + ' ' + version
);
} catch (error) { } catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
} }
} }
// call the run function // call the run function
run(); (async () => {
await run();
})().catch(error => {
core.setFailed(error.message);
});

View File

@@ -1,219 +0,0 @@
step_log() {
message=$1
printf "\n\033[90;1m==> \033[0m\033[37;1m%s\033[0m\n" "$message"
}
add_log() {
mark=$1
shift
subjects=("$@")
for subject in "${subjects[@]}"; do
if [ "$mark" = "$tick" ]; then
printf "\033[32;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "Added $subject"
else
printf "\033[31;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "Failed to setup $subject"
fi
done
}
fix_ownership() {
dir=$1
sudo chown -R "$USER":"$(id -g -n)" "$(dirname "$dir")"
}
link_apt_fast() {
if ! command -v apt-fast >/dev/null; then
sudo ln -sf /usr/bin/apt-get /usr/bin/apt-fast
fi
}
fetch_package() {
if ! [ -e /tmp/Packages ]; then
deb_build_arch=$(dpkg-architecture -q DEB_BUILD_ARCH)
curl -o /tmp/Packages.gz -sL "http://ppa.launchpad.net/ondrej/php/ubuntu/dists/$DISTRIB_CODENAME/main/binary-$deb_build_arch/Packages.gz"
gzip -df /tmp/Packages.gz
fi
}
get_dependencies() {
package=$1
prefix=$2
sed -e '/Package:\s'"$package$"'/,/^\s*$/!d' /tmp/Packages | grep -Eo "^Depends.*" | tr ',' '\n' | awk -v ORS='' '/^\s'"$prefix"'/{print$0}' | sed -e 's/([^()]*)//g' | sort | uniq | xargs echo -n
}
get_package_link() {
package=$1
trunk="http://ppa.launchpad.net/ondrej/php/ubuntu"
file=$(sed -e '/Package:\s'"$package$"'/,/^\s*$/!d' /tmp/Packages | grep -Eo "^Filename.*" | cut -d' ' -f 2 | tr -d '\r')
echo "$trunk/$file"
}
linux_extension_dir() {
api_version=$1
if [[ "$version" =~ $old_versions|$nightly_versions ]]; then
echo "/usr/local/php/$version/lib/php/extensions/no-debug-non-zts-$api_version"
else
echo "/usr/lib/php/$api_version"
fi
}
darwin_extension_dir() {
api_version=$1
if [[ "$version" =~ $old_versions ]]; then
echo "/opt/local/lib/php${version/./}/extensions/no-debug-non-zts-$api_version"
else
if [[ "$(sysctl -n hw.optional.arm64 2>/dev/null)" == "1" ]]; then
echo "/opt/homebrew/lib/php/pecl/$api_version"
else
echo "/usr/local/lib/php/pecl/$api_version"
fi
fi
}
get_api_version() {
case $version in
5.3) echo "20090626" ;;
5.4) echo "20100525" ;;
5.5) echo "20121212" ;;
5.6) echo "20131226" ;;
7.0) echo "20151012" ;;
7.1) echo "20160303" ;;
7.2) echo "20170718" ;;
7.3) echo "20180731" ;;
7.4) echo "20190902" ;;
8.0) echo "20200930" ;;
*)
php_header="https://raw.githubusercontent.com/php/php-src/master/main/php.h"
curl -sSL --retry 5 "$php_header" | grep "PHP_API_VERSION" | cut -d' ' -f 3
;;
esac
}
add_config() {
dependent_extension=$1
dependency_extension=$2
echo "$dependency_extension" | sudo tee "$cache_directory/$dependent_extension/$dependency_extension" >/dev/null 2>&1
}
setup_extension() {
dependent_extension=$1
dependency_extension=$2
extension_dir=$3
if ! [ -e "$extension_dir/$dependency_extension.so" ]; then
extension_package_link="$(get_package_link "php$version-$dependency_extension")"
sudo curl -H "User-Agent: Debian APT-HTTP/GHA(ce)" -o "$dependency_extension".deb -sL "$extension_package_link"
sudo dpkg-deb -x "$dependency_extension".deb /
fix_ownership "$dir"
fi
if [ -e "$extension_dir/$dependency_extension.so" ]; then
add_config "$dependent_extension" "$dependency_extension"
add_log "$tick" "$dependency_extension"
else
add_log "$cross" "$dependency_extension"
fi
}
filter_dependencies_libs() {
libraries="$(echo "$1" | xargs -n1 | uniq | xargs)"
script_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )
for library in $libraries; do
if grep -i -q -w "$library" "$script_dir"/lists/"$DISTRIB_CODENAME"-libs; then
libraries=${libraries//$library/}
fi
done
echo "$libraries"
}
setup_dependencies_libs() {
libraries=$1
if [[ -n "${libraries// }" ]]; then
libraries=$(filter_dependencies_libs "$libraries")
if [[ -n "${libraries// }" ]]; then
step_log "Setup libraries"
IFS=' ' read -r -a libraries_array <<<"$libraries"
link_apt_fast
(
sudo DEBIAN_FRONTEND=noninteractive apt-fast install --no-install-recommends --no-upgrade -y "${libraries_array[@]}" >/dev/null 2>&1 &&
add_log "$tick" "${libraries_array[@]}"
) || add_log "$cross" "${libraries_array[@]}"
fi
fi
}
setup_dependencies_extensions() {
extension_dir=$1
shift
extensions_array=("$@")
. /etc/lsb-release
cache_directory=/tmp/extcache
sudo rm -rf "$cache_directory" || true
libraries=""
for extension_package in "${extensions_array[@]}"; do
fetch_package
libraries="$libraries $(get_dependencies "$extension_package" "lib")"
extension="${extension_package/php$version-/}"
if ! [ -d "$cache_directory"/"$extension" ]; then
extension_dependencies=$(get_dependencies "$extension_package" "php$version-")
extension_dependencies="${extension_dependencies//php$version-common/}"
if [[ -n "${extension_dependencies// }" ]]; then
step_log "Setup extensions for $extension"
extension_dependencies_array=()
IFS=' ' read -r -a extension_dependencies_array <<<"$extension_dependencies"
sudo mkdir -p "$cache_directory"/"$extension"
(
cd "$cache_directory" || exit 1
to_wait=()
for extension_dependeny_package in "${extension_dependencies_array[@]}"; do
if [[ -n "${extension_dependeny_package// }" ]]; then
extension_dependency=${extension_dependeny_package/php$version-/}
setup_extension "$extension" "$extension_dependency" "$extension_dir" &
to_wait+=($!)
fi
done
wait "${to_wait[@]}"
)
fi
fi
done
setup_dependencies_libs "$libraries"
}
setup_dependencies() {
extensions=$1
extension_dir=$2
if [[ -n "${extensions// }" ]]; then
IFS=' ' read -r -a extensions_array <<<"$(echo "$extensions" | sed -e "s/pdo[_-]//g" -Ee "s/^|,\s*/ php$version-/g")"
setup_dependencies_extensions "$extension_dir" "${extensions_array[@]}"
fi
}
extensions=$1
key=$2
version=$3
tick="✓"
cross="✗"
os=$(uname -s)
old_versions="5.[3-5]"
nightly_versions="8.[1-9]"
date='20210313'
if [ "$os" = "Linux" ]; then
. /etc/lsb-release
os=$os-$DISTRIB_CODENAME
api_version=$(get_api_version)
dir=$(linux_extension_dir "$api_version")
sudo mkdir -p "$dir" && fix_ownership "$dir"
setup_dependencies "$extensions" "$dir"
elif [ "$os" = "Darwin" ]; then
api_version=$(get_api_version)
dir=$(darwin_extension_dir "$api_version")
sudo mkdir -p "$dir" && fix_ownership "$dir"
[[ "$extensions" == *"imagick"* ]] && date='20210622'
else
os="Windows"
dir='C:\\tools\\php\\ext'
[[ "$extensions" == *"imagick"* ]] && date='20210512'
fi
key="$os"-ext-"$version"-$(echo -n "$extensions-$key" | openssl dgst -sha256 | cut -d ' ' -f 2)
key="$key-$date"
echo "::set-output name=dir::$dir"
echo "::set-output name=key::$key"

View File

@@ -0,0 +1,12 @@
amqp
grpc
imagick
imap
memcached
pecl_http
phalcon3
phalcon4
psr
rdkafka
redis
zmq

125
src/scripts/cache.sh Normal file
View File

@@ -0,0 +1,125 @@
step_log() {
message=$1
printf "\n\033[90;1m==> \033[0m\033[37;1m%s\033[0m\n" "$message"
}
add_log() {
mark=$1
shift
subjects=("$@")
for subject in "${subjects[@]}"; do
if [ "$mark" = "$tick" ]; then
printf "\033[32;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "Added $subject"
else
printf "\033[31;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "Failed to setup $subject"
fi
done
}
get_api_version_from_repo() {
php_header="https://raw.githubusercontent.com/php/php-src/PHP-$version/main/php.h"
status_code=$(curl -sSL -o /tmp/php.h -w "%{http_code}" "$php_header")
if [ "$status_code" != "200" ]; then
curl -sSL --retry 5 "${php_header/PHP-$version/master}" | grep "PHP_API_VERSION" | cut -d' ' -f 3
else
grep "PHP_API_VERSION" /tmp/php.h | cut -d' ' -f 3
fi
}
get_api_version() {
case $version in
5.3) echo "20090626" ;;
5.4) echo "20100525" ;;
5.5) echo "20121212" ;;
5.6) echo "20131226" ;;
7.0) echo "20151012" ;;
7.1) echo "20160303" ;;
7.2) echo "20170718" ;;
7.3) echo "20180731" ;;
7.4) echo "20190902" ;;
8.0) echo "20200930" ;;
*) get_api_version_from_repo ;;
esac
}
fix_ownership() {
dir=$1
sudo chown -R "$USER":"$(id -g -n)" "$(dirname "$dir")"
}
add_config() {
dependent_extension=$1
dependency_extension=$2
echo "$dependency_extension" | sudo tee "${ext_config_directory:?}/$dependent_extension/$dependency_extension" >/dev/null 2>&1
}
extension_dir_darwin() {
api_version=$1
if [[ "${version:?}" =~ ${old_versions:?} ]]; then
echo "/opt/local/lib/php${version/./}/extensions/no-debug-non-zts-$api_version"
else
if [[ "$(sysctl -n hw.optional.arm64 2>/dev/null)" == "1" ]]; then
echo "/opt/homebrew/lib/php/pecl/$api_version"
else
echo "/usr/local/lib/php/pecl/$api_version"
fi
fi
}
extension_dir_linux() {
api_version=$1
if [[ "${version:?}" =~ ${old_versions:?}|${nightly_versions:?} ]]; then
echo "/usr/local/php/$version/lib/php/extensions/no-debug-non-zts-$api_version"
else
echo "/usr/lib/php/$api_version"
fi
}
data() {
old_versions="5.[3-5]"
nightly_versions="8.[1-9]"
date='20210703'
if [ "$os" = "Linux" ]; then
. /etc/lsb-release
os=$os-$DISTRIB_CODENAME
api_version=$(get_api_version)
dir=$(extension_dir_linux "$api_version")
sudo mkdir -p "$dir/deps" && fix_ownership "$dir"
elif [ "$os" = "Darwin" ]; then
api_version=$(get_api_version)
dir=$(extension_dir_darwin "$api_version")
sudo mkdir -p "$dir/deps" && fix_ownership "$dir"
[[ "$extensions" == *"imagick"* ]] && date='20210703'
else
os="Windows"
dir='C:\\tools\\php\\ext'
[[ "$extensions" == *"imagick"* ]] && date='20210512'
fi
key="$os"-ext-"$version"-$(echo -n "$extensions-$key" | openssl dgst -sha256 | cut -d ' ' -f 2)
key="$key-$date"
echo "$dir" > "${RUNNER_TEMP:?}"/dir
echo "$key" > "${RUNNER_TEMP:?}"/key
echo "::set-output name=dir::$dir"
echo "::set-output name=key::$key"
}
dependencies() {
if [ "$os" = "Linux" ] || [ "$os" = "Darwin" ]; then
export tick="✓"
export cross="✗"
export ext_config_directory="/tmp/extcache"
export deps_cache_directory="${RUNNER_TOOL_CACHE}"/deps
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)
# shellcheck disable=SC1090
. "$script_dir/$(echo "$os" | tr '[:upper:]' '[:lower:]').sh"
setup_dependencies "$extensions" "$(cat "${RUNNER_TEMP:?}"/dir)"
fi
}
run=$1
extensions=$2
version=$3
key=$4
os=$(uname -s)
$run

118
src/scripts/darwin.sh Normal file
View File

@@ -0,0 +1,118 @@
fetch_brew_tap() {
tap=$1
tap_user=$(dirname "$tap")
tap_name=$(basename "$tap")
mkdir -p "$tap_dir/$tap_user"
curl -sL "https://github.com/$tap/archive/master.tar.gz" | sudo tar -xzf - -C "$tap_dir/$tap_user"
if [ -d "$tap_dir/$tap_user/$tap_name-master" ]; then
sudo mv "$tap_dir/$tap_user/$tap_name-master" "$tap_dir/$tap_user/$tap_name"
fi
}
add_brew_tap() {
tap=$1
if ! [ -d "$tap_dir/$tap" ]; then
if [ "${ImageOS:=}-${ImageVersion:=}" = "-" ]; then
brew tap --shallow "$tap" >/dev/null 2>&1
else
fetch_brew_tap "$tap" >/dev/null 2>&1
if ! [ -d "$tap_dir/$tap" ]; then
brew tap --shallow "$tap" >/dev/null 2>&1
fi
fi
fi
}
filter_extensions() {
extensions_array=("$@")
filtered_extensions=()
for ext in "${extensions_array[@]}"; do
if grep -i -q -w "$ext" "${script_dir:?}"/../lists/darwin-extensions; then
filtered_extensions+=("$ext")
fi
done
echo "${filtered_extensions[@]}"
}
setup_extensions_helper() {
dependent_extension=$1
dependency_extension=$2
extension_dir=$3
cached_extension="${deps_cache_directory:?}/$dependency_extension.so"
if ! [ -e "$cached_extension" ]; then
brew install "$dependency_extension@${version:?}"
sudo find "$brew_cellar/$dependency_extension@${version:?}" -name "$dependency_extension.so" -exec cp {} "$cached_extension" \;
else
echo "Found $dependency_extension extension in cache"
sudo cp "$cached_extension" "$extension_dir/"
fi
add_config "$dependent_extension" "$dependency_extension"
}
setup_extensions() {
dependent_extension=$1
extension_dir=$2
shift 2
dependency_extensions_array=("$@")
sudo mkdir -p "$cache_directory"/"$extension"
echo "::group::Logs to set up extensions required for $extension"
for dependency_extension in "${dependency_extensions_array[@]}"; do
setup_extensions_helper "$dependent_extension" "$dependency_extension" "$extension_dir"
done
echo "::endgroup::"
add_log "${tick:?}" "${dependency_extensions_array[@]}"
}
setup_libraries() {
extension=$1
shift 1
libraries_array=("$@")
ext_deps_dir="$deps_cache_directory/$extension"
sudo cp -a "$tap_dir"/shivammathur/homebrew-extensions/.github/deps/"$extension"/*.rb "$tap_dir"/homebrew/homebrew-core/Formula/
sudo mkdir -p "$ext_deps_dir"
libs_count="$(find "$ext_deps_dir" -maxdepth 1 -name "*.dylib" | wc -l | sed 's/^ *//')"
if [ "$libs_count" = "0" ]; then
echo "::group::Logs to set up libraries required for $extension"
for lib in "${libraries_array[@]}"; do
brew list "$lib" &>/dev/null || brew install "$lib"
IFS=' ' read -r -a deps_array <<<"$(brew deps "$lib" | tr '\n' ' ')"
for dep in "$lib" "${deps_array[@]}"; do
sudo find "$brew_cellar/$dep" -name "*.dylib" -exec cp "{}" "$ext_deps_dir/" \;
done
done
echo "::endgroup::"
else
sudo find "$ext_deps_dir" -name "*.dylib" -exec cp "{}" "$brew_prefix/lib/" \;
fi
add_log "$tick" "${libraries_array[@]}"
}
setup_dependencies() {
extensions=$1
extension_dir=$2
cache_directory=/tmp/extcache
[[ -z "${extensions// /}" ]] && return
IFS=' ' read -r -a extensions_array <<<"$(echo "$extensions" | sed -e "s/pdo[_-]//g" -Ee "s/^|,\s*/ /g")"
IFS=' ' read -r -a extensions_array <<<"$(filter_extensions "${extensions_array[@]}")"
if [[ -n "${extensions_array[*]// /}" ]]; then
add_brew_tap "shivammathur/homebrew-php"
add_brew_tap "shivammathur/homebrew-extensions"
for extension in "${extensions_array[@]}"; do
IFS=' ' read -r -a dependency_array <<<"$(grep "depends_on" "$tap_dir/shivammathur/homebrew-extensions/Formula/$extension@$version.rb" | cut -d '"' -f 2 | tr '\n' ' ')"
IFS=' ' read -r -a extension_array <<<"$(echo "${dependency_array[@]}" | grep -Eo "[a-z]*@" | sed 's/@//' | tr '\n' ' ')"
IFS=' ' read -r -a libraries_array <<<"${dependency_array[@]//shivammathur*/}"
if [[ -n "${libraries_array[*]// /}" ]]; then
step_log "Setup libraries for $extension"
setup_libraries "$extension" "${libraries_array[@]}"
fi
if [[ -n "${extension_array[*]// /}" ]]; then
step_log "Setup extensions for $extension"
setup_extensions "$extension" "$extension_dir" "${extension_array[@]}"
fi
done
fi
}
brew_prefix="$(brew --prefix)"
brew_cellar="$brew_prefix/Cellar"
tap_dir="$(brew --repository)"/Library/Taps

107
src/scripts/linux.sh Normal file
View File

@@ -0,0 +1,107 @@
link_apt_fast() {
if ! command -v apt-fast >/dev/null; then
sudo ln -sf /usr/bin/apt-get /usr/bin/apt-fast
fi
}
fetch_package() {
if ! [ -e /tmp/Packages ]; then
. /etc/lsb-release
deb_build_arch=$(dpkg-architecture -q DEB_BUILD_ARCH)
curl -o /tmp/Packages.gz -sL "http://ppa.launchpad.net/ondrej/php/ubuntu/dists/$DISTRIB_CODENAME/main/binary-$deb_build_arch/Packages.gz"
gzip -df /tmp/Packages.gz
fi
}
get_dependencies() {
package=$1
prefix=$2
sed -e '/Package:\s'"$package$"'/,/^\s*$/!d' /tmp/Packages | grep -Eo "^Depends.*" | tr ',' '\n' | awk -v ORS='' '/^\s'"$prefix"'/{print$0}' | sed -e 's/([^()]*)//g' | sort | uniq | xargs echo -n
}
get_package_link() {
package=$1
trunk="http://ppa.launchpad.net/ondrej/php/ubuntu"
file=$(sed -e '/Package:\s'"$package$"'/,/^\s*$/!d' /tmp/Packages | grep -Eo "^Filename.*" | cut -d' ' -f 2 | tr -d '\r')
echo "$trunk/$file"
}
setup_extensions_helper() {
dependency_extension=$1
extension_dir=$2
cached_extension="${deps_cache_directory:?}/$dependency_extension.so"
if ! [ -e "$extension_dir/$dependency_extension.so" ]; then
if ! [ -e "$cached_extension" ]; then
extension_package_link="$(get_package_link "php${version:?}-$dependency_extension")"
sudo curl -H "User-Agent: Debian APT-HTTP/GHA(ce)" -o "/tmp/$dependency_extension".deb -sL "$extension_package_link"
sudo dpkg-deb -x "/tmp/$dependency_extension".deb /
sudo cp "$extension_dir/$dependency_extension.so" "$cached_extension"
fix_ownership "$extension_dir"
else
sudo cp "$cached_extension" "$extension_dir/"
fi
fi
}
setup_extensions() {
extension_dir=$1
IFS=' ' read -r -a dependency_extension_array <<<"$(echo "$2" | xargs -n1 | sort | uniq | xargs)"
to_wait=()
for dependency_extension in "${dependency_extension_array[@]}"; do
setup_extensions_helper "$dependency_extension" "$extension_dir" &
to_wait+=($!)
done
wait "${to_wait[@]}"
add_log "${tick:?}" "${dependency_extension_array[@]}"
}
filter_libraries() {
libraries="$(echo "$1" | xargs -n1 | sort | uniq | xargs)"
for library in $libraries; do
if grep -i -q -w "$library" "${script_dir:?}"/../lists/"$DISTRIB_CODENAME"-libs; then
libraries=${libraries//$library/}
fi
done
echo "$libraries"
}
setup_libraries() {
libraries=$1
if [[ -n "${libraries// /}" ]]; then
libraries=$(filter_libraries "$libraries")
if [[ -n "${libraries// /}" ]]; then
step_log "Setup libraries"
IFS=' ' read -r -a libraries_array <<<"$libraries"
link_apt_fast
echo "::group::Logs to set up required libraries"
sudo DEBIAN_FRONTEND=noninteractive apt-fast install --no-install-recommends --no-upgrade -y "${libraries_array[@]}"
ec="$?"
echo "::endgroup::"
if [ "$ec" -eq "0" ]; then mark="${tick:?}"; else mark="${cross:?}"; fi
add_log "$mark" "${libraries_array[@]}"
fi
fi
}
setup_dependencies() {
extensions=$1
extension_dir=$2
[[ -z "${extensions// }" ]] && return
IFS=' ' read -r -a extensions_array <<<"$(echo "$extensions" | sed -e "s/pdo[_-]//g" -Ee "s/^|,\s*/ php$version-/g")"
. /etc/lsb-release
sudo rm -rf "${ext_config_directory:?}" || true
libraries=""
extension_packages=""
for extension_package in "${extensions_array[@]}"; do
fetch_package
libraries="$libraries $(get_dependencies "$extension_package" "lib")"
extension_packages="$extension_packages $(get_dependencies "$extension_package" "php$version-")"
extension_packages="${extension_packages//php$version-common/}"
done
if [[ -n "${libraries// /}" ]]; then
setup_libraries "$libraries"
fi
if [[ -n "${extension_packages// /}" ]]; then
setup_extensions "$extension_dir" "${extension_packages//php$version-/}"
fi
}

View File

@@ -1,4 +1,5 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path';
import * as core from '@actions/core'; import * as core from '@actions/core';
/** /**
@@ -40,6 +41,16 @@ export async function getInput(
} }
} }
/**
* Function to get outputs
*/
export async function getOutput(output: string): Promise<string> {
return fs.readFileSync(
path.join(await readEnv('RUNNER_TEMP'), output),
'utf8'
);
}
/** /**
* Function to parse PHP version. * Function to parse PHP version.
* *
@@ -65,10 +76,26 @@ export async function parseVersion(version: string): Promise<string> {
* @param extension_csv * @param extension_csv
*/ */
export async function filterExtensions(extension_csv: string): Promise<string> { export async function filterExtensions(extension_csv: string): Promise<string> {
return extension_csv return JSON.stringify(
.split(',') extension_csv
.filter(extension => { .split(',')
return extension.trim()[0] != ':'; .filter(extension => {
}) return extension.trim()[0] != ':';
.join(','); })
.join(',')
);
}
/**
* Function to get script call
*
* @param fn
* @param args
*/
export async function scriptCall(
fn: string,
...args: string[]
): Promise<string> {
const script: string = path.join(__dirname, '../src/scripts/cache.sh');
return ['bash', script, fn, ...args].join(' ');
} }