diff --git a/CLAUDE.md b/CLAUDE.md index 9d82a1e..c002df6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -71,7 +71,7 @@ Flat structure. Each action self-contained with `action.yml`. -**30 Actions**: Setup (node-setup, language-version-detect), Utilities (action-versioning, version-file-parser), +**26 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), Testing (php-tests, php-laravel-phpunit, php-composer), Build (csharp-build, go-build, docker-build), Publishing (npm-publish, docker-publish, csharp-publish), diff --git a/_tests/integration/workflows/node-setup-test.yml b/_tests/integration/workflows/node-setup-test.yml deleted file mode 100644 index 460c801..0000000 --- a/_tests/integration/workflows/node-setup-test.yml +++ /dev/null @@ -1,510 +0,0 @@ ---- -name: Integration Test - Node Setup -on: - workflow_dispatch: - push: - paths: - - 'node-setup/**' - - '_tests/integration/workflows/node-setup-test.yml' - -jobs: - test-node-setup-version-validation: - name: Test Version Validation - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Test invalid default version format (alphabetic) - run: | - VERSION="abc" - if [[ "$VERSION" =~ ^[0-9]+(\.[0-9]+(\.[0-9]+)?)?$ ]]; then - echo "❌ ERROR: Should reject alphabetic version" - exit 1 - fi - echo "✓ Alphabetic version correctly rejected" - - - name: Test invalid default version (too low) - run: | - VERSION="10" - major=$(echo "$VERSION" | cut -d'.' -f1) - if [ "$major" -lt 14 ] || [ "$major" -gt 30 ]; then - echo "✓ Version $VERSION correctly rejected (major < 14)" - else - echo "❌ ERROR: Should reject Node.js $VERSION" - exit 1 - fi - - - name: Test invalid default version (too high) - run: | - VERSION="50" - major=$(echo "$VERSION" | cut -d'.' -f1) - if [ "$major" -lt 14 ] || [ "$major" -gt 30 ]; then - echo "✓ Version $VERSION correctly rejected (major > 30)" - else - echo "❌ ERROR: Should reject Node.js $VERSION" - exit 1 - fi - - - name: Test valid version formats - run: | - for version in "20" "20.9" "20.9.0" "18" "22.1.0"; do - if [[ "$version" =~ ^[0-9]+(\.[0-9]+(\.[0-9]+)?)?$ ]]; then - major=$(echo "$version" | cut -d'.' -f1) - if [ "$major" -ge 14 ] && [ "$major" -le 30 ]; then - echo "✓ Version $version accepted" - else - echo "❌ ERROR: Version $version should be accepted" - exit 1 - fi - else - echo "❌ ERROR: Version $version format validation failed" - exit 1 - fi - done - - test-node-setup-package-manager-validation: - name: Test Package Manager Validation - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Test valid package managers - run: | - for pm in "npm" "yarn" "pnpm" "bun" "auto"; do - case "$pm" in - "npm"|"yarn"|"pnpm"|"bun"|"auto") - echo "✓ Package manager $pm accepted" - ;; - *) - echo "❌ ERROR: Valid package manager $pm rejected" - exit 1 - ;; - esac - done - - - name: Test invalid package manager - run: | - PM="invalid-pm" - case "$PM" in - "npm"|"yarn"|"pnpm"|"bun"|"auto") - echo "❌ ERROR: Invalid package manager should be rejected" - exit 1 - ;; - *) - echo "✓ Invalid package manager correctly rejected" - ;; - esac - - test-node-setup-url-validation: - name: Test URL Validation - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Test valid registry URLs - run: | - for url in "https://registry.npmjs.org" "http://localhost:4873" "https://npm.custom.com/"; do - if [[ "$url" == "https://"* ]] || [[ "$url" == "http://"* ]]; then - echo "✓ Registry URL $url accepted" - else - echo "❌ ERROR: Valid URL $url rejected" - exit 1 - fi - done - - - name: Test invalid registry URLs - run: | - for url in "ftp://registry.com" "not-a-url" "registry.com"; do - if [[ "$url" == "https://"* ]] || [[ "$url" == "http://"* ]]; then - echo "❌ ERROR: Invalid URL $url should be rejected" - exit 1 - else - echo "✓ Invalid URL $url correctly rejected" - fi - done - - test-node-setup-retries-validation: - name: Test Retries Validation - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Test valid retry counts - run: | - for retries in "1" "3" "5" "10"; do - if [[ "$retries" =~ ^[0-9]+$ ]] && [ "$retries" -gt 0 ] && [ "$retries" -le 10 ]; then - echo "✓ Max retries $retries accepted" - else - echo "❌ ERROR: Valid retry count $retries rejected" - exit 1 - fi - done - - - name: Test invalid retry counts - run: | - for retries in "0" "11" "abc" "-1"; do - if [[ "$retries" =~ ^[0-9]+$ ]] && [ "$retries" -gt 0 ] && [ "$retries" -le 10 ]; then - echo "❌ ERROR: Invalid retry count $retries should be rejected" - exit 1 - else - echo "✓ Invalid retry count $retries correctly rejected" - fi - done - - test-node-setup-boolean-validation: - name: Test Boolean Validation - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Test valid boolean values - run: | - for value in "true" "false"; do - if [[ "$value" == "true" ]] || [[ "$value" == "false" ]]; then - echo "✓ Boolean value $value accepted" - else - echo "❌ ERROR: Valid boolean $value rejected" - exit 1 - fi - done - - - name: Test invalid boolean values - run: | - for value in "yes" "no" "1" "0" "True" "FALSE" ""; do - if [[ "$value" != "true" ]] && [[ "$value" != "false" ]]; then - echo "✓ Invalid boolean value '$value' correctly rejected" - else - echo "❌ ERROR: Invalid boolean $value should be rejected" - exit 1 - fi - done - - test-node-setup-token-validation: - name: Test Auth Token Validation - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Test injection pattern detection - run: | - for token in "token;malicious" "token&&command" "token|pipe"; do - if [[ "$token" == *";"* ]] || [[ "$token" == *"&&"* ]] || [[ "$token" == *"|"* ]]; then - echo "✓ Injection pattern in token correctly detected" - else - echo "❌ ERROR: Should detect injection pattern in: $token" - exit 1 - fi - done - - - name: Test valid tokens - run: | - for token in "npm_AbCdEf1234567890" "github_pat_12345abcdef" "simple-token"; do - if [[ "$token" == *";"* ]] || [[ "$token" == *"&&"* ]] || [[ "$token" == *"|"* ]]; then - echo "❌ ERROR: Valid token should not be rejected: $token" - exit 1 - else - echo "✓ Valid token accepted" - fi - done - - test-node-setup-package-manager-resolution: - name: Test Package Manager Resolution - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Test auto detection with detected PM - run: | - INPUT_PM="auto" - DETECTED_PM="pnpm" - - if [ "$INPUT_PM" = "auto" ]; then - if [ -n "$DETECTED_PM" ]; then - FINAL_PM="$DETECTED_PM" - else - FINAL_PM="npm" - fi - else - FINAL_PM="$INPUT_PM" - fi - - if [[ "$FINAL_PM" != "pnpm" ]]; then - echo "❌ ERROR: Should use detected PM (pnpm)" - exit 1 - fi - echo "✓ Auto-detected package manager correctly resolved" - - - name: Test auto detection without detected PM - run: | - INPUT_PM="auto" - DETECTED_PM="" - - if [ "$INPUT_PM" = "auto" ]; then - if [ -n "$DETECTED_PM" ]; then - FINAL_PM="$DETECTED_PM" - else - FINAL_PM="npm" - fi - else - FINAL_PM="$INPUT_PM" - fi - - if [[ "$FINAL_PM" != "npm" ]]; then - echo "❌ ERROR: Should default to npm" - exit 1 - fi - echo "✓ Defaults to npm when no detection" - - - name: Test explicit package manager - run: | - INPUT_PM="yarn" - DETECTED_PM="pnpm" - - if [ "$INPUT_PM" = "auto" ]; then - if [ -n "$DETECTED_PM" ]; then - FINAL_PM="$DETECTED_PM" - else - FINAL_PM="npm" - fi - else - FINAL_PM="$INPUT_PM" - fi - - if [[ "$FINAL_PM" != "yarn" ]]; then - echo "❌ ERROR: Should use explicit PM (yarn)" - exit 1 - fi - echo "✓ Explicit package manager correctly used" - - test-node-setup-feature-detection: - name: Test Feature Detection - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Create test package.json with ESM - run: | - mkdir -p test-esm - cd test-esm - cat > package.json <<'EOF' - { - "name": "test-esm", - "version": "1.0.0", - "type": "module" - } - EOF - - - name: Test ESM detection - run: | - cd test-esm - if command -v jq >/dev/null 2>&1; then - pkg_type=$(jq -r '.type // "commonjs"' package.json 2>/dev/null) - if [[ "$pkg_type" == "module" ]]; then - echo "✓ ESM support correctly detected" - else - echo "❌ ERROR: Should detect ESM support" - exit 1 - fi - else - echo "⚠️ jq not available, skipping ESM detection test" - echo "✓ ESM detection logic verified (jq would be required in actual action)" - fi - - - name: Create test with TypeScript - run: | - mkdir -p test-ts - cd test-ts - touch tsconfig.json - cat > package.json <<'EOF' - { - "name": "test-ts", - "devDependencies": { - "typescript": "^5.0.0" - } - } - EOF - - - name: Test TypeScript detection - run: | - cd test-ts - typescript_support="false" - if [ -f tsconfig.json ]; then - typescript_support="true" - fi - if [[ "$typescript_support" != "true" ]]; then - echo "❌ ERROR: Should detect TypeScript" - exit 1 - fi - echo "✓ TypeScript support correctly detected" - - - name: Create test with frameworks - run: | - mkdir -p test-frameworks - cd test-frameworks - cat > package.json <<'EOF' - { - "name": "test-frameworks", - "dependencies": { - "react": "^18.0.0", - "next": "^14.0.0" - } - } - EOF - - - name: Test framework detection - run: | - cd test-frameworks - if command -v jq >/dev/null 2>&1; then - has_next=$(jq -e '.dependencies.next or .devDependencies.next' package.json >/dev/null 2>&1 && echo "yes" || echo "no") - has_react=$(jq -e '.dependencies.react or .devDependencies.react' package.json >/dev/null 2>&1 && echo "yes" || echo "no") - - if [[ "$has_next" == "yes" ]] && [[ "$has_react" == "yes" ]]; then - echo "✓ Frameworks (Next.js, React) correctly detected" - else - echo "❌ ERROR: Should detect Next.js and React" - exit 1 - fi - else - echo "⚠️ jq not available, skipping framework detection test" - echo "✓ Framework detection logic verified (jq would be required in actual action)" - fi - - test-node-setup-security: - name: Test Security Measures - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Test token sanitization - run: | - TOKEN="test-token - with-newline" - - # Should remove newlines - sanitized=$(echo "$TOKEN" | tr -d '\n\r') - - if [[ "$sanitized" == *$'\n'* ]] || [[ "$sanitized" == *$'\r'* ]]; then - echo "❌ ERROR: Newlines not removed" - exit 1 - fi - echo "✓ Token sanitization works correctly" - - - name: Test package manager sanitization - run: | - PM="npm - with-newline" - - # Should remove newlines - sanitized=$(echo "$PM" | tr -d '\n\r') - - if [[ "$sanitized" == *$'\n'* ]] || [[ "$sanitized" == *$'\r'* ]]; then - echo "❌ ERROR: Newlines not removed from PM" - exit 1 - fi - echo "✓ Package manager sanitization works correctly" - - test-node-setup-integration-workflow: - name: Test Integration Workflow - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Simulate complete workflow - run: | - echo "=== Simulating Node Setup Workflow ===" - - # 1. Validation - echo "Step 1: Validate inputs" - DEFAULT_VERSION="20" - PACKAGE_MANAGER="npm" - REGISTRY_URL="https://registry.npmjs.org" - CACHE="true" - INSTALL="true" - MAX_RETRIES="3" - echo "✓ Inputs validated" - - # 2. Version parsing - echo "Step 2: Parse Node.js version" - NODE_VERSION="20.9.0" - echo "✓ Version parsed: $NODE_VERSION" - - # 3. Package manager resolution - echo "Step 3: Resolve package manager" - if [ "$PACKAGE_MANAGER" = "auto" ]; then - FINAL_PM="npm" - else - FINAL_PM="$PACKAGE_MANAGER" - fi - echo "✓ Package manager resolved: $FINAL_PM" - - # 4. Setup Node.js - echo "Step 4: Setup Node.js $NODE_VERSION" - if command -v node >/dev/null 2>&1; then - echo "✓ Node.js available: $(node --version)" - fi - - # 5. Enable Corepack - echo "Step 5: Enable Corepack" - if command -v corepack >/dev/null 2>&1; then - echo "✓ Corepack available" - else - echo "⚠️ Corepack not available in test environment" - fi - - # 6. Cache dependencies - if [[ "$CACHE" == "true" ]]; then - echo "Step 6: Cache dependencies" - echo "✓ Would use actions/cache action" - fi - - # 7. Install dependencies - if [[ "$INSTALL" == "true" ]]; then - echo "Step 7: Install dependencies" - echo "✓ Would run: $FINAL_PM install" - fi - - echo "=== Workflow simulation completed ===" - - integration-test-summary: - name: Integration Test Summary - runs-on: ubuntu-latest - needs: - - test-node-setup-version-validation - - test-node-setup-package-manager-validation - - test-node-setup-url-validation - - test-node-setup-retries-validation - - test-node-setup-boolean-validation - - test-node-setup-token-validation - - test-node-setup-package-manager-resolution - - test-node-setup-feature-detection - - test-node-setup-security - - test-node-setup-integration-workflow - steps: - - name: Summary - run: | - echo "==========================================" - echo "Node Setup Integration Tests - PASSED" - echo "==========================================" - echo "" - echo "✓ Version validation tests" - echo "✓ Package manager validation tests" - echo "✓ URL validation tests" - echo "✓ Retries validation tests" - echo "✓ Boolean validation tests" - echo "✓ Token validation tests" - echo "✓ Package manager resolution tests" - echo "✓ Feature detection tests" - echo "✓ Security measure tests" - echo "✓ Integration workflow tests" - echo "" - echo "All node-setup integration tests completed successfully!" diff --git a/_tests/unit/node-setup/validation.spec.sh b/_tests/unit/node-setup/validation.spec.sh deleted file mode 100755 index 1616804..0000000 --- a/_tests/unit/node-setup/validation.spec.sh +++ /dev/null @@ -1,242 +0,0 @@ -#!/usr/bin/env shellspec -# Unit tests for node-setup action - -# Framework is automatically loaded via spec_helper.sh - -Describe "node-setup action" -ACTION_DIR="node-setup" -ACTION_FILE="$ACTION_DIR/action.yml" - -# Framework is automatically initialized via spec_helper.sh - -Context "when validating inputs" -It "accepts valid Node.js version" -When call validate_input_python "node-setup" "default-version" "18.17.0" -The status should be success -End - -It "accepts valid package manager" -When call validate_input_python "node-setup" "package-manager" "npm" -The status should be success -End - -It "accepts yarn as package manager" -When call validate_input_python "node-setup" "package-manager" "yarn" -The status should be success -End - -It "accepts pnpm as package manager" -When call validate_input_python "node-setup" "package-manager" "pnpm" -The status should be success -End - -It "accepts bun as package manager" -When call validate_input_python "node-setup" "package-manager" "bun" -The status should be success -End - -It "rejects invalid package manager" -When call validate_input_python "node-setup" "package-manager" "invalid-manager" -The status should be failure -End - -It "rejects malformed Node.js version" -When call validate_input_python "node-setup" "default-version" "not-a-version" -The status should be failure -End - -It "rejects command injection in inputs" -When call validate_input_python "node-setup" "default-version" "18.0.0; rm -rf /" -The status should be failure -End -End - -Context "when checking action 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" -When call get_action_name "$ACTION_FILE" -The output should equal "Node Setup" -End - -It "defines expected inputs" -When call get_action_inputs "$ACTION_FILE" -The output should include "default-version" -The output should include "package-manager" -End - -It "defines expected outputs" -When call get_action_outputs "$ACTION_FILE" -The output should include "node-version" -The output should include "package-manager" -The output should include "cache-hit" -End -End - -Context "when testing Node.js version detection" -BeforeEach "shellspec_setup_test_env 'node-version-detection'" -AfterEach "shellspec_cleanup_test_env 'node-version-detection'" - -It "detects version from package.json engines field" -create_mock_node_repo - -# Mock action output based on package.json -echo "node-version=18.0.0" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "node-version" "18.0.0" -The status should be success -End - -It "detects version from .nvmrc file" -create_mock_node_repo -echo "18.17.1" >.nvmrc - -# Mock action output -echo "node-version=18.17.1" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "node-version" "18.17.1" -The status should be success -End - -It "uses default version when none specified" -create_mock_node_repo -# Remove engines field simulation - -# Mock default version output -echo "node-version=20.0.0" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "node-version" "20.0.0" -The status should be success -End -End - -Context "when testing package manager detection" -BeforeEach "shellspec_setup_test_env 'package-manager-detection'" -AfterEach "shellspec_cleanup_test_env 'package-manager-detection'" - -It "detects bun from bun.lockb" -create_mock_node_repo -touch bun.lockb - -echo "package-manager=bun" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "package-manager" "bun" -The status should be success -End - -It "detects pnpm from pnpm-lock.yaml" -create_mock_node_repo -touch pnpm-lock.yaml - -echo "package-manager=pnpm" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "package-manager" "pnpm" -The status should be success -End - -It "detects yarn from yarn.lock" -create_mock_node_repo -touch yarn.lock - -echo "package-manager=yarn" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "package-manager" "yarn" -The status should be success -End - -It "detects npm from package-lock.json" -create_mock_node_repo -touch package-lock.json - -echo "package-manager=npm" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "package-manager" "npm" -The status should be success -End - -It "detects packageManager field from package.json" -create_mock_node_repo - -# Add packageManager field to package.json -cat >package.json <=18.0.0" - } -} -EOF - -echo "package-manager=pnpm" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "package-manager" "pnpm" -The status should be success -End -End - -Context "when testing Corepack integration" -BeforeEach "shellspec_setup_test_env 'corepack-test'" -AfterEach "shellspec_cleanup_test_env 'corepack-test'" - -It "enables Corepack when packageManager is specified" -create_mock_node_repo - -# Simulate packageManager field -cat >package.json <>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "corepack-enabled" "true" -The status should be success -End -End - -Context "when testing cache functionality" -BeforeEach "shellspec_setup_test_env 'cache-test'" -AfterEach "shellspec_cleanup_test_env 'cache-test'" - -It "reports cache hit when dependencies are cached" -create_mock_node_repo -touch package-lock.json -mkdir -p node_modules - -# Mock cache hit -echo "cache-hit=true" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "cache-hit" "true" -The status should be success -End - -It "reports cache miss when no cache exists" -create_mock_node_repo -touch package-lock.json - -# Mock cache miss -echo "cache-hit=false" >>"$GITHUB_OUTPUT" - -When call shellspec_validate_action_output "cache-hit" "false" -The status should be success -End -End - -Context "when testing output consistency" -It "produces all expected outputs" -When call test_action_outputs "$ACTION_DIR" "node-version" "18.0.0" "package-manager" "npm" -The status should be success -The stderr should include "Testing action outputs for: node-setup" -The stderr should include "Output test passed for: node-setup" -End -End -End diff --git a/action-versioning/rules.yml b/action-versioning/rules.yml index 62aedb3..4c72c5a 100644 --- a/action-versioning/rules.yml +++ b/action-versioning/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for action-versioning action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: action-versioning description: Automatically update SHA-pinned action references to match latest version tags diff --git a/ansible-lint-fix/rules.yml b/ansible-lint-fix/rules.yml index f37d3de..108bc70 100644 --- a/ansible-lint-fix/rules.yml +++ b/ansible-lint-fix/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for ansible-lint-fix action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: ansible-lint-fix description: Lints and fixes Ansible playbooks, commits changes, and uploads SARIF report. diff --git a/biome-lint/action.yml b/biome-lint/action.yml index d695935..0140ab0 100644 --- a/biome-lint/action.yml +++ b/biome-lint/action.yml @@ -137,24 +137,76 @@ runs: with: token: ${{ inputs.token || github.token }} - - name: Node Setup - id: node-setup - uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 + - name: Detect Package Manager + id: detect-pm + shell: sh + run: | + set -eu + + # Detect package manager from lockfiles + if [ -f bun.lockb ]; then + package_manager="bun" + elif [ -f pnpm-lock.yaml ]; then + package_manager="pnpm" + elif [ -f yarn.lock ]; then + package_manager="yarn" + else + package_manager="npm" + fi + + printf 'package-manager=%s\n' "$package_manager" >> "$GITHUB_OUTPUT" + echo "Detected package manager: $package_manager" + + - name: Setup Node.js + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: '22' + + - name: Enable Corepack + shell: sh + run: | + set -eu + corepack enable + + - name: Install Package Manager + shell: sh + env: + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} + run: | + set -eu + + case "$PACKAGE_MANAGER" in + pnpm) + corepack prepare pnpm@latest --activate + ;; + yarn) + corepack prepare yarn@stable --activate + ;; + bun|npm) + # Bun installed separately, npm built-in + ;; + esac + + - name: Setup Bun + if: steps.detect-pm.outputs.package-manager == 'bun' + uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2 + with: + bun-version: latest - name: Cache Node Dependencies id: cache uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: node_modules - key: ${{ runner.os }}-biome-lint-${{ inputs.mode }}-${{ steps.node-setup.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} + key: ${{ runner.os }}-biome-lint-${{ inputs.mode }}-${{ steps.detect-pm.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} restore-keys: | - ${{ runner.os }}-biome-lint-${{ inputs.mode }}-${{ steps.node-setup.outputs.package-manager }}- + ${{ runner.os }}-biome-lint-${{ inputs.mode }}-${{ steps.detect-pm.outputs.package-manager }}- ${{ runner.os }}-biome-lint-${{ inputs.mode }}- - name: Install Biome shell: bash env: - PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} MAX_RETRIES: ${{ inputs.max-retries }} run: | set -euo pipefail diff --git a/biome-lint/rules.yml b/biome-lint/rules.yml index c577002..6a455ac 100644 --- a/biome-lint/rules.yml +++ b/biome-lint/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for biome-lint action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: biome-lint description: Run Biome linter in check or fix mode diff --git a/codeql-analysis/rules.yml b/codeql-analysis/rules.yml index 86c3490..3f819df 100644 --- a/codeql-analysis/rules.yml +++ b/codeql-analysis/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for codeql-analysis action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: codeql-analysis description: Run CodeQL security analysis for a single language with configurable query suites diff --git a/compress-images/rules.yml b/compress-images/rules.yml index 2301f29..f87a225 100644 --- a/compress-images/rules.yml +++ b/compress-images/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for compress-images action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: compress-images description: Compress images on demand (workflow_dispatch), and at 11pm every Sunday (schedule). diff --git a/csharp-build/rules.yml b/csharp-build/rules.yml index 105660b..de339e6 100644 --- a/csharp-build/rules.yml +++ b/csharp-build/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for csharp-build action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: csharp-build description: Builds and tests C# projects. diff --git a/csharp-lint-check/README.md b/csharp-lint-check/README.md index 49fb1b0..c561e64 100644 --- a/csharp-lint-check/README.md +++ b/csharp-lint-check/README.md @@ -8,18 +8,18 @@ Runs linters like StyleCop or dotnet-format for C# code style checks. ### Inputs -| name | description | required | default | -|------------------|----------------------------------------|----------|---------| -| `dotnet-version` |

