Files
actions/php-composer/action.yml
2025-11-03 12:59:49 +02:00

229 lines
7.2 KiB
YAML

# yaml-language-server: $schema=https://json.schemastore.org/github-action.json
# permissions:
# - contents: read # Required for checking out repository
---
name: Run Composer Install
description: 'Runs Composer install on a repository with advanced caching and configuration.'
author: 'Ismo Vuorinen'
branding:
icon: server
color: gray-dark
inputs:
php:
description: 'PHP Version to use.'
required: true
default: '8.4'
extensions:
description: 'Comma-separated list of PHP extensions to install'
required: false
default: 'mbstring, xml, zip, curl, json'
tools:
description: 'Comma-separated list of Composer tools to install'
required: false
default: 'composer:v2'
args:
description: 'Arguments to pass to Composer.'
required: false
default: '--no-progress --prefer-dist --optimize-autoloader'
composer-version:
description: 'Composer version to use (1 or 2)'
required: false
default: '2'
stability:
description: 'Minimum stability (stable, RC, beta, alpha, dev)'
required: false
default: 'stable'
cache-directories:
description: 'Additional directories to cache (comma-separated)'
required: false
default: ''
token:
description: 'GitHub token for private repository access'
required: false
default: ''
max-retries:
description: 'Maximum number of retry attempts for Composer commands'
required: false
default: '3'
outputs:
lock:
description: 'composer.lock or composer.json file hash'
value: ${{ steps.hash.outputs.lock }}
php-version:
description: 'Installed PHP version'
value: ${{ steps.php.outputs.version }}
composer-version:
description: 'Installed Composer version'
value: ${{ steps.composer.outputs.version }}
cache-hit:
description: 'Indicates if there was a cache hit'
value: ${{ steps.composer-cache.outputs.cache-hit }}
runs:
using: composite
steps:
- name: Mask Secrets
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.token || github.token }}
run: |
echo "::add-mask::$GITHUB_TOKEN"
- name: Checkout Repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
token: ${{ inputs.token || github.token }}
- name: Validate Inputs
id: validate
uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with:
action-type: php-composer
- name: Setup PHP
id: php
uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # 2.35.5
with:
php-version: ${{ inputs.php }}
extensions: ${{ inputs.extensions }}
tools: ${{ inputs.tools }}
coverage: none
ini-values: memory_limit=1G, max_execution_time=600
fail-fast: true
- name: Get Dependency Hashes
id: hash
shell: bash
env:
CACHE_DIRECTORIES: ${{ inputs.cache-directories }}
COMPOSER_LOCK_HASH: ${{ hashFiles('**/composer.lock') }}
COMPOSER_JSON_HASH: ${{ hashFiles('**/composer.json') }}
run: |
set -euo pipefail
# Function to calculate directory hash
calculate_dir_hash() {
local dir=$1
if [ -d "$dir" ]; then
find "$dir" -type f -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1
fi
}
# Get composer.lock hash or composer.json hash
if [ -f composer.lock ]; then
echo "lock=$COMPOSER_LOCK_HASH" >> $GITHUB_OUTPUT
else
echo "lock=$COMPOSER_JSON_HASH" >> $GITHUB_OUTPUT
fi
# Calculate additional directory hashes
if [ -n "$CACHE_DIRECTORIES" ]; then
IFS=',' read -ra DIRS <<< "$CACHE_DIRECTORIES"
for dir in "${DIRS[@]}"; do
dir_hash=$(calculate_dir_hash "$dir")
if [ -n "$dir_hash" ]; then
echo "${dir}_hash=$dir_hash" >> $GITHUB_OUTPUT
fi
done
fi
- name: Configure Composer
id: composer
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.token || github.token }}
STABILITY: ${{ inputs.stability }}
COMPOSER_VERSION: ${{ inputs.composer-version }}
run: |
set -euo pipefail
# Configure Composer environment
composer config --global process-timeout 600
composer config --global allow-plugins true
composer config --global github-oauth.github.com "$GITHUB_TOKEN"
if [ "$STABILITY" != "stable" ]; then
composer config minimum-stability "$STABILITY"
fi
# Verify Composer installation
composer_full_version=$(composer --version | grep -oP 'Composer version \K[0-9]+\.[0-9]+\.[0-9]+')
if [ -z "$composer_full_version" ]; then
echo "::error::Failed to detect Composer version"
exit 1
fi
# Extract major version for comparison
composer_major_version=${composer_full_version%%.*}
expected_version="$COMPOSER_VERSION"
echo "Detected Composer version: $composer_full_version (major: $composer_major_version)"
if [ "$composer_major_version" != "$expected_version" ]; then
echo "::error::Composer major version mismatch. Expected $expected_version.x, got $composer_full_version"
exit 1
fi
# Store full version for output
echo "version=$composer_full_version" >> "$GITHUB_OUTPUT"
# Log Composer configuration
echo "Composer Configuration:"
composer config --list
- name: Cache Composer packages
id: composer-cache
uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with:
type: 'composer'
paths: vendor,~/.composer/cache${{ inputs.cache-directories != "" && format(",{0}", inputs.cache-directories) || "" }}
key-prefix: 'php-${{ inputs.php }}-composer-${{ inputs.composer-version }}'
key-files: 'composer.lock,composer.json'
restore-keys: |
${{ runner.os }}-php-${{ inputs.php }}-composer-${{ inputs.composer-version }}-
${{ runner.os }}-php-${{ inputs.php }}-composer-
${{ runner.os }}-php-${{ inputs.php }}-
- name: Clear Composer Cache Before Final Attempt
if: steps.composer-cache.outputs.cache-hit != 'true'
shell: bash
run: |
set -euo pipefail
echo "Clearing Composer cache to ensure clean installation..."
composer clear-cache
- name: Install Dependencies
uses: ivuorinen/actions/common-retry@0fa9a68f07a1260b321f814202658a6089a43d42
with:
command: composer install ${{ inputs.args }}
max-retries: ${{ inputs.max-retries }}
retry-delay: '30'
description: 'Installing PHP dependencies via Composer'
- name: Verify Installation
shell: bash
run: |
set -euo pipefail
# Verify vendor directory
if [ ! -d "vendor" ]; then
echo "::error::vendor directory not found"
exit 1
fi
# Verify autoloader
if [ ! -f "vendor/autoload.php" ]; then
echo "::error::autoload.php not found"
exit 1
fi
- name: Generate Optimized Autoloader
if: success()
shell: bash
run: |-
set -euo pipefail
composer dump-autoload --optimize --classmap-authoritative