mirror of
https://github.com/ivuorinen/actions.git
synced 2026-03-20 08:00:54 +00:00
refactor: consolidate PHP testing actions with Laravel detection
Merge php-tests, php-laravel-phpunit, and php-composer into single php-tests action: Consolidation: - Merge three PHP actions into one with framework auto-detection - Add framework input (auto/laravel/generic) with artisan file detection - Inline PHP version detection from multiple sources - Inline Composer setup, caching, and dependency installation - Add conditional Laravel-specific setup steps Features: - Auto-detect Laravel via artisan file presence - PHP version detection from .tool-versions, Dockerfile, composer.json, etc. - Composer dependency management with retry logic and caching - Laravel setup: .env copy, key generation, permissions, SQLite database - Smart test execution: composer test for Laravel, direct PHPUnit for generic Outputs: - framework: Detected framework (laravel/generic) - php-version, composer-version, cache-hit: Setup metadata - test-status, tests-run, tests-passed: Test results Deleted: - php-laravel-phpunit/: Laravel-specific testing action - php-composer/: Composer dependency management action - Related test files and custom validators Updated: - CLAUDE.md: 26 → 24 actions - generate_listing.cjs: Remove php-laravel-phpunit, php-composer - validate-inputs: Remove php-laravel-phpunit custom validator Result: 3 actions → 1 action, maintained all functionality with simpler interface.
This commit is contained in:
@@ -71,9 +71,9 @@
|
|||||||
|
|
||||||
Flat structure. Each action self-contained with `action.yml`.
|
Flat structure. Each action self-contained with `action.yml`.
|
||||||
|
|
||||||
**26 Actions**: Setup (language-version-detect), Utilities (action-versioning, version-file-parser),
|
**24 Actions**: Setup (language-version-detect), Utilities (action-versioning, version-file-parser),
|
||||||
Linting (ansible-lint-fix, biome-lint, csharp-lint-check, eslint-lint, go-lint, pr-lint, pre-commit, prettier-lint, python-lint-fix, terraform-lint-fix),
|
Linting (ansible-lint-fix, biome-lint, csharp-lint-check, eslint-lint, go-lint, pr-lint, pre-commit, prettier-lint, python-lint-fix, terraform-lint-fix),
|
||||||
Testing (php-tests, php-laravel-phpunit, php-composer), Build (csharp-build, go-build, docker-build),
|
Testing (php-tests), Build (csharp-build, go-build, docker-build),
|
||||||
Publishing (npm-publish, docker-publish, csharp-publish),
|
Publishing (npm-publish, docker-publish, csharp-publish),
|
||||||
Repository (release-monthly, sync-labels, stale, compress-images, codeql-analysis),
|
Repository (release-monthly, sync-labels, stale, compress-images, codeql-analysis),
|
||||||
Validation (validate-inputs)
|
Validation (validate-inputs)
|
||||||
|
|||||||
70
README.md
70
README.md
@@ -22,15 +22,15 @@ Each action is fully self-contained and can be used independently in any GitHub
|
|||||||
|
|
||||||
## 📚 Action Catalog
|
## 📚 Action Catalog
|
||||||
|
|
||||||
This repository contains **28 reusable GitHub Actions** for CI/CD automation.
|
This repository contains **25 reusable GitHub Actions** for CI/CD automation.
|
||||||
|
|
||||||
### Quick Reference (28 Actions)
|
### Quick Reference (25 Actions)
|
||||||
|
|
||||||
| Icon | Action | Category | Description | Key Features |
|
| Icon | Action | Category | Description | Key Features |
|
||||||
|:----:|:-----------------------------------------------------|:-----------|:----------------------------------------------------------------|:---------------------------------------------|
|
|:----:|:-----------------------------------------------------|:-----------|:----------------------------------------------------------------|:---------------------------------------------|
|
||||||
| 🔀 | [`action-versioning`][action-versioning] | Utilities | Automatically update SHA-pinned action references to match l... | Token auth, Outputs |
|
| 🔀 | [`action-versioning`][action-versioning] | Utilities | Automatically update SHA-pinned action references to match l... | Token auth, Outputs |
|
||||||
| 📦 | [`ansible-lint-fix`][ansible-lint-fix] | Linting | Lints and fixes Ansible playbooks, commits changes, and uplo... | Caching, Token auth, Outputs |
|
| 📦 | [`ansible-lint-fix`][ansible-lint-fix] | Linting | Lints and fixes Ansible playbooks, commits changes, and uplo... | Caching, Token auth, Outputs |
|
||||||
| ✅ | [`biome-lint`][biome-lint] | Linting | Run Biome linter in check or fix mode | Caching, Token auth, Outputs |
|
| ✅ | [`biome-lint`][biome-lint] | Linting | Run Biome linter in check or fix mode | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 🛡️ | [`codeql-analysis`][codeql-analysis] | Repository | Run CodeQL security analysis for a single language with conf... | Auto-detection, Token auth, Outputs |
|
| 🛡️ | [`codeql-analysis`][codeql-analysis] | Repository | Run CodeQL security analysis for a single language with conf... | Auto-detection, Token auth, Outputs |
|
||||||
| 🖼️ | [`compress-images`][compress-images] | Repository | Compress images on demand (workflow_dispatch), and at 11pm e... | Token auth, Outputs |
|
| 🖼️ | [`compress-images`][compress-images] | Repository | Compress images on demand (workflow_dispatch), and at 11pm e... | Token auth, Outputs |
|
||||||
| 📝 | [`csharp-build`][csharp-build] | Build | Builds and tests C# projects. | Caching, Auto-detection, Token auth, Outputs |
|
| 📝 | [`csharp-build`][csharp-build] | Build | Builds and tests C# projects. | Caching, Auto-detection, Token auth, Outputs |
|
||||||
@@ -38,18 +38,15 @@ This repository contains **28 reusable GitHub Actions** for CI/CD automation.
|
|||||||
| 📦 | [`csharp-publish`][csharp-publish] | Publishing | Publishes a C# project to GitHub Packages. | Caching, Auto-detection, Token auth, Outputs |
|
| 📦 | [`csharp-publish`][csharp-publish] | Publishing | Publishes a C# project to GitHub Packages. | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📦 | [`docker-build`][docker-build] | Build | Builds a Docker image for multiple architectures with enhanc... | Caching, Auto-detection, Token auth, Outputs |
|
| 📦 | [`docker-build`][docker-build] | Build | Builds a Docker image for multiple architectures with enhanc... | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| ☁️ | [`docker-publish`][docker-publish] | Publishing | Simple wrapper to publish Docker images to GitHub Packages a... | Token auth, Outputs |
|
| ☁️ | [`docker-publish`][docker-publish] | Publishing | Simple wrapper to publish Docker images to GitHub Packages a... | Token auth, Outputs |
|
||||||
| ✅ | [`eslint-lint`][eslint-lint] | Linting | Run ESLint in check or fix mode with advanced configuration ... | Caching, Token auth, Outputs |
|
| ✅ | [`eslint-lint`][eslint-lint] | Linting | Run ESLint in check or fix mode with advanced configuration ... | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📦 | [`go-build`][go-build] | Build | Builds the Go project. | Caching, Auto-detection, Token auth, Outputs |
|
| 📦 | [`go-build`][go-build] | Build | Builds the Go project. | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📝 | [`go-lint`][go-lint] | Linting | Run golangci-lint with advanced configuration, caching, and ... | Caching, Token auth, Outputs |
|
| 📝 | [`go-lint`][go-lint] | Linting | Run golangci-lint with advanced configuration, caching, and ... | Caching, Token auth, Outputs |
|
||||||
| 📝 | [`language-version-detect`][language-version-detect] | Setup | DEPRECATED: This action is deprecated. Inline version detect... | Auto-detection, Token auth, Outputs |
|
| 📝 | [`language-version-detect`][language-version-detect] | Setup | DEPRECATED: This action is deprecated. Inline version detect... | Auto-detection, Token auth, Outputs |
|
||||||
| 🖥️ | [`node-setup`][node-setup] | Setup | Sets up Node.js environment with version detection and packa... | Auto-detection, Token auth, Outputs |
|
| 📦 | [`npm-publish`][npm-publish] | Publishing | Publishes the package to the NPM registry with configurable ... | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📦 | [`npm-publish`][npm-publish] | Publishing | Publishes the package to the NPM registry with configurable ... | Caching, Token auth, Outputs |
|
| ✅ | [`php-tests`][php-tests] | Testing | Run PHPUnit tests with optional Laravel setup and Composer d... | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 🖥️ | [`php-composer`][php-composer] | Testing | Runs Composer install on a repository with advanced caching ... | Caching, Auto-detection, Token auth, Outputs |
|
|
||||||
| 💻 | [`php-laravel-phpunit`][php-laravel-phpunit] | Testing | Setup PHP, install dependencies, generate key, create databa... | Auto-detection, Token auth, Outputs |
|
|
||||||
| ✅ | [`php-tests`][php-tests] | Testing | Run PHPUnit tests on the repository | Token auth, Outputs |
|
|
||||||
| ✅ | [`pr-lint`][pr-lint] | Linting | Runs MegaLinter against pull requests | Caching, Auto-detection, Token auth, Outputs |
|
| ✅ | [`pr-lint`][pr-lint] | Linting | Runs MegaLinter against pull requests | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📦 | [`pre-commit`][pre-commit] | Linting | Runs pre-commit on the repository and pushes the fixes back ... | Auto-detection, Token auth, Outputs |
|
| 📦 | [`pre-commit`][pre-commit] | Linting | Runs pre-commit on the repository and pushes the fixes back ... | Auto-detection, Token auth, Outputs |
|
||||||
| ✅ | [`prettier-lint`][prettier-lint] | Linting | Run Prettier in check or fix mode with advanced configuratio... | Caching, Token auth, Outputs |
|
| ✅ | [`prettier-lint`][prettier-lint] | Linting | Run Prettier in check or fix mode with advanced configuratio... | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📝 | [`python-lint-fix`][python-lint-fix] | Linting | Lints and fixes Python files, commits changes, and uploads S... | Caching, Auto-detection, Token auth, Outputs |
|
| 📝 | [`python-lint-fix`][python-lint-fix] | Linting | Lints and fixes Python files, commits changes, and uploads S... | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📦 | [`release-monthly`][release-monthly] | Repository | Creates a release for the current month, incrementing patch ... | Token auth, Outputs |
|
| 📦 | [`release-monthly`][release-monthly] | Repository | Creates a release for the current month, incrementing patch ... | Token auth, Outputs |
|
||||||
| 📦 | [`stale`][stale] | Repository | A GitHub Action to close stale issues and pull requests. | Token auth, Outputs |
|
| 📦 | [`stale`][stale] | Repository | A GitHub Action to close stale issues and pull requests. | Token auth, Outputs |
|
||||||
@@ -59,12 +56,11 @@ This repository contains **28 reusable GitHub Actions** for CI/CD automation.
|
|||||||
|
|
||||||
### Actions by Category
|
### Actions by Category
|
||||||
|
|
||||||
#### 🔧 Setup (2 actions)
|
#### 🔧 Setup (1 action)
|
||||||
|
|
||||||
| Action | Description | Languages | Features |
|
| Action | Description | Languages | Features |
|
||||||
|:--------------------------------------------------------|:------------------------------------------------------|:--------------------------------|:------------------------------------|
|
|:--------------------------------------------------------|:------------------------------------------------------|:-------------------------------|:------------------------------------|
|
||||||
| 📝 [`language-version-detect`][language-version-detect] | DEPRECATED: This action is deprecated. Inline vers... | PHP, Python, Go, .NET, Node.js | Auto-detection, Token auth, Outputs |
|
| 📝 [`language-version-detect`][language-version-detect] | DEPRECATED: This action is deprecated. Inline vers... | PHP, Python, Go, .NET, Node.js | Auto-detection, Token auth, Outputs |
|
||||||
| 🖥️ [`node-setup`][node-setup] | Sets up Node.js environment with version detection... | Node.js, JavaScript, TypeScript | Auto-detection, Token auth, Outputs |
|
|
||||||
|
|
||||||
#### 🛠️ Utilities (1 action)
|
#### 🛠️ Utilities (1 action)
|
||||||
|
|
||||||
@@ -77,23 +73,21 @@ This repository contains **28 reusable GitHub Actions** for CI/CD automation.
|
|||||||
| Action | Description | Languages | Features |
|
| Action | Description | Languages | Features |
|
||||||
|:-----------------------------------------------|:------------------------------------------------------|:---------------------------------------------|:---------------------------------------------|
|
|:-----------------------------------------------|:------------------------------------------------------|:---------------------------------------------|:---------------------------------------------|
|
||||||
| 📦 [`ansible-lint-fix`][ansible-lint-fix] | Lints and fixes Ansible playbooks, commits changes... | Ansible, YAML | Caching, Token auth, Outputs |
|
| 📦 [`ansible-lint-fix`][ansible-lint-fix] | Lints and fixes Ansible playbooks, commits changes... | Ansible, YAML | Caching, Token auth, Outputs |
|
||||||
| ✅ [`biome-lint`][biome-lint] | Run Biome linter in check or fix mode | JavaScript, TypeScript, JSON | Caching, Token auth, Outputs |
|
| ✅ [`biome-lint`][biome-lint] | Run Biome linter in check or fix mode | JavaScript, TypeScript, JSON | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📝 [`csharp-lint-check`][csharp-lint-check] | Runs linters like StyleCop or dotnet-format for C#... | C#, .NET | Auto-detection, Token auth, Outputs |
|
| 📝 [`csharp-lint-check`][csharp-lint-check] | Runs linters like StyleCop or dotnet-format for C#... | C#, .NET | Auto-detection, Token auth, Outputs |
|
||||||
| ✅ [`eslint-lint`][eslint-lint] | Run ESLint in check or fix mode with advanced conf... | JavaScript, TypeScript | Caching, Token auth, Outputs |
|
| ✅ [`eslint-lint`][eslint-lint] | Run ESLint in check or fix mode with advanced conf... | JavaScript, TypeScript | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📝 [`go-lint`][go-lint] | Run golangci-lint with advanced configuration, cac... | Go | Caching, Token auth, Outputs |
|
| 📝 [`go-lint`][go-lint] | Run golangci-lint with advanced configuration, cac... | Go | Caching, Token auth, Outputs |
|
||||||
| ✅ [`pr-lint`][pr-lint] | Runs MegaLinter against pull requests | Conventional Commits | Caching, Auto-detection, Token auth, Outputs |
|
| ✅ [`pr-lint`][pr-lint] | Runs MegaLinter against pull requests | Conventional Commits | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📦 [`pre-commit`][pre-commit] | Runs pre-commit on the repository and pushes the f... | Python, Multiple Languages | Auto-detection, Token auth, Outputs |
|
| 📦 [`pre-commit`][pre-commit] | Runs pre-commit on the repository and pushes the f... | Python, Multiple Languages | Auto-detection, Token auth, Outputs |
|
||||||
| ✅ [`prettier-lint`][prettier-lint] | Run Prettier in check or fix mode with advanced co... | JavaScript, TypeScript, Markdown, YAML, JSON | Caching, Token auth, Outputs |
|
| ✅ [`prettier-lint`][prettier-lint] | Run Prettier in check or fix mode with advanced co... | JavaScript, TypeScript, Markdown, YAML, JSON | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 📝 [`python-lint-fix`][python-lint-fix] | Lints and fixes Python files, commits changes, and... | Python | Caching, Auto-detection, Token auth, Outputs |
|
| 📝 [`python-lint-fix`][python-lint-fix] | Lints and fixes Python files, commits changes, and... | Python | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 🖥️ [`terraform-lint-fix`][terraform-lint-fix] | Lints and fixes Terraform files with advanced vali... | Terraform, HCL | Token auth, Outputs |
|
| 🖥️ [`terraform-lint-fix`][terraform-lint-fix] | Lints and fixes Terraform files with advanced vali... | Terraform, HCL | Token auth, Outputs |
|
||||||
|
|
||||||
#### 🧪 Testing (3 actions)
|
#### 🧪 Testing (1 action)
|
||||||
|
|
||||||
| Action | Description | Languages | Features |
|
| Action | Description | Languages | Features |
|
||||||
|:------------------------------------------------|:------------------------------------------------------|:-------------|:---------------------------------------------|
|
|:---------------------------|:------------------------------------------------------|:-------------|:---------------------------------------------|
|
||||||
| 🖥️ [`php-composer`][php-composer] | Runs Composer install on a repository with advance... | PHP | Caching, Auto-detection, Token auth, Outputs |
|
| ✅ [`php-tests`][php-tests] | Run PHPUnit tests with optional Laravel setup and ... | PHP, Laravel | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| 💻 [`php-laravel-phpunit`][php-laravel-phpunit] | Setup PHP, install dependencies, generate key, cre... | PHP, Laravel | Auto-detection, Token auth, Outputs |
|
|
||||||
| ✅ [`php-tests`][php-tests] | Run PHPUnit tests on the repository | PHP | Token auth, Outputs |
|
|
||||||
|
|
||||||
#### 🏗️ Build (3 actions)
|
#### 🏗️ Build (3 actions)
|
||||||
|
|
||||||
@@ -109,7 +103,7 @@ This repository contains **28 reusable GitHub Actions** for CI/CD automation.
|
|||||||
|:--------------------------------------|:------------------------------------------------------|:-------------|:---------------------------------------------|
|
|:--------------------------------------|:------------------------------------------------------|:-------------|:---------------------------------------------|
|
||||||
| 📦 [`csharp-publish`][csharp-publish] | Publishes a C# project to GitHub Packages. | C#, .NET | Caching, Auto-detection, Token auth, Outputs |
|
| 📦 [`csharp-publish`][csharp-publish] | Publishes a C# project to GitHub Packages. | C#, .NET | Caching, Auto-detection, Token auth, Outputs |
|
||||||
| ☁️ [`docker-publish`][docker-publish] | Simple wrapper to publish Docker images to GitHub ... | Docker | Token auth, Outputs |
|
| ☁️ [`docker-publish`][docker-publish] | Simple wrapper to publish Docker images to GitHub ... | Docker | Token auth, Outputs |
|
||||||
| 📦 [`npm-publish`][npm-publish] | Publishes the package to the NPM registry with con... | Node.js, npm | Caching, Token auth, Outputs |
|
| 📦 [`npm-publish`][npm-publish] | Publishes the package to the NPM registry with con... | Node.js, npm | Caching, Auto-detection, Token auth, Outputs |
|
||||||
|
|
||||||
#### 📦 Repository (5 actions)
|
#### 📦 Repository (5 actions)
|
||||||
|
|
||||||
@@ -133,7 +127,7 @@ This repository contains **28 reusable GitHub Actions** for CI/CD automation.
|
|||||||
|:-----------------------------------------------------|:-------:|:--------------:|:----------:|:-------:|
|
|:-----------------------------------------------------|:-------:|:--------------:|:----------:|:-------:|
|
||||||
| [`action-versioning`][action-versioning] | - | - | ✅ | ✅ |
|
| [`action-versioning`][action-versioning] | - | - | ✅ | ✅ |
|
||||||
| [`ansible-lint-fix`][ansible-lint-fix] | ✅ | - | ✅ | ✅ |
|
| [`ansible-lint-fix`][ansible-lint-fix] | ✅ | - | ✅ | ✅ |
|
||||||
| [`biome-lint`][biome-lint] | ✅ | - | ✅ | ✅ |
|
| [`biome-lint`][biome-lint] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`codeql-analysis`][codeql-analysis] | - | ✅ | ✅ | ✅ |
|
| [`codeql-analysis`][codeql-analysis] | - | ✅ | ✅ | ✅ |
|
||||||
| [`compress-images`][compress-images] | - | - | ✅ | ✅ |
|
| [`compress-images`][compress-images] | - | - | ✅ | ✅ |
|
||||||
| [`csharp-build`][csharp-build] | ✅ | ✅ | ✅ | ✅ |
|
| [`csharp-build`][csharp-build] | ✅ | ✅ | ✅ | ✅ |
|
||||||
@@ -141,18 +135,15 @@ This repository contains **28 reusable GitHub Actions** for CI/CD automation.
|
|||||||
| [`csharp-publish`][csharp-publish] | ✅ | ✅ | ✅ | ✅ |
|
| [`csharp-publish`][csharp-publish] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`docker-build`][docker-build] | ✅ | ✅ | ✅ | ✅ |
|
| [`docker-build`][docker-build] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`docker-publish`][docker-publish] | - | - | ✅ | ✅ |
|
| [`docker-publish`][docker-publish] | - | - | ✅ | ✅ |
|
||||||
| [`eslint-lint`][eslint-lint] | ✅ | - | ✅ | ✅ |
|
| [`eslint-lint`][eslint-lint] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`go-build`][go-build] | ✅ | ✅ | ✅ | ✅ |
|
| [`go-build`][go-build] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`go-lint`][go-lint] | ✅ | - | ✅ | ✅ |
|
| [`go-lint`][go-lint] | ✅ | - | ✅ | ✅ |
|
||||||
| [`language-version-detect`][language-version-detect] | - | ✅ | ✅ | ✅ |
|
| [`language-version-detect`][language-version-detect] | - | ✅ | ✅ | ✅ |
|
||||||
| [`node-setup`][node-setup] | - | ✅ | ✅ | ✅ |
|
| [`npm-publish`][npm-publish] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`npm-publish`][npm-publish] | ✅ | - | ✅ | ✅ |
|
| [`php-tests`][php-tests] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`php-composer`][php-composer] | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| [`php-laravel-phpunit`][php-laravel-phpunit] | - | ✅ | ✅ | ✅ |
|
|
||||||
| [`php-tests`][php-tests] | - | - | ✅ | ✅ |
|
|
||||||
| [`pr-lint`][pr-lint] | ✅ | ✅ | ✅ | ✅ |
|
| [`pr-lint`][pr-lint] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`pre-commit`][pre-commit] | - | ✅ | ✅ | ✅ |
|
| [`pre-commit`][pre-commit] | - | ✅ | ✅ | ✅ |
|
||||||
| [`prettier-lint`][prettier-lint] | ✅ | - | ✅ | ✅ |
|
| [`prettier-lint`][prettier-lint] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`python-lint-fix`][python-lint-fix] | ✅ | ✅ | ✅ | ✅ |
|
| [`python-lint-fix`][python-lint-fix] | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [`release-monthly`][release-monthly] | - | - | ✅ | ✅ |
|
| [`release-monthly`][release-monthly] | - | - | ✅ | ✅ |
|
||||||
| [`stale`][stale] | - | - | ✅ | ✅ |
|
| [`stale`][stale] | - | - | ✅ | ✅ |
|
||||||
@@ -178,17 +169,17 @@ This repository contains **28 reusable GitHub Actions** for CI/CD automation.
|
|||||||
| JPEG | [`compress-images`][compress-images] |
|
| JPEG | [`compress-images`][compress-images] |
|
||||||
| JSON | [`biome-lint`][biome-lint], [`prettier-lint`][prettier-lint] |
|
| JSON | [`biome-lint`][biome-lint], [`prettier-lint`][prettier-lint] |
|
||||||
| Java | [`codeql-analysis`][codeql-analysis] |
|
| Java | [`codeql-analysis`][codeql-analysis] |
|
||||||
| JavaScript | [`biome-lint`][biome-lint], [`codeql-analysis`][codeql-analysis], [`eslint-lint`][eslint-lint], [`node-setup`][node-setup], [`prettier-lint`][prettier-lint] |
|
| JavaScript | [`biome-lint`][biome-lint], [`codeql-analysis`][codeql-analysis], [`eslint-lint`][eslint-lint], [`prettier-lint`][prettier-lint] |
|
||||||
| Laravel | [`php-laravel-phpunit`][php-laravel-phpunit] |
|
| Laravel | [`php-tests`][php-tests] |
|
||||||
| Markdown | [`prettier-lint`][prettier-lint] |
|
| Markdown | [`prettier-lint`][prettier-lint] |
|
||||||
| Multiple Languages | [`pre-commit`][pre-commit] |
|
| Multiple Languages | [`pre-commit`][pre-commit] |
|
||||||
| Node.js | [`language-version-detect`][language-version-detect], [`node-setup`][node-setup], [`npm-publish`][npm-publish] |
|
| Node.js | [`language-version-detect`][language-version-detect], [`npm-publish`][npm-publish] |
|
||||||
| PHP | [`language-version-detect`][language-version-detect], [`php-composer`][php-composer], [`php-laravel-phpunit`][php-laravel-phpunit], [`php-tests`][php-tests] |
|
| PHP | [`language-version-detect`][language-version-detect], [`php-tests`][php-tests] |
|
||||||
| PNG | [`compress-images`][compress-images] |
|
| PNG | [`compress-images`][compress-images] |
|
||||||
| Python | [`codeql-analysis`][codeql-analysis], [`language-version-detect`][language-version-detect], [`pre-commit`][pre-commit], [`python-lint-fix`][python-lint-fix] |
|
| Python | [`codeql-analysis`][codeql-analysis], [`language-version-detect`][language-version-detect], [`pre-commit`][pre-commit], [`python-lint-fix`][python-lint-fix] |
|
||||||
| Ruby | [`codeql-analysis`][codeql-analysis] |
|
| Ruby | [`codeql-analysis`][codeql-analysis] |
|
||||||
| Terraform | [`terraform-lint-fix`][terraform-lint-fix] |
|
| Terraform | [`terraform-lint-fix`][terraform-lint-fix] |
|
||||||
| TypeScript | [`biome-lint`][biome-lint], [`codeql-analysis`][codeql-analysis], [`eslint-lint`][eslint-lint], [`node-setup`][node-setup], [`prettier-lint`][prettier-lint] |
|
| TypeScript | [`biome-lint`][biome-lint], [`codeql-analysis`][codeql-analysis], [`eslint-lint`][eslint-lint], [`prettier-lint`][prettier-lint] |
|
||||||
| YAML | [`ansible-lint-fix`][ansible-lint-fix], [`prettier-lint`][prettier-lint], [`sync-labels`][sync-labels], [`validate-inputs`][validate-inputs] |
|
| YAML | [`ansible-lint-fix`][ansible-lint-fix], [`prettier-lint`][prettier-lint], [`sync-labels`][sync-labels], [`validate-inputs`][validate-inputs] |
|
||||||
| npm | [`npm-publish`][npm-publish] |
|
| npm | [`npm-publish`][npm-publish] |
|
||||||
|
|
||||||
@@ -226,10 +217,7 @@ All actions can be used independently in your workflows:
|
|||||||
[go-build]: go-build/README.md
|
[go-build]: go-build/README.md
|
||||||
[go-lint]: go-lint/README.md
|
[go-lint]: go-lint/README.md
|
||||||
[language-version-detect]: language-version-detect/README.md
|
[language-version-detect]: language-version-detect/README.md
|
||||||
[node-setup]: node-setup/README.md
|
|
||||||
[npm-publish]: npm-publish/README.md
|
[npm-publish]: npm-publish/README.md
|
||||||
[php-composer]: php-composer/README.md
|
|
||||||
[php-laravel-phpunit]: php-laravel-phpunit/README.md
|
|
||||||
[php-tests]: php-tests/README.md
|
[php-tests]: php-tests/README.md
|
||||||
[pr-lint]: pr-lint/README.md
|
[pr-lint]: pr-lint/README.md
|
||||||
[pre-commit]: pre-commit/README.md
|
[pre-commit]: pre-commit/README.md
|
||||||
|
|||||||
@@ -1,407 +0,0 @@
|
|||||||
#!/usr/bin/env shellspec
|
|
||||||
# Unit tests for php-composer action validation and logic
|
|
||||||
|
|
||||||
# Framework is automatically loaded via spec_helper.sh
|
|
||||||
|
|
||||||
Describe "php-composer action"
|
|
||||||
ACTION_DIR="php-composer"
|
|
||||||
ACTION_FILE="$ACTION_DIR/action.yml"
|
|
||||||
|
|
||||||
Context "when validating php input"
|
|
||||||
It "accepts valid PHP version"
|
|
||||||
When call validate_input_python "php-composer" "php" "8.4"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts PHP version with patch"
|
|
||||||
When call validate_input_python "php-composer" "php" "8.4.1"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts PHP 7.4"
|
|
||||||
When call validate_input_python "php-composer" "php" "7.4"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts PHP 8.0"
|
|
||||||
When call validate_input_python "php-composer" "php" "8.0"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts PHP 8.1"
|
|
||||||
When call validate_input_python "php-composer" "php" "8.1"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects PHP version too old"
|
|
||||||
When call validate_input_python "php-composer" "php" "5.5"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects invalid version format"
|
|
||||||
When call validate_input_python "php-composer" "php" "php8.4"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects version with command injection"
|
|
||||||
When call validate_input_python "php-composer" "php" "8.4; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects empty version"
|
|
||||||
When call validate_input_python "php-composer" "php" ""
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating extensions input"
|
|
||||||
It "accepts valid PHP extensions"
|
|
||||||
When call validate_input_python "php-composer" "extensions" "mbstring, xml, zip"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts single extension"
|
|
||||||
When call validate_input_python "php-composer" "extensions" "mbstring"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts extensions without spaces"
|
|
||||||
When call validate_input_python "php-composer" "extensions" "mbstring,xml,zip"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts extensions with underscores"
|
|
||||||
When call validate_input_python "php-composer" "extensions" "pdo_mysql, gd_jpeg"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects extensions with special characters"
|
|
||||||
When call validate_input_python "php-composer" "extensions" "mbstring@xml"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects extensions with command injection"
|
|
||||||
When call validate_input_python "php-composer" "extensions" "mbstring; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects empty extensions"
|
|
||||||
When call validate_input_python "php-composer" "extensions" ""
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating tools input"
|
|
||||||
It "accepts valid Composer tools"
|
|
||||||
When call validate_input_python "php-composer" "tools" "composer:v2"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts multiple tools"
|
|
||||||
When call validate_input_python "php-composer" "tools" "composer:v2, phpunit:^9.0"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts tools with version constraints"
|
|
||||||
When call validate_input_python "php-composer" "tools" "phpcs, phpstan:1.10"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts tools with stability flags (@ allowed)"
|
|
||||||
When call validate_input_python "php-composer" "tools" "dev-master@dev"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts tools with version and stability flag"
|
|
||||||
When call validate_input_python "php-composer" "tools" "monolog/monolog@dev"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects tools with backticks"
|
|
||||||
When call validate_input_python "php-composer" "tools" "composer\`whoami\`"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects tools with command injection"
|
|
||||||
When call validate_input_python "php-composer" "tools" "composer; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects empty tools"
|
|
||||||
When call validate_input_python "php-composer" "tools" ""
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating composer-version input"
|
|
||||||
It "accepts composer version 1"
|
|
||||||
When call validate_input_python "php-composer" "composer-version" "1"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts composer version 2"
|
|
||||||
When call validate_input_python "php-composer" "composer-version" "2"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects invalid composer version"
|
|
||||||
When call validate_input_python "php-composer" "composer-version" "3"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects non-numeric composer version"
|
|
||||||
When call validate_input_python "php-composer" "composer-version" "latest"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects empty composer version"
|
|
||||||
When call validate_input_python "php-composer" "composer-version" ""
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating stability input"
|
|
||||||
It "accepts stable"
|
|
||||||
When call validate_input_python "php-composer" "stability" "stable"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts RC"
|
|
||||||
When call validate_input_python "php-composer" "stability" "RC"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts beta"
|
|
||||||
When call validate_input_python "php-composer" "stability" "beta"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts alpha"
|
|
||||||
When call validate_input_python "php-composer" "stability" "alpha"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts dev"
|
|
||||||
When call validate_input_python "php-composer" "stability" "dev"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects invalid stability"
|
|
||||||
When call validate_input_python "php-composer" "stability" "unstable"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects stability with injection"
|
|
||||||
When call validate_input_python "php-composer" "stability" "stable; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating cache-directories input"
|
|
||||||
It "accepts valid cache directory"
|
|
||||||
When call validate_input_python "php-composer" "cache-directories" "vendor/cache"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts multiple cache directories"
|
|
||||||
When call validate_input_python "php-composer" "cache-directories" "vendor/cache, .cache"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts directories with underscores and hyphens"
|
|
||||||
When call validate_input_python "php-composer" "cache-directories" "cache_dir, cache-dir"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects path traversal"
|
|
||||||
When call validate_input_python "php-composer" "cache-directories" "../malicious"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects absolute paths"
|
|
||||||
When call validate_input_python "php-composer" "cache-directories" "/etc/passwd"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects directories with command injection"
|
|
||||||
When call validate_input_python "php-composer" "cache-directories" "cache; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects empty cache directories"
|
|
||||||
When call validate_input_python "php-composer" "cache-directories" ""
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating token input"
|
|
||||||
It "accepts GitHub token expression"
|
|
||||||
When call validate_input_python "php-composer" "token" "\${{ github.token }}"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts GitHub fine-grained token"
|
|
||||||
When call validate_input_python "php-composer" "token" "ghp_abcdefghijklmnopqrstuvwxyz1234567890"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts GitHub app token"
|
|
||||||
When call validate_input_python "php-composer" "token" "ghs_abcdefghijklmnopqrstuvwxyz1234567890"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects invalid token format"
|
|
||||||
When call validate_input_python "php-composer" "token" "invalid-token"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects empty token"
|
|
||||||
When call validate_input_python "php-composer" "token" ""
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating max-retries input"
|
|
||||||
It "accepts valid retry count"
|
|
||||||
When call validate_input_python "php-composer" "max-retries" "3"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts minimum retries"
|
|
||||||
When call validate_input_python "php-composer" "max-retries" "1"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts maximum retries"
|
|
||||||
When call validate_input_python "php-composer" "max-retries" "10"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects zero retries"
|
|
||||||
When call validate_input_python "php-composer" "max-retries" "0"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects too many retries"
|
|
||||||
When call validate_input_python "php-composer" "max-retries" "11"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects non-numeric retries"
|
|
||||||
When call validate_input_python "php-composer" "max-retries" "many"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects negative retries"
|
|
||||||
When call validate_input_python "php-composer" "max-retries" "-1"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating args input"
|
|
||||||
It "accepts valid Composer arguments"
|
|
||||||
When call validate_input_python "php-composer" "args" "--no-progress --prefer-dist"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects empty args"
|
|
||||||
When call validate_input_python "php-composer" "args" ""
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects args with command injection"
|
|
||||||
When call validate_input_python "php-composer" "args" "--no-progress; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects args with pipe"
|
|
||||||
When call validate_input_python "php-composer" "args" "--no-progress | cat /etc/passwd"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when checking action.yml structure"
|
|
||||||
It "has valid YAML syntax"
|
|
||||||
When call validate_action_yml_quiet "$ACTION_FILE"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "has correct action name"
|
|
||||||
name=$(get_action_name "$ACTION_FILE")
|
|
||||||
When call echo "$name"
|
|
||||||
The output should equal "Run Composer Install"
|
|
||||||
End
|
|
||||||
|
|
||||||
It "defines expected inputs"
|
|
||||||
When call get_action_inputs "$ACTION_FILE"
|
|
||||||
The output should include "php"
|
|
||||||
The output should include "extensions"
|
|
||||||
The output should include "tools"
|
|
||||||
The output should include "args"
|
|
||||||
The output should include "composer-version"
|
|
||||||
The output should include "stability"
|
|
||||||
The output should include "cache-directories"
|
|
||||||
The output should include "token"
|
|
||||||
The output should include "max-retries"
|
|
||||||
End
|
|
||||||
|
|
||||||
It "defines expected outputs"
|
|
||||||
When call get_action_outputs "$ACTION_FILE"
|
|
||||||
The output should include "lock"
|
|
||||||
The output should include "php-version"
|
|
||||||
The output should include "composer-version"
|
|
||||||
The output should include "cache-hit"
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when testing input requirements"
|
|
||||||
It "requires php input"
|
|
||||||
When call uv run "_tests/shared/validation_core.py" --property "$ACTION_FILE" "php" "required"
|
|
||||||
The output should equal "required"
|
|
||||||
End
|
|
||||||
|
|
||||||
It "has extensions as optional input"
|
|
||||||
When call uv run "_tests/shared/validation_core.py" --property "$ACTION_FILE" "extensions" "optional"
|
|
||||||
The output should equal "optional"
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when testing security validations"
|
|
||||||
It "validates against path traversal in cache directories"
|
|
||||||
When call validate_input_python "php-composer" "cache-directories" "../../etc/passwd"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates against shell metacharacters in tools"
|
|
||||||
When call validate_input_python "php-composer" "tools" "composer && rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates against backtick injection in args"
|
|
||||||
When call validate_input_python "php-composer" "args" "--no-progress \`whoami\`"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates against variable expansion in extensions"
|
|
||||||
When call validate_input_python "php-composer" "extensions" "mbstring,\${HOME}"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when testing PHP-specific validations"
|
|
||||||
It "validates PHP version boundaries"
|
|
||||||
When call validate_input_python "php-composer" "php" "10.0"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates Composer version enum restriction"
|
|
||||||
When call validate_input_python "php-composer" "composer-version" "0"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates stability enum values"
|
|
||||||
When call validate_input_python "php-composer" "stability" "experimental"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
End
|
|
||||||
@@ -1,280 +0,0 @@
|
|||||||
#!/usr/bin/env shellspec
|
|
||||||
# Unit tests for php-laravel-phpunit action validation and logic
|
|
||||||
|
|
||||||
# Framework is automatically loaded via spec_helper.sh
|
|
||||||
|
|
||||||
Describe "php-laravel-phpunit action"
|
|
||||||
ACTION_DIR="php-laravel-phpunit"
|
|
||||||
ACTION_FILE="$ACTION_DIR/action.yml"
|
|
||||||
|
|
||||||
Context "when validating php-version input"
|
|
||||||
It "accepts latest"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version" "latest"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts valid PHP version"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version" "8.4"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts PHP version with patch"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version" "8.4.1"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts PHP 7.4"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version" "7.4"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts PHP 8.0"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version" "8.0"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects invalid version format"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version" "php8.4"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects version with command injection"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version" "8.4; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts empty version (uses default)"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version" ""
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating php-version-file input"
|
|
||||||
It "accepts valid PHP version file"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version-file" ".php-version"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts custom version file"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version-file" "custom-php-version"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts version file with path"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version-file" "config/.php-version"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects path traversal in version file"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version-file" "../../../etc/passwd"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects absolute path in version file"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version-file" "/etc/passwd"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects version file with command injection"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version-file" ".php-version; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts empty version file"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version-file" ""
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating extensions input"
|
|
||||||
It "accepts valid PHP extensions"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" "mbstring, intl, json"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts single extension"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" "mbstring"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts extensions without spaces"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" "mbstring,intl,json"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts extensions with underscores"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" "pdo_sqlite, pdo_mysql"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts extensions with numbers"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" "sqlite3, gd2"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects extensions with special characters"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" "mbstring@intl"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects extensions with command injection"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" "mbstring; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts empty extensions"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" ""
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating coverage input"
|
|
||||||
It "accepts none coverage"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "coverage" "none"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts xdebug coverage"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "coverage" "xdebug"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts pcov coverage"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "coverage" "pcov"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts xdebug3 coverage"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "coverage" "xdebug3"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects invalid coverage driver"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "coverage" "invalid"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects coverage with command injection"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "coverage" "none; rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts empty coverage"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "coverage" ""
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when validating token input"
|
|
||||||
It "accepts GitHub token expression"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "token" "\${{ github.token }}"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts GitHub fine-grained token"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "token" "ghp_abcdefghijklmnopqrstuvwxyz1234567890"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts GitHub app token"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "token" "ghs_abcdefghijklmnopqrstuvwxyz1234567890"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "rejects invalid token format"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "token" "invalid-token"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "accepts empty token"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "token" ""
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when checking action.yml structure"
|
|
||||||
It "has valid YAML syntax"
|
|
||||||
When call validate_action_yml_quiet "$ACTION_FILE"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
|
|
||||||
It "has correct action name"
|
|
||||||
name=$(get_action_name "$ACTION_FILE")
|
|
||||||
When call echo "$name"
|
|
||||||
The output should equal "Laravel Setup and Composer test"
|
|
||||||
End
|
|
||||||
|
|
||||||
It "defines expected inputs"
|
|
||||||
When call get_action_inputs "$ACTION_FILE"
|
|
||||||
The output should include "php-version"
|
|
||||||
The output should include "php-version-file"
|
|
||||||
The output should include "extensions"
|
|
||||||
The output should include "coverage"
|
|
||||||
The output should include "token"
|
|
||||||
End
|
|
||||||
|
|
||||||
It "defines expected outputs"
|
|
||||||
When call get_action_outputs "$ACTION_FILE"
|
|
||||||
The output should include "php-version"
|
|
||||||
The output should include "php-version-file"
|
|
||||||
The output should include "extensions"
|
|
||||||
The output should include "coverage"
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when testing input requirements"
|
|
||||||
It "has all inputs as optional"
|
|
||||||
When call uv run "_tests/shared/validation_core.py" --property "$ACTION_FILE" "" "all_optional"
|
|
||||||
The output should equal "none"
|
|
||||||
End
|
|
||||||
|
|
||||||
It "has correct default php-version"
|
|
||||||
When call uv run "_tests/shared/validation_core.py" --property "$ACTION_FILE" "php-version" "default"
|
|
||||||
The output should equal "latest"
|
|
||||||
End
|
|
||||||
|
|
||||||
It "has correct default php-version-file"
|
|
||||||
When call uv run "_tests/shared/validation_core.py" --property "$ACTION_FILE" "php-version-file" "default"
|
|
||||||
The output should equal ".php-version"
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when testing security validations"
|
|
||||||
It "validates against path traversal in php-version-file"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version-file" "../../etc/passwd"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates against shell metacharacters in extensions"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" "mbstring && rm -rf /"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates against backtick injection in coverage"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "coverage" "none\`whoami\`"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates against variable expansion in php-version"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version" "8.4\${HOME}"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
End
|
|
||||||
|
|
||||||
Context "when testing Laravel-specific validations"
|
|
||||||
It "validates coverage driver enum values"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "coverage" "invalid-driver"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates php-version-file path safety"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "php-version-file" "/etc/shadow"
|
|
||||||
The status should be failure
|
|
||||||
End
|
|
||||||
|
|
||||||
It "validates extensions format for Laravel requirements"
|
|
||||||
When call validate_input_python "php-laravel-phpunit" "extensions" "mbstring, intl, json, pdo_sqlite, sqlite3"
|
|
||||||
The status should be success
|
|
||||||
End
|
|
||||||
End
|
|
||||||
End
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for action-versioning action
|
# Validation rules for action-versioning action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: action-versioning
|
action: action-versioning
|
||||||
description: Automatically update SHA-pinned action references to match latest version tags
|
description: Automatically update SHA-pinned action references to match latest version tags
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for ansible-lint-fix action
|
# Validation rules for ansible-lint-fix action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: ansible-lint-fix
|
action: ansible-lint-fix
|
||||||
description: Lints and fixes Ansible playbooks, commits changes, and uploads SARIF report.
|
description: Lints and fixes Ansible playbooks, commits changes, and uploads SARIF report.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for biome-lint action
|
# Validation rules for biome-lint action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: biome-lint
|
action: biome-lint
|
||||||
description: Run Biome linter in check or fix mode
|
description: Run Biome linter in check or fix mode
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for codeql-analysis action
|
# Validation rules for codeql-analysis action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: codeql-analysis
|
action: codeql-analysis
|
||||||
description: Run CodeQL security analysis for a single language with configurable query suites
|
description: Run CodeQL security analysis for a single language with configurable query suites
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for compress-images action
|
# Validation rules for compress-images action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: compress-images
|
action: compress-images
|
||||||
description: Compress images on demand (workflow_dispatch), and at 11pm every Sunday (schedule).
|
description: Compress images on demand (workflow_dispatch), and at 11pm every Sunday (schedule).
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for csharp-build action
|
# Validation rules for csharp-build action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: csharp-build
|
action: csharp-build
|
||||||
description: Builds and tests C# projects.
|
description: Builds and tests C# projects.
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ Runs linters like StyleCop or dotnet-format for C# code style checks.
|
|||||||
|
|
||||||
### Inputs
|
### Inputs
|
||||||
|
|
||||||
| name | description | required | default |
|
| name | description | required | default |
|
||||||
| --- | --- | --- | --- |
|
|------------------|----------------------------------------|----------|---------|
|
||||||
| `dotnet-version` | <p>Version of .NET SDK to use.</p> | `false` | `""` |
|
| `dotnet-version` | <p>Version of .NET SDK to use.</p> | `false` | `""` |
|
||||||
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
||||||
|
|
||||||
### Outputs
|
### Outputs
|
||||||
|
|
||||||
| name | description |
|
| name | description |
|
||||||
| --- | --- |
|
|------------------|----------------------------------------------|
|
||||||
| `lint_status` | <p>Overall lint status (success/failure)</p> |
|
| `lint_status` | <p>Overall lint status (success/failure)</p> |
|
||||||
| `errors_count` | <p>Number of formatting errors found</p> |
|
| `errors_count` | <p>Number of formatting errors found</p> |
|
||||||
| `warnings_count` | <p>Number of formatting warnings found</p> |
|
| `warnings_count` | <p>Number of formatting warnings found</p> |
|
||||||
|
|
||||||
### Runs
|
### Runs
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for csharp-lint-check action
|
# Validation rules for csharp-lint-check action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: csharp-lint-check
|
action: csharp-lint-check
|
||||||
description: Runs linters like StyleCop or dotnet-format for C# code style checks.
|
description: Runs linters like StyleCop or dotnet-format for C# code style checks.
|
||||||
|
|||||||
@@ -8,19 +8,19 @@ Publishes a C# project to GitHub Packages.
|
|||||||
|
|
||||||
### Inputs
|
### Inputs
|
||||||
|
|
||||||
| name | description | required | default |
|
| name | description | required | default |
|
||||||
| --- | --- | --- | --- |
|
|------------------|----------------------------------------------------|----------|-------------|
|
||||||
| `dotnet-version` | <p>Version of .NET SDK to use.</p> | `false` | `""` |
|
| `dotnet-version` | <p>Version of .NET SDK to use.</p> | `false` | `""` |
|
||||||
| `namespace` | <p>GitHub namespace for the package.</p> | `true` | `ivuorinen` |
|
| `namespace` | <p>GitHub namespace for the package.</p> | `true` | `ivuorinen` |
|
||||||
| `token` | <p>GitHub token with package write permissions</p> | `false` | `""` |
|
| `token` | <p>GitHub token with package write permissions</p> | `false` | `""` |
|
||||||
|
|
||||||
### Outputs
|
### Outputs
|
||||||
|
|
||||||
| name | description |
|
| name | description |
|
||||||
| --- | --- |
|
|-------------------|-------------------------------------------------|
|
||||||
| `publish_status` | <p>Overall publish status (success/failure)</p> |
|
| `publish_status` | <p>Overall publish status (success/failure)</p> |
|
||||||
| `package_version` | <p>Version of the published package</p> |
|
| `package_version` | <p>Version of the published package</p> |
|
||||||
| `package_url` | <p>URL of the published package</p> |
|
| `package_url` | <p>URL of the published package</p> |
|
||||||
|
|
||||||
### Runs
|
### Runs
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for csharp-publish action
|
# Validation rules for csharp-publish action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: csharp-publish
|
action: csharp-publish
|
||||||
description: Publishes a C# project to GitHub Packages.
|
description: Publishes a C# project to GitHub Packages.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for docker-build action
|
# Validation rules for docker-build action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: docker-build
|
action: docker-build
|
||||||
description: Builds a Docker image for multiple architectures with enhanced security and reliability.
|
description: Builds a Docker image for multiple architectures with enhanced security and reliability.
|
||||||
|
|||||||
@@ -8,28 +8,28 @@ Simple wrapper to publish Docker images to GitHub Packages and/or Docker Hub
|
|||||||
|
|
||||||
### Inputs
|
### Inputs
|
||||||
|
|
||||||
| name | description | required | default |
|
| name | description | required | default |
|
||||||
| --- | --- | --- | --- |
|
|----------------------|-------------------------------------------------------------------|----------|---------------------------|
|
||||||
| `registry` | <p>Registry to publish to (dockerhub, github, or both)</p> | `false` | `both` |
|
| `registry` | <p>Registry to publish to (dockerhub, github, or both)</p> | `false` | `both` |
|
||||||
| `image-name` | <p>Docker image name (defaults to repository name)</p> | `false` | `""` |
|
| `image-name` | <p>Docker image name (defaults to repository name)</p> | `false` | `""` |
|
||||||
| `tags` | <p>Comma-separated list of tags (e.g., latest,v1.0.0)</p> | `false` | `latest` |
|
| `tags` | <p>Comma-separated list of tags (e.g., latest,v1.0.0)</p> | `false` | `latest` |
|
||||||
| `platforms` | <p>Platforms to build for (comma-separated)</p> | `false` | `linux/amd64,linux/arm64` |
|
| `platforms` | <p>Platforms to build for (comma-separated)</p> | `false` | `linux/amd64,linux/arm64` |
|
||||||
| `context` | <p>Build context path</p> | `false` | `.` |
|
| `context` | <p>Build context path</p> | `false` | `.` |
|
||||||
| `dockerfile` | <p>Path to Dockerfile</p> | `false` | `Dockerfile` |
|
| `dockerfile` | <p>Path to Dockerfile</p> | `false` | `Dockerfile` |
|
||||||
| `build-args` | <p>Build arguments (newline-separated KEY=VALUE pairs)</p> | `false` | `""` |
|
| `build-args` | <p>Build arguments (newline-separated KEY=VALUE pairs)</p> | `false` | `""` |
|
||||||
| `push` | <p>Whether to push the image</p> | `false` | `true` |
|
| `push` | <p>Whether to push the image</p> | `false` | `true` |
|
||||||
| `token` | <p>GitHub token for authentication (for GitHub registry)</p> | `false` | `""` |
|
| `token` | <p>GitHub token for authentication (for GitHub registry)</p> | `false` | `""` |
|
||||||
| `dockerhub-username` | <p>Docker Hub username (required if publishing to Docker Hub)</p> | `false` | `""` |
|
| `dockerhub-username` | <p>Docker Hub username (required if publishing to Docker Hub)</p> | `false` | `""` |
|
||||||
| `dockerhub-token` | <p>Docker Hub token (required if publishing to Docker Hub)</p> | `false` | `""` |
|
| `dockerhub-token` | <p>Docker Hub token (required if publishing to Docker Hub)</p> | `false` | `""` |
|
||||||
|
|
||||||
### Outputs
|
### Outputs
|
||||||
|
|
||||||
| name | description |
|
| name | description |
|
||||||
| --- | --- |
|
|--------------|--------------------------------------|
|
||||||
| `image-name` | <p>Full image name with registry</p> |
|
| `image-name` | <p>Full image name with registry</p> |
|
||||||
| `tags` | <p>Tags that were published</p> |
|
| `tags` | <p>Tags that were published</p> |
|
||||||
| `digest` | <p>Image digest</p> |
|
| `digest` | <p>Image digest</p> |
|
||||||
| `metadata` | <p>Build metadata</p> |
|
| `metadata` | <p>Build metadata</p> |
|
||||||
|
|
||||||
### Runs
|
### Runs
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for docker-publish action
|
# Validation rules for docker-publish action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: docker-publish
|
action: docker-publish
|
||||||
description: Simple wrapper to publish Docker images to GitHub Packages and/or Docker Hub
|
description: Simple wrapper to publish Docker images to GitHub Packages and/or Docker Hub
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for eslint-lint action
|
# Validation rules for eslint-lint action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: eslint-lint
|
action: eslint-lint
|
||||||
description: Run ESLint in check or fix mode with advanced configuration and reporting
|
description: Run ESLint in check or fix mode with advanced configuration and reporting
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ const CATEGORIES = {
|
|||||||
|
|
||||||
// Testing & Quality
|
// Testing & Quality
|
||||||
'php-tests': 'Testing',
|
'php-tests': 'Testing',
|
||||||
'php-laravel-phpunit': 'Testing',
|
|
||||||
'php-composer': 'Testing',
|
|
||||||
|
|
||||||
// Build & Package
|
// Build & Package
|
||||||
'csharp-build': 'Build',
|
'csharp-build': 'Build',
|
||||||
@@ -55,9 +53,7 @@ const CATEGORIES = {
|
|||||||
// Language support mappings
|
// Language support mappings
|
||||||
const LANGUAGE_SUPPORT = {
|
const LANGUAGE_SUPPORT = {
|
||||||
'language-version-detect': ['PHP', 'Python', 'Go', '.NET', 'Node.js'],
|
'language-version-detect': ['PHP', 'Python', 'Go', '.NET', 'Node.js'],
|
||||||
'php-tests': ['PHP'],
|
'php-tests': ['PHP', 'Laravel'],
|
||||||
'php-laravel-phpunit': ['PHP', 'Laravel'],
|
|
||||||
'php-composer': ['PHP'],
|
|
||||||
'python-lint-fix': ['Python'],
|
'python-lint-fix': ['Python'],
|
||||||
'go-lint': ['Go'],
|
'go-lint': ['Go'],
|
||||||
'go-build': ['Go'],
|
'go-build': ['Go'],
|
||||||
|
|||||||
@@ -8,22 +8,22 @@ Builds the Go project.
|
|||||||
|
|
||||||
### Inputs
|
### Inputs
|
||||||
|
|
||||||
| name | description | required | default |
|
| name | description | required | default |
|
||||||
| --- | --- | --- | --- |
|
|---------------|------------------------------------------------------------------------|----------|---------|
|
||||||
| `go-version` | <p>Go version to use.</p> | `false` | `""` |
|
| `go-version` | <p>Go version to use.</p> | `false` | `""` |
|
||||||
| `destination` | <p>Build destination directory.</p> | `false` | `./bin` |
|
| `destination` | <p>Build destination directory.</p> | `false` | `./bin` |
|
||||||
| `max-retries` | <p>Maximum number of retry attempts for go mod download operations</p> | `false` | `3` |
|
| `max-retries` | <p>Maximum number of retry attempts for go mod download operations</p> | `false` | `3` |
|
||||||
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
||||||
|
|
||||||
### Outputs
|
### Outputs
|
||||||
|
|
||||||
| name | description |
|
| name | description |
|
||||||
| --- | --- |
|
|-----------------|--------------------------------------------------------|
|
||||||
| `build_status` | <p>Build completion status (success/failure)</p> |
|
| `build_status` | <p>Build completion status (success/failure)</p> |
|
||||||
| `test_status` | <p>Test execution status (success/failure/skipped)</p> |
|
| `test_status` | <p>Test execution status (success/failure/skipped)</p> |
|
||||||
| `go_version` | <p>Version of Go used</p> |
|
| `go_version` | <p>Version of Go used</p> |
|
||||||
| `binary_path` | <p>Path to built binaries</p> |
|
| `binary_path` | <p>Path to built binaries</p> |
|
||||||
| `coverage_path` | <p>Path to coverage report</p> |
|
| `coverage_path` | <p>Path to coverage report</p> |
|
||||||
|
|
||||||
### Runs
|
### Runs
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for go-build action
|
# Validation rules for go-build action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: go-build
|
action: go-build
|
||||||
description: Builds the Go project.
|
description: Builds the Go project.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for go-lint action
|
# Validation rules for go-lint action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: go-lint
|
action: go-lint
|
||||||
description: Run golangci-lint with advanced configuration, caching, and reporting
|
description: Run golangci-lint with advanced configuration, caching, and reporting
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for language-version-detect action
|
# Validation rules for language-version-detect action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,9 +8,11 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: language-version-detect
|
action: language-version-detect
|
||||||
description: 'DEPRECATED: This action is deprecated. Inline version detection directly in your actions instead. Detects language version from project configuration files with support for PHP, Python, Go, and .NET.'
|
description: 'DEPRECATED: This action is deprecated. Inline version detection directly in your actions instead. Detects language
|
||||||
|
version from project configuration files with support for PHP, Python, Go, and .NET.'
|
||||||
generator_version: 1.0.0
|
generator_version: 1.0.0
|
||||||
required_inputs:
|
required_inputs:
|
||||||
- language
|
- language
|
||||||
|
|||||||
@@ -8,21 +8,21 @@ Publishes the package to the NPM registry with configurable scope and registry U
|
|||||||
|
|
||||||
### Inputs
|
### Inputs
|
||||||
|
|
||||||
| name | description | required | default |
|
| name | description | required | default |
|
||||||
| --- | --- | --- | --- |
|
|-------------------|----------------------------------------|----------|----------------------------------------|
|
||||||
| `npm_token` | <p>NPM token.</p> | `true` | `""` |
|
| `npm_token` | <p>NPM token.</p> | `true` | `""` |
|
||||||
| `registry-url` | <p>Registry URL for publishing.</p> | `false` | `https://registry.npmjs.org/` |
|
| `registry-url` | <p>Registry URL for publishing.</p> | `false` | `https://registry.npmjs.org/` |
|
||||||
| `scope` | <p>Package scope to use.</p> | `false` | `@ivuorinen` |
|
| `scope` | <p>Package scope to use.</p> | `false` | `@ivuorinen` |
|
||||||
| `package-version` | <p>The version to publish.</p> | `false` | `${{ github.event.release.tag_name }}` |
|
| `package-version` | <p>The version to publish.</p> | `false` | `${{ github.event.release.tag_name }}` |
|
||||||
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
||||||
|
|
||||||
### Outputs
|
### Outputs
|
||||||
|
|
||||||
| name | description |
|
| name | description |
|
||||||
| --- | --- |
|
|-------------------|-------------------------------------|
|
||||||
| `registry-url` | <p>Registry URL for publishing.</p> |
|
| `registry-url` | <p>Registry URL for publishing.</p> |
|
||||||
| `scope` | <p>Package scope to use.</p> |
|
| `scope` | <p>Package scope to use.</p> |
|
||||||
| `package-version` | <p>The version to publish.</p> |
|
| `package-version` | <p>The version to publish.</p> |
|
||||||
|
|
||||||
### Runs
|
### Runs
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for npm-publish action
|
# Validation rules for npm-publish action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: npm-publish
|
action: npm-publish
|
||||||
description: Publishes the package to the NPM registry with configurable scope and registry URL.
|
description: Publishes the package to the NPM registry with configurable scope and registry URL.
|
||||||
|
|||||||
@@ -1,228 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Custom validator for php-composer action."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Add validate-inputs directory to path to import validators
|
|
||||||
validate_inputs_path = Path(__file__).parent.parent / "validate-inputs"
|
|
||||||
sys.path.insert(0, str(validate_inputs_path))
|
|
||||||
|
|
||||||
from validators.base import BaseValidator
|
|
||||||
from validators.boolean import BooleanValidator
|
|
||||||
from validators.file import FileValidator
|
|
||||||
from validators.numeric import NumericValidator
|
|
||||||
from validators.security import SecurityValidator
|
|
||||||
from validators.token import TokenValidator
|
|
||||||
from validators.version import VersionValidator
|
|
||||||
|
|
||||||
|
|
||||||
class CustomValidator(BaseValidator):
|
|
||||||
"""Custom validator for php-composer action."""
|
|
||||||
|
|
||||||
def __init__(self, action_type: str = "php-composer") -> None:
|
|
||||||
"""Initialize php-composer validator."""
|
|
||||||
super().__init__(action_type)
|
|
||||||
self.boolean_validator = BooleanValidator()
|
|
||||||
self.file_validator = FileValidator()
|
|
||||||
self.numeric_validator = NumericValidator()
|
|
||||||
self.security_validator = SecurityValidator()
|
|
||||||
self.token_validator = TokenValidator()
|
|
||||||
self.version_validator = VersionValidator()
|
|
||||||
|
|
||||||
def validate_inputs(self, inputs: dict[str, str]) -> bool:
|
|
||||||
"""Validate php-composer action inputs."""
|
|
||||||
valid = True
|
|
||||||
|
|
||||||
# Validate required input: php
|
|
||||||
if "php" not in inputs or not inputs["php"]:
|
|
||||||
self.add_error("Input 'php' is required")
|
|
||||||
valid = False
|
|
||||||
elif inputs["php"]:
|
|
||||||
php_version = inputs["php"]
|
|
||||||
if not self.is_github_expression(php_version):
|
|
||||||
# PHP version validation with minimum version check
|
|
||||||
result = self.version_validator.validate_php_version(php_version, "php")
|
|
||||||
for error in self.version_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.version_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
elif php_version and not php_version.startswith("$"):
|
|
||||||
# Additional check for minimum PHP version (7.0)
|
|
||||||
try:
|
|
||||||
parts = php_version.split(".")
|
|
||||||
major = int(parts[0])
|
|
||||||
minor = int(parts[1]) if len(parts) > 1 else 0
|
|
||||||
if major < 7 or (major == 7 and minor < 0):
|
|
||||||
self.add_error("PHP version must be 7.0 or higher")
|
|
||||||
valid = False
|
|
||||||
except (ValueError, IndexError):
|
|
||||||
pass # Already handled by validate_php_version
|
|
||||||
|
|
||||||
# Validate extensions (empty string is invalid)
|
|
||||||
if "extensions" in inputs:
|
|
||||||
extensions = inputs["extensions"]
|
|
||||||
if extensions == "":
|
|
||||||
self.add_error("Extensions cannot be empty string")
|
|
||||||
valid = False
|
|
||||||
elif extensions:
|
|
||||||
if not self.is_github_expression(extensions):
|
|
||||||
# Extensions should be comma-separated list (spaces allowed after commas)
|
|
||||||
if not re.match(r"^[a-zA-Z0-9_-]+(\s*,\s*[a-zA-Z0-9_-]+)*$", extensions):
|
|
||||||
self.add_error("Invalid extensions format: must be comma-separated list")
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Check for injection
|
|
||||||
result = self.security_validator.validate_no_injection(extensions, "extensions")
|
|
||||||
for error in self.security_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.security_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate tools (empty string is invalid)
|
|
||||||
if "tools" in inputs:
|
|
||||||
tools = inputs["tools"]
|
|
||||||
if tools == "":
|
|
||||||
self.add_error("Tools cannot be empty string")
|
|
||||||
valid = False
|
|
||||||
elif tools:
|
|
||||||
if not self.is_github_expression(tools):
|
|
||||||
# Tools should be comma-separated list with optional version constraints
|
|
||||||
# Allow: letters, numbers, dash, underscore, colon, dot, caret, tilde, @, /
|
|
||||||
# @ symbol allows Composer stability flags like dev-master@dev
|
|
||||||
# / allows vendor/package format like monolog/monolog@dev
|
|
||||||
# spaces after commas
|
|
||||||
if not re.match(
|
|
||||||
r"^[a-zA-Z0-9_:.@/\-^~]+(\s*,\s*[a-zA-Z0-9_:.@/\-^~]+)*$", tools
|
|
||||||
):
|
|
||||||
self.add_error("Invalid tools format: must be comma-separated list")
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Check for injection
|
|
||||||
result = self.security_validator.validate_no_injection(tools, "tools")
|
|
||||||
for error in self.security_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.security_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate composer-version (empty string is invalid, only 1 or 2 accepted)
|
|
||||||
if "composer-version" in inputs:
|
|
||||||
composer_version = inputs["composer-version"]
|
|
||||||
if composer_version == "":
|
|
||||||
self.add_error("Composer version cannot be empty string")
|
|
||||||
valid = False
|
|
||||||
elif composer_version:
|
|
||||||
if not self.is_github_expression(composer_version) and composer_version not in [
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
]:
|
|
||||||
self.add_error("Composer version must be 1 or 2")
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate stability
|
|
||||||
if inputs.get("stability"):
|
|
||||||
stability = inputs["stability"]
|
|
||||||
if not self.is_github_expression(stability):
|
|
||||||
valid_stabilities = ["stable", "RC", "beta", "alpha", "dev", "snapshot"]
|
|
||||||
if stability not in valid_stabilities:
|
|
||||||
self.add_error(
|
|
||||||
f"Invalid stability: {stability}. "
|
|
||||||
f"Must be one of: {', '.join(valid_stabilities)}"
|
|
||||||
)
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Check for injection
|
|
||||||
result = self.security_validator.validate_no_injection(stability, "stability")
|
|
||||||
for error in self.security_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.security_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate cache-directories (empty string is invalid, accepts directory paths)
|
|
||||||
if "cache-directories" in inputs:
|
|
||||||
cache_dirs = inputs["cache-directories"]
|
|
||||||
if cache_dirs == "":
|
|
||||||
self.add_error("Cache directories cannot be empty string")
|
|
||||||
valid = False
|
|
||||||
elif cache_dirs:
|
|
||||||
if not self.is_github_expression(cache_dirs):
|
|
||||||
# Should be comma-separated list of directories
|
|
||||||
dirs = cache_dirs.split(",")
|
|
||||||
for dir_path in dirs:
|
|
||||||
dir_path = dir_path.strip()
|
|
||||||
if dir_path:
|
|
||||||
result = self.file_validator.validate_file_path(
|
|
||||||
dir_path, "cache-directories"
|
|
||||||
)
|
|
||||||
for error in self.file_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.file_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate token (empty string is invalid)
|
|
||||||
if "token" in inputs:
|
|
||||||
token = inputs["token"]
|
|
||||||
if token == "":
|
|
||||||
self.add_error("Token cannot be empty string")
|
|
||||||
valid = False
|
|
||||||
elif token:
|
|
||||||
result = self.token_validator.validate_github_token(token, required=False)
|
|
||||||
for error in self.token_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.token_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate max-retries
|
|
||||||
if inputs.get("max-retries"):
|
|
||||||
result = self.numeric_validator.validate_numeric_range(
|
|
||||||
inputs["max-retries"], min_val=1, max_val=10, name="max-retries"
|
|
||||||
)
|
|
||||||
for error in self.numeric_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.numeric_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate args (empty string is invalid, checks for injection if provided)
|
|
||||||
if "args" in inputs:
|
|
||||||
args = inputs["args"]
|
|
||||||
if args == "":
|
|
||||||
self.add_error("Args cannot be empty string")
|
|
||||||
valid = False
|
|
||||||
elif args:
|
|
||||||
if not self.is_github_expression(args):
|
|
||||||
# Check for command injection patterns
|
|
||||||
result = self.security_validator.validate_no_injection(args, "args")
|
|
||||||
for error in self.security_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.security_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
return valid
|
|
||||||
|
|
||||||
def get_required_inputs(self) -> list[str]:
|
|
||||||
"""Get list of required inputs."""
|
|
||||||
return ["php"]
|
|
||||||
|
|
||||||
def get_validation_rules(self) -> dict:
|
|
||||||
"""Get validation rules."""
|
|
||||||
rules_path = Path(__file__).parent / "rules.yml"
|
|
||||||
return self.load_rules(rules_path)
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
# ivuorinen/actions/php-composer
|
|
||||||
|
|
||||||
## Run Composer Install
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
Runs Composer install on a repository with advanced caching and configuration.
|
|
||||||
|
|
||||||
### Inputs
|
|
||||||
|
|
||||||
| name | description | required | default |
|
|
||||||
|--------------------|---------------------------------------------------------------|----------|-----------------------------------------------------|
|
|
||||||
| `php` | <p>PHP Version to use.</p> | `true` | `8.4` |
|
|
||||||
| `extensions` | <p>Comma-separated list of PHP extensions to install</p> | `false` | `mbstring, xml, zip, curl, json` |
|
|
||||||
| `tools` | <p>Comma-separated list of Composer tools to install</p> | `false` | `composer:v2` |
|
|
||||||
| `args` | <p>Arguments to pass to Composer.</p> | `false` | `--no-progress --prefer-dist --optimize-autoloader` |
|
|
||||||
| `composer-version` | <p>Composer version to use (1 or 2)</p> | `false` | `2` |
|
|
||||||
| `stability` | <p>Minimum stability (stable, RC, beta, alpha, dev)</p> | `false` | `stable` |
|
|
||||||
| `token` | <p>GitHub token for private repository access</p> | `false` | `""` |
|
|
||||||
| `max-retries` | <p>Maximum number of retry attempts for Composer commands</p> | `false` | `3` |
|
|
||||||
|
|
||||||
### Outputs
|
|
||||||
|
|
||||||
| name | description |
|
|
||||||
|--------------------|-------------------------------------------------|
|
|
||||||
| `lock` | <p>composer.lock or composer.json file hash</p> |
|
|
||||||
| `php-version` | <p>Installed PHP version</p> |
|
|
||||||
| `composer-version` | <p>Installed Composer version</p> |
|
|
||||||
| `cache-hit` | <p>Indicates if there was a cache hit</p> |
|
|
||||||
|
|
||||||
### Runs
|
|
||||||
|
|
||||||
This action is a `composite` action.
|
|
||||||
|
|
||||||
### Usage
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- uses: ivuorinen/actions/php-composer@main
|
|
||||||
with:
|
|
||||||
php:
|
|
||||||
# PHP Version to use.
|
|
||||||
#
|
|
||||||
# Required: true
|
|
||||||
# Default: 8.4
|
|
||||||
|
|
||||||
extensions:
|
|
||||||
# Comma-separated list of PHP extensions to install
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: mbstring, xml, zip, curl, json
|
|
||||||
|
|
||||||
tools:
|
|
||||||
# Comma-separated list of Composer tools to install
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: composer:v2
|
|
||||||
|
|
||||||
args:
|
|
||||||
# Arguments to pass to Composer.
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: --no-progress --prefer-dist --optimize-autoloader
|
|
||||||
|
|
||||||
composer-version:
|
|
||||||
# Composer version to use (1 or 2)
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: 2
|
|
||||||
|
|
||||||
stability:
|
|
||||||
# Minimum stability (stable, RC, beta, alpha, dev)
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: stable
|
|
||||||
|
|
||||||
token:
|
|
||||||
# GitHub token for private repository access
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: ""
|
|
||||||
|
|
||||||
max-retries:
|
|
||||||
# Maximum number of retry attempts for Composer commands
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: 3
|
|
||||||
```
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
# 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'
|
|
||||||
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@71cf2267d89c5cb81562390fa70a37fa40b1305e # v6-beta
|
|
||||||
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:
|
|
||||||
COMPOSER_LOCK_HASH: ${{ hashFiles('**/composer.lock') }}
|
|
||||||
COMPOSER_JSON_HASH: ${{ hashFiles('**/composer.json') }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
- 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: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
vendor
|
|
||||||
~/.composer/cache
|
|
||||||
key: ${{ runner.os }}-php-${{ inputs.php }}-composer-${{ inputs.composer-version }}-composer-${{ hashFiles('composer.lock', 'composer.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-php-${{ inputs.php }}-composer-${{ inputs.composer-version }}-composer-
|
|
||||||
${{ 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: step-security/retry@e1d59ce1f574b32f0915e3a8df055cfe9f99be5d # v3
|
|
||||||
with:
|
|
||||||
timeout_minutes: 10
|
|
||||||
max_attempts: ${{ inputs.max-retries }}
|
|
||||||
retry_wait_seconds: 30
|
|
||||||
command: composer install ${{ inputs.args }}
|
|
||||||
|
|
||||||
- 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
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
# Validation rules for php-composer action
|
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
|
||||||
# Schema version: 1.0
|
|
||||||
# Coverage: 50% (4/8 inputs)
|
|
||||||
#
|
|
||||||
# This file defines validation rules for the php-composer GitHub Action.
|
|
||||||
# Rules are automatically applied by validate-inputs action when this
|
|
||||||
# action is used.
|
|
||||||
#
|
|
||||||
schema_version: '1.0'
|
|
||||||
action: php-composer
|
|
||||||
description: Runs Composer install on a repository with advanced caching and configuration.
|
|
||||||
generator_version: 1.0.0
|
|
||||||
required_inputs:
|
|
||||||
- php
|
|
||||||
optional_inputs:
|
|
||||||
- args
|
|
||||||
- composer-version
|
|
||||||
- extensions
|
|
||||||
- max-retries
|
|
||||||
- stability
|
|
||||||
- token
|
|
||||||
- tools
|
|
||||||
conventions:
|
|
||||||
composer-version: semantic_version
|
|
||||||
max-retries: numeric_range_1_10
|
|
||||||
php: semantic_version
|
|
||||||
token: github_token
|
|
||||||
overrides: {}
|
|
||||||
statistics:
|
|
||||||
total_inputs: 8
|
|
||||||
validated_inputs: 4
|
|
||||||
skipped_inputs: 0
|
|
||||||
coverage_percentage: 50
|
|
||||||
validation_coverage: 50
|
|
||||||
auto_detected: true
|
|
||||||
manual_review_required: true
|
|
||||||
quality_indicators:
|
|
||||||
has_required_inputs: true
|
|
||||||
has_token_validation: true
|
|
||||||
has_version_validation: true
|
|
||||||
has_file_validation: false
|
|
||||||
has_security_validation: true
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Custom validator for php-laravel-phpunit action."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Add validate-inputs directory to path to import validators
|
|
||||||
validate_inputs_path = Path(__file__).parent.parent / "validate-inputs"
|
|
||||||
sys.path.insert(0, str(validate_inputs_path))
|
|
||||||
|
|
||||||
from validators.base import BaseValidator
|
|
||||||
from validators.file import FileValidator
|
|
||||||
from validators.token import TokenValidator
|
|
||||||
from validators.version import VersionValidator
|
|
||||||
|
|
||||||
|
|
||||||
class CustomValidator(BaseValidator):
|
|
||||||
"""Custom validator for php-laravel-phpunit action."""
|
|
||||||
|
|
||||||
def __init__(self, action_type: str = "php-laravel-phpunit") -> None:
|
|
||||||
"""Initialize php-laravel-phpunit validator."""
|
|
||||||
super().__init__(action_type)
|
|
||||||
self.version_validator = VersionValidator()
|
|
||||||
self.file_validator = FileValidator()
|
|
||||||
self.token_validator = TokenValidator()
|
|
||||||
|
|
||||||
def validate_inputs(self, inputs: dict[str, str]) -> bool:
|
|
||||||
"""Validate php-laravel-phpunit action inputs."""
|
|
||||||
valid = True
|
|
||||||
|
|
||||||
# Validate php-version if provided and not empty
|
|
||||||
if inputs.get("php-version"):
|
|
||||||
value = inputs["php-version"]
|
|
||||||
# Special case: "latest" is allowed
|
|
||||||
if value != "latest":
|
|
||||||
result = self.version_validator.validate_php_version(value, "php-version")
|
|
||||||
|
|
||||||
# Propagate errors from the version validator
|
|
||||||
for error in self.version_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
|
|
||||||
self.version_validator.clear_errors()
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
# Validate php-version-file if provided
|
|
||||||
if inputs.get("php-version-file"):
|
|
||||||
result = self.file_validator.validate_file_path(
|
|
||||||
inputs["php-version-file"], "php-version-file"
|
|
||||||
)
|
|
||||||
for error in self.file_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.file_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate extensions if provided
|
|
||||||
if inputs.get("extensions"):
|
|
||||||
value = inputs["extensions"]
|
|
||||||
# Basic validation for PHP extensions list
|
|
||||||
if ";" in value and not value.startswith("${{"):
|
|
||||||
self.add_error(f"Invalid extensions format in extensions: {value}")
|
|
||||||
valid = False
|
|
||||||
# Check for dangerous characters and invalid format (@ is not valid in PHP extensions)
|
|
||||||
if any(char in value for char in ["`", "$", "&", "|", ">", "<", "@", "\n", "\r"]):
|
|
||||||
self.add_error(f"Invalid characters in extensions: {value}")
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate coverage if provided
|
|
||||||
if inputs.get("coverage"):
|
|
||||||
value = inputs["coverage"]
|
|
||||||
# Valid coverage drivers for PHPUnit
|
|
||||||
valid_coverage = ["none", "xdebug", "xdebug3", "pcov"]
|
|
||||||
if value not in valid_coverage:
|
|
||||||
# Check for command injection attempts
|
|
||||||
if any(char in value for char in [";", "`", "$", "&", "|", ">", "<", "\n", "\r"]):
|
|
||||||
self.add_error(f"Command injection attempt in coverage: {value}")
|
|
||||||
valid = False
|
|
||||||
elif value and not value.startswith("${{"):
|
|
||||||
self.add_error(
|
|
||||||
f"Invalid coverage driver: {value}. "
|
|
||||||
f"Must be one of: {', '.join(valid_coverage)}"
|
|
||||||
)
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
# Validate token if provided
|
|
||||||
if inputs.get("token"):
|
|
||||||
result = self.token_validator.validate_github_token(inputs["token"])
|
|
||||||
for error in self.token_validator.errors:
|
|
||||||
if error not in self.errors:
|
|
||||||
self.add_error(error)
|
|
||||||
self.token_validator.clear_errors()
|
|
||||||
if not result:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
return valid
|
|
||||||
|
|
||||||
def get_required_inputs(self) -> list[str]:
|
|
||||||
"""Get list of required inputs."""
|
|
||||||
return []
|
|
||||||
|
|
||||||
def get_validation_rules(self) -> dict:
|
|
||||||
"""Get validation rules."""
|
|
||||||
return {
|
|
||||||
"php-version": {
|
|
||||||
"type": "php_version",
|
|
||||||
"required": False,
|
|
||||||
"description": "PHP version to use",
|
|
||||||
},
|
|
||||||
"php-version-file": {
|
|
||||||
"type": "file",
|
|
||||||
"required": False,
|
|
||||||
"description": "PHP version file",
|
|
||||||
},
|
|
||||||
"extensions": {
|
|
||||||
"type": "string",
|
|
||||||
"required": False,
|
|
||||||
"description": "PHP extensions to install",
|
|
||||||
},
|
|
||||||
"coverage": {
|
|
||||||
"type": "string",
|
|
||||||
"required": False,
|
|
||||||
"description": "Coverage driver",
|
|
||||||
},
|
|
||||||
"token": {
|
|
||||||
"type": "token",
|
|
||||||
"required": False,
|
|
||||||
"description": "GitHub token",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
# ivuorinen/actions/php-laravel-phpunit
|
|
||||||
|
|
||||||
## Laravel Setup and Composer test
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
Setup PHP, install dependencies, generate key, create database and run composer test
|
|
||||||
|
|
||||||
### Inputs
|
|
||||||
|
|
||||||
| name | description | required | default |
|
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| `php-version` | <p>PHP Version to use, see https://github.com/marketplace/actions/setup-php-action#php-version-optional</p> | `false` | `latest` |
|
|
||||||
| `php-version-file` | <p>PHP Version file to use, see https://github.com/marketplace/actions/setup-php-action#php-version-file-optional</p> | `false` | `.php-version` |
|
|
||||||
| `extensions` | <p>PHP extensions to install, see https://github.com/marketplace/actions/setup-php-action#extensions-optional</p> | `false` | `mbstring, intl, json, pdo_sqlite, sqlite3` |
|
|
||||||
| `coverage` | <p>Specify code-coverage driver, see https://github.com/marketplace/actions/setup-php-action#coverage-optional</p> | `false` | `none` |
|
|
||||||
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
|
||||||
|
|
||||||
### Outputs
|
|
||||||
|
|
||||||
| name | description |
|
|
||||||
| --- | --- |
|
|
||||||
| `php-version` | <p>The PHP version that was setup</p> |
|
|
||||||
| `php-version-file` | <p>The PHP version file that was used</p> |
|
|
||||||
| `extensions` | <p>The PHP extensions that were installed</p> |
|
|
||||||
| `coverage` | <p>The code-coverage driver that was setup</p> |
|
|
||||||
|
|
||||||
### Runs
|
|
||||||
|
|
||||||
This action is a `composite` action.
|
|
||||||
|
|
||||||
### Usage
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- uses: ivuorinen/actions/php-laravel-phpunit@main
|
|
||||||
with:
|
|
||||||
php-version:
|
|
||||||
# PHP Version to use, see https://github.com/marketplace/actions/setup-php-action#php-version-optional
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: latest
|
|
||||||
|
|
||||||
php-version-file:
|
|
||||||
# PHP Version file to use, see https://github.com/marketplace/actions/setup-php-action#php-version-file-optional
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: .php-version
|
|
||||||
|
|
||||||
extensions:
|
|
||||||
# PHP extensions to install, see https://github.com/marketplace/actions/setup-php-action#extensions-optional
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: mbstring, intl, json, pdo_sqlite, sqlite3
|
|
||||||
|
|
||||||
coverage:
|
|
||||||
# Specify code-coverage driver, see https://github.com/marketplace/actions/setup-php-action#coverage-optional
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: none
|
|
||||||
|
|
||||||
token:
|
|
||||||
# GitHub token for authentication
|
|
||||||
#
|
|
||||||
# Required: false
|
|
||||||
# Default: ""
|
|
||||||
```
|
|
||||||
@@ -1,243 +0,0 @@
|
|||||||
# yaml-language-server: $schema=https://json.schemastore.org/github-action.json
|
|
||||||
# permissions:
|
|
||||||
# - contents: read # Required for checking out repository
|
|
||||||
---
|
|
||||||
name: Laravel Setup and Composer test
|
|
||||||
description: 'Setup PHP, install dependencies, generate key, create database and run composer test'
|
|
||||||
author: 'Ismo Vuorinen'
|
|
||||||
|
|
||||||
branding:
|
|
||||||
icon: 'terminal'
|
|
||||||
color: 'blue'
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
php-version:
|
|
||||||
description: 'PHP Version to use, see https://github.com/marketplace/actions/setup-php-action#php-version-optional'
|
|
||||||
required: false
|
|
||||||
default: 'latest'
|
|
||||||
php-version-file:
|
|
||||||
description: 'PHP Version file to use, see https://github.com/marketplace/actions/setup-php-action#php-version-file-optional'
|
|
||||||
required: false
|
|
||||||
default: '.php-version'
|
|
||||||
extensions:
|
|
||||||
description: 'PHP extensions to install, see https://github.com/marketplace/actions/setup-php-action#extensions-optional'
|
|
||||||
required: false
|
|
||||||
default: 'mbstring, intl, json, pdo_sqlite, sqlite3'
|
|
||||||
coverage:
|
|
||||||
description: 'Specify code-coverage driver, see https://github.com/marketplace/actions/setup-php-action#coverage-optional'
|
|
||||||
required: false
|
|
||||||
default: 'none'
|
|
||||||
token:
|
|
||||||
description: 'GitHub token for authentication'
|
|
||||||
required: false
|
|
||||||
default: ''
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
php-version:
|
|
||||||
description: 'The PHP version that was setup'
|
|
||||||
value: ${{ steps.setup-php.outputs.php-version }}
|
|
||||||
php-version-file:
|
|
||||||
description: 'The PHP version file that was used'
|
|
||||||
value: ${{ steps.setup-php.outputs.php-version-file }}
|
|
||||||
extensions:
|
|
||||||
description: 'The PHP extensions that were installed'
|
|
||||||
value: ${{ steps.setup-php.outputs.extensions }}
|
|
||||||
coverage:
|
|
||||||
description: 'The code-coverage driver that was setup'
|
|
||||||
value: ${{ steps.setup-php.outputs.coverage }}
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: composite
|
|
||||||
steps:
|
|
||||||
- name: Mask Secrets
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ inputs.token }}
|
|
||||||
run: |
|
|
||||||
if [ -n "$GITHUB_TOKEN" ]; then
|
|
||||||
echo "::add-mask::$GITHUB_TOKEN"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Detect PHP Version
|
|
||||||
id: php-version
|
|
||||||
shell: sh
|
|
||||||
env:
|
|
||||||
DEFAULT_VERSION: "${{ inputs.php-version || '8.4' }}"
|
|
||||||
run: |
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Function to validate version format
|
|
||||||
validate_version() {
|
|
||||||
version=$1
|
|
||||||
case "$version" in
|
|
||||||
[0-9]*.[0-9]* | [0-9]*.[0-9]*.[0-9]*)
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to clean version string
|
|
||||||
clean_version() {
|
|
||||||
printf '%s' "$1" | sed 's/^[vV]//' | tr -d ' \n\r'
|
|
||||||
}
|
|
||||||
|
|
||||||
detected_version=""
|
|
||||||
|
|
||||||
# Parse .tool-versions file
|
|
||||||
if [ -f .tool-versions ]; then
|
|
||||||
echo "Checking .tool-versions for php..." >&2
|
|
||||||
version=$(awk '/^php[[:space:]]/ {gsub(/#.*/, ""); print $2; exit}' .tool-versions 2>/dev/null || echo "")
|
|
||||||
if [ -n "$version" ]; then
|
|
||||||
version=$(clean_version "$version")
|
|
||||||
if validate_version "$version"; then
|
|
||||||
echo "Found PHP version in .tool-versions: $version" >&2
|
|
||||||
detected_version="$version"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse Dockerfile
|
|
||||||
if [ -z "$detected_version" ] && [ -f Dockerfile ]; then
|
|
||||||
echo "Checking Dockerfile for php..." >&2
|
|
||||||
version=$(grep -iF "FROM" Dockerfile | grep -F "php:" | head -1 | \
|
|
||||||
sed -n -E "s/.*php:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "")
|
|
||||||
if [ -n "$version" ]; then
|
|
||||||
version=$(clean_version "$version")
|
|
||||||
if validate_version "$version"; then
|
|
||||||
echo "Found PHP version in Dockerfile: $version" >&2
|
|
||||||
detected_version="$version"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse devcontainer.json
|
|
||||||
if [ -z "$detected_version" ] && [ -f .devcontainer/devcontainer.json ]; then
|
|
||||||
echo "Checking devcontainer.json for php..." >&2
|
|
||||||
if command -v jq >/dev/null 2>&1; then
|
|
||||||
version=$(jq -r '.image // empty' .devcontainer/devcontainer.json 2>/dev/null | sed -n -E "s/.*php:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "")
|
|
||||||
if [ -n "$version" ]; then
|
|
||||||
version=$(clean_version "$version")
|
|
||||||
if validate_version "$version"; then
|
|
||||||
echo "Found PHP version in devcontainer: $version" >&2
|
|
||||||
detected_version="$version"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "jq not found; skipping devcontainer.json parsing" >&2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse .php-version file
|
|
||||||
if [ -z "$detected_version" ] && [ -f .php-version ]; then
|
|
||||||
echo "Checking .php-version..." >&2
|
|
||||||
version=$(tr -d '\r' < .php-version | head -1)
|
|
||||||
if [ -n "$version" ]; then
|
|
||||||
version=$(clean_version "$version")
|
|
||||||
if validate_version "$version"; then
|
|
||||||
echo "Found PHP version in .php-version: $version" >&2
|
|
||||||
detected_version="$version"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse composer.json
|
|
||||||
if [ -z "$detected_version" ] && [ -f composer.json ]; then
|
|
||||||
echo "Checking composer.json..." >&2
|
|
||||||
if command -v jq >/dev/null 2>&1; then
|
|
||||||
version=$(jq -r '.require.php // empty' composer.json 2>/dev/null | sed -n 's/[^0-9]*\\([0-9]\\+\\.[0-9]\\+\\(\\.[0-9]\\+\\)\\?\\).*/\\1/p')
|
|
||||||
if [ -z "$version" ]; then
|
|
||||||
version=$(jq -r '.config.platform.php // empty' composer.json 2>/dev/null | sed -n 's/[^0-9]*\\([0-9]\\+\\.[0-9]\\+\\(\\.[0-9]\\+\\)\\?\\).*/\\1/p')
|
|
||||||
fi
|
|
||||||
if [ -n "$version" ]; then
|
|
||||||
version=$(clean_version "$version")
|
|
||||||
if validate_version "$version"; then
|
|
||||||
echo "Found PHP version in composer.json: $version" >&2
|
|
||||||
detected_version="$version"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "jq not found; skipping composer.json parsing" >&2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use default version if nothing detected
|
|
||||||
if [ -z "$detected_version" ]; then
|
|
||||||
detected_version="$DEFAULT_VERSION"
|
|
||||||
echo "Using default PHP version: $detected_version" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set output
|
|
||||||
printf 'detected-version=%s\n' "$detected_version" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "Final detected PHP version: $detected_version" >&2
|
|
||||||
|
|
||||||
- uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # 2.35.5
|
|
||||||
id: setup-php
|
|
||||||
with:
|
|
||||||
php-version: ${{ steps.php-version.outputs.detected-version }}
|
|
||||||
extensions: ${{ inputs.extensions }}
|
|
||||||
coverage: ${{ inputs.coverage }}
|
|
||||||
|
|
||||||
- uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e # v6-beta
|
|
||||||
with:
|
|
||||||
token: ${{ inputs.token != '' && inputs.token || github.token }}
|
|
||||||
|
|
||||||
- name: 'Check file existence'
|
|
||||||
id: check_files
|
|
||||||
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0
|
|
||||||
with:
|
|
||||||
files: 'package.json, artisan'
|
|
||||||
|
|
||||||
- name: Copy .env
|
|
||||||
if: steps.check_files.outputs.files_exists == 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
php -r "file_exists('.env') || copy('.env.example', '.env');"
|
|
||||||
|
|
||||||
- name: Install Dependencies
|
|
||||||
if: steps.check_files.outputs.files_exists == 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
|
||||||
|
|
||||||
- name: Generate key
|
|
||||||
if: steps.check_files.outputs.files_exists == 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
php artisan key:generate
|
|
||||||
|
|
||||||
- name: Directory Permissions
|
|
||||||
if: steps.check_files.outputs.files_exists == 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
chmod -R 777 storage bootstrap/cache
|
|
||||||
|
|
||||||
- name: Create Database
|
|
||||||
if: steps.check_files.outputs.files_exists == 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
mkdir -p database
|
|
||||||
touch database/database.sqlite
|
|
||||||
|
|
||||||
- name: Execute composer test (Unit and Feature tests)
|
|
||||||
if: steps.check_files.outputs.files_exists == 'true'
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
DB_CONNECTION: sqlite
|
|
||||||
DB_DATABASE: database/database.sqlite
|
|
||||||
run: |-
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
composer test
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# Validation rules for php-laravel-phpunit action
|
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
|
||||||
# Schema version: 1.0
|
|
||||||
# Coverage: 100% (5/5 inputs)
|
|
||||||
#
|
|
||||||
# This file defines validation rules for the php-laravel-phpunit GitHub Action.
|
|
||||||
# Rules are automatically applied by validate-inputs action when this
|
|
||||||
# action is used.
|
|
||||||
#
|
|
||||||
schema_version: '1.0'
|
|
||||||
action: php-laravel-phpunit
|
|
||||||
description: Setup PHP, install dependencies, generate key, create database and run composer test
|
|
||||||
generator_version: 1.0.0
|
|
||||||
required_inputs: []
|
|
||||||
optional_inputs:
|
|
||||||
- coverage
|
|
||||||
- extensions
|
|
||||||
- php-version
|
|
||||||
- php-version-file
|
|
||||||
- token
|
|
||||||
conventions:
|
|
||||||
coverage: coverage_driver
|
|
||||||
extensions: php_extensions
|
|
||||||
php-version: semantic_version
|
|
||||||
php-version-file: file_path
|
|
||||||
token: github_token
|
|
||||||
overrides: {}
|
|
||||||
statistics:
|
|
||||||
total_inputs: 5
|
|
||||||
validated_inputs: 5
|
|
||||||
skipped_inputs: 0
|
|
||||||
coverage_percentage: 100
|
|
||||||
validation_coverage: 100
|
|
||||||
auto_detected: true
|
|
||||||
manual_review_required: false
|
|
||||||
quality_indicators:
|
|
||||||
has_required_inputs: false
|
|
||||||
has_token_validation: true
|
|
||||||
has_version_validation: true
|
|
||||||
has_file_validation: true
|
|
||||||
has_security_validation: true
|
|
||||||
@@ -4,24 +4,33 @@
|
|||||||
|
|
||||||
### Description
|
### Description
|
||||||
|
|
||||||
Run PHPUnit tests on the repository
|
Run PHPUnit tests with optional Laravel setup and Composer dependency management
|
||||||
|
|
||||||
### Inputs
|
### Inputs
|
||||||
|
|
||||||
| name | description | required | default |
|
| name | description | required | default |
|
||||||
| --- | --- | --- | --- |
|
|-----------------|----------------------------------------------------------------------------------------------------------------|----------|-----------------------------------------------------|
|
||||||
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
| `framework` | <p>Framework detection mode (auto=detect Laravel via artisan, laravel=force Laravel, generic=no framework)</p> | `false` | `auto` |
|
||||||
| `username` | <p>GitHub username for commits</p> | `false` | `github-actions` |
|
| `php-version` | <p>PHP Version to use (latest, 8.4, 8.3, etc.)</p> | `false` | `latest` |
|
||||||
| `email` | <p>GitHub email for commits</p> | `false` | `github-actions@github.com` |
|
| `extensions` | <p>PHP extensions to install (comma-separated)</p> | `false` | `mbstring, intl, json, pdo_sqlite, sqlite3` |
|
||||||
|
| `coverage` | <p>Code-coverage driver (none, xdebug, pcov)</p> | `false` | `none` |
|
||||||
|
| `composer-args` | <p>Arguments to pass to Composer install</p> | `false` | `--no-progress --prefer-dist --optimize-autoloader` |
|
||||||
|
| `max-retries` | <p>Maximum number of retry attempts for Composer commands</p> | `false` | `3` |
|
||||||
|
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
||||||
|
| `username` | <p>GitHub username for commits</p> | `false` | `github-actions` |
|
||||||
|
| `email` | <p>GitHub email for commits</p> | `false` | `github-actions@github.com` |
|
||||||
|
|
||||||
### Outputs
|
### Outputs
|
||||||
|
|
||||||
| name | description |
|
| name | description |
|
||||||
| --- | --- |
|
|--------------------|------------------------------------------------|
|
||||||
| `test_status` | <p>Test execution status (success/failure/skipped)</p> |
|
| `framework` | <p>Detected framework (laravel or generic)</p> |
|
||||||
| `tests_run` | <p>Number of tests executed</p> |
|
| `php-version` | <p>The PHP version that was setup</p> |
|
||||||
| `tests_passed` | <p>Number of tests passed</p> |
|
| `composer-version` | <p>Installed Composer version</p> |
|
||||||
| `coverage_path` | <p>Path to coverage report</p> |
|
| `cache-hit` | <p>Indicates if there was a cache hit</p> |
|
||||||
|
| `test-status` | <p>Test execution status (success/failure)</p> |
|
||||||
|
| `tests-run` | <p>Number of tests executed</p> |
|
||||||
|
| `tests-passed` | <p>Number of tests passed</p> |
|
||||||
|
|
||||||
### Runs
|
### Runs
|
||||||
|
|
||||||
@@ -32,6 +41,42 @@ This action is a `composite` action.
|
|||||||
```yaml
|
```yaml
|
||||||
- uses: ivuorinen/actions/php-tests@main
|
- uses: ivuorinen/actions/php-tests@main
|
||||||
with:
|
with:
|
||||||
|
framework:
|
||||||
|
# Framework detection mode (auto=detect Laravel via artisan, laravel=force Laravel, generic=no framework)
|
||||||
|
#
|
||||||
|
# Required: false
|
||||||
|
# Default: auto
|
||||||
|
|
||||||
|
php-version:
|
||||||
|
# PHP Version to use (latest, 8.4, 8.3, etc.)
|
||||||
|
#
|
||||||
|
# Required: false
|
||||||
|
# Default: latest
|
||||||
|
|
||||||
|
extensions:
|
||||||
|
# PHP extensions to install (comma-separated)
|
||||||
|
#
|
||||||
|
# Required: false
|
||||||
|
# Default: mbstring, intl, json, pdo_sqlite, sqlite3
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
# Code-coverage driver (none, xdebug, pcov)
|
||||||
|
#
|
||||||
|
# Required: false
|
||||||
|
# Default: none
|
||||||
|
|
||||||
|
composer-args:
|
||||||
|
# Arguments to pass to Composer install
|
||||||
|
#
|
||||||
|
# Required: false
|
||||||
|
# Default: --no-progress --prefer-dist --optimize-autoloader
|
||||||
|
|
||||||
|
max-retries:
|
||||||
|
# Maximum number of retry attempts for Composer commands
|
||||||
|
#
|
||||||
|
# Required: false
|
||||||
|
# Default: 3
|
||||||
|
|
||||||
token:
|
token:
|
||||||
# GitHub token for authentication
|
# GitHub token for authentication
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# - contents: read # Required for checking out repository
|
# - contents: read # Required for checking out repository
|
||||||
---
|
---
|
||||||
name: PHP Tests
|
name: PHP Tests
|
||||||
description: Run PHPUnit tests on the repository
|
description: Run PHPUnit tests with optional Laravel setup and Composer dependency management
|
||||||
author: Ismo Vuorinen
|
author: Ismo Vuorinen
|
||||||
|
|
||||||
branding:
|
branding:
|
||||||
@@ -11,6 +11,30 @@ branding:
|
|||||||
color: green
|
color: green
|
||||||
|
|
||||||
inputs:
|
inputs:
|
||||||
|
framework:
|
||||||
|
description: 'Framework detection mode (auto=detect Laravel via artisan, laravel=force Laravel, generic=no framework)'
|
||||||
|
required: false
|
||||||
|
default: 'auto'
|
||||||
|
php-version:
|
||||||
|
description: 'PHP Version to use (latest, 8.4, 8.3, etc.)'
|
||||||
|
required: false
|
||||||
|
default: 'latest'
|
||||||
|
extensions:
|
||||||
|
description: 'PHP extensions to install (comma-separated)'
|
||||||
|
required: false
|
||||||
|
default: 'mbstring, intl, json, pdo_sqlite, sqlite3'
|
||||||
|
coverage:
|
||||||
|
description: 'Code-coverage driver (none, xdebug, pcov)'
|
||||||
|
required: false
|
||||||
|
default: 'none'
|
||||||
|
composer-args:
|
||||||
|
description: 'Arguments to pass to Composer install'
|
||||||
|
required: false
|
||||||
|
default: '--no-progress --prefer-dist --optimize-autoloader'
|
||||||
|
max-retries:
|
||||||
|
description: 'Maximum number of retry attempts for Composer commands'
|
||||||
|
required: false
|
||||||
|
default: '3'
|
||||||
token:
|
token:
|
||||||
description: 'GitHub token for authentication'
|
description: 'GitHub token for authentication'
|
||||||
required: false
|
required: false
|
||||||
@@ -25,56 +49,103 @@ inputs:
|
|||||||
default: 'github-actions@github.com'
|
default: 'github-actions@github.com'
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
test_status:
|
framework:
|
||||||
description: 'Test execution status (success/failure/skipped)'
|
description: 'Detected framework (laravel or generic)'
|
||||||
|
value: ${{ steps.detect-framework.outputs.framework }}
|
||||||
|
php-version:
|
||||||
|
description: 'The PHP version that was setup'
|
||||||
|
value: ${{ steps.setup-php.outputs.php-version }}
|
||||||
|
composer-version:
|
||||||
|
description: 'Installed Composer version'
|
||||||
|
value: ${{ steps.composer-config.outputs.version }}
|
||||||
|
cache-hit:
|
||||||
|
description: 'Indicates if there was a cache hit'
|
||||||
|
value: ${{ steps.composer-cache.outputs.cache-hit }}
|
||||||
|
test-status:
|
||||||
|
description: 'Test execution status (success/failure)'
|
||||||
value: ${{ steps.test.outputs.status }}
|
value: ${{ steps.test.outputs.status }}
|
||||||
tests_run:
|
tests-run:
|
||||||
description: 'Number of tests executed'
|
description: 'Number of tests executed'
|
||||||
value: ${{ steps.test.outputs.tests_run }}
|
value: ${{ steps.test.outputs.tests_run }}
|
||||||
tests_passed:
|
tests-passed:
|
||||||
description: 'Number of tests passed'
|
description: 'Number of tests passed'
|
||||||
value: ${{ steps.test.outputs.tests_passed }}
|
value: ${{ steps.test.outputs.tests_passed }}
|
||||||
coverage_path:
|
|
||||||
description: 'Path to coverage report'
|
|
||||||
value: 'coverage.xml'
|
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
|
- name: Mask Secrets
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ inputs.token }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ -n "$GITHUB_TOKEN" ]; then
|
||||||
|
echo "::add-mask::$GITHUB_TOKEN"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Validate Inputs
|
- name: Validate Inputs
|
||||||
id: validate
|
id: validate
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ inputs.token }}
|
FRAMEWORK: ${{ inputs.framework }}
|
||||||
|
PHP_VERSION: ${{ inputs.php-version }}
|
||||||
|
COVERAGE: ${{ inputs.coverage }}
|
||||||
|
MAX_RETRIES: ${{ inputs.max-retries }}
|
||||||
EMAIL: ${{ inputs.email }}
|
EMAIL: ${{ inputs.email }}
|
||||||
USERNAME: ${{ inputs.username }}
|
USERNAME: ${{ inputs.username }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Validate GitHub token format (basic validation)
|
# Validate framework mode
|
||||||
if [[ -n "$GITHUB_TOKEN" ]]; then
|
case "$FRAMEWORK" in
|
||||||
# Skip validation for GitHub expressions (they'll be resolved at runtime)
|
auto|laravel|generic)
|
||||||
if ! [[ "$GITHUB_TOKEN" =~ ^gh[efpousr]_[a-zA-Z0-9]{36}$ ]] && ! [[ "$GITHUB_TOKEN" =~ ^\$\{\{ ]]; then
|
echo "Framework mode: $FRAMEWORK"
|
||||||
echo "::warning::GitHub token format may be invalid. Expected format: gh*_36characters"
|
;;
|
||||||
|
*)
|
||||||
|
echo "::error::Invalid framework: '$FRAMEWORK'. Must be 'auto', 'laravel', or 'generic'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Validate PHP version format
|
||||||
|
if [[ "$PHP_VERSION" != "latest" ]]; then
|
||||||
|
if ! [[ "$PHP_VERSION" =~ ^[0-9]+(\.[0-9]+)?(\.[0-9]+)?$ ]]; then
|
||||||
|
echo "::error::Invalid php-version format: '$PHP_VERSION'. Expected format: X.Y or X.Y.Z (e.g., 8.4, 8.3.0)"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Validate email format (basic check)
|
# Validate coverage driver
|
||||||
|
case "$COVERAGE" in
|
||||||
|
none|xdebug|pcov)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "::error::Invalid coverage driver: '$COVERAGE'. Must be 'none', 'xdebug', or 'pcov'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Validate max retries
|
||||||
|
if ! [[ "$MAX_RETRIES" =~ ^[0-9]+$ ]] || [ "$MAX_RETRIES" -le 0 ] || [ "$MAX_RETRIES" -gt 10 ]; then
|
||||||
|
echo "::error::Invalid max-retries: '$MAX_RETRIES'. Must be a positive integer between 1 and 10"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validate email format
|
||||||
if [[ "$EMAIL" != *"@"* ]] || [[ "$EMAIL" != *"."* ]]; then
|
if [[ "$EMAIL" != *"@"* ]] || [[ "$EMAIL" != *"."* ]]; then
|
||||||
echo "::error::Invalid email format: '$EMAIL'. Expected valid email address"
|
echo "::error::Invalid email format: '$EMAIL'. Expected valid email address"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Validate username format (prevent command injection)
|
# Validate username format
|
||||||
if [[ "$USERNAME" == *";"* ]] || [[ "$USERNAME" == *"&&"* ]] || [[ "$USERNAME" == *"|"* ]]; then
|
if [[ "$USERNAME" == *";"* ]] || [[ "$USERNAME" == *"&&"* ]] || [[ "$USERNAME" == *"|"* ]]; then
|
||||||
echo "::error::Invalid username: '$USERNAME'. Command injection patterns not allowed"
|
echo "::error::Invalid username: '$USERNAME'. Command injection patterns not allowed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Validate username length
|
if [ ${#USERNAME} -gt 39 ]; then
|
||||||
username="$USERNAME"
|
echo "::error::Username too long: ${#USERNAME} characters. GitHub usernames are max 39 characters"
|
||||||
if [ ${#username} -gt 39 ]; then
|
|
||||||
echo "::error::Username too long: ${#username} characters. GitHub usernames are max 39 characters"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -85,18 +156,289 @@ runs:
|
|||||||
with:
|
with:
|
||||||
token: ${{ inputs.token || github.token }}
|
token: ${{ inputs.token || github.token }}
|
||||||
|
|
||||||
- name: Composer Install
|
- name: Detect Framework
|
||||||
uses: ivuorinen/actions/php-composer@0fa9a68f07a1260b321f814202658a6089a43d42
|
id: detect-framework
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
FRAMEWORK_MODE: ${{ inputs.framework }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
framework="generic"
|
||||||
|
|
||||||
|
if [ "$FRAMEWORK_MODE" = "laravel" ]; then
|
||||||
|
framework="laravel"
|
||||||
|
echo "Framework mode forced to Laravel"
|
||||||
|
elif [ "$FRAMEWORK_MODE" = "auto" ]; then
|
||||||
|
if [ -f "artisan" ]; then
|
||||||
|
framework="laravel"
|
||||||
|
echo "Detected Laravel framework (artisan file found)"
|
||||||
|
else
|
||||||
|
echo "No Laravel framework detected (no artisan file)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Framework mode set to generic"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'framework=%s\n' "$framework" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Detect PHP Version
|
||||||
|
id: detect-php-version
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
DEFAULT_VERSION: ${{ inputs.php-version }}
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Function to validate version format
|
||||||
|
validate_version() {
|
||||||
|
version=$1
|
||||||
|
case "$version" in
|
||||||
|
[0-9]*.[0-9]* | [0-9]*.[0-9]*.[0-9]*)
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to clean version string
|
||||||
|
clean_version() {
|
||||||
|
printf '%s' "$1" | sed 's/^[vV]//' | tr -d ' \n\r'
|
||||||
|
}
|
||||||
|
|
||||||
|
detected_version=""
|
||||||
|
|
||||||
|
# Parse .tool-versions file
|
||||||
|
if [ -f .tool-versions ]; then
|
||||||
|
echo "Checking .tool-versions for php..." >&2
|
||||||
|
version=$(awk '/^php[[:space:]]/ {gsub(/#.*/, ""); print $2; exit}' .tool-versions 2>/dev/null || echo "")
|
||||||
|
if [ -n "$version" ]; then
|
||||||
|
version=$(clean_version "$version")
|
||||||
|
if validate_version "$version"; then
|
||||||
|
echo "Found PHP version in .tool-versions: $version" >&2
|
||||||
|
detected_version="$version"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse Dockerfile
|
||||||
|
if [ -z "$detected_version" ] && [ -f Dockerfile ]; then
|
||||||
|
echo "Checking Dockerfile for php..." >&2
|
||||||
|
version=$(grep -iF "FROM" Dockerfile | grep -F "php:" | head -1 | \
|
||||||
|
sed -n -E "s/.*php:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "")
|
||||||
|
if [ -n "$version" ]; then
|
||||||
|
version=$(clean_version "$version")
|
||||||
|
if validate_version "$version"; then
|
||||||
|
echo "Found PHP version in Dockerfile: $version" >&2
|
||||||
|
detected_version="$version"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse devcontainer.json
|
||||||
|
if [ -z "$detected_version" ] && [ -f .devcontainer/devcontainer.json ]; then
|
||||||
|
echo "Checking devcontainer.json for php..." >&2
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
version=$(jq -r '.image // empty' .devcontainer/devcontainer.json 2>/dev/null | sed -n -E "s/.*php:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "")
|
||||||
|
if [ -n "$version" ]; then
|
||||||
|
version=$(clean_version "$version")
|
||||||
|
if validate_version "$version"; then
|
||||||
|
echo "Found PHP version in devcontainer: $version" >&2
|
||||||
|
detected_version="$version"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "jq not found; skipping devcontainer.json parsing" >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse .php-version file
|
||||||
|
if [ -z "$detected_version" ] && [ -f .php-version ]; then
|
||||||
|
echo "Checking .php-version..." >&2
|
||||||
|
version=$(tr -d '\r' < .php-version | head -1)
|
||||||
|
if [ -n "$version" ]; then
|
||||||
|
version=$(clean_version "$version")
|
||||||
|
if validate_version "$version"; then
|
||||||
|
echo "Found PHP version in .php-version: $version" >&2
|
||||||
|
detected_version="$version"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse composer.json
|
||||||
|
if [ -z "$detected_version" ] && [ -f composer.json ]; then
|
||||||
|
echo "Checking composer.json..." >&2
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
version=$(jq -r '.require.php // empty' composer.json 2>/dev/null | sed -n 's/[^0-9]*\([0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*/\1/p')
|
||||||
|
if [ -z "$version" ]; then
|
||||||
|
version=$(jq -r '.config.platform.php // empty' composer.json 2>/dev/null | sed -n 's/[^0-9]*\([0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*/\1/p')
|
||||||
|
fi
|
||||||
|
if [ -n "$version" ]; then
|
||||||
|
version=$(clean_version "$version")
|
||||||
|
if validate_version "$version"; then
|
||||||
|
echo "Found PHP version in composer.json: $version" >&2
|
||||||
|
detected_version="$version"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "jq not found; skipping composer.json parsing" >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use default version if nothing detected
|
||||||
|
if [ -z "$detected_version" ]; then
|
||||||
|
detected_version="$DEFAULT_VERSION"
|
||||||
|
echo "Using default PHP version: $detected_version" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set output
|
||||||
|
printf 'detected-version=%s\n' "$detected_version" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Final detected PHP version: $detected_version" >&2
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
id: setup-php
|
||||||
|
uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # 2.35.5
|
||||||
|
with:
|
||||||
|
php-version: ${{ steps.detect-php-version.outputs.detected-version }}
|
||||||
|
extensions: ${{ inputs.extensions }}
|
||||||
|
coverage: ${{ inputs.coverage }}
|
||||||
|
ini-values: memory_limit=1G, max_execution_time=600
|
||||||
|
fail-fast: true
|
||||||
|
|
||||||
|
- name: Configure Composer
|
||||||
|
id: composer-config
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ inputs.token || github.token }}
|
||||||
|
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"
|
||||||
|
|
||||||
|
# Verify Composer installation
|
||||||
|
composer_full_version=$(composer --version | grep -oP 'Composer version \K[0-9]+\.[0-9]+\.[0-9]+' || echo "")
|
||||||
|
if [ -z "$composer_full_version" ]; then
|
||||||
|
echo "::error::Failed to detect Composer version"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Detected Composer version: $composer_full_version"
|
||||||
|
printf 'version=%s\n' "$composer_full_version" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
# Log Composer configuration
|
||||||
|
echo "Composer Configuration:"
|
||||||
|
composer config --list
|
||||||
|
|
||||||
|
- name: Cache Composer packages
|
||||||
|
id: composer-cache
|
||||||
|
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
vendor
|
||||||
|
~/.composer/cache
|
||||||
|
key: ${{ runner.os }}-php-${{ steps.setup-php.outputs.php-version }}-composer-${{ hashFiles('composer.lock', 'composer.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-php-${{ steps.setup-php.outputs.php-version }}-composer-
|
||||||
|
${{ runner.os }}-php-${{ steps.setup-php.outputs.php-version }}-
|
||||||
|
${{ runner.os }}-php-
|
||||||
|
|
||||||
|
- name: Clear Composer Cache Before Install
|
||||||
|
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 Composer Dependencies
|
||||||
|
uses: step-security/retry@e1d59ce1f574b32f0915e3a8df055cfe9f99be5d # v3
|
||||||
|
with:
|
||||||
|
timeout_minutes: 10
|
||||||
|
max_attempts: ${{ inputs.max-retries }}
|
||||||
|
retry_wait_seconds: 30
|
||||||
|
command: composer install ${{ inputs.composer-args }}
|
||||||
|
|
||||||
|
- name: Verify Composer 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
|
||||||
|
|
||||||
|
echo "✅ Composer installation verified"
|
||||||
|
|
||||||
|
- name: Laravel Setup - Copy .env
|
||||||
|
if: steps.detect-framework.outputs.framework == 'laravel'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
php -r "file_exists('.env') || copy('.env.example', '.env');"
|
||||||
|
echo "✅ Laravel .env file configured"
|
||||||
|
|
||||||
|
- name: Laravel Setup - Generate Key
|
||||||
|
if: steps.detect-framework.outputs.framework == 'laravel'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
php artisan key:generate
|
||||||
|
echo "✅ Laravel application key generated"
|
||||||
|
|
||||||
|
- name: Laravel Setup - Directory Permissions
|
||||||
|
if: steps.detect-framework.outputs.framework == 'laravel'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
chmod -R 777 storage bootstrap/cache
|
||||||
|
echo "✅ Laravel directory permissions configured"
|
||||||
|
|
||||||
|
- name: Laravel Setup - Create Database
|
||||||
|
if: steps.detect-framework.outputs.framework == 'laravel'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
mkdir -p database
|
||||||
|
touch database/database.sqlite
|
||||||
|
echo "✅ Laravel SQLite database created"
|
||||||
|
|
||||||
- name: Run PHPUnit Tests
|
- name: Run PHPUnit Tests
|
||||||
id: test
|
id: test
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |-
|
env:
|
||||||
|
IS_LARAVEL: ${{ steps.detect-framework.outputs.framework == 'laravel' }}
|
||||||
|
DB_CONNECTION: sqlite
|
||||||
|
DB_DATABASE: database/database.sqlite
|
||||||
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "Running PHPUnit tests..."
|
||||||
|
|
||||||
# Run PHPUnit and capture results
|
# Run PHPUnit and capture results
|
||||||
phpunit_exit_code=0
|
phpunit_exit_code=0
|
||||||
phpunit_output=$(vendor/bin/phpunit --verbose 2>&1) || phpunit_exit_code=$?
|
if [ "$IS_LARAVEL" = "true" ] && [ -f "composer.json" ] && grep -q '"test"' composer.json; then
|
||||||
|
echo "Running Laravel tests via composer test..."
|
||||||
|
phpunit_output=$(composer test 2>&1) || phpunit_exit_code=$?
|
||||||
|
elif [ -f "vendor/bin/phpunit" ]; then
|
||||||
|
echo "Running PHPUnit directly..."
|
||||||
|
phpunit_output=$(vendor/bin/phpunit --verbose 2>&1) || phpunit_exit_code=$?
|
||||||
|
else
|
||||||
|
echo "::error::PHPUnit not found. Ensure Composer dependencies are installed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "$phpunit_output"
|
echo "$phpunit_output"
|
||||||
|
|
||||||
@@ -107,15 +449,16 @@ runs:
|
|||||||
# Determine status
|
# Determine status
|
||||||
if [ $phpunit_exit_code -eq 0 ]; then
|
if [ $phpunit_exit_code -eq 0 ]; then
|
||||||
status="success"
|
status="success"
|
||||||
|
echo "✅ Tests passed: $tests_passed/$tests_run"
|
||||||
else
|
else
|
||||||
status="failure"
|
status="failure"
|
||||||
|
echo "❌ Tests failed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Output results
|
# Output results
|
||||||
echo "tests_run=$tests_run" >> $GITHUB_OUTPUT
|
printf 'tests_run=%s\n' "$tests_run" >> "$GITHUB_OUTPUT"
|
||||||
echo "tests_passed=$tests_passed" >> $GITHUB_OUTPUT
|
printf 'tests_passed=%s\n' "$tests_passed" >> "$GITHUB_OUTPUT"
|
||||||
echo "status=$status" >> $GITHUB_OUTPUT
|
printf 'status=%s\n' "$status" >> "$GITHUB_OUTPUT"
|
||||||
echo "coverage_path=coverage.xml" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
# Exit with original code to maintain test failure behavior
|
# Exit with original code to maintain test failure behavior
|
||||||
exit $phpunit_exit_code
|
exit $phpunit_exit_code
|
||||||
|
|||||||
@@ -1,37 +1,49 @@
|
|||||||
|
---
|
||||||
# Validation rules for php-tests action
|
# Validation rules for php-tests action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
# Coverage: 100% (3/3 inputs)
|
# Coverage: 78% (7/9 inputs)
|
||||||
#
|
#
|
||||||
# This file defines validation rules for the php-tests GitHub Action.
|
# This file defines validation rules for the php-tests GitHub Action.
|
||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: php-tests
|
action: php-tests
|
||||||
description: Run PHPUnit tests on the repository
|
description: Run PHPUnit tests with optional Laravel setup and Composer dependency management
|
||||||
generator_version: 1.0.0
|
generator_version: 1.0.0
|
||||||
required_inputs: []
|
required_inputs: []
|
||||||
optional_inputs:
|
optional_inputs:
|
||||||
|
- composer-args
|
||||||
|
- coverage
|
||||||
- email
|
- email
|
||||||
|
- extensions
|
||||||
|
- framework
|
||||||
|
- max-retries
|
||||||
|
- php-version
|
||||||
- token
|
- token
|
||||||
- username
|
- username
|
||||||
conventions:
|
conventions:
|
||||||
|
coverage: coverage_driver
|
||||||
email: email
|
email: email
|
||||||
|
framework: boolean
|
||||||
|
max-retries: numeric_range_1_10
|
||||||
|
php-version: semantic_version
|
||||||
token: github_token
|
token: github_token
|
||||||
username: username
|
username: username
|
||||||
overrides: {}
|
overrides: {}
|
||||||
statistics:
|
statistics:
|
||||||
total_inputs: 3
|
total_inputs: 9
|
||||||
validated_inputs: 3
|
validated_inputs: 7
|
||||||
skipped_inputs: 0
|
skipped_inputs: 0
|
||||||
coverage_percentage: 100
|
coverage_percentage: 78
|
||||||
validation_coverage: 100
|
validation_coverage: 78
|
||||||
auto_detected: true
|
auto_detected: true
|
||||||
manual_review_required: false
|
manual_review_required: true
|
||||||
quality_indicators:
|
quality_indicators:
|
||||||
has_required_inputs: false
|
has_required_inputs: false
|
||||||
has_token_validation: true
|
has_token_validation: true
|
||||||
has_version_validation: false
|
has_version_validation: true
|
||||||
has_file_validation: false
|
has_file_validation: false
|
||||||
has_security_validation: true
|
has_security_validation: true
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for pr-lint action
|
# Validation rules for pr-lint action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: pr-lint
|
action: pr-lint
|
||||||
description: Runs MegaLinter against pull requests
|
description: Runs MegaLinter against pull requests
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for pre-commit action
|
# Validation rules for pre-commit action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: pre-commit
|
action: pre-commit
|
||||||
description: Runs pre-commit on the repository and pushes the fixes back to the repository
|
description: Runs pre-commit on the repository and pushes the fixes back to the repository
|
||||||
|
|||||||
@@ -8,32 +8,32 @@ Run Prettier in check or fix mode with advanced configuration and reporting
|
|||||||
|
|
||||||
### Inputs
|
### Inputs
|
||||||
|
|
||||||
| name | description | required | default |
|
| name | description | required | default |
|
||||||
| --- | --- | --- | --- |
|
|---------------------|------------------------------------------------------------|----------|--------------------------------------------------|
|
||||||
| `mode` | <p>Mode to run (check or fix)</p> | `false` | `check` |
|
| `mode` | <p>Mode to run (check or fix)</p> | `false` | `check` |
|
||||||
| `working-directory` | <p>Directory containing files to format</p> | `false` | `.` |
|
| `working-directory` | <p>Directory containing files to format</p> | `false` | `.` |
|
||||||
| `prettier-version` | <p>Prettier version to use</p> | `false` | `latest` |
|
| `prettier-version` | <p>Prettier version to use</p> | `false` | `latest` |
|
||||||
| `config-file` | <p>Path to Prettier config file</p> | `false` | `.prettierrc` |
|
| `config-file` | <p>Path to Prettier config file</p> | `false` | `.prettierrc` |
|
||||||
| `ignore-file` | <p>Path to Prettier ignore file</p> | `false` | `.prettierignore` |
|
| `ignore-file` | <p>Path to Prettier ignore file</p> | `false` | `.prettierignore` |
|
||||||
| `file-pattern` | <p>Files to include (glob pattern)</p> | `false` | `**/*.{js,jsx,ts,tsx,css,scss,json,md,yaml,yml}` |
|
| `file-pattern` | <p>Files to include (glob pattern)</p> | `false` | `**/*.{js,jsx,ts,tsx,css,scss,json,md,yaml,yml}` |
|
||||||
| `cache` | <p>Enable Prettier caching</p> | `false` | `true` |
|
| `cache` | <p>Enable Prettier caching</p> | `false` | `true` |
|
||||||
| `fail-on-error` | <p>Fail workflow if issues are found (check mode only)</p> | `false` | `true` |
|
| `fail-on-error` | <p>Fail workflow if issues are found (check mode only)</p> | `false` | `true` |
|
||||||
| `report-format` | <p>Output format for check mode (json, sarif)</p> | `false` | `sarif` |
|
| `report-format` | <p>Output format for check mode (json, sarif)</p> | `false` | `sarif` |
|
||||||
| `max-retries` | <p>Maximum number of retry attempts</p> | `false` | `3` |
|
| `max-retries` | <p>Maximum number of retry attempts</p> | `false` | `3` |
|
||||||
| `plugins` | <p>Comma-separated list of Prettier plugins to install</p> | `false` | `""` |
|
| `plugins` | <p>Comma-separated list of Prettier plugins to install</p> | `false` | `""` |
|
||||||
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
||||||
| `username` | <p>GitHub username for commits (fix mode only)</p> | `false` | `github-actions` |
|
| `username` | <p>GitHub username for commits (fix mode only)</p> | `false` | `github-actions` |
|
||||||
| `email` | <p>GitHub email for commits (fix mode only)</p> | `false` | `github-actions@github.com` |
|
| `email` | <p>GitHub email for commits (fix mode only)</p> | `false` | `github-actions@github.com` |
|
||||||
|
|
||||||
### Outputs
|
### Outputs
|
||||||
|
|
||||||
| name | description |
|
| name | description |
|
||||||
| --- | --- |
|
|---------------------|-----------------------------------------------------------------|
|
||||||
| `status` | <p>Overall status (success/failure)</p> |
|
| `status` | <p>Overall status (success/failure)</p> |
|
||||||
| `files-checked` | <p>Number of files checked (check mode only)</p> |
|
| `files-checked` | <p>Number of files checked (check mode only)</p> |
|
||||||
| `unformatted-files` | <p>Number of files with formatting issues (check mode only)</p> |
|
| `unformatted-files` | <p>Number of files with formatting issues (check mode only)</p> |
|
||||||
| `sarif-file` | <p>Path to SARIF report file (check mode only)</p> |
|
| `sarif-file` | <p>Path to SARIF report file (check mode only)</p> |
|
||||||
| `files-changed` | <p>Number of files changed (fix mode only)</p> |
|
| `files-changed` | <p>Number of files changed (fix mode only)</p> |
|
||||||
|
|
||||||
### Runs
|
### Runs
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for prettier-lint action
|
# Validation rules for prettier-lint action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: prettier-lint
|
action: prettier-lint
|
||||||
description: Run Prettier in check or fix mode with advanced configuration and reporting
|
description: Run Prettier in check or fix mode with advanced configuration and reporting
|
||||||
|
|||||||
@@ -8,25 +8,25 @@ Lints and fixes Python files, commits changes, and uploads SARIF report.
|
|||||||
|
|
||||||
### Inputs
|
### Inputs
|
||||||
|
|
||||||
| name | description | required | default |
|
| name | description | required | default |
|
||||||
| --- | --- | --- | --- |
|
|---------------------|-----------------------------------------------------------------------|----------|-----------------------------|
|
||||||
| `python-version` | <p>Python version to use</p> | `false` | `3.11` |
|
| `python-version` | <p>Python version to use</p> | `false` | `3.11` |
|
||||||
| `flake8-version` | <p>Flake8 version to use</p> | `false` | `7.0.0` |
|
| `flake8-version` | <p>Flake8 version to use</p> | `false` | `7.0.0` |
|
||||||
| `autopep8-version` | <p>Autopep8 version to use</p> | `false` | `2.0.4` |
|
| `autopep8-version` | <p>Autopep8 version to use</p> | `false` | `2.0.4` |
|
||||||
| `max-retries` | <p>Maximum number of retry attempts for installations and linting</p> | `false` | `3` |
|
| `max-retries` | <p>Maximum number of retry attempts for installations and linting</p> | `false` | `3` |
|
||||||
| `working-directory` | <p>Directory containing Python files to lint</p> | `false` | `.` |
|
| `working-directory` | <p>Directory containing Python files to lint</p> | `false` | `.` |
|
||||||
| `fail-on-error` | <p>Whether to fail the action if linting errors are found</p> | `false` | `true` |
|
| `fail-on-error` | <p>Whether to fail the action if linting errors are found</p> | `false` | `true` |
|
||||||
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
| `token` | <p>GitHub token for authentication</p> | `false` | `""` |
|
||||||
| `username` | <p>GitHub username for commits</p> | `false` | `github-actions` |
|
| `username` | <p>GitHub username for commits</p> | `false` | `github-actions` |
|
||||||
| `email` | <p>GitHub email for commits</p> | `false` | `github-actions@github.com` |
|
| `email` | <p>GitHub email for commits</p> | `false` | `github-actions@github.com` |
|
||||||
|
|
||||||
### Outputs
|
### Outputs
|
||||||
|
|
||||||
| name | description |
|
| name | description |
|
||||||
| --- | --- |
|
|---------------|--------------------------------------------------------|
|
||||||
| `lint-result` | <p>Result of the linting process (success/failure)</p> |
|
| `lint-result` | <p>Result of the linting process (success/failure)</p> |
|
||||||
| `fixed-files` | <p>Number of files that were fixed</p> |
|
| `fixed-files` | <p>Number of files that were fixed</p> |
|
||||||
| `error-count` | <p>Number of errors found</p> |
|
| `error-count` | <p>Number of errors found</p> |
|
||||||
|
|
||||||
### Runs
|
### Runs
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for python-lint-fix action
|
# Validation rules for python-lint-fix action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: python-lint-fix
|
action: python-lint-fix
|
||||||
description: Lints and fixes Python files, commits changes, and uploads SARIF report.
|
description: Lints and fixes Python files, commits changes, and uploads SARIF report.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for release-monthly action
|
# Validation rules for release-monthly action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: release-monthly
|
action: release-monthly
|
||||||
description: Creates a release for the current month, incrementing patch number if necessary.
|
description: Creates a release for the current month, incrementing patch number if necessary.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for stale action
|
# Validation rules for stale action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: stale
|
action: stale
|
||||||
description: A GitHub Action to close stale issues and pull requests.
|
description: A GitHub Action to close stale issues and pull requests.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for sync-labels action
|
# Validation rules for sync-labels action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: sync-labels
|
action: sync-labels
|
||||||
description: Sync labels from a YAML file to a GitHub repository
|
description: Sync labels from a YAML file to a GitHub repository
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Validation rules for terraform-lint-fix action
|
# Validation rules for terraform-lint-fix action
|
||||||
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
|
||||||
# Schema version: 1.0
|
# Schema version: 1.0
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
# Rules are automatically applied by validate-inputs action when this
|
# Rules are automatically applied by validate-inputs action when this
|
||||||
# action is used.
|
# action is used.
|
||||||
#
|
#
|
||||||
|
|
||||||
schema_version: '1.0'
|
schema_version: '1.0'
|
||||||
action: terraform-lint-fix
|
action: terraform-lint-fix
|
||||||
description: Lints and fixes Terraform files with advanced validation and security checks.
|
description: Lints and fixes Terraform files with advanced validation and security checks.
|
||||||
|
|||||||
@@ -331,9 +331,6 @@ class ValidationRuleGenerator:
|
|||||||
"file-pattern": "file_pattern",
|
"file-pattern": "file_pattern",
|
||||||
"plugins": "plugin_list",
|
"plugins": "plugin_list",
|
||||||
},
|
},
|
||||||
"php-laravel-phpunit": {
|
|
||||||
"extensions": "php_extensions",
|
|
||||||
},
|
|
||||||
"codeql-analysis": {
|
"codeql-analysis": {
|
||||||
"language": "codeql_language",
|
"language": "codeql_language",
|
||||||
"queries": "codeql_queries",
|
"queries": "codeql_queries",
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
"""Tests for php-composer custom validator.
|
|
||||||
|
|
||||||
Generated by generate-tests.py - Do not edit manually.
|
|
||||||
"""
|
|
||||||
# pylint: disable=invalid-name # Test file name matches action name
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# Add action directory to path to import custom validator
|
|
||||||
action_path = Path(__file__).parent.parent.parent / "php-composer"
|
|
||||||
sys.path.insert(0, str(action_path))
|
|
||||||
|
|
||||||
# pylint: disable=wrong-import-position
|
|
||||||
from CustomValidator import CustomValidator
|
|
||||||
|
|
||||||
|
|
||||||
class TestCustomPhpComposerValidator:
|
|
||||||
"""Test cases for php-composer custom validator."""
|
|
||||||
|
|
||||||
def setup_method(self):
|
|
||||||
"""Set up test fixtures."""
|
|
||||||
self.validator = CustomValidator("php-composer")
|
|
||||||
|
|
||||||
def teardown_method(self):
|
|
||||||
"""Clean up after tests."""
|
|
||||||
self.validator.clear_errors()
|
|
||||||
|
|
||||||
def test_validate_inputs_valid(self):
|
|
||||||
"""Test validation with valid inputs."""
|
|
||||||
# TODO: Add specific valid inputs for php-composer
|
|
||||||
inputs = {}
|
|
||||||
result = self.validator.validate_inputs(inputs)
|
|
||||||
# Adjust assertion based on required inputs
|
|
||||||
assert isinstance(result, bool)
|
|
||||||
|
|
||||||
def test_validate_inputs_invalid(self):
|
|
||||||
"""Test validation with invalid inputs."""
|
|
||||||
# TODO: Add specific invalid inputs for php-composer
|
|
||||||
inputs = {"invalid_key": "invalid_value"}
|
|
||||||
result = self.validator.validate_inputs(inputs)
|
|
||||||
# Custom validators may have specific validation rules
|
|
||||||
assert isinstance(result, bool)
|
|
||||||
|
|
||||||
def test_required_inputs(self):
|
|
||||||
"""Test required inputs detection."""
|
|
||||||
required = self.validator.get_required_inputs()
|
|
||||||
assert isinstance(required, list)
|
|
||||||
# TODO: Assert specific required inputs for php-composer
|
|
||||||
|
|
||||||
def test_validation_rules(self):
|
|
||||||
"""Test validation rules."""
|
|
||||||
rules = self.validator.get_validation_rules()
|
|
||||||
assert isinstance(rules, dict)
|
|
||||||
# TODO: Assert specific validation rules for php-composer
|
|
||||||
|
|
||||||
def test_github_expressions(self):
|
|
||||||
"""Test GitHub expression handling."""
|
|
||||||
inputs = {
|
|
||||||
"test_input": "${{ github.token }}",
|
|
||||||
}
|
|
||||||
result = self.validator.validate_inputs(inputs)
|
|
||||||
assert isinstance(result, bool)
|
|
||||||
# GitHub expressions should generally be accepted
|
|
||||||
|
|
||||||
def test_error_propagation(self):
|
|
||||||
"""Test error propagation from sub-validators."""
|
|
||||||
# Custom validators often use sub-validators
|
|
||||||
# Test that errors are properly propagated
|
|
||||||
inputs = {"test": "value"}
|
|
||||||
self.validator.validate_inputs(inputs)
|
|
||||||
# Check error handling
|
|
||||||
if self.validator.has_errors():
|
|
||||||
assert len(self.validator.errors) > 0
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
"""Tests for php-laravel-phpunit custom validator.
|
|
||||||
|
|
||||||
Generated by generate-tests.py - Do not edit manually.
|
|
||||||
"""
|
|
||||||
# pylint: disable=invalid-name # Test file name matches action name
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# Add action directory to path to import custom validator
|
|
||||||
action_path = Path(__file__).parent.parent.parent / "php-laravel-phpunit"
|
|
||||||
sys.path.insert(0, str(action_path))
|
|
||||||
|
|
||||||
# pylint: disable=wrong-import-position
|
|
||||||
from CustomValidator import CustomValidator
|
|
||||||
|
|
||||||
|
|
||||||
class TestCustomPhpLaravelPhpunitValidator:
|
|
||||||
"""Test cases for php-laravel-phpunit custom validator."""
|
|
||||||
|
|
||||||
def setup_method(self):
|
|
||||||
"""Set up test fixtures."""
|
|
||||||
self.validator = CustomValidator("php-laravel-phpunit")
|
|
||||||
|
|
||||||
def teardown_method(self):
|
|
||||||
"""Clean up after tests."""
|
|
||||||
self.validator.clear_errors()
|
|
||||||
|
|
||||||
def test_validate_inputs_valid(self):
|
|
||||||
"""Test validation with valid inputs."""
|
|
||||||
# TODO: Add specific valid inputs for php-laravel-phpunit
|
|
||||||
inputs = {}
|
|
||||||
result = self.validator.validate_inputs(inputs)
|
|
||||||
# Adjust assertion based on required inputs
|
|
||||||
assert isinstance(result, bool)
|
|
||||||
|
|
||||||
def test_validate_inputs_invalid(self):
|
|
||||||
"""Test validation with invalid inputs."""
|
|
||||||
# TODO: Add specific invalid inputs for php-laravel-phpunit
|
|
||||||
inputs = {"invalid_key": "invalid_value"}
|
|
||||||
result = self.validator.validate_inputs(inputs)
|
|
||||||
# Custom validators may have specific validation rules
|
|
||||||
assert isinstance(result, bool)
|
|
||||||
|
|
||||||
def test_required_inputs(self):
|
|
||||||
"""Test required inputs detection."""
|
|
||||||
required = self.validator.get_required_inputs()
|
|
||||||
assert isinstance(required, list)
|
|
||||||
# TODO: Assert specific required inputs for php-laravel-phpunit
|
|
||||||
|
|
||||||
def test_validation_rules(self):
|
|
||||||
"""Test validation rules."""
|
|
||||||
rules = self.validator.get_validation_rules()
|
|
||||||
assert isinstance(rules, dict)
|
|
||||||
# TODO: Assert specific validation rules for php-laravel-phpunit
|
|
||||||
|
|
||||||
def test_github_expressions(self):
|
|
||||||
"""Test GitHub expression handling."""
|
|
||||||
inputs = {
|
|
||||||
"test_input": "${{ github.token }}",
|
|
||||||
}
|
|
||||||
result = self.validator.validate_inputs(inputs)
|
|
||||||
assert isinstance(result, bool)
|
|
||||||
# GitHub expressions should generally be accepted
|
|
||||||
|
|
||||||
def test_error_propagation(self):
|
|
||||||
"""Test error propagation from sub-validators."""
|
|
||||||
# Custom validators often use sub-validators
|
|
||||||
# Test that errors are properly propagated
|
|
||||||
inputs = {"test": "value"}
|
|
||||||
self.validator.validate_inputs(inputs)
|
|
||||||
# Check error handling
|
|
||||||
if self.validator.has_errors():
|
|
||||||
assert len(self.validator.errors) > 0
|
|
||||||
Reference in New Issue
Block a user