Version of .NET SDK to use.

| `false` | `""` | -| `token` |

GitHub token for authentication

| `false` | `""` | +| name | description | required | default | +| --- | --- | --- | --- | +| `dotnet-version` |

Version of .NET SDK to use.

| `false` | `""` | +| `token` |

GitHub token for authentication

| `false` | `""` | ### Outputs -| name | description | -|------------------|----------------------------------------------| -| `lint_status` |

Overall lint status (success/failure)

| -| `errors_count` |

Number of formatting errors found

| -| `warnings_count` |

Number of formatting warnings found

| +| name | description | +| --- | --- | +| `lint_status` |

Overall lint status (success/failure)

| +| `errors_count` |

Number of formatting errors found

| +| `warnings_count` |

Number of formatting warnings found

| ### Runs diff --git a/csharp-lint-check/rules.yml b/csharp-lint-check/rules.yml index 11966fe..d767d50 100644 --- a/csharp-lint-check/rules.yml +++ b/csharp-lint-check/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for csharp-lint-check action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: csharp-lint-check description: Runs linters like StyleCop or dotnet-format for C# code style checks. diff --git a/csharp-publish/README.md b/csharp-publish/README.md index b425e4f..2bfb2f0 100644 --- a/csharp-publish/README.md +++ b/csharp-publish/README.md @@ -8,19 +8,19 @@ Publishes a C# project to GitHub Packages. ### Inputs -| name | description | required | default | -|------------------|----------------------------------------------------|----------|-------------| -| `dotnet-version` |

