Files
actions/_tests/README.md
Ismo Vuorinen 78fdad69e5 feat: fixes, tweaks, new actions, linting (#186)
* feat: fixes, tweaks, new actions, linting
* fix: improve docker publish loops and dotnet parsing (#193)
* fix: harden action scripts and version checks (#191)
* refactor: major repository restructuring and security enhancements

Add comprehensive development infrastructure:
- Add Makefile with automated documentation generation, formatting, and linting tasks
- Add TODO.md tracking self-containment progress and repository improvements
- Add .nvmrc for consistent Node.js version management
- Create python-version-detect-v2 action for enhanced Python detection

Enhance all GitHub Actions with standardized patterns:
- Add consistent token handling across 27 actions using standardized input patterns
- Implement bash error handling (set -euo pipefail) in all shell steps
- Add comprehensive input validation for path traversal and command injection protection
- Standardize checkout token authentication to prevent rate limiting
- Remove relative action dependencies to ensure external usability

Rewrite security workflow for PR-focused analysis:
- Transform security-suite.yml to PR-only security analysis workflow
- Remove scheduled runs, repository issue management, and Slack notifications
- Implement smart comment generation showing only sections with content
- Add GitHub Actions permission diff analysis and new action detection
- Integrate OWASP, Semgrep, and TruffleHog for comprehensive PR security scanning

Improve version detection and dependency management:
- Simplify version detection actions to use inline logic instead of shared utilities
- Fix Makefile version detection fallback to properly return 'main' when version not found
- Update all external action references to use SHA-pinned versions
- Remove deprecated run.sh in favor of Makefile automation

Update documentation and project standards:
- Enhance CLAUDE.md with self-containment requirements and linting standards
- Update README.md with improved action descriptions and usage examples
- Standardize code formatting with updated .editorconfig and .prettierrc.yml
- Improve GitHub templates for issues and security reporting

This refactoring ensures all 40 actions are fully self-contained and can be used independently when
referenced as ivuorinen/actions/action-name@main, addressing the critical requirement for external
usability while maintaining comprehensive security analysis and development automation.

* feat: add automated action catalog generation system

- Create generate_listing.cjs script for comprehensive action catalog
- Add package.json with development tooling and npm scripts
- Implement automated README.md catalog section with --update flag
- Generate markdown reference-style links for all 40 actions
- Add categorized tables with features, language support matrices
- Replace static reference links with auto-generated dynamic links
- Enable complete automation of action documentation maintenance

* feat: enhance actions with improved documentation and functionality

- Add comprehensive README files for 12 actions with usage examples
- Implement new utility actions (go-version-detect, dotnet-version-detect)
- Enhance node-setup with extensive configuration options
- Improve error handling and validation across all actions
- Update package.json scripts for better development workflow
- Expand TODO.md with detailed roadmap and improvement plans
- Standardize action structure with consistent inputs/outputs

* feat: add comprehensive output handling across all actions

- Add standardized outputs to 15 actions that previously had none
- Implement consistent snake_case naming convention for all outputs
- Add build status and test results outputs to build actions
- Add files changed and status outputs to lint/fix actions
- Add test execution metrics to php-tests action
- Add stale/closed counts to stale action
- Add release URLs and IDs to github-release action
- Update documentation with output specifications
- Mark comprehensive output handling task as complete in TODO.md

* feat: implement shared cache strategy across all actions

- Add caching to 10 actions that previously had none (Node.js, .NET, Python, Go)
- Standardize 4 existing actions to use common-cache instead of direct actions/cache
- Implement consistent cache-hit optimization to skip installations when cache available
- Add language-specific cache configurations with appropriate key files
- Create unified caching approach using ivuorinen/actions/common-cache@main
- Fix YAML syntax error in php-composer action paths parameter
- Update TODO.md to mark shared cache strategy as complete

* feat: implement comprehensive retry logic for network operations

- Create new common-retry action for standardized retry patterns with configurable strategies
- Add retry logic to 9 actions missing network retry capabilities
- Implement exponential backoff, custom timeouts, and flexible error handling
- Add max-retries input parameter to all network-dependent actions (Node.js, .NET, Python, Go)
- Standardize existing retry implementations to use common-retry utility
- Update action catalog to include new common-retry action (41 total actions)
- Update documentation with retry configuration examples and parameters
- Mark retry logic implementation as complete in TODO.md roadmap

* feat: enhance Node.js support with Corepack and Bun

- Add Corepack support for automatic package manager version management
- Add Bun package manager support across all Node.js actions
- Improve Yarn Berry/PnP support with .yarnrc.yml detection
- Add Node.js feature detection (ESM, TypeScript, frameworks)
- Update package manager detection priority and lockfile support
- Enhance caching with package-manager-specific keys
- Update eslint, prettier, and biome actions for multi-package-manager support

* fix: resolve critical runtime issues across multiple actions

- Fix token validation by removing ineffective literal string comparisons
- Add missing @microsoft/eslint-formatter-sarif dependency for SARIF output
- Fix Bash variable syntax errors in username and changelog length checks
- Update Dockerfile version regex to handle tags with suffixes (e.g., -alpine)
- Simplify version selection logic with single grep command
- Fix command execution in retry action with proper bash -c wrapper
- Correct step output references using .outcome instead of .outputs.outcome
- Add missing step IDs for version detection actions
- Include go.mod in cache key files for accurate invalidation
- Require minor version in all version regex patterns
- Improve Bun installation security by verifying script before execution
- Replace bc with sort -V for portable PHP version comparison
- Remove non-existent pre-commit output references

These fixes ensure proper runtime behavior, improved security, and better
cross-platform compatibility across all affected actions.

* fix: resolve critical runtime and security issues across actions

- Fix biome-fix files_changed calculation using git diff instead of git status delta
- Fix compress-images output description and add absolute path validation
- Remove csharp-publish token default and fix token fallback in push commands
- Add @microsoft/eslint-formatter-sarif to all package managers in eslint-check
- Fix eslint-check command syntax by using variable assignment
- Improve node-setup Bun installation security and remove invalid frozen-lockfile flag
- Fix pre-commit token validation by removing ineffective literal comparison
- Fix prettier-fix token comparison and expand regex for all GitHub token types
- Add version-file-parser regex validation safety and fix csproj wildcard handling

These fixes address security vulnerabilities, runtime errors, and functional issues
to ensure reliable operation across all affected GitHub Actions.

* feat: enhance Docker actions with advanced multi-architecture support

Major enhancement to Docker build and publish actions with comprehensive
multi-architecture capabilities and enterprise-grade features.

Added features:
- Advanced buildx configuration (version control, cache modes, build contexts)
- Auto-detect platforms for dynamic architecture discovery
- Performance optimizations with enhanced caching strategies
- Security scanning with Trivy and image signing with Cosign
- SBOM generation in multiple formats with validation
- Verbose logging and dry-run modes for debugging
- Platform-specific build args and fallback mechanisms

Enhanced all Docker actions:
- docker-build: Core buildx features and multi-arch support
- docker-publish-gh: GitHub Packages with security features
- docker-publish-hub: Docker Hub with scanning and signing
- docker-publish: Orchestrator with unified configuration

Updated documentation across all modified actions.

* fix: resolve documentation generation placeholder issue

Fixed Makefile and package.json to properly replace placeholder tokens in generated documentation, ensuring all README files show correct repository paths instead of ***PROJECT***@***VERSION***.

* chore: simplify github token validation
* chore(lint): optional yamlfmt, config and fixes
* feat: use relative `uses` names

* feat: comprehensive testing infrastructure and Python validation system

- Migrate from tests/ to _tests/ directory structure with ShellSpec framework
- Add comprehensive validation system with Python-based input validation
- Implement dual testing approach (ShellSpec + pytest) for complete coverage
- Add modern Python tooling (uv, ruff, pytest-cov) and dependencies
- Create centralized validation rules with automatic generation system
- Update project configuration and build system for new architecture
- Enhance documentation to reflect current testing capabilities

This establishes a robust foundation for action validation and testing
with extensive coverage across all GitHub Actions in the repository.

* chore: remove Dockerfile for now
* chore: code review fixes

* feat: comprehensive GitHub Actions restructuring and tooling improvements

This commit represents a major restructuring of the GitHub Actions monorepo
with improved tooling, testing infrastructure, and comprehensive PR #186
review implementation.

## Major Changes

### 🔧 Development Tooling & Configuration
- **Shellcheck integration**: Exclude shellspec test files from linting
  - Updated .pre-commit-config.yaml to exclude _tests/*.sh from shellcheck/shfmt
  - Modified Makefile shellcheck pattern to skip shellspec files
  - Updated CLAUDE.md documentation with proper exclusion syntax
- **Testing infrastructure**: Enhanced Python validation framework
  - Fixed nested if statements and boolean parameter issues in validation.py
  - Improved code quality with explicit keyword arguments
  - All pre-commit hooks now passing

### 🏗️ Project Structure & Documentation
- **Added Serena AI integration** with comprehensive project memories:
  - Project overview, structure, and technical stack documentation
  - Code style conventions and completion requirements
  - Comprehensive PR #186 review analysis and implementation tracking
- **Enhanced configuration**: Updated .gitignore, .yamlfmt.yml, pyproject.toml
- **Improved testing**: Added integration workflows and enhanced test specs

### 🚀 GitHub Actions Improvements (30+ actions updated)
- **Centralized validation**: Updated 41 validation rule files
- **Enhanced actions**: Improvements across all action categories:
  - Setup actions (node-setup, version detectors)
  - Utility actions (version-file-parser, version-validator)
  - Linting actions (biome, eslint, terraform-lint-fix major refactor)
  - Build/publish actions (docker-build, npm-publish, csharp-*)
  - Repository management actions

### 📝 Documentation Updates
- **README consistency**: Updated version references across action READMEs
- **Enhanced documentation**: Improved action descriptions and usage examples
- **CLAUDE.md**: Updated with current tooling and best practices

## Technical Improvements
- **Security enhancements**: Input validation and sanitization improvements
- **Performance optimizations**: Streamlined action logic and dependencies
- **Cross-platform compatibility**: Better Windows/macOS/Linux support
- **Error handling**: Improved error reporting and user feedback

## Files Changed
- 100 files changed
- 13 new Serena memory files documenting project state
- 41 validation rules updated for consistency
- 30+ GitHub Actions and READMEs improved
- Core tooling configuration enhanced

* feat: comprehensive GitHub Actions improvements and PR review fixes

Major Infrastructure Improvements:
- Add comprehensive testing framework with 17+ ShellSpec validation tests
- Implement Docker-based testing tools with automated test runner
- Add CodeRabbit configuration for automated code reviews
- Restructure documentation and memory management system
- Update validation rules for 25+ actions with enhanced input validation
- Modernize CI/CD workflows and testing infrastructure

Critical PR Review Fixes (All Issues Resolved):
- Fix double caching in node-setup (eliminate redundant cache operations)
- Optimize shell pipeline in version-file-parser (single awk vs complex pipeline)
- Fix GitHub expression interpolation in prettier-check cache keys
- Resolve terraform command order issue (validation after setup)
- Add missing flake8-sarif dependency for Python SARIF output
- Fix environment variable scope in pr-lint (export to GITHUB_ENV)

Performance & Reliability:
- Eliminate duplicate cache operations saving CI time
- Improve shell script efficiency with optimized parsing
- Fix command execution dependencies preventing runtime failures
- Ensure proper dependency installation for all linting tools
- Resolve workflow conditional logic issues

Security & Quality:
- All input validation rules updated with latest security patterns
- Cross-platform compatibility improvements maintained
- Comprehensive error handling and retry logic preserved
- Modern development tooling and best practices adopted

This commit addresses 100% of actionable feedback from PR review analysis,
implements comprehensive testing infrastructure, and maintains high code
quality standards across all 41 GitHub Actions.

* feat: enhance expression handling and version parsing

- Fix node-setup force-version expression logic for proper empty string handling
- Improve version-file-parser with secure regex validation and enhanced Python detection
- Add CodeRabbit configuration for CalVer versioning and README review guidance

* feat(validate-inputs): implement modular validation system

- Add modular validator architecture with specialized validators
- Implement base validator classes for different input types
- Add validators: boolean, docker, file, network, numeric, security, token, version
- Add convention mapper for automatic input validation
- Add comprehensive documentation for the validation system
- Implement PCRE regex support and injection protection

* feat(validate-inputs): add validation rules for all actions

- Add YAML validation rules for 42 GitHub Actions
- Auto-generated rules with convention mappings
- Include metadata for validation coverage and quality indicators
- Mark rules as auto-generated to prevent manual edits

* test(validate-inputs): add comprehensive test suite for validators

- Add unit tests for all validator modules
- Add integration tests for the validation system
- Add fixtures for version test data
- Test coverage for boolean, docker, file, network, numeric, security, token, and version validators
- Add tests for convention mapper and registry

* feat(tools): add validation scripts and utilities

- Add update-validators.py script for auto-generating rules
- Add benchmark-validator.py for performance testing
- Add debug-validator.py for troubleshooting
- Add generate-tests.py for test generation
- Add check-rules-not-manually-edited.sh for CI validation
- Add fix-local-action-refs.py tool for fixing action references

* feat(actions): add CustomValidator.py files for specialized validation

- Add custom validators for actions requiring special validation logic
- Implement validators for docker, go, node, npm, php, python, terraform actions
- Add specialized validation for compress-images, common-cache, common-file-check
- Implement version detection validators with language-specific logic
- Add validation for build arguments, architectures, and version formats

* test: update ShellSpec test framework for Python validation

- Update all validation.spec.sh files to use Python validator
- Add shared validation_core.py for common test utilities
- Remove obsolete bash validation helpers
- Update test output expectations for Python validator format
- Add codeql-analysis test suite
- Refactor framework utilities for Python integration
- Remove deprecated test files

* feat(actions): update action.yml files to use validate-inputs

- Replace inline bash validation with validate-inputs action
- Standardize validation across all 42 actions
- Add new codeql-analysis action
- Update action metadata and branding
- Add validation step as first step in composite actions
- Maintain backward compatibility with existing inputs/outputs

* ci: update GitHub workflows for enhanced security and testing

- Add new codeql-new.yml workflow
- Update security scanning workflows
- Enhance dependency review configuration
- Update test-actions workflow for new validation system
- Improve workflow permissions and security settings
- Update action versions to latest SHA-pinned releases

* build: update build configuration and dependencies

- Update Makefile with new validation targets
- Add Python dependencies in pyproject.toml
- Update npm dependencies and scripts
- Enhance Docker testing tools configuration
- Add targets for validator updates and local ref fixes
- Configure uv for Python package management

* chore: update linting and documentation configuration

- Update EditorConfig settings for consistent formatting
- Enhance pre-commit hooks configuration
- Update prettier and yamllint ignore patterns
- Update gitleaks security scanning rules
- Update CodeRabbit review configuration
- Update CLAUDE.md with latest project standards and rules

* docs: update Serena memory files and project metadata

- Remove obsolete PR-186 memory files
- Update project overview with current architecture
- Update project structure documentation
- Add quality standards and communication guidelines
- Add modular validator architecture documentation
- Add shellspec testing framework documentation
- Update project.yml with latest configuration

* feat: moved rules.yml to same folder as action, fixes

* fix(validators): correct token patterns and fix validator bugs

- Fix GitHub classic PAT pattern: ghp_ + 36 chars = 40 total
- Fix GitHub fine-grained PAT pattern: github_pat_ + 71 chars = 82 total
- Initialize result variable in convention_mapper to prevent UnboundLocalError
- Fix empty URL validation in network validator to return error
- Add GitHub expression check to docker architectures validator
- Update docker-build CustomValidator parallel-builds max to 16

* test(validators): fix test fixtures and expectations

- Fix token lengths in test data: github_pat 71 chars, ghp/gho 36 chars
- Update integration tests with correct token lengths
- Fix file validator test to expect absolute paths rejected for security
- Rename TestGenerator import to avoid pytest collection warning
- Update custom validator tests with correct input names
- Change docker-build tests: platforms->architectures, tags->tag
- Update docker-publish tests to match new registry enum validation

* test(shellspec): fix token lengths in test helpers and specs

- Fix default token lengths in spec_helper.sh to use correct 40-char format
- Update csharp-publish default tokens in 4 locations
- Update codeql-analysis default tokens in 2 locations
- Fix codeql-analysis test tokens to correct lengths (40 and 82 chars)
- Fix npm-publish fine-grained token test to use 82-char format

* feat(actions): add permissions documentation and environment variable usage

- Add permissions comments to all action.yml files documenting required GitHub permissions
- Convert direct input usage to environment variables in shell steps for security
- Add validation steps with proper error handling
- Update input descriptions and add security notes where applicable
- Ensure all actions follow consistent patterns for input validation

* chore(workflows): update GitHub Actions workflow versions

- Update workflow action versions to latest
- Improve workflow consistency and maintainability

* docs(security): add comprehensive security policy

- Document security features and best practices
- Add vulnerability reporting process
- Include audit history and security testing information

* docs(memory): add GitHub workflow reference documentation

- Add GitHub Actions workflow commands reference
- Add GitHub workflow expressions guide
- Add secure workflow usage patterns and best practices

* chore: token optimization, code style conventions
* chore: cr fixes
* fix: trivy reported Dockerfile problems
* fix(security): more security fixes
* chore: dockerfile and make targets for publishing
* fix(ci): add creds to test-actions workflow
* fix: security fix and checkout step to codeql-new
* chore: test fixes
* fix(security): codeql detected issues
* chore: code review fixes, ReDos protection
* style: apply MegaLinter fixes
* fix(ci): missing packages read permission
* fix(ci): add missing working directory setting
* chore: linting, add validation-regex to use regex_pattern
* chore: code review fixes
* chore(deps): update actions
* fix(security): codeql fixes
* chore(cr): apply cr comments
* chore: improve POSIX compatibility
* chore(cr): apply cr comments
* fix: codeql warning in Dockerfile, build failures
* chore(cr): apply cr comments
* fix: docker-testing-tools/Dockerfile
* chore(cr): apply cr comments
* fix(docker): update testing-tools image for GitHub Actions compatibility
* chore(cr): apply cr comments
* feat: add more tests, fix issues
* chore: fix codeql issues, update actions
* chore(cr): apply cr comments
* fix: integration tests
* chore: deduplication and fixes
* style: apply MegaLinter fixes
* chore(cr): apply cr comments
* feat: dry-run mode for generate-tests
* fix(ci): kcov installation
* chore(cr): apply cr comments
* chore(cr): apply cr comments
* chore(cr): apply cr comments
* chore(cr): apply cr comments, simplify action testing, use uv
* fix: run-tests.sh action counting
* chore(cr): apply cr comments
* chore(cr): apply cr comments
2025-10-14 13:37:58 +03:00

20 KiB

GitHub Actions Testing Framework

A comprehensive testing framework for validating GitHub Actions in this monorepo. This guide covers everything from basic usage to advanced testing patterns.

🚀 Quick Start

# Run all tests
make test

# Run only unit tests
make test-unit

# Run tests for specific action
make test-action ACTION=node-setup

# Run with coverage reporting
make test-coverage

Prerequisites

# Install ShellSpec (testing framework)
curl -fsSL https://github.com/shellspec/shellspec/releases/latest/download/shellspec-dist.tar.gz | tar -xz
sudo make -C shellspec-* install

# Install nektos/act (optional, for integration tests)
brew install act  # macOS
# or: curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash

📁 Framework Overview

Architecture

The testing framework uses a multi-level testing strategy:

  1. Unit Tests - Fast validation of action logic, inputs, and outputs
  2. Integration Tests - Test actions in realistic workflow environments
  3. External Usage Tests - Validate actions work as ivuorinen/actions/action-name@main

Technology Stack

  • Primary Framework: ShellSpec - BDD testing for shell scripts
  • Local Execution: nektos/act - Run GitHub Actions locally
  • Coverage: kcov integration for shell script coverage
  • Mocking: Custom GitHub API and service mocks
  • CI Integration: GitHub Actions workflows

Directory Structure

_tests/
├── README.md                    # This documentation
├── run-tests.sh                 # Main test runner script
├── framework/                   # Core testing utilities
│   ├── setup.sh                # Test environment setup
│   ├── utils.sh                # Common testing functions
│   ├── validation_helpers.sh   # Validation helper functions
│   ├── validation.py           # Python validation utilities
│   └── mocks/                  # Mock services (GitHub API, etc.)
├── unit/                       # Unit tests by action
│   ├── version-file-parser/    # Example unit tests
│   ├── node-setup/            # Example unit tests
│   └── ...                    # One directory per action
├── integration/               # Integration tests
│   ├── workflows/             # Test workflows for nektos/act
│   └── external-usage/        # External reference tests
├── coverage/                  # Coverage reports
└── reports/                   # Test execution reports

✍️ Writing Tests

Basic Unit Test Structure

#!/usr/bin/env shellspec
# _tests/unit/my-action/validation.spec.sh

Include _tests/framework/utils.sh

Describe "my-action validation"
  ACTION_DIR="my-action"
  ACTION_FILE="$ACTION_DIR/action.yml"

  BeforeAll "init_testing_framework"

  Context "input validation"
    It "validates all inputs comprehensively"
      # Use validation helpers for comprehensive testing
      test_boolean_input "verbose"
      test_boolean_input "dry-run"

      # Numeric range validations (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "max-retries" "1" "success"
      test_input_validation "$ACTION_DIR" "max-retries" "10" "success"
      test_input_validation "$ACTION_DIR" "timeout" "3600" "success"

      # Enum validations (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "strategy" "fast" "success"
      test_input_validation "$ACTION_DIR" "format" "json" "success"

      # Version validations (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "tool-version" "1.0.0" "success"

      # Security and path validations (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "command" "echo test" "success"
      test_input_validation "$ACTION_DIR" "working-directory" "." "success"
    End
  End

  Context "action structure"
    It "has valid structure and metadata"
      test_standard_action_structure "$ACTION_FILE" "Expected Action Name"
    End
  End
End

Integration Test Example

# _tests/integration/workflows/my-action-test.yml
name: Test my-action Integration
on: workflow_dispatch

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Test action locally
        id: test-local
        uses: ./my-action
        with:
          required-input: 'test-value'

      - name: Validate outputs
        run: |
          echo "Output: ${{ steps.test-local.outputs.result }}"
          [[ -n "${{ steps.test-local.outputs.result }}" ]] || exit 1

      - name: Test external reference
        uses: ivuorinen/actions/my-action@main
        with:
          required-input: 'test-value'

🛠️ Testing Helpers

Available Validation Helpers

The framework provides comprehensive validation helpers that handle common testing patterns:

Boolean Input Testing

test_boolean_input "verbose"          # Tests: true, false, rejects invalid
test_boolean_input "enable-cache"
test_boolean_input "dry-run"

Numeric Range Testing

# Note: test_numeric_range_input helper is not yet implemented.
# Use test_input_validation with appropriate test values instead:
test_input_validation "$ACTION_DIR" "max-retries" "1" "success"    # min value
test_input_validation "$ACTION_DIR" "max-retries" "10" "success"   # max value
test_input_validation "$ACTION_DIR" "max-retries" "0" "failure"    # below min
test_input_validation "$ACTION_DIR" "timeout" "3600" "success"
test_input_validation "$ACTION_DIR" "parallel-jobs" "8" "success"

Version Testing

# Note: test_version_input helper is not yet implemented.
# Use test_input_validation with appropriate test values instead:
test_input_validation "$ACTION_DIR" "version" "1.0.0" "success"           # semver
test_input_validation "$ACTION_DIR" "version" "v1.0.0" "success"          # v-prefix
test_input_validation "$ACTION_DIR" "version" "1.0.0-rc.1" "success"      # pre-release
test_input_validation "$ACTION_DIR" "tool-version" "2.3.4" "success"

Enum Testing

# Note: test_enum_input helper is not yet implemented.
# Use test_input_validation with appropriate test values instead:
test_input_validation "$ACTION_DIR" "strategy" "linear" "success"
test_input_validation "$ACTION_DIR" "strategy" "exponential" "success"
test_input_validation "$ACTION_DIR" "strategy" "invalid" "failure"
test_input_validation "$ACTION_DIR" "format" "json" "success"
test_input_validation "$ACTION_DIR" "format" "yaml" "success"

Docker-Specific Testing

# Available framework helpers:
test_input_validation "$action_dir" "$input_name" "$test_value" "$expected_result"
test_action_outputs "$action_dir"
test_external_usage "$action_dir"

# Note: Docker-specific helpers (test_docker_image_input, test_docker_tag_input,
# test_docker_platforms_input) are referenced in examples but not yet implemented.
# Use test_input_validation with appropriate test values instead.

Complete Action Validation Example

Describe "comprehensive-action validation"
  ACTION_DIR="comprehensive-action"
  ACTION_FILE="$ACTION_DIR/action.yml"

  Context "complete input validation"
    It "validates all input types systematically"
      # Boolean inputs
      test_boolean_input "verbose"
      test_boolean_input "enable-cache"
      test_boolean_input "dry-run"

      # Numeric ranges (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "max-retries" "1" "success"
      test_input_validation "$ACTION_DIR" "max-retries" "10" "success"
      test_input_validation "$ACTION_DIR" "timeout" "3600" "success"
      test_input_validation "$ACTION_DIR" "parallel-jobs" "8" "success"

      # Enums (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "strategy" "fast" "success"
      test_input_validation "$ACTION_DIR" "format" "json" "success"

      # Docker-specific (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "image-name" "myapp:latest" "success"
      test_input_validation "$ACTION_DIR" "tag" "1.0.0" "success"
      test_input_validation "$ACTION_DIR" "platforms" "linux/amd64,linux/arm64" "success"

      # Security validation (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "command" "echo test" "success"
      test_input_validation "$ACTION_DIR" "build-args" "ARG1=value" "success"

      # Paths (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "working-directory" "." "success"
      test_input_validation "$ACTION_DIR" "output-directory" "./output" "success"

      # Versions (use test_input_validation helper)
      test_input_validation "$ACTION_DIR" "tool-version" "1.0.0" "success"

      # Action structure
      test_standard_action_structure "$ACTION_FILE" "Comprehensive Action"
    End
  End
End

🎯 Testing Patterns by Action Type

Setup Actions (node-setup, php-version-detect, etc.)

Focus on version detection and environment setup:

Context "version detection"
  It "detects version from config files"
    create_mock_node_repo  # or appropriate repo type

    # Test version detection logic
    export INPUT_LANGUAGE="node"
    echo "detected-version=18.0.0" >> "$GITHUB_OUTPUT"

    When call validate_action_output "detected-version" "18.0.0"
    The status should be success
  End

  It "falls back to default when no version found"
    # Use test_input_validation helper for version validation
    test_input_validation "$ACTION_DIR" "default-version" "1.0.0" "success"
  End
End

Linting Actions (eslint-fix, prettier-fix, etc.)

Focus on file processing and fix capabilities:

Context "file processing"
  BeforeEach "setup_test_env 'lint-test'"
  AfterEach "cleanup_test_env 'lint-test'"

  It "validates inputs and processes files"
    test_boolean_input "fix-only"
    # Use test_input_validation helper for path and security validations
    test_input_validation "$ACTION_DIR" "working-directory" "." "success"
    test_input_validation "$ACTION_DIR" "custom-command" "echo test" "success"

    # Mock file processing
    echo "files_changed=3" >> "$GITHUB_OUTPUT"
    echo "status=changes_made" >> "$GITHUB_OUTPUT"

    When call validate_action_output "status" "changes_made"
    The status should be success
  End
End

Build Actions (docker-build, go-build, etc.)

Focus on build processes and artifact generation:

Context "build process"
  BeforeEach "setup_test_env 'build-test'"
  AfterEach "cleanup_test_env 'build-test'"

  It "validates build inputs"
    # Use test_input_validation helper for Docker inputs
    test_input_validation "$ACTION_DIR" "image-name" "myapp:latest" "success"
    test_input_validation "$ACTION_DIR" "tag" "1.0.0" "success"
    test_input_validation "$ACTION_DIR" "platforms" "linux/amd64,linux/arm64" "success"
    test_input_validation "$ACTION_DIR" "parallel-builds" "8" "success"

    # Mock successful build
    echo "build-status=success" >> "$GITHUB_OUTPUT"
    echo "build-time=45" >> "$GITHUB_OUTPUT"

    When call validate_action_output "build-status" "success"
    The status should be success
  End
End

Publishing Actions (npm-publish, docker-publish, etc.)

Focus on registry interactions using mocks:

Context "publishing"
  BeforeEach "setup_mock_environment"
  AfterEach "cleanup_mock_environment"

  It "validates publishing inputs"
    # Use test_input_validation helper for version, security, and enum validations
    test_input_validation "$ACTION_DIR" "package-version" "1.0.0" "success"
    test_input_validation "$ACTION_DIR" "registry-token" "ghp_test123" "success"
    test_input_validation "$ACTION_DIR" "registry" "npm" "success"
    test_input_validation "$ACTION_DIR" "registry" "github" "success"

    # Mock successful publish
    echo "publish-status=success" >> "$GITHUB_OUTPUT"
    echo "registry-url=https://registry.npmjs.org/" >> "$GITHUB_OUTPUT"

    When call validate_action_output "publish-status" "success"
    The status should be success
  End
End

🔧 Running Tests

Command Line Interface

# Basic usage
./_tests/run-tests.sh [OPTIONS] [ACTION_NAME...]

# Examples
./_tests/run-tests.sh                           # All tests, all actions
./_tests/run-tests.sh -t unit                   # Unit tests only
./_tests/run-tests.sh -a node-setup             # Specific action
./_tests/run-tests.sh -t integration docker-build  # Integration tests for docker-build
./_tests/run-tests.sh --format json --coverage  # JSON output with coverage

Options

Option Description
-t, --type TYPE Test type: unit, integration, e2e, all
-a, --action ACTION Filter by action name pattern
-j, --jobs JOBS Number of parallel jobs (default: 4)
-c, --coverage Enable coverage reporting
-f, --format FORMAT Output format: console, json, junit
-v, --verbose Enable verbose output
-h, --help Show help message

Make Targets

make test                    # Run all tests
make test-unit              # Unit tests only
make test-integration       # Integration tests only
make test-coverage          # Tests with coverage
make test-action ACTION=name # Test specific action

🤝 Contributing Tests

Adding Tests for New Actions

  1. Create Unit Test Directory

    mkdir -p _tests/unit/new-action
    
  2. Write Comprehensive Unit Tests

    # Copy template and customize
    cp _tests/unit/version-file-parser/validation.spec.sh \
       _tests/unit/new-action/validation.spec.sh
    
  3. Use Validation Helpers

    # Focus on using helpers for comprehensive coverage
    test_boolean_input "verbose"
    # Use test_input_validation helper for numeric, security, and other validations
    test_input_validation "$ACTION_DIR" "timeout" "3600" "success"
    test_input_validation "$ACTION_DIR" "command" "echo test" "success"
    test_standard_action_structure "$ACTION_FILE" "New Action"
    
  4. Create Integration Test

    cp _tests/integration/workflows/version-file-parser-test.yml \
       _tests/integration/workflows/new-action-test.yml
    
  5. Test Your Tests

    make test-action ACTION=new-action
    

Pull Request Checklist

  • Tests use validation helpers for common patterns
  • All test types pass locally (make test)
  • Integration test workflow created
  • Security testing included for user inputs
  • Tests are independent and isolated
  • Proper cleanup in test teardown
  • Documentation updated if needed

💡 Best Practices

1. Use Validation Helpers

Good:

test_boolean_input "verbose"
# Use test_input_validation helper for other validations
test_input_validation "$ACTION_DIR" "timeout" "3600" "success"
test_input_validation "$ACTION_DIR" "format" "json" "success"

Avoid:

# Don't write manual tests for boolean inputs when test_boolean_input exists
When call test_input_validation "$ACTION_DIR" "verbose" "true" "success"
When call test_input_validation "$ACTION_DIR" "verbose" "false" "success"
# Use test_boolean_input "verbose" instead

Good:

Context "complete input validation"
  It "validates all input types"
    test_boolean_input "verbose"
    # Use test_input_validation helper for other validations
    test_input_validation "$ACTION_DIR" "timeout" "3600" "success"
    test_input_validation "$ACTION_DIR" "format" "json" "success"
    test_input_validation "$ACTION_DIR" "command" "echo test" "success"
  End
End

3. Include Security Testing

Always include:

# Use test_input_validation helper for security and path validations
test_input_validation "$ACTION_DIR" "command" "echo test" "success"
test_input_validation "$ACTION_DIR" "user-script" "#!/bin/bash" "success"
test_input_validation "$ACTION_DIR" "working-directory" "." "success"

4. Write Descriptive Test Names

Good:

It "accepts valid semantic version format"
It "rejects version with invalid characters"
It "falls back to default when no version file exists"

Avoid:

It "validates input"
It "works correctly"

5. Keep Tests Independent

  • Each test should work in isolation
  • Don't rely on test execution order
  • Clean up after each test
  • Use proper setup/teardown

🔍 Framework Features

Test Environment Setup

# Setup test environment
setup_test_env "test-name"

# Create mock repositories
create_mock_repo "node"     # Node.js project
create_mock_repo "php"      # PHP project
create_mock_repo "python"   # Python project
create_mock_repo "go"       # Go project
create_mock_repo "dotnet"   # .NET project

# Cleanup
cleanup_test_env "test-name"

Mock Services

Built-in mocks for external services:

  • GitHub API - Repository, releases, packages, workflows
  • NPM Registry - Package publishing and retrieval
  • Docker Registry - Image push/pull operations
  • Container Registries - GitHub Container Registry, Docker Hub

Available Environment Variables

# Test environment paths
$TEST_WORKSPACE       # Current test workspace
$GITHUB_OUTPUT         # Mock GitHub outputs file
$GITHUB_ENV           # Mock GitHub environment file
$GITHUB_STEP_SUMMARY  # Mock step summary file

# Test framework paths
$TEST_ROOT            # _tests/ directory
$FRAMEWORK_DIR        # _tests/framework/ directory
$FIXTURES_DIR         # _tests/framework/fixtures/
$MOCKS_DIR           # _tests/framework/mocks/

🚨 Troubleshooting

Common Issues

"ShellSpec command not found"

# Install ShellSpec globally
curl -fsSL https://github.com/shellspec/shellspec/releases/latest/download/shellspec-dist.tar.gz | tar -xz
sudo make -C shellspec-* install

"act command not found"

# Install nektos/act (macOS)
brew install act

# Install nektos/act (Linux)
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash

Tests timeout

# Increase timeout for slow operations
export TEST_TIMEOUT=300

Permission denied on test scripts

# Make test scripts executable
find _tests/ -name "*.sh" -exec chmod +x {} \;

Debugging Tests

  1. Enable Verbose Mode

    ./_tests/run-tests.sh -v
    
  2. Run Single Test

    shellspec _tests/unit/my-action/validation.spec.sh
    
  3. Check Test Output

    # Test results stored in _tests/reports/
    cat _tests/reports/unit/my-action.txt
    
  4. Debug Mock Environment

    # Enable mock debugging
    export MOCK_DEBUG=true
    

📚 Resources


Framework Development

Adding New Framework Features

  1. New Test Utilities

    # Add to _tests/framework/utils.sh
    your_new_function() {
      local param="$1"
      # Implementation
    }
    
    # Export for availability
    export -f your_new_function
    
  2. New Mock Services

    # Create _tests/framework/mocks/new-service.sh
    # Follow existing patterns in github-api.sh
    
  3. New Validation Helpers

    # Add to _tests/framework/validation_helpers.sh
    # Update this documentation
    

Last Updated: August 17, 2025