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.json b/package.json index b5bd61e6..ab16aa14 100644 --- a/package.json +++ b/package.json @@ -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; + } +}