Version of .NET SDK to use.

| `false` | `""` | -| `namespace` |

GitHub namespace for the package.

| `true` | `ivuorinen` | -| `token` |

GitHub token with package write permissions

| `false` | `""` | +| name | description | required | default | +| --- | --- | --- | --- | +| `dotnet-version` |

Version of .NET SDK to use.

| `false` | `""` | +| `namespace` |

GitHub namespace for the package.

| `true` | `ivuorinen` | +| `token` |

GitHub token with package write permissions

| `false` | `""` | ### Outputs -| name | description | -|-------------------|-------------------------------------------------| -| `publish_status` |

Overall publish status (success/failure)

| -| `package_version` |

Version of the published package

| -| `package_url` |

URL of the published package

| +| name | description | +| --- | --- | +| `publish_status` |

Overall publish status (success/failure)

| +| `package_version` |

Version of the published package

| +| `package_url` |

URL of the published package

| ### Runs diff --git a/csharp-publish/rules.yml b/csharp-publish/rules.yml index 342f4f9..6552bd7 100644 --- a/csharp-publish/rules.yml +++ b/csharp-publish/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for csharp-publish action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: csharp-publish description: Publishes a C# project to GitHub Packages. diff --git a/docker-build/rules.yml b/docker-build/rules.yml index 708e088..d53970a 100644 --- a/docker-build/rules.yml +++ b/docker-build/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for docker-build action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: docker-build description: Builds a Docker image for multiple architectures with enhanced security and reliability. diff --git a/docker-publish/README.md b/docker-publish/README.md index b3d6386..3171e4c 100644 --- a/docker-publish/README.md +++ b/docker-publish/README.md @@ -8,28 +8,28 @@ Simple wrapper to publish Docker images to GitHub Packages and/or Docker Hub ### Inputs -| name | description | required | default | -|----------------------|-------------------------------------------------------------------|----------|---------------------------| -| `registry` |

Registry to publish to (dockerhub, github, or both)

| `false` | `both` | -| `image-name` |

Docker image name (defaults to repository name)

| `false` | `""` | -| `tags` |

Comma-separated list of tags (e.g., latest,v1.0.0)

| `false` | `latest` | -| `platforms` |

Platforms to build for (comma-separated)

| `false` | `linux/amd64,linux/arm64` | -| `context` |

Build context path

| `false` | `.` | -| `dockerfile` |

Path to Dockerfile

| `false` | `Dockerfile` | -| `build-args` |

Build arguments (newline-separated KEY=VALUE pairs)

| `false` | `""` | -| `push` |

Whether to push the image

| `false` | `true` | -| `token` |

GitHub token for authentication (for GitHub registry)

| `false` | `""` | -| `dockerhub-username` |

Docker Hub username (required if publishing to Docker Hub)

| `false` | `""` | -| `dockerhub-token` |

Docker Hub token (required if publishing to Docker Hub)

| `false` | `""` | +| name | description | required | default | +| --- | --- | --- | --- | +| `registry` |

Registry to publish to (dockerhub, github, or both)

| `false` | `both` | +| `image-name` |

Docker image name (defaults to repository name)

| `false` | `""` | +| `tags` |

Comma-separated list of tags (e.g., latest,v1.0.0)

| `false` | `latest` | +| `platforms` |

Platforms to build for (comma-separated)

| `false` | `linux/amd64,linux/arm64` | +| `context` |

Build context path

| `false` | `.` | +| `dockerfile` |

Path to Dockerfile

| `false` | `Dockerfile` | +| `build-args` |

Build arguments (newline-separated KEY=VALUE pairs)

| `false` | `""` | +| `push` |

Whether to push the image

| `false` | `true` | +| `token` |

GitHub token for authentication (for GitHub registry)

| `false` | `""` | +| `dockerhub-username` |

Docker Hub username (required if publishing to Docker Hub)

| `false` | `""` | +| `dockerhub-token` |

Docker Hub token (required if publishing to Docker Hub)

| `false` | `""` | ### Outputs -| name | description | -|--------------|--------------------------------------| +| name | description | +| --- | --- | | `image-name` |

Full image name with registry

| -| `tags` |

Tags that were published

| -| `digest` |

Image digest

| -| `metadata` |

Build metadata

| +| `tags` |

Tags that were published

| +| `digest` |

Image digest

| +| `metadata` |

Build metadata

| ### Runs diff --git a/docker-publish/rules.yml b/docker-publish/rules.yml index 70aa1bc..b328ec8 100644 --- a/docker-publish/rules.yml +++ b/docker-publish/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for docker-publish action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: docker-publish description: Simple wrapper to publish Docker images to GitHub Packages and/or Docker Hub diff --git a/eslint-lint/action.yml b/eslint-lint/action.yml index ad1f817..854bfc9 100644 --- a/eslint-lint/action.yml +++ b/eslint-lint/action.yml @@ -242,25 +242,77 @@ runs: with: token: ${{ inputs.token || github.token }} - - name: Node Setup - id: node-setup - uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 + - name: Detect Package Manager + id: detect-pm + shell: sh + run: | + set -eu + + # Detect package manager from lockfiles + if [ -f bun.lockb ]; then + package_manager="bun" + elif [ -f pnpm-lock.yaml ]; then + package_manager="pnpm" + elif [ -f yarn.lock ]; then + package_manager="yarn" + else + package_manager="npm" + fi + + printf 'package-manager=%s\n' "$package_manager" >> "$GITHUB_OUTPUT" + echo "Detected package manager: $package_manager" + + - name: Setup Node.js + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: '22' + + - name: Enable Corepack + shell: sh + run: | + set -eu + corepack enable + + - name: Install Package Manager + shell: sh + env: + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} + run: | + set -eu + + case "$PACKAGE_MANAGER" in + pnpm) + corepack prepare pnpm@latest --activate + ;; + yarn) + corepack prepare yarn@stable --activate + ;; + bun|npm) + # Bun installed separately, npm built-in + ;; + esac + + - name: Setup Bun + if: steps.detect-pm.outputs.package-manager == 'bun' + uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2 + with: + bun-version: latest - name: Cache Node Dependencies id: cache uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: node_modules - key: ${{ runner.os }}-eslint-lint-${{ inputs.mode }}-${{ steps.node-setup.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} + key: ${{ runner.os }}-eslint-lint-${{ inputs.mode }}-${{ steps.detect-pm.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} restore-keys: | - ${{ runner.os }}-eslint-lint-${{ inputs.mode }}-${{ steps.node-setup.outputs.package-manager }}- + ${{ runner.os }}-eslint-lint-${{ inputs.mode }}-${{ steps.detect-pm.outputs.package-manager }}- ${{ runner.os }}-eslint-lint-${{ inputs.mode }}- - name: Install Dependencies if: steps.cache.outputs.cache-hit != 'true' shell: bash env: - PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} run: | set -euo pipefail @@ -293,7 +345,7 @@ runs: shell: bash working-directory: ${{ inputs.working-directory }} env: - PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} ESLINT_VERSION: ${{ inputs.eslint-version }} CONFIG_FILE: ${{ inputs.config-file }} CACHE: ${{ inputs.cache }} @@ -377,7 +429,7 @@ runs: shell: bash working-directory: ${{ inputs.working-directory }} env: - PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} run: | set -euo pipefail diff --git a/eslint-lint/rules.yml b/eslint-lint/rules.yml index ce75119..32d067a 100644 --- a/eslint-lint/rules.yml +++ b/eslint-lint/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for eslint-lint action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: eslint-lint description: Run ESLint in check or fix mode with advanced configuration and reporting diff --git a/generate_listing.cjs b/generate_listing.cjs index e241110..93b488c 100755 --- a/generate_listing.cjs +++ b/generate_listing.cjs @@ -8,7 +8,6 @@ const { markdownTable } = require('markdown-table'); // Category mappings const CATEGORIES = { // Setup & Environment - 'node-setup': 'Setup', 'language-version-detect': 'Setup', // Utilities @@ -55,7 +54,6 @@ const CATEGORIES = { // Language support mappings const LANGUAGE_SUPPORT = { - 'node-setup': ['Node.js', 'JavaScript', 'TypeScript'], 'language-version-detect': ['PHP', 'Python', 'Go', '.NET', 'Node.js'], 'php-tests': ['PHP'], 'php-laravel-phpunit': ['PHP', 'Laravel'], diff --git a/go-build/README.md b/go-build/README.md index 571cb45..fd21832 100644 --- a/go-build/README.md +++ b/go-build/README.md @@ -8,22 +8,22 @@ Builds the Go project. ### Inputs -| name | description | required | default | -|---------------|------------------------------------------------------------------------|----------|---------| -| `go-version` |

Go version to use.

| `false` | `""` | -| `destination` |

Build destination directory.

| `false` | `./bin` | -| `max-retries` |

Maximum number of retry attempts for go mod download operations

| `false` | `3` | -| `token` |

GitHub token for authentication

| `false` | `""` | +| name | description | required | default | +| --- | --- | --- | --- | +| `go-version` |

Go version to use.

| `false` | `""` | +| `destination` |

Build destination directory.

| `false` | `./bin` | +| `max-retries` |

Maximum number of retry attempts for go mod download operations

| `false` | `3` | +| `token` |

GitHub token for authentication

| `false` | `""` | ### Outputs -| name | description | -|-----------------|--------------------------------------------------------| -| `build_status` |

Build completion status (success/failure)

| -| `test_status` |

Test execution status (success/failure/skipped)

| -| `go_version` |

Version of Go used

| -| `binary_path` |

Path to built binaries

| -| `coverage_path` |

Path to coverage report

| +| name | description | +| --- | --- | +| `build_status` |

Build completion status (success/failure)

| +| `test_status` |

Test execution status (success/failure/skipped)

| +| `go_version` |

Version of Go used

| +| `binary_path` |

Path to built binaries

| +| `coverage_path` |

Path to coverage report

| ### Runs diff --git a/go-build/rules.yml b/go-build/rules.yml index 1dd23b5..c5a9f50 100644 --- a/go-build/rules.yml +++ b/go-build/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for go-build action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: go-build description: Builds the Go project. diff --git a/go-lint/rules.yml b/go-lint/rules.yml index bfcd950..6cfbdf1 100644 --- a/go-lint/rules.yml +++ b/go-lint/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for go-lint action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: go-lint description: Run golangci-lint with advanced configuration, caching, and reporting diff --git a/language-version-detect/rules.yml b/language-version-detect/rules.yml index dc600aa..1427f33 100644 --- a/language-version-detect/rules.yml +++ b/language-version-detect/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for language-version-detect action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,11 +7,9 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' 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 required_inputs: - language diff --git a/node-setup/CustomValidator.py b/node-setup/CustomValidator.py deleted file mode 100755 index b3b58eb..0000000 --- a/node-setup/CustomValidator.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -"""Custom validator for node-setup 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.version import VersionValidator - - -class CustomValidator(BaseValidator): - """Custom validator for node-setup action.""" - - def __init__(self, action_type: str = "node-setup") -> None: - """Initialize node-setup validator.""" - super().__init__(action_type) - self.version_validator = VersionValidator() - - def validate_inputs(self, inputs: dict[str, str]) -> bool: - """Validate node-setup action inputs.""" - valid = True - - # Validate default-version if provided - if "default-version" in inputs: - value = inputs["default-version"] - - # Empty string should fail validation - if value == "": - self.add_error("Node version cannot be empty") - valid = False - elif value: - # Use the Node version validator - result = self.version_validator.validate_node_version(value, "default-version") - - # Propagate errors from the version validator - for error in self.version_validator.errors: - if error not in self.errors: - self.add_error(error) - - # Clear the version validator's errors after propagating - self.version_validator.clear_errors() - - if not result: - valid = False - - # Validate package-manager if provided - if "package-manager" in inputs: - value = inputs["package-manager"] - if value and value not in ["npm", "yarn", "pnpm", "bun"]: - self.add_error( - f"Invalid package manager: {value}. Must be one of: npm, yarn, pnpm, bun" - ) - 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 { - "default-version": { - "type": "node_version", - "required": False, - "description": "Default Node.js version to use", - }, - "package-manager": { - "type": "string", - "required": False, - "description": "Package manager to use", - }, - } diff --git a/node-setup/README.md b/node-setup/README.md deleted file mode 100644 index fbac71a..0000000 --- a/node-setup/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# ivuorinen/actions/node-setup - -## Node Setup - -### Description - -Sets up Node.js environment with version detection and package manager configuration. - -### Inputs - -| name | description | required | default | -|-------------------|--------------------------------------------------------------------------|----------|------------------------------| -| `default-version` |

Default Node.js version to use if no configuration file is found.

| `false` | `22` | -| `package-manager` |

Node.js package manager to use (npm, yarn, pnpm, bun, auto)

| `false` | `auto` | -| `registry-url` |

Custom NPM registry URL

| `false` | `https://registry.npmjs.org` | -| `token` |

Auth token for private registry

| `false` | `""` | -| `node-mirror` |

Custom Node.js binary mirror

| `false` | `""` | -| `force-version` |

Force specific Node.js version regardless of config files

| `false` | `""` | - -### Outputs - -| name | description | -|-------------------|-------------------------------------| -| `node-version` |

Installed Node.js version

| -| `package-manager` |

Selected package manager

| -| `node-path` |

Path to Node.js installation

| - -### Runs - -This action is a `composite` action. - -### Usage - -```yaml -- uses: ivuorinen/actions/node-setup@main - with: - default-version: - # Default Node.js version to use if no configuration file is found. - # - # Required: false - # Default: 22 - - package-manager: - # Node.js package manager to use (npm, yarn, pnpm, bun, auto) - # - # Required: false - # Default: auto - - registry-url: - # Custom NPM registry URL - # - # Required: false - # Default: https://registry.npmjs.org - - token: - # Auth token for private registry - # - # Required: false - # Default: "" - - node-mirror: - # Custom Node.js binary mirror - # - # Required: false - # Default: "" - - force-version: - # Force specific Node.js version regardless of config files - # - # Required: false - # Default: "" -``` diff --git a/node-setup/action.yml b/node-setup/action.yml deleted file mode 100644 index 8b16d68..0000000 --- a/node-setup/action.yml +++ /dev/null @@ -1,370 +0,0 @@ -# yaml-language-server: $schema=https://json.schemastore.org/github-action.json -# permissions: -# - (none required) # Setup action, no repository writes ---- -name: Node Setup -description: 'Sets up Node.js environment with version detection and package manager configuration.' -author: 'Ismo Vuorinen' - -branding: - icon: server - color: green - -inputs: - default-version: - description: 'Default Node.js version to use if no configuration file is found.' - required: false - default: '22' - package-manager: - description: 'Node.js package manager to use (npm, yarn, pnpm, bun, auto)' - required: false - default: 'auto' - registry-url: - description: 'Custom NPM registry URL' - required: false - default: 'https://registry.npmjs.org' - token: - description: 'Auth token for private registry' - required: false - node-mirror: - description: 'Custom Node.js binary mirror' - required: false - force-version: - description: 'Force specific Node.js version regardless of config files' - required: false - -outputs: - node-version: - description: 'Installed Node.js version' - value: ${{ steps.setup.outputs.node-version }} - package-manager: - description: 'Selected package manager' - value: ${{ steps.package-manager-resolution.outputs.final-package-manager }} - node-path: - description: 'Path to Node.js installation' - value: ${{ steps.final-outputs.outputs.node-path }} - -runs: - using: composite - steps: - - name: Validate Inputs - id: validate - shell: bash - env: - DEFAULT_VERSION: ${{ inputs.default-version }} - FORCE_VERSION: ${{ inputs.force-version }} - PACKAGE_MANAGER: ${{ inputs.package-manager }} - REGISTRY_URL: ${{ inputs.registry-url }} - NODE_MIRROR: ${{ inputs.node-mirror }} - AUTH_TOKEN: ${{ inputs.token }} - run: | - set -euo pipefail - - # Validate default-version format - if [[ -n "$DEFAULT_VERSION" ]]; then - if ! [[ "$DEFAULT_VERSION" =~ ^[0-9]+(\.[0-9]+(\.[0-9]+)?)?$ ]]; then - echo "::error::Invalid default-version format: '$DEFAULT_VERSION'. Expected format: X or X.Y or X.Y.Z (e.g., 22, 20.9, 18.17.1)" - exit 1 - fi - - # Check for reasonable version range (prevent malicious inputs) - major_version=$(echo "$DEFAULT_VERSION" | cut -d'.' -f1) - if [ "$major_version" -lt 14 ] || [ "$major_version" -gt 30 ]; then - echo "::error::Invalid default-version: '$DEFAULT_VERSION'. Node.js major version should be between 14 and 30" - exit 1 - fi - fi - - # Validate force-version format if provided - if [[ -n "$FORCE_VERSION" ]]; then - if ! [[ "$FORCE_VERSION" =~ ^[0-9]+(\.[0-9]+(\.[0-9]+)?)?$ ]]; then - echo "::error::Invalid force-version format: '$FORCE_VERSION'. Expected format: X or X.Y or X.Y.Z (e.g., 22, 20.9, 18.17.1)" - exit 1 - fi - - # Check for reasonable version range - major_version=$(echo "$FORCE_VERSION" | cut -d'.' -f1) - if [ "$major_version" -lt 14 ] || [ "$major_version" -gt 30 ]; then - echo "::error::Invalid force-version: '$FORCE_VERSION'. Node.js major version should be between 14 and 30" - exit 1 - fi - fi - - # Validate package-manager - case "$PACKAGE_MANAGER" in - "npm"|"yarn"|"pnpm"|"bun"|"auto") - # Valid package managers - ;; - *) - echo "::error::Invalid package-manager: '$PACKAGE_MANAGER'. Must be one of: npm, yarn, pnpm, bun, auto" - exit 1 - ;; - esac - - # Validate registry-url format (basic URL validation) - if [[ "$REGISTRY_URL" != "https://"* ]] && [[ "$REGISTRY_URL" != "http://"* ]]; then - echo "::error::Invalid registry-url: '$REGISTRY_URL'. Must be a valid HTTP/HTTPS URL" - exit 1 - fi - - # Validate node-mirror format if provided - if [[ -n "$NODE_MIRROR" ]]; then - if [[ "$NODE_MIRROR" != "https://"* ]] && [[ "$NODE_MIRROR" != "http://"* ]]; then - echo "::error::Invalid node-mirror: '$NODE_MIRROR'. Must be a valid HTTP/HTTPS URL" - exit 1 - fi - fi - - # Validate auth token format if provided (basic check for NPM tokens) - if [[ -n "$AUTH_TOKEN" ]]; then - if [[ "$AUTH_TOKEN" == *";"* ]] || [[ "$AUTH_TOKEN" == *"&&"* ]] || [[ "$AUTH_TOKEN" == *"|"* ]]; then - echo "::error::Invalid token format: command injection patterns not allowed" - exit 1 - fi - fi - - echo "Input validation completed successfully" - - - name: Checkout Repository - uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e # v6-beta - with: - token: ${{ inputs.token || github.token }} - - - name: Detect Node.js Version - id: version - shell: sh - env: - DEFAULT_VERSION: "${{ inputs.force-version != '' && inputs.force-version || inputs.default-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="" - detected_package_manager="" - - # Parse .nvmrc file (highest priority for Node.js) - if [ -f .nvmrc ]; then - echo "Checking .nvmrc..." >&2 - version=$(tr -d '\r' < .nvmrc | head -1) - if [ -n "$version" ]; then - version=$(clean_version "$version") - if validate_version "$version"; then - echo "Found Node.js version in .nvmrc: $version" >&2 - detected_version="$version" - fi - fi - fi - - # Parse package.json - if [ -z "$detected_version" ] && [ -f package.json ]; then - echo "Checking package.json for Node.js version..." >&2 - if command -v jq >/dev/null 2>&1; then - version=$(jq -r '.engines.node // empty' package.json 2>/dev/null | sed -n 's/[^0-9]*\([0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*/\1/p') - if [ -n "$version" ]; then - version=$(clean_version "$version") - if validate_version "$version"; then - echo "Found Node.js version in package.json: $version" >&2 - detected_version="$version" - fi - fi - else - echo "jq not found; skipping package.json version parsing" >&2 - fi - fi - - # Parse .tool-versions file - if [ -z "$detected_version" ] && [ -f .tool-versions ]; then - echo "Checking .tool-versions for nodejs..." >&2 - version=$(awk '/^nodejs[[: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 Node.js 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 node..." >&2 - version=$(grep -iF "FROM" Dockerfile | grep -F "node:" | head -1 | \ - sed -n -E "s/.*node:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "") - if [ -n "$version" ]; then - version=$(clean_version "$version") - if validate_version "$version"; then - echo "Found Node.js 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 node..." >&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/.*node:([0-9]+(\.[0-9]+)*)(-[^:]*)?.*/\1/p" || echo "") - if [ -n "$version" ]; then - version=$(clean_version "$version") - if validate_version "$version"; then - echo "Found Node.js version in devcontainer: $version" >&2 - detected_version="$version" - fi - fi - else - echo "jq not found; skipping devcontainer.json parsing" >&2 - fi - fi - - # Detect package manager - if [ -f bun.lockb ]; then - detected_package_manager="bun" - elif [ -f pnpm-lock.yaml ]; then - detected_package_manager="pnpm" - elif [ -f yarn.lock ]; then - detected_package_manager="yarn" - elif [ -f package-lock.json ]; then - detected_package_manager="npm" - elif [ -f package.json ]; then - if command -v jq >/dev/null 2>&1; then - pkg_manager=$(jq -r '.packageManager // empty' package.json 2>/dev/null | sed 's/@.*//') - if [ -n "$pkg_manager" ]; then - detected_package_manager="$pkg_manager" - else - detected_package_manager="npm" - fi - else - detected_package_manager="npm" - fi - else - detected_package_manager="npm" - fi - - # Use default version if nothing detected - if [ -z "$detected_version" ]; then - detected_version="$DEFAULT_VERSION" - echo "Using default Node.js version: $detected_version" >&2 - fi - - # Set outputs - printf 'detected-version=%s\n' "$detected_version" >> "$GITHUB_OUTPUT" - printf 'package-manager=%s\n' "$detected_package_manager" >> "$GITHUB_OUTPUT" - echo "Final detected Node.js version: $detected_version" >&2 - echo "Detected package manager: $detected_package_manager" >&2 - - - name: Resolve Package Manager - id: package-manager-resolution - shell: bash - env: - INPUT_PM: ${{ inputs.package-manager }} - DETECTED_PM: ${{ steps.version.outputs.package-manager }} - run: | - set -euo pipefail - - input_pm="$INPUT_PM" - detected_pm="$DETECTED_PM" - final_pm="" - - if [ "$input_pm" = "auto" ]; then - if [ -n "$detected_pm" ]; then - final_pm="$detected_pm" - echo "Auto-detected package manager: $final_pm" - else - final_pm="npm" - echo "No package manager detected, using default: $final_pm" - fi - else - final_pm="$input_pm" - echo "Using specified package manager: $final_pm" - fi - - echo "final-package-manager=$final_pm" >> $GITHUB_OUTPUT - echo "Final package manager: $final_pm" - - - name: Setup Node.js - id: setup - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: ${{ steps.version.outputs.detected-version }} - registry-url: ${{ inputs.registry-url }} - - - name: Enable Corepack - id: corepack - shell: bash - run: | - set -euo pipefail - echo "Enabling Corepack for package manager management..." - corepack enable - echo "✅ Corepack enabled successfully" - - - name: Set Auth Token - if: inputs.token != '' - shell: bash - env: - TOKEN: ${{ inputs.token }} - run: | - # Sanitize token by removing newlines to prevent env var injection - sanitized_token="$(echo "$TOKEN" | tr -d '\n\r')" - printf 'NODE_AUTH_TOKEN=%s\n' "$sanitized_token" >> "$GITHUB_ENV" - - - name: Setup Package Manager - shell: bash - env: - PACKAGE_MANAGER: ${{ steps.package-manager-resolution.outputs.final-package-manager }} - run: | - set -euo pipefail - - package_manager="$PACKAGE_MANAGER" - echo "Setting up package manager: $package_manager" - - case "$package_manager" in - "pnpm") - echo "Installing PNPM via Corepack..." - corepack prepare pnpm@latest --activate - echo "✅ PNPM installed successfully" - ;; - "yarn") - echo "Installing Yarn via Corepack..." - corepack prepare yarn@stable --activate - echo "✅ Yarn installed successfully" - ;; - "bun") - # Bun installation handled by separate step below - echo "Bun will be installed via official setup-bun action" - ;; - "npm") - echo "Using built-in NPM" - ;; - *) - echo "::warning::Unknown package manager: $package_manager, using NPM" - ;; - esac - - - name: Setup Bun - if: steps.package-manager-resolution.outputs.final-package-manager == 'bun' - uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2 - with: - bun-version: latest - - - name: Set Final Outputs - id: final-outputs - shell: bash - run: | - echo "node-path=$(which node)" >> $GITHUB_OUTPUT diff --git a/node-setup/rules.yml b/node-setup/rules.yml deleted file mode 100644 index efc7687..0000000 --- a/node-setup/rules.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- -# Validation rules for node-setup action -# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY -# Schema version: 1.0 -# Coverage: 83% (5/6 inputs) -# -# This file defines validation rules for the node-setup GitHub Action. -# Rules are automatically applied by validate-inputs action when this -# action is used. -# - -schema_version: '1.0' -action: node-setup -description: Sets up Node.js environment with version detection and package manager configuration. -generator_version: 1.0.0 -required_inputs: [] -optional_inputs: - - default-version - - force-version - - node-mirror - - package-manager - - registry-url - - token -conventions: - default-version: semantic_version - force-version: semantic_version - package-manager: boolean - registry-url: url - token: github_token -overrides: - package-manager: package_manager_enum -statistics: - total_inputs: 6 - validated_inputs: 5 - skipped_inputs: 0 - coverage_percentage: 83 -validation_coverage: 83 -auto_detected: true -manual_review_required: false -quality_indicators: - has_required_inputs: false - has_token_validation: true - has_version_validation: true - has_file_validation: false - has_security_validation: true diff --git a/npm-publish/README.md b/npm-publish/README.md index 6c0f50f..c0ec44a 100644 --- a/npm-publish/README.md +++ b/npm-publish/README.md @@ -8,21 +8,21 @@ Publishes the package to the NPM registry with configurable scope and registry U ### Inputs -| name | description | required | default | -|-------------------|----------------------------------------|----------|----------------------------------------| -| `npm_token` |

NPM token.

| `true` | `""` | -| `registry-url` |

Registry URL for publishing.

| `false` | `https://registry.npmjs.org/` | -| `scope` |

Package scope to use.

| `false` | `@ivuorinen` | -| `package-version` |

The version to publish.

| `false` | `${{ github.event.release.tag_name }}` | -| `token` |

GitHub token for authentication

| `false` | `""` | +| name | description | required | default | +| --- | --- | --- | --- | +| `npm_token` |

NPM token.

| `true` | `""` | +| `registry-url` |

Registry URL for publishing.

| `false` | `https://registry.npmjs.org/` | +| `scope` |

Package scope to use.

| `false` | `@ivuorinen` | +| `package-version` |

The version to publish.

| `false` | `${{ github.event.release.tag_name }}` | +| `token` |

GitHub token for authentication

| `false` | `""` | ### Outputs -| name | description | -|-------------------|-------------------------------------| -| `registry-url` |

Registry URL for publishing.

| -| `scope` |

Package scope to use.

| -| `package-version` |

The version to publish.

| +| name | description | +| --- | --- | +| `registry-url` |

Registry URL for publishing.

| +| `scope` |

Package scope to use.

| +| `package-version` |

The version to publish.

| ### Runs diff --git a/npm-publish/action.yml b/npm-publish/action.yml index f2e88a1..03a5bf1 100644 --- a/npm-publish/action.yml +++ b/npm-publish/action.yml @@ -100,24 +100,76 @@ runs: with: token: ${{ inputs.token || github.token }} + - name: Detect Package Manager + id: detect-pm + shell: sh + run: | + set -eu + + # Detect package manager from lockfiles + if [ -f bun.lockb ]; then + package_manager="bun" + elif [ -f pnpm-lock.yaml ]; then + package_manager="pnpm" + elif [ -f yarn.lock ]; then + package_manager="yarn" + else + package_manager="npm" + fi + + printf 'package-manager=%s\n' "$package_manager" >> "$GITHUB_OUTPUT" + echo "Detected package manager: $package_manager" + - name: Setup Node.js - id: node-setup - uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: '22' + + - name: Enable Corepack + shell: sh + run: | + set -eu + corepack enable + + - name: Install Package Manager + shell: sh + env: + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} + run: | + set -eu + + case "$PACKAGE_MANAGER" in + pnpm) + corepack prepare pnpm@latest --activate + ;; + yarn) + corepack prepare yarn@stable --activate + ;; + bun|npm) + # Bun installed separately, npm built-in + ;; + esac + + - name: Setup Bun + if: steps.detect-pm.outputs.package-manager == 'bun' + uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2 + with: + bun-version: latest - name: Cache Node Dependencies id: cache uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: node_modules - key: ${{ runner.os }}-npm-publish-${{ steps.node-setup.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} + key: ${{ runner.os }}-npm-publish-${{ steps.detect-pm.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} restore-keys: | - ${{ runner.os }}-npm-publish-${{ steps.node-setup.outputs.package-manager }}- + ${{ runner.os }}-npm-publish-${{ steps.detect-pm.outputs.package-manager }}- - name: Install Dependencies if: steps.cache.outputs.cache-hit != 'true' shell: sh env: - PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} run: | set -eu diff --git a/npm-publish/rules.yml b/npm-publish/rules.yml index 678f1bf..773dcde 100644 --- a/npm-publish/rules.yml +++ b/npm-publish/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for npm-publish action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: npm-publish description: Publishes the package to the NPM registry with configurable scope and registry URL. diff --git a/php-composer/rules.yml b/php-composer/rules.yml index 15aef62..3324d41 100644 --- a/php-composer/rules.yml +++ b/php-composer/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for php-composer action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # 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. diff --git a/php-laravel-phpunit/README.md b/php-laravel-phpunit/README.md index c21d2c7..53f499d 100644 --- a/php-laravel-phpunit/README.md +++ b/php-laravel-phpunit/README.md @@ -8,22 +8,22 @@ Setup PHP, install dependencies, generate key, create database and run composer ### Inputs -| name | description | required | default | -|--------------------|-----------------------------------------------------------------------------------------------------------------------|----------|---------------------------------------------| -| `php-version` |

PHP Version to use, see https://github.com/marketplace/actions/setup-php-action#php-version-optional

| `false` | `latest` | -| `php-version-file` |

PHP Version file to use, see https://github.com/marketplace/actions/setup-php-action#php-version-file-optional

| `false` | `.php-version` | -| `extensions` |

PHP extensions to install, see https://github.com/marketplace/actions/setup-php-action#extensions-optional

| `false` | `mbstring, intl, json, pdo_sqlite, sqlite3` | -| `coverage` |

Specify code-coverage driver, see https://github.com/marketplace/actions/setup-php-action#coverage-optional

| `false` | `none` | -| `token` |

GitHub token for authentication

| `false` | `""` | +| name | description | required | default | +| --- | --- | --- | --- | +| `php-version` |

PHP Version to use, see https://github.com/marketplace/actions/setup-php-action#php-version-optional

| `false` | `latest` | +| `php-version-file` |

PHP Version file to use, see https://github.com/marketplace/actions/setup-php-action#php-version-file-optional

| `false` | `.php-version` | +| `extensions` |

PHP extensions to install, see https://github.com/marketplace/actions/setup-php-action#extensions-optional

| `false` | `mbstring, intl, json, pdo_sqlite, sqlite3` | +| `coverage` |

Specify code-coverage driver, see https://github.com/marketplace/actions/setup-php-action#coverage-optional

| `false` | `none` | +| `token` |

GitHub token for authentication

| `false` | `""` | ### Outputs -| name | description | -|--------------------|------------------------------------------------| -| `php-version` |

The PHP version that was setup

| -| `php-version-file` |

The PHP version file that was used

| -| `extensions` |

The PHP extensions that were installed

| -| `coverage` |

The code-coverage driver that was setup

| +| name | description | +| --- | --- | +| `php-version` |

The PHP version that was setup

| +| `php-version-file` |

The PHP version file that was used

| +| `extensions` |

The PHP extensions that were installed

| +| `coverage` |

The code-coverage driver that was setup

| ### Runs diff --git a/php-laravel-phpunit/rules.yml b/php-laravel-phpunit/rules.yml index d3576b5..f7249ef 100644 --- a/php-laravel-phpunit/rules.yml +++ b/php-laravel-phpunit/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for php-laravel-phpunit action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # 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 diff --git a/php-tests/README.md b/php-tests/README.md index 992255f..a3c6112 100644 --- a/php-tests/README.md +++ b/php-tests/README.md @@ -8,20 +8,20 @@ Run PHPUnit tests on the repository ### Inputs -| name | description | required | default | -|------------|----------------------------------------|----------|-----------------------------| -| `token` |

GitHub token for authentication

| `false` | `""` | -| `username` |

GitHub username for commits

| `false` | `github-actions` | -| `email` |

GitHub email for commits

| `false` | `github-actions@github.com` | +| name | description | required | default | +| --- | --- | --- | --- | +| `token` |

GitHub token for authentication

| `false` | `""` | +| `username` |

GitHub username for commits

| `false` | `github-actions` | +| `email` |

GitHub email for commits

| `false` | `github-actions@github.com` | ### Outputs -| name | description | -|-----------------|--------------------------------------------------------| -| `test_status` |

Test execution status (success/failure/skipped)

| -| `tests_run` |

Number of tests executed

| -| `tests_passed` |

Number of tests passed

| -| `coverage_path` |

Path to coverage report

| +| name | description | +| --- | --- | +| `test_status` |

Test execution status (success/failure/skipped)

| +| `tests_run` |

Number of tests executed

| +| `tests_passed` |

Number of tests passed

| +| `coverage_path` |

Path to coverage report

| ### Runs diff --git a/php-tests/rules.yml b/php-tests/rules.yml index 057d08a..4eeb9fd 100644 --- a/php-tests/rules.yml +++ b/php-tests/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for php-tests action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: php-tests description: Run PHPUnit tests on the repository diff --git a/pr-lint/action.yml b/pr-lint/action.yml index d7e04ed..dc701d5 100644 --- a/pr-lint/action.yml +++ b/pr-lint/action.yml @@ -76,10 +76,65 @@ runs: printf '%s\n' "found=true" >> "$GITHUB_OUTPUT" fi - - name: Setup Node.js environment + - name: Detect Package Manager if: steps.detect-node.outputs.found == 'true' - id: node-setup - uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 + id: detect-pm + shell: sh + run: | + set -eu + + # Detect package manager from lockfiles + if [ -f bun.lockb ]; then + package_manager="bun" + elif [ -f pnpm-lock.yaml ]; then + package_manager="pnpm" + elif [ -f yarn.lock ]; then + package_manager="yarn" + else + package_manager="npm" + fi + + printf 'package-manager=%s\n' "$package_manager" >> "$GITHUB_OUTPUT" + echo "Detected package manager: $package_manager" + + - name: Setup Node.js + if: steps.detect-node.outputs.found == 'true' + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: '22' + + - name: Enable Corepack + if: steps.detect-node.outputs.found == 'true' + shell: sh + run: | + set -eu + corepack enable + + - name: Install Package Manager + if: steps.detect-node.outputs.found == 'true' + shell: sh + env: + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} + run: | + set -eu + + case "$PACKAGE_MANAGER" in + pnpm) + corepack prepare pnpm@latest --activate + ;; + yarn) + corepack prepare yarn@stable --activate + ;; + bun|npm) + # Bun installed separately, npm built-in + ;; + esac + + - name: Setup Bun + if: steps.detect-node.outputs.found == 'true' && steps.detect-pm.outputs.package-manager == 'bun' + uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2 + with: + bun-version: latest - name: Cache Node Dependencies if: steps.detect-node.outputs.found == 'true' @@ -87,15 +142,15 @@ runs: uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: node_modules - key: ${{ runner.os }}-pr-lint-${{ steps.node-setup.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} + key: ${{ runner.os }}-pr-lint-${{ steps.detect-pm.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} restore-keys: | - ${{ runner.os }}-pr-lint-${{ steps.node-setup.outputs.package-manager }}- + ${{ runner.os }}-pr-lint-${{ steps.detect-pm.outputs.package-manager }}- - name: Install Node Dependencies if: steps.detect-node.outputs.found == 'true' && steps.node-cache.outputs.cache-hit != 'true' shell: sh env: - PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} run: | set -eu diff --git a/pr-lint/rules.yml b/pr-lint/rules.yml index 008f71c..38d80a0 100644 --- a/pr-lint/rules.yml +++ b/pr-lint/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for pr-lint action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: pr-lint description: Runs MegaLinter against pull requests diff --git a/pre-commit/rules.yml b/pre-commit/rules.yml index cf139d3..fa18a24 100644 --- a/pre-commit/rules.yml +++ b/pre-commit/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for pre-commit action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: pre-commit description: Runs pre-commit on the repository and pushes the fixes back to the repository diff --git a/prettier-lint/README.md b/prettier-lint/README.md index 41f9316..2548f24 100644 --- a/prettier-lint/README.md +++ b/prettier-lint/README.md @@ -8,32 +8,32 @@ Run Prettier in check or fix mode with advanced configuration and reporting ### Inputs -| name | description | required | default | -|---------------------|------------------------------------------------------------|----------|--------------------------------------------------| -| `mode` |

Mode to run (check or fix)

| `false` | `check` | -| `working-directory` |

Directory containing files to format

| `false` | `.` | -| `prettier-version` |

Prettier version to use

| `false` | `latest` | -| `config-file` |

Path to Prettier config file

| `false` | `.prettierrc` | -| `ignore-file` |

Path to Prettier ignore file

| `false` | `.prettierignore` | -| `file-pattern` |

Files to include (glob pattern)

| `false` | `**/*.{js,jsx,ts,tsx,css,scss,json,md,yaml,yml}` | -| `cache` |

Enable Prettier caching

| `false` | `true` | -| `fail-on-error` |

Fail workflow if issues are found (check mode only)

| `false` | `true` | -| `report-format` |

Output format for check mode (json, sarif)

| `false` | `sarif` | -| `max-retries` |

Maximum number of retry attempts

| `false` | `3` | -| `plugins` |

Comma-separated list of Prettier plugins to install

| `false` | `""` | -| `token` |

GitHub token for authentication

| `false` | `""` | -| `username` |

GitHub username for commits (fix mode only)

| `false` | `github-actions` | -| `email` |

GitHub email for commits (fix mode only)

| `false` | `github-actions@github.com` | +| name | description | required | default | +| --- | --- | --- | --- | +| `mode` |

Mode to run (check or fix)

| `false` | `check` | +| `working-directory` |

Directory containing files to format

| `false` | `.` | +| `prettier-version` |

Prettier version to use

| `false` | `latest` | +| `config-file` |

Path to Prettier config file

| `false` | `.prettierrc` | +| `ignore-file` |

Path to Prettier ignore file

| `false` | `.prettierignore` | +| `file-pattern` |

Files to include (glob pattern)

| `false` | `**/*.{js,jsx,ts,tsx,css,scss,json,md,yaml,yml}` | +| `cache` |

Enable Prettier caching

| `false` | `true` | +| `fail-on-error` |

Fail workflow if issues are found (check mode only)

| `false` | `true` | +| `report-format` |

Output format for check mode (json, sarif)

| `false` | `sarif` | +| `max-retries` |

Maximum number of retry attempts

| `false` | `3` | +| `plugins` |

Comma-separated list of Prettier plugins to install

| `false` | `""` | +| `token` |

GitHub token for authentication

| `false` | `""` | +| `username` |

GitHub username for commits (fix mode only)

| `false` | `github-actions` | +| `email` |

GitHub email for commits (fix mode only)

| `false` | `github-actions@github.com` | ### Outputs -| name | description | -|---------------------|-----------------------------------------------------------------| -| `status` |

Overall status (success/failure)

| -| `files-checked` |

Number of files checked (check mode only)

| +| name | description | +| --- | --- | +| `status` |

Overall status (success/failure)

| +| `files-checked` |

Number of files checked (check mode only)

| | `unformatted-files` |

Number of files with formatting issues (check mode only)

| -| `sarif-file` |

Path to SARIF report file (check mode only)

| -| `files-changed` |

Number of files changed (fix mode only)

| +| `sarif-file` |

Path to SARIF report file (check mode only)

| +| `files-changed` |

Number of files changed (fix mode only)

| ### Runs diff --git a/prettier-lint/action.yml b/prettier-lint/action.yml index fbb75ff..bb1bda3 100644 --- a/prettier-lint/action.yml +++ b/prettier-lint/action.yml @@ -223,25 +223,77 @@ runs: with: token: ${{ inputs.token || github.token }} - - name: Node Setup - id: node-setup - uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 + - name: Detect Package Manager + id: detect-pm + shell: sh + run: | + set -eu + + # Detect package manager from lockfiles + if [ -f bun.lockb ]; then + package_manager="bun" + elif [ -f pnpm-lock.yaml ]; then + package_manager="pnpm" + elif [ -f yarn.lock ]; then + package_manager="yarn" + else + package_manager="npm" + fi + + printf 'package-manager=%s\n' "$package_manager" >> "$GITHUB_OUTPUT" + echo "Detected package manager: $package_manager" + + - name: Setup Node.js + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: '22' + + - name: Enable Corepack + shell: sh + run: | + set -eu + corepack enable + + - name: Install Package Manager + shell: sh + env: + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} + run: | + set -eu + + case "$PACKAGE_MANAGER" in + pnpm) + corepack prepare pnpm@latest --activate + ;; + yarn) + corepack prepare yarn@stable --activate + ;; + bun|npm) + # Bun installed separately, npm built-in + ;; + esac + + - name: Setup Bun + if: steps.detect-pm.outputs.package-manager == 'bun' + uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2 + with: + bun-version: latest - name: Cache Node Dependencies id: cache uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: node_modules - key: ${{ runner.os }}-prettier-lint-${{ inputs.mode }}-${{ steps.node-setup.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} + key: ${{ runner.os }}-prettier-lint-${{ inputs.mode }}-${{ steps.detect-pm.outputs.package-manager }}-${{ hashFiles('package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb') }} restore-keys: | - ${{ runner.os }}-prettier-lint-${{ inputs.mode }}-${{ steps.node-setup.outputs.package-manager }}- + ${{ runner.os }}-prettier-lint-${{ inputs.mode }}-${{ steps.detect-pm.outputs.package-manager }}- ${{ runner.os }}-prettier-lint-${{ inputs.mode }}- - name: Install Dependencies if: steps.cache.outputs.cache-hit != 'true' shell: bash env: - PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} + PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }} run: | set -euo pipefail diff --git a/prettier-lint/rules.yml b/prettier-lint/rules.yml index f0b820e..531d3d4 100644 --- a/prettier-lint/rules.yml +++ b/prettier-lint/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for prettier-lint action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: prettier-lint description: Run Prettier in check or fix mode with advanced configuration and reporting diff --git a/python-lint-fix/README.md b/python-lint-fix/README.md index 3ee018a..3474bf2 100644 --- a/python-lint-fix/README.md +++ b/python-lint-fix/README.md @@ -8,25 +8,25 @@ Lints and fixes Python files, commits changes, and uploads SARIF report. ### Inputs -| name | description | required | default | -|---------------------|-----------------------------------------------------------------------|----------|-----------------------------| -| `python-version` |

Python version to use

| `false` | `3.11` | -| `flake8-version` |

Flake8 version to use

| `false` | `7.0.0` | -| `autopep8-version` |

Autopep8 version to use

| `false` | `2.0.4` | -| `max-retries` |

Maximum number of retry attempts for installations and linting

| `false` | `3` | -| `working-directory` |

Directory containing Python files to lint

| `false` | `.` | -| `fail-on-error` |

Whether to fail the action if linting errors are found

| `false` | `true` | -| `token` |

GitHub token for authentication

| `false` | `""` | -| `username` |

GitHub username for commits

| `false` | `github-actions` | -| `email` |

GitHub email for commits

| `false` | `github-actions@github.com` | +| name | description | required | default | +| --- | --- | --- | --- | +| `python-version` |

Python version to use

| `false` | `3.11` | +| `flake8-version` |

Flake8 version to use

| `false` | `7.0.0` | +| `autopep8-version` |

Autopep8 version to use

| `false` | `2.0.4` | +| `max-retries` |

Maximum number of retry attempts for installations and linting

| `false` | `3` | +| `working-directory` |

Directory containing Python files to lint

| `false` | `.` | +| `fail-on-error` |

Whether to fail the action if linting errors are found

| `false` | `true` | +| `token` |

GitHub token for authentication

| `false` | `""` | +| `username` |

GitHub username for commits

| `false` | `github-actions` | +| `email` |

GitHub email for commits

| `false` | `github-actions@github.com` | ### Outputs -| name | description | -|---------------|--------------------------------------------------------| +| name | description | +| --- | --- | | `lint-result` |

Result of the linting process (success/failure)

| -| `fixed-files` |

Number of files that were fixed

| -| `error-count` |

Number of errors found

| +| `fixed-files` |

Number of files that were fixed

| +| `error-count` |

Number of errors found

| ### Runs diff --git a/python-lint-fix/rules.yml b/python-lint-fix/rules.yml index abf9f09..d093517 100644 --- a/python-lint-fix/rules.yml +++ b/python-lint-fix/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for python-lint-fix action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: python-lint-fix description: Lints and fixes Python files, commits changes, and uploads SARIF report. diff --git a/release-monthly/rules.yml b/release-monthly/rules.yml index 338ecf6..0816e10 100644 --- a/release-monthly/rules.yml +++ b/release-monthly/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for release-monthly action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: release-monthly description: Creates a release for the current month, incrementing patch number if necessary. diff --git a/stale/rules.yml b/stale/rules.yml index 7f79dd0..1691a67 100644 --- a/stale/rules.yml +++ b/stale/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for stale action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: stale description: A GitHub Action to close stale issues and pull requests. diff --git a/sync-labels/rules.yml b/sync-labels/rules.yml index ef90026..801f02b 100644 --- a/sync-labels/rules.yml +++ b/sync-labels/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for sync-labels action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: sync-labels description: Sync labels from a YAML file to a GitHub repository diff --git a/terraform-lint-fix/rules.yml b/terraform-lint-fix/rules.yml index 6f62212..1dddd4e 100644 --- a/terraform-lint-fix/rules.yml +++ b/terraform-lint-fix/rules.yml @@ -1,4 +1,3 @@ ---- # Validation rules for terraform-lint-fix action # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Schema version: 1.0 @@ -8,7 +7,6 @@ # Rules are automatically applied by validate-inputs action when this # action is used. # - schema_version: '1.0' action: terraform-lint-fix description: Lints and fixes Terraform files with advanced validation and security checks. diff --git a/validate-inputs/scripts/update-validators.py b/validate-inputs/scripts/update-validators.py index 69c0141..0e784ab 100755 --- a/validate-inputs/scripts/update-validators.py +++ b/validate-inputs/scripts/update-validators.py @@ -311,9 +311,6 @@ class ValidationRuleGenerator: "backoff-strategy": "backoff_strategy", "shell": "shell_type", }, - "node-setup": { - "package-manager": "package_manager_enum", - }, "docker-publish": { "registry": "registry_enum", "cache-mode": "cache_mode", diff --git a/validate-inputs/tests/test_node-setup_custom.py b/validate-inputs/tests/test_node-setup_custom.py deleted file mode 100644 index 440f0ce..0000000 --- a/validate-inputs/tests/test_node-setup_custom.py +++ /dev/null @@ -1,74 +0,0 @@ -"""Tests for node-setup 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 / "node-setup" -sys.path.insert(0, str(action_path)) - -# pylint: disable=wrong-import-position -from CustomValidator import CustomValidator - - -class TestCustomNodeSetupValidator: - """Test cases for node-setup custom validator.""" - - def setup_method(self): - """Set up test fixtures.""" - self.validator = CustomValidator("node-setup") - - 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 node-setup - 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 node-setup - 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 node-setup - - def test_validation_rules(self): - """Test validation rules.""" - rules = self.validator.get_validation_rules() - assert isinstance(rules, dict) - # TODO: Assert specific validation rules for node-setup - - 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