diff --git a/Dockerfile b/Dockerfile index eb7a8b36..c47b4683 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,8 +9,10 @@ RUN npm ci COPY ./src ./src RUN npm run build - +FROM ghcr.io/boesing/composer-semver:1.0 as composer-semver +FROM php:8.1.9-cli-alpine as php FROM node:18-alpine + LABEL "repository"="http://github.com/laminas/laminas-ci-matrix-action" LABEL "homepage"="http://github.com/laminas/laminas-ci-matrix-action" LABEL "maintainer"="https://github.com/laminas/technical-steering-committee/" @@ -25,6 +27,16 @@ ADD laminas-ci.schema.json /action/ COPY --from=compiler /usr/local/source/dist/main.js /action/ RUN chmod u+x /action/main.js +# Setup PHP +RUN mkdir -p /usr/local/bin /usr/local/etc /usr/local/lib +COPY --from=php /usr/local/bin/php /usr/local/bin +COPY --from=php /usr/local/etc/* /usr/local/etc +COPY --from=php /usr/local/lib/php/* /usr/local/lib/php +COPY --from=php /usr/lib/* /usr/lib +COPY --from=php /lib/* /lib + +COPY --from=composer-semver /usr/local/bin/main.phar /usr/local/bin/composer-semver.phar + ADD entrypoint.sh /usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] diff --git a/package-lock.json b/package-lock.json index d8bb51bb..ab24a971 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,7 @@ "dependencies": { "@actions/core": "^1.6.0", "@cfworker/json-schema": "^1.12.2", - "@types/semver": "^7.3.9", - "semver": "^7.3.5" + "child_process": "^1.0.2" }, "devDependencies": { "@types/node": "^18.6.4", @@ -759,11 +758,6 @@ "dev": true, "peer": true }, - "node_modules/@types/semver": { - "version": "7.3.10", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.10.tgz", - "integrity": "sha512-zsv3fsC7S84NN6nPK06u79oWgrPVd0NvOyqgghV1haPaFcVxIrP4DLomRwGAXk0ui4HZA7mOcSFL98sMVW9viw==" - }, "node_modules/@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -1480,6 +1474,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/child_process": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", + "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==" + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -3415,6 +3414,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -4315,6 +4315,7 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -5026,7 +5027,8 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/yocto-queue": { "version": "0.1.0", @@ -5636,11 +5638,6 @@ "dev": true, "peer": true }, - "@types/semver": { - "version": "7.3.10", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.10.tgz", - "integrity": "sha512-zsv3fsC7S84NN6nPK06u79oWgrPVd0NvOyqgghV1haPaFcVxIrP4DLomRwGAXk0ui4HZA7mOcSFL98sMVW9viw==" - }, "@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -6148,6 +6145,11 @@ "dev": true, "peer": true }, + "child_process": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", + "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==" + }, "chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -7577,6 +7579,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "requires": { "yallist": "^4.0.0" } @@ -8239,6 +8242,7 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -8734,7 +8738,8 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "yocto-queue": { "version": "0.1.0", diff --git a/package.json b/package.json index b5bd61e6..e24bea86 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ }, "type": "commonjs", "devDependencies": { + "@types/node": "^18.6.4", "@typescript-eslint/eslint-plugin": "^5.16.0", "@typescript-eslint/parser": "^5.16.0", - "@types/node": "^18.6.4", "eslint": "^8.11.0", "eslint-config-incredible": "^2.4.2", "eslint-import-resolver-typescript": "^2.7.0", @@ -25,7 +25,6 @@ "dependencies": { "@actions/core": "^1.6.0", "@cfworker/json-schema": "^1.12.2", - "@types/semver": "^7.3.9", - "semver": "^7.3.5" + "child_process": "^1.0.2" } } diff --git a/src/app.ts b/src/app.ts index 504674b5..9c25e9b7 100644 --- a/src/app.ts +++ b/src/app.ts @@ -81,7 +81,8 @@ export class App { this.checkRequirements(filesFromDiff), this.composerJsonFileName, this.composerLockJsonFileName, - this.continousIntegrationConfigurationJsonFileName + this.continousIntegrationConfigurationJsonFileName, + this.logger ); } diff --git a/src/config/app.ts b/src/config/app.ts index 8b1df24b..633c52b0 100644 --- a/src/config/app.ts +++ b/src/config/app.ts @@ -1,11 +1,11 @@ import fs, {PathLike} from 'fs'; -import semver from 'semver'; import parseJsonFile from '../json'; import {Tool, ToolExecutionType} from '../tools'; import {Logger} from '../logging'; import {CURRENT_STABLE, INSTALLABLE_VERSIONS, InstallablePhpVersionType, isInstallableVersion} from './php'; import {ComposerJson} from './composer'; import {ConfigurationFromFile, isAdditionalChecksConfiguration, isAnyComposerDependencySet, isAnyPhpVersionType, isConfigurationContainingJobExclusions, isExplicitChecksConfiguration, isLatestPhpVersionType, isLowestPhpVersionType, JobDefinitionFromFile, JobFromFile, JobToExcludeFromFile} from './input'; +import {satisfies} from "../semver"; export const OPERATING_SYSTEM = 'ubuntu-latest'; export const ACTION = 'laminas/laminas-continuous-integration-action@v1'; @@ -16,19 +16,29 @@ export enum ComposerDependencySet { LATEST = 'latest', } -function gatherVersions(composerJson: ComposerJson): InstallablePhpVersionType[] { +function gatherVersions(composerJson: ComposerJson, logger: Logger): InstallablePhpVersionType[] { if (JSON.stringify(composerJson) === '{}') { + logger.debug('The composer.json file is either empty or does not exist.'); return []; } const composerPhpVersion: string = (composerJson.require?.php ?? '').replace(/,\s/, ' '); if (composerPhpVersion === '') { + logger.debug('`composer.json` does not contain any PHP requirement.'); return []; } return INSTALLABLE_VERSIONS - .filter((version) => semver.satisfies(`${version}.0`, composerPhpVersion)); + .filter((version) => { + if (satisfies(`${version}.0`, composerPhpVersion)) { + logger.debug(`PHP ${version} is supported by projects \`composer.json\`!`) + return true; + } + + logger.debug(`PHP ${version} is NOT supported by projects \`composer.json\`!`) + return false; + }); } function gatherExtensions(composerJson: ComposerJson): Set { @@ -418,12 +428,13 @@ export default function createConfig( requirements: Requirements, composerJsonFileName: PathLike, composerLockJsonFileName: PathLike, - continousIntegrationConfigurationJsonFileName: PathLike + continousIntegrationConfigurationJsonFileName: PathLike, + logger: Logger ): Config { const composerJson: ComposerJson = parseJsonFile(composerJsonFileName) as ComposerJson; const configurationFromFile: ConfigurationFromFile = parseJsonFile(continousIntegrationConfigurationJsonFileName) as ConfigurationFromFile; - const phpVersionsSupportedByProject: InstallablePhpVersionType[] = gatherVersions(composerJson); + const phpVersionsSupportedByProject: InstallablePhpVersionType[] = gatherVersions(composerJson, logger); let phpExtensions: Set = gatherExtensions(composerJson); let stablePHPVersion: InstallablePhpVersionType = CURRENT_STABLE; diff --git a/src/semver.ts b/src/semver.ts new file mode 100644 index 00000000..e9ba01c1 --- /dev/null +++ b/src/semver.ts @@ -0,0 +1,10 @@ +import {execSync} from "child_process"; + +export function satisfies(version: string, constraint: string): boolean { + try { + execSync(`/usr/local/bin/composer-semver.phar semver:match "${version}" "${constraint}" > /dev/null`) + return true; + } catch (error) { + return false; + } +}