3 Commits
1.5.1 ... 1.6.0

Author SHA1 Message Date
Shivam Mathur
96afc02cad Fix library cache on macOS 2021-07-07 13:08:12 +05:30
Shivam Mathur
024a2e796f Add brew environment variables 2021-07-03 16:49:08 +05:30
Shivam Mathur
65ea75914e 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
2021-07-03 16:12:27 +05:30
13 changed files with 60565 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"
date='20210707'
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

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

@@ -0,0 +1,171 @@
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[@]}"
}
add_library_helper() {
dep_name=$1
cache_dir=$2
sudo cp -R "$brew_cellar/$dep_name" "$cache_dir/"
sudo chmod -R 777 "$cache_dir/$dep_name"
echo "$dep_name" | sudo tee -a "$cache_dir"/list >/dev/null 2>&1
(
cd "$cache_dir" || exit 1
if command -v gtar >/dev/null; then
sudo gtar -I "zstd -T0" -cf "$cache_dir"/"$dep_name".tar.zst "$dep_name"
else
sudo tar -cf - "$dep_name" | zstd -T0 > "$cache_dir"/"$dep_name".tar.zst
fi
)
}
add_library() {
lib=$1
cache_dir=$2
brew list "$lib" &>/dev/null || brew install "$lib"
IFS=' ' read -r -a deps_array <<<"$(brew deps "$lib" | tr '\n' ' ')"
to_wait=()
for dep_name in "$lib" "${deps_array[@]}"; do
add_library_helper "$dep_name" "$cache_dir" &
to_wait+=($!)
done
wait "${to_wait[@]}"
sudo rm -R -- "${cache_dir:?}"/*/
}
restore_library_helper() {
dep_name=$1
cache_dir=$2
if command -v gtar >/dev/null; then
sudo gtar -I "zstd -d" -xf "$cache_dir"/"$dep_name".tar.zst -C "$brew_cellar"
else
sudo zstd -dq "$cache_dir"/"$dep_name".tar.zst && sudo tar -xf "$cache_dir"/"$dep_name".tar -C "$brew_cellar"
fi
if ! [ -d "$brew_prefix/opt/$dep_name" ]; then
brew link --force --overwrite "$dep_name" 2>/dev/null || true
fi
}
restore_library() {
cache_dir=$1
to_wait=()
while read -r dep_name; do
restore_library_helper "$dep_name" "$cache_dir" &
to_wait+=($!)
done <"$cache_dir"/list
wait "${to_wait[@]}"
}
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"
echo "::group::Logs to set up libraries required for $extension"
for lib in "${libraries_array[@]}"; do
if ! [ -e "$ext_deps_dir"/list ]; then
add_library "$lib" "$ext_deps_dir"
else
restore_library "$ext_deps_dir"
fi
done
echo "::endgroup::"
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
}
export HOMEBREW_CHANGE_ARCH_TO_ARM=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
export HOMEBREW_NO_AUTO_UPDATE=1
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
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(' ');
} }