refactor: inline node-setup across Node.js actions

Phase 6A: Remove node-setup abstraction layer and inline Node.js setup.

Changes:
- Replace node-setup calls with direct actions/setup-node@v6.0.0
- Inline package manager detection (lockfile-based)
- Add Corepack enablement and package manager installation
- Use Node.js 22 as default version

Actions migrated (5):
- prettier-lint: Inline Node.js setup + package manager detection
- biome-lint: Inline Node.js setup + package manager detection
- eslint-lint: Inline Node.js setup + package manager detection
- pr-lint: Inline Node.js setup (conditional on package.json)
- npm-publish: Inline Node.js setup + package manager detection

Removed:
- node-setup/action.yml (371 lines)
- node-setup/README.md, rules.yml, CustomValidator.py
- _tests/unit/node-setup/validation.spec.sh
- _tests/integration/workflows/node-setup-test.yml
- validate-inputs/tests/test_node-setup_custom.py

Documentation updates:
- CLAUDE.md: Remove node-setup from action list (26 actions)
- generate_listing.cjs: Remove node-setup mappings
- update-validators.py: Remove node-setup custom validator

Result: 26 actions (down from 27), eliminated internal dependency layer.
This commit is contained in:
2025-11-20 21:17:37 +02:00
parent 97238212eb
commit 49d232f590
50 changed files with 419 additions and 1607 deletions

View File

@@ -71,7 +71,7 @@
Flat structure. Each action self-contained with `action.yml`. 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), Linting (ansible-lint-fix, biome-lint, csharp-lint-check, eslint-lint, go-lint, pr-lint, pre-commit, prettier-lint, python-lint-fix, terraform-lint-fix),
Testing (php-tests, php-laravel-phpunit, php-composer), Build (csharp-build, go-build, docker-build), Testing (php-tests, php-laravel-phpunit, php-composer), Build (csharp-build, go-build, docker-build),
Publishing (npm-publish, docker-publish, csharp-publish), Publishing (npm-publish, docker-publish, csharp-publish),

View File

@@ -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!"

View File

@@ -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 <<EOF
{
"name": "test-project",
"version": "1.0.0",
"packageManager": "pnpm@8.0.0",
"engines": {
"node": ">=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 <<EOF
{
"name": "test-project",
"version": "1.0.0",
"packageManager": "yarn@3.6.0"
}
EOF
# Mock Corepack enabled output
echo "corepack-enabled=true" >>"$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

View File

@@ -1,4 +1,3 @@
---
# Validation rules for action-versioning action # Validation rules for action-versioning action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: action-versioning action: action-versioning
description: Automatically update SHA-pinned action references to match latest version tags description: Automatically update SHA-pinned action references to match latest version tags

View File

@@ -1,4 +1,3 @@
---
# Validation rules for ansible-lint-fix action # Validation rules for ansible-lint-fix action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: ansible-lint-fix action: ansible-lint-fix
description: Lints and fixes Ansible playbooks, commits changes, and uploads SARIF report. description: Lints and fixes Ansible playbooks, commits changes, and uploads SARIF report.

View File

@@ -137,24 +137,76 @@ runs:
with: with:
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}
- name: Node Setup - name: Detect Package Manager
id: node-setup id: detect-pm
uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 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 - name: Cache Node Dependencies
id: cache id: cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with: with:
path: node_modules 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: | 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 }}- ${{ runner.os }}-biome-lint-${{ inputs.mode }}-
- name: Install Biome - name: Install Biome
shell: bash shell: bash
env: env:
PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }}
MAX_RETRIES: ${{ inputs.max-retries }} MAX_RETRIES: ${{ inputs.max-retries }}
run: | run: |
set -euo pipefail set -euo pipefail

View File

@@ -1,4 +1,3 @@
---
# Validation rules for biome-lint action # Validation rules for biome-lint action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: biome-lint action: biome-lint
description: Run Biome linter in check or fix mode description: Run Biome linter in check or fix mode

View File

@@ -1,4 +1,3 @@
---
# Validation rules for codeql-analysis action # Validation rules for codeql-analysis action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: codeql-analysis action: codeql-analysis
description: Run CodeQL security analysis for a single language with configurable query suites description: Run CodeQL security analysis for a single language with configurable query suites

View File

@@ -1,4 +1,3 @@
---
# Validation rules for compress-images action # Validation rules for compress-images action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: compress-images action: compress-images
description: Compress images on demand (workflow_dispatch), and at 11pm every Sunday (schedule). description: Compress images on demand (workflow_dispatch), and at 11pm every Sunday (schedule).

View File

@@ -1,4 +1,3 @@
---
# Validation rules for csharp-build action # Validation rules for csharp-build action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: csharp-build action: csharp-build
description: Builds and tests C# projects. description: Builds and tests C# projects.

View File

@@ -8,18 +8,18 @@ Runs linters like StyleCop or dotnet-format for C# code style checks.
### Inputs ### Inputs
| name | description | required | default | | name | description | required | default |
|------------------|----------------------------------------|----------|---------| | --- | --- | --- | --- |
| `dotnet-version` | <p>Version of .NET SDK to use.</p> | `false` | `""` | | `dotnet-version` | <p>Version of .NET SDK to use.</p> | `false` | `""` |
| `token` | <p>GitHub token for authentication</p> | `false` | `""` | | `token` | <p>GitHub token for authentication</p> | `false` | `""` |
### Outputs ### Outputs
| name | description | | name | description |
|------------------|----------------------------------------------| | --- | --- |
| `lint_status` | <p>Overall lint status (success/failure)</p> | | `lint_status` | <p>Overall lint status (success/failure)</p> |
| `errors_count` | <p>Number of formatting errors found</p> | | `errors_count` | <p>Number of formatting errors found</p> |
| `warnings_count` | <p>Number of formatting warnings found</p> | | `warnings_count` | <p>Number of formatting warnings found</p> |
### Runs ### Runs

View File

@@ -1,4 +1,3 @@
---
# Validation rules for csharp-lint-check action # Validation rules for csharp-lint-check action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: csharp-lint-check action: csharp-lint-check
description: Runs linters like StyleCop or dotnet-format for C# code style checks. description: Runs linters like StyleCop or dotnet-format for C# code style checks.

View File

@@ -8,19 +8,19 @@ Publishes a C# project to GitHub Packages.
### Inputs ### Inputs
| name | description | required | default | | name | description | required | default |
|------------------|----------------------------------------------------|----------|-------------| | --- | --- | --- | --- |
| `dotnet-version` | <p>Version of .NET SDK to use.</p> | `false` | `""` | | `dotnet-version` | <p>Version of .NET SDK to use.</p> | `false` | `""` |
| `namespace` | <p>GitHub namespace for the package.</p> | `true` | `ivuorinen` | | `namespace` | <p>GitHub namespace for the package.</p> | `true` | `ivuorinen` |
| `token` | <p>GitHub token with package write permissions</p> | `false` | `""` | | `token` | <p>GitHub token with package write permissions</p> | `false` | `""` |
### Outputs ### Outputs
| name | description | | name | description |
|-------------------|-------------------------------------------------| | --- | --- |
| `publish_status` | <p>Overall publish status (success/failure)</p> | | `publish_status` | <p>Overall publish status (success/failure)</p> |
| `package_version` | <p>Version of the published package</p> | | `package_version` | <p>Version of the published package</p> |
| `package_url` | <p>URL of the published package</p> | | `package_url` | <p>URL of the published package</p> |
### Runs ### Runs

View File

@@ -1,4 +1,3 @@
---
# Validation rules for csharp-publish action # Validation rules for csharp-publish action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: csharp-publish action: csharp-publish
description: Publishes a C# project to GitHub Packages. description: Publishes a C# project to GitHub Packages.

View File

@@ -1,4 +1,3 @@
---
# Validation rules for docker-build action # Validation rules for docker-build action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: docker-build action: docker-build
description: Builds a Docker image for multiple architectures with enhanced security and reliability. description: Builds a Docker image for multiple architectures with enhanced security and reliability.

View File

@@ -8,28 +8,28 @@ Simple wrapper to publish Docker images to GitHub Packages and/or Docker Hub
### Inputs ### Inputs
| name | description | required | default | | name | description | required | default |
|----------------------|-------------------------------------------------------------------|----------|---------------------------| | --- | --- | --- | --- |
| `registry` | <p>Registry to publish to (dockerhub, github, or both)</p> | `false` | `both` | | `registry` | <p>Registry to publish to (dockerhub, github, or both)</p> | `false` | `both` |
| `image-name` | <p>Docker image name (defaults to repository name)</p> | `false` | `""` | | `image-name` | <p>Docker image name (defaults to repository name)</p> | `false` | `""` |
| `tags` | <p>Comma-separated list of tags (e.g., latest,v1.0.0)</p> | `false` | `latest` | | `tags` | <p>Comma-separated list of tags (e.g., latest,v1.0.0)</p> | `false` | `latest` |
| `platforms` | <p>Platforms to build for (comma-separated)</p> | `false` | `linux/amd64,linux/arm64` | | `platforms` | <p>Platforms to build for (comma-separated)</p> | `false` | `linux/amd64,linux/arm64` |
| `context` | <p>Build context path</p> | `false` | `.` | | `context` | <p>Build context path</p> | `false` | `.` |
| `dockerfile` | <p>Path to Dockerfile</p> | `false` | `Dockerfile` | | `dockerfile` | <p>Path to Dockerfile</p> | `false` | `Dockerfile` |
| `build-args` | <p>Build arguments (newline-separated KEY=VALUE pairs)</p> | `false` | `""` | | `build-args` | <p>Build arguments (newline-separated KEY=VALUE pairs)</p> | `false` | `""` |
| `push` | <p>Whether to push the image</p> | `false` | `true` | | `push` | <p>Whether to push the image</p> | `false` | `true` |
| `token` | <p>GitHub token for authentication (for GitHub registry)</p> | `false` | `""` | | `token` | <p>GitHub token for authentication (for GitHub registry)</p> | `false` | `""` |
| `dockerhub-username` | <p>Docker Hub username (required if publishing to Docker Hub)</p> | `false` | `""` | | `dockerhub-username` | <p>Docker Hub username (required if publishing to Docker Hub)</p> | `false` | `""` |
| `dockerhub-token` | <p>Docker Hub token (required if publishing to Docker Hub)</p> | `false` | `""` | | `dockerhub-token` | <p>Docker Hub token (required if publishing to Docker Hub)</p> | `false` | `""` |
### Outputs ### Outputs
| name | description | | name | description |
|--------------|--------------------------------------| | --- | --- |
| `image-name` | <p>Full image name with registry</p> | | `image-name` | <p>Full image name with registry</p> |
| `tags` | <p>Tags that were published</p> | | `tags` | <p>Tags that were published</p> |
| `digest` | <p>Image digest</p> | | `digest` | <p>Image digest</p> |
| `metadata` | <p>Build metadata</p> | | `metadata` | <p>Build metadata</p> |
### Runs ### Runs

View File

@@ -1,4 +1,3 @@
---
# Validation rules for docker-publish action # Validation rules for docker-publish action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: docker-publish action: docker-publish
description: Simple wrapper to publish Docker images to GitHub Packages and/or Docker Hub description: Simple wrapper to publish Docker images to GitHub Packages and/or Docker Hub

View File

@@ -242,25 +242,77 @@ runs:
with: with:
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}
- name: Node Setup - name: Detect Package Manager
id: node-setup id: detect-pm
uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 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 - name: Cache Node Dependencies
id: cache id: cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with: with:
path: node_modules 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: | 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 }}- ${{ runner.os }}-eslint-lint-${{ inputs.mode }}-
- name: Install Dependencies - name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true' if: steps.cache.outputs.cache-hit != 'true'
shell: bash shell: bash
env: env:
PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }}
run: | run: |
set -euo pipefail set -euo pipefail
@@ -293,7 +345,7 @@ runs:
shell: bash shell: bash
working-directory: ${{ inputs.working-directory }} working-directory: ${{ inputs.working-directory }}
env: env:
PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }}
ESLINT_VERSION: ${{ inputs.eslint-version }} ESLINT_VERSION: ${{ inputs.eslint-version }}
CONFIG_FILE: ${{ inputs.config-file }} CONFIG_FILE: ${{ inputs.config-file }}
CACHE: ${{ inputs.cache }} CACHE: ${{ inputs.cache }}
@@ -377,7 +429,7 @@ runs:
shell: bash shell: bash
working-directory: ${{ inputs.working-directory }} working-directory: ${{ inputs.working-directory }}
env: env:
PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }}
run: | run: |
set -euo pipefail set -euo pipefail

View File

@@ -1,4 +1,3 @@
---
# Validation rules for eslint-lint action # Validation rules for eslint-lint action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: eslint-lint action: eslint-lint
description: Run ESLint in check or fix mode with advanced configuration and reporting description: Run ESLint in check or fix mode with advanced configuration and reporting

View File

@@ -8,7 +8,6 @@ const { markdownTable } = require('markdown-table');
// Category mappings // Category mappings
const CATEGORIES = { const CATEGORIES = {
// Setup & Environment // Setup & Environment
'node-setup': 'Setup',
'language-version-detect': 'Setup', 'language-version-detect': 'Setup',
// Utilities // Utilities
@@ -55,7 +54,6 @@ const CATEGORIES = {
// Language support mappings // Language support mappings
const LANGUAGE_SUPPORT = { const LANGUAGE_SUPPORT = {
'node-setup': ['Node.js', 'JavaScript', 'TypeScript'],
'language-version-detect': ['PHP', 'Python', 'Go', '.NET', 'Node.js'], 'language-version-detect': ['PHP', 'Python', 'Go', '.NET', 'Node.js'],
'php-tests': ['PHP'], 'php-tests': ['PHP'],
'php-laravel-phpunit': ['PHP', 'Laravel'], 'php-laravel-phpunit': ['PHP', 'Laravel'],

View File

@@ -8,22 +8,22 @@ Builds the Go project.
### Inputs ### Inputs
| name | description | required | default | | name | description | required | default |
|---------------|------------------------------------------------------------------------|----------|---------| | --- | --- | --- | --- |
| `go-version` | <p>Go version to use.</p> | `false` | `""` | | `go-version` | <p>Go version to use.</p> | `false` | `""` |
| `destination` | <p>Build destination directory.</p> | `false` | `./bin` | | `destination` | <p>Build destination directory.</p> | `false` | `./bin` |
| `max-retries` | <p>Maximum number of retry attempts for go mod download operations</p> | `false` | `3` | | `max-retries` | <p>Maximum number of retry attempts for go mod download operations</p> | `false` | `3` |
| `token` | <p>GitHub token for authentication</p> | `false` | `""` | | `token` | <p>GitHub token for authentication</p> | `false` | `""` |
### Outputs ### Outputs
| name | description | | name | description |
|-----------------|--------------------------------------------------------| | --- | --- |
| `build_status` | <p>Build completion status (success/failure)</p> | | `build_status` | <p>Build completion status (success/failure)</p> |
| `test_status` | <p>Test execution status (success/failure/skipped)</p> | | `test_status` | <p>Test execution status (success/failure/skipped)</p> |
| `go_version` | <p>Version of Go used</p> | | `go_version` | <p>Version of Go used</p> |
| `binary_path` | <p>Path to built binaries</p> | | `binary_path` | <p>Path to built binaries</p> |
| `coverage_path` | <p>Path to coverage report</p> | | `coverage_path` | <p>Path to coverage report</p> |
### Runs ### Runs

View File

@@ -1,4 +1,3 @@
---
# Validation rules for go-build action # Validation rules for go-build action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: go-build action: go-build
description: Builds the Go project. description: Builds the Go project.

View File

@@ -1,4 +1,3 @@
---
# Validation rules for go-lint action # Validation rules for go-lint action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: go-lint action: go-lint
description: Run golangci-lint with advanced configuration, caching, and reporting description: Run golangci-lint with advanced configuration, caching, and reporting

View File

@@ -1,4 +1,3 @@
---
# Validation rules for language-version-detect action # Validation rules for language-version-detect action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,11 +7,9 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: language-version-detect action: language-version-detect
description: 'DEPRECATED: This action is deprecated. Inline version detection directly in your actions instead. Detects language 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.'
version from project configuration files with support for PHP, Python, Go, and .NET.'
generator_version: 1.0.0 generator_version: 1.0.0
required_inputs: required_inputs:
- language - language

View File

@@ -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",
},
}

View File

@@ -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` | <p>Default Node.js version to use if no configuration file is found.</p> | `false` | `22` |
| `package-manager` | <p>Node.js package manager to use (npm, yarn, pnpm, bun, auto)</p> | `false` | `auto` |
| `registry-url` | <p>Custom NPM registry URL</p> | `false` | `https://registry.npmjs.org` |
| `token` | <p>Auth token for private registry</p> | `false` | `""` |
| `node-mirror` | <p>Custom Node.js binary mirror</p> | `false` | `""` |
| `force-version` | <p>Force specific Node.js version regardless of config files</p> | `false` | `""` |
### Outputs
| name | description |
|-------------------|-------------------------------------|
| `node-version` | <p>Installed Node.js version</p> |
| `package-manager` | <p>Selected package manager</p> |
| `node-path` | <p>Path to Node.js installation</p> |
### 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: ""
```

View File

@@ -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

View File

@@ -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

View File

@@ -8,21 +8,21 @@ Publishes the package to the NPM registry with configurable scope and registry U
### Inputs ### Inputs
| name | description | required | default | | name | description | required | default |
|-------------------|----------------------------------------|----------|----------------------------------------| | --- | --- | --- | --- |
| `npm_token` | <p>NPM token.</p> | `true` | `""` | | `npm_token` | <p>NPM token.</p> | `true` | `""` |
| `registry-url` | <p>Registry URL for publishing.</p> | `false` | `https://registry.npmjs.org/` | | `registry-url` | <p>Registry URL for publishing.</p> | `false` | `https://registry.npmjs.org/` |
| `scope` | <p>Package scope to use.</p> | `false` | `@ivuorinen` | | `scope` | <p>Package scope to use.</p> | `false` | `@ivuorinen` |
| `package-version` | <p>The version to publish.</p> | `false` | `${{ github.event.release.tag_name }}` | | `package-version` | <p>The version to publish.</p> | `false` | `${{ github.event.release.tag_name }}` |
| `token` | <p>GitHub token for authentication</p> | `false` | `""` | | `token` | <p>GitHub token for authentication</p> | `false` | `""` |
### Outputs ### Outputs
| name | description | | name | description |
|-------------------|-------------------------------------| | --- | --- |
| `registry-url` | <p>Registry URL for publishing.</p> | | `registry-url` | <p>Registry URL for publishing.</p> |
| `scope` | <p>Package scope to use.</p> | | `scope` | <p>Package scope to use.</p> |
| `package-version` | <p>The version to publish.</p> | | `package-version` | <p>The version to publish.</p> |
### Runs ### Runs

View File

@@ -100,24 +100,76 @@ runs:
with: with:
token: ${{ inputs.token || github.token }} 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 - name: Setup Node.js
id: node-setup uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 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 - name: Cache Node Dependencies
id: cache id: cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with: with:
path: node_modules 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: | 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 - name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true' if: steps.cache.outputs.cache-hit != 'true'
shell: sh shell: sh
env: env:
PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }}
run: | run: |
set -eu set -eu

View File

@@ -1,4 +1,3 @@
---
# Validation rules for npm-publish action # Validation rules for npm-publish action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: npm-publish action: npm-publish
description: Publishes the package to the NPM registry with configurable scope and registry URL. description: Publishes the package to the NPM registry with configurable scope and registry URL.

View File

@@ -1,4 +1,3 @@
---
# Validation rules for php-composer action # Validation rules for php-composer action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: php-composer action: php-composer
description: Runs Composer install on a repository with advanced caching and configuration. description: Runs Composer install on a repository with advanced caching and configuration.

View File

@@ -8,22 +8,22 @@ Setup PHP, install dependencies, generate key, create database and run composer
### Inputs ### Inputs
| name | description | required | default | | name | description | required | default |
|--------------------|-----------------------------------------------------------------------------------------------------------------------|----------|---------------------------------------------| | --- | --- | --- | --- |
| `php-version` | <p>PHP Version to use, see https://github.com/marketplace/actions/setup-php-action#php-version-optional</p> | `false` | `latest` | | `php-version` | <p>PHP Version to use, see https://github.com/marketplace/actions/setup-php-action#php-version-optional</p> | `false` | `latest` |
| `php-version-file` | <p>PHP Version file to use, see https://github.com/marketplace/actions/setup-php-action#php-version-file-optional</p> | `false` | `.php-version` | | `php-version-file` | <p>PHP Version file to use, see https://github.com/marketplace/actions/setup-php-action#php-version-file-optional</p> | `false` | `.php-version` |
| `extensions` | <p>PHP extensions to install, see https://github.com/marketplace/actions/setup-php-action#extensions-optional</p> | `false` | `mbstring, intl, json, pdo_sqlite, sqlite3` | | `extensions` | <p>PHP extensions to install, see https://github.com/marketplace/actions/setup-php-action#extensions-optional</p> | `false` | `mbstring, intl, json, pdo_sqlite, sqlite3` |
| `coverage` | <p>Specify code-coverage driver, see https://github.com/marketplace/actions/setup-php-action#coverage-optional</p> | `false` | `none` | | `coverage` | <p>Specify code-coverage driver, see https://github.com/marketplace/actions/setup-php-action#coverage-optional</p> | `false` | `none` |
| `token` | <p>GitHub token for authentication</p> | `false` | `""` | | `token` | <p>GitHub token for authentication</p> | `false` | `""` |
### Outputs ### Outputs
| name | description | | name | description |
|--------------------|------------------------------------------------| | --- | --- |
| `php-version` | <p>The PHP version that was setup</p> | | `php-version` | <p>The PHP version that was setup</p> |
| `php-version-file` | <p>The PHP version file that was used</p> | | `php-version-file` | <p>The PHP version file that was used</p> |
| `extensions` | <p>The PHP extensions that were installed</p> | | `extensions` | <p>The PHP extensions that were installed</p> |
| `coverage` | <p>The code-coverage driver that was setup</p> | | `coverage` | <p>The code-coverage driver that was setup</p> |
### Runs ### Runs

View File

@@ -1,4 +1,3 @@
---
# Validation rules for php-laravel-phpunit action # Validation rules for php-laravel-phpunit action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: php-laravel-phpunit action: php-laravel-phpunit
description: Setup PHP, install dependencies, generate key, create database and run composer test description: Setup PHP, install dependencies, generate key, create database and run composer test

View File

@@ -8,20 +8,20 @@ Run PHPUnit tests on the repository
### Inputs ### Inputs
| name | description | required | default | | name | description | required | default |
|------------|----------------------------------------|----------|-----------------------------| | --- | --- | --- | --- |
| `token` | <p>GitHub token for authentication</p> | `false` | `""` | | `token` | <p>GitHub token for authentication</p> | `false` | `""` |
| `username` | <p>GitHub username for commits</p> | `false` | `github-actions` | | `username` | <p>GitHub username for commits</p> | `false` | `github-actions` |
| `email` | <p>GitHub email for commits</p> | `false` | `github-actions@github.com` | | `email` | <p>GitHub email for commits</p> | `false` | `github-actions@github.com` |
### Outputs ### Outputs
| name | description | | name | description |
|-----------------|--------------------------------------------------------| | --- | --- |
| `test_status` | <p>Test execution status (success/failure/skipped)</p> | | `test_status` | <p>Test execution status (success/failure/skipped)</p> |
| `tests_run` | <p>Number of tests executed</p> | | `tests_run` | <p>Number of tests executed</p> |
| `tests_passed` | <p>Number of tests passed</p> | | `tests_passed` | <p>Number of tests passed</p> |
| `coverage_path` | <p>Path to coverage report</p> | | `coverage_path` | <p>Path to coverage report</p> |
### Runs ### Runs

View File

@@ -1,4 +1,3 @@
---
# Validation rules for php-tests action # Validation rules for php-tests action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: php-tests action: php-tests
description: Run PHPUnit tests on the repository description: Run PHPUnit tests on the repository

View File

@@ -76,10 +76,65 @@ runs:
printf '%s\n' "found=true" >> "$GITHUB_OUTPUT" printf '%s\n' "found=true" >> "$GITHUB_OUTPUT"
fi fi
- name: Setup Node.js environment - name: Detect Package Manager
if: steps.detect-node.outputs.found == 'true' if: steps.detect-node.outputs.found == 'true'
id: node-setup id: detect-pm
uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 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 - name: Cache Node Dependencies
if: steps.detect-node.outputs.found == 'true' if: steps.detect-node.outputs.found == 'true'
@@ -87,15 +142,15 @@ runs:
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with: with:
path: node_modules 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: | 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 - name: Install Node Dependencies
if: steps.detect-node.outputs.found == 'true' && steps.node-cache.outputs.cache-hit != 'true' if: steps.detect-node.outputs.found == 'true' && steps.node-cache.outputs.cache-hit != 'true'
shell: sh shell: sh
env: env:
PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }}
run: | run: |
set -eu set -eu

View File

@@ -1,4 +1,3 @@
---
# Validation rules for pr-lint action # Validation rules for pr-lint action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: pr-lint action: pr-lint
description: Runs MegaLinter against pull requests description: Runs MegaLinter against pull requests

View File

@@ -1,4 +1,3 @@
---
# Validation rules for pre-commit action # Validation rules for pre-commit action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: pre-commit action: pre-commit
description: Runs pre-commit on the repository and pushes the fixes back to the repository description: Runs pre-commit on the repository and pushes the fixes back to the repository

View File

@@ -8,32 +8,32 @@ Run Prettier in check or fix mode with advanced configuration and reporting
### Inputs ### Inputs
| name | description | required | default | | name | description | required | default |
|---------------------|------------------------------------------------------------|----------|--------------------------------------------------| | --- | --- | --- | --- |
| `mode` | <p>Mode to run (check or fix)</p> | `false` | `check` | | `mode` | <p>Mode to run (check or fix)</p> | `false` | `check` |
| `working-directory` | <p>Directory containing files to format</p> | `false` | `.` | | `working-directory` | <p>Directory containing files to format</p> | `false` | `.` |
| `prettier-version` | <p>Prettier version to use</p> | `false` | `latest` | | `prettier-version` | <p>Prettier version to use</p> | `false` | `latest` |
| `config-file` | <p>Path to Prettier config file</p> | `false` | `.prettierrc` | | `config-file` | <p>Path to Prettier config file</p> | `false` | `.prettierrc` |
| `ignore-file` | <p>Path to Prettier ignore file</p> | `false` | `.prettierignore` | | `ignore-file` | <p>Path to Prettier ignore file</p> | `false` | `.prettierignore` |
| `file-pattern` | <p>Files to include (glob pattern)</p> | `false` | `**/*.{js,jsx,ts,tsx,css,scss,json,md,yaml,yml}` | | `file-pattern` | <p>Files to include (glob pattern)</p> | `false` | `**/*.{js,jsx,ts,tsx,css,scss,json,md,yaml,yml}` |
| `cache` | <p>Enable Prettier caching</p> | `false` | `true` | | `cache` | <p>Enable Prettier caching</p> | `false` | `true` |
| `fail-on-error` | <p>Fail workflow if issues are found (check mode only)</p> | `false` | `true` | | `fail-on-error` | <p>Fail workflow if issues are found (check mode only)</p> | `false` | `true` |
| `report-format` | <p>Output format for check mode (json, sarif)</p> | `false` | `sarif` | | `report-format` | <p>Output format for check mode (json, sarif)</p> | `false` | `sarif` |
| `max-retries` | <p>Maximum number of retry attempts</p> | `false` | `3` | | `max-retries` | <p>Maximum number of retry attempts</p> | `false` | `3` |
| `plugins` | <p>Comma-separated list of Prettier plugins to install</p> | `false` | `""` | | `plugins` | <p>Comma-separated list of Prettier plugins to install</p> | `false` | `""` |
| `token` | <p>GitHub token for authentication</p> | `false` | `""` | | `token` | <p>GitHub token for authentication</p> | `false` | `""` |
| `username` | <p>GitHub username for commits (fix mode only)</p> | `false` | `github-actions` | | `username` | <p>GitHub username for commits (fix mode only)</p> | `false` | `github-actions` |
| `email` | <p>GitHub email for commits (fix mode only)</p> | `false` | `github-actions@github.com` | | `email` | <p>GitHub email for commits (fix mode only)</p> | `false` | `github-actions@github.com` |
### Outputs ### Outputs
| name | description | | name | description |
|---------------------|-----------------------------------------------------------------| | --- | --- |
| `status` | <p>Overall status (success/failure)</p> | | `status` | <p>Overall status (success/failure)</p> |
| `files-checked` | <p>Number of files checked (check mode only)</p> | | `files-checked` | <p>Number of files checked (check mode only)</p> |
| `unformatted-files` | <p>Number of files with formatting issues (check mode only)</p> | | `unformatted-files` | <p>Number of files with formatting issues (check mode only)</p> |
| `sarif-file` | <p>Path to SARIF report file (check mode only)</p> | | `sarif-file` | <p>Path to SARIF report file (check mode only)</p> |
| `files-changed` | <p>Number of files changed (fix mode only)</p> | | `files-changed` | <p>Number of files changed (fix mode only)</p> |
### Runs ### Runs

View File

@@ -223,25 +223,77 @@ runs:
with: with:
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}
- name: Node Setup - name: Detect Package Manager
id: node-setup id: detect-pm
uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42 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 - name: Cache Node Dependencies
id: cache id: cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with: with:
path: node_modules 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: | 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 }}- ${{ runner.os }}-prettier-lint-${{ inputs.mode }}-
- name: Install Dependencies - name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true' if: steps.cache.outputs.cache-hit != 'true'
shell: bash shell: bash
env: env:
PACKAGE_MANAGER: ${{ steps.node-setup.outputs.package-manager }} PACKAGE_MANAGER: ${{ steps.detect-pm.outputs.package-manager }}
run: | run: |
set -euo pipefail set -euo pipefail

View File

@@ -1,4 +1,3 @@
---
# Validation rules for prettier-lint action # Validation rules for prettier-lint action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: prettier-lint action: prettier-lint
description: Run Prettier in check or fix mode with advanced configuration and reporting description: Run Prettier in check or fix mode with advanced configuration and reporting

View File

@@ -8,25 +8,25 @@ Lints and fixes Python files, commits changes, and uploads SARIF report.
### Inputs ### Inputs
| name | description | required | default | | name | description | required | default |
|---------------------|-----------------------------------------------------------------------|----------|-----------------------------| | --- | --- | --- | --- |
| `python-version` | <p>Python version to use</p> | `false` | `3.11` | | `python-version` | <p>Python version to use</p> | `false` | `3.11` |
| `flake8-version` | <p>Flake8 version to use</p> | `false` | `7.0.0` | | `flake8-version` | <p>Flake8 version to use</p> | `false` | `7.0.0` |
| `autopep8-version` | <p>Autopep8 version to use</p> | `false` | `2.0.4` | | `autopep8-version` | <p>Autopep8 version to use</p> | `false` | `2.0.4` |
| `max-retries` | <p>Maximum number of retry attempts for installations and linting</p> | `false` | `3` | | `max-retries` | <p>Maximum number of retry attempts for installations and linting</p> | `false` | `3` |
| `working-directory` | <p>Directory containing Python files to lint</p> | `false` | `.` | | `working-directory` | <p>Directory containing Python files to lint</p> | `false` | `.` |
| `fail-on-error` | <p>Whether to fail the action if linting errors are found</p> | `false` | `true` | | `fail-on-error` | <p>Whether to fail the action if linting errors are found</p> | `false` | `true` |
| `token` | <p>GitHub token for authentication</p> | `false` | `""` | | `token` | <p>GitHub token for authentication</p> | `false` | `""` |
| `username` | <p>GitHub username for commits</p> | `false` | `github-actions` | | `username` | <p>GitHub username for commits</p> | `false` | `github-actions` |
| `email` | <p>GitHub email for commits</p> | `false` | `github-actions@github.com` | | `email` | <p>GitHub email for commits</p> | `false` | `github-actions@github.com` |
### Outputs ### Outputs
| name | description | | name | description |
|---------------|--------------------------------------------------------| | --- | --- |
| `lint-result` | <p>Result of the linting process (success/failure)</p> | | `lint-result` | <p>Result of the linting process (success/failure)</p> |
| `fixed-files` | <p>Number of files that were fixed</p> | | `fixed-files` | <p>Number of files that were fixed</p> |
| `error-count` | <p>Number of errors found</p> | | `error-count` | <p>Number of errors found</p> |
### Runs ### Runs

View File

@@ -1,4 +1,3 @@
---
# Validation rules for python-lint-fix action # Validation rules for python-lint-fix action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: python-lint-fix action: python-lint-fix
description: Lints and fixes Python files, commits changes, and uploads SARIF report. description: Lints and fixes Python files, commits changes, and uploads SARIF report.

View File

@@ -1,4 +1,3 @@
---
# Validation rules for release-monthly action # Validation rules for release-monthly action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: release-monthly action: release-monthly
description: Creates a release for the current month, incrementing patch number if necessary. description: Creates a release for the current month, incrementing patch number if necessary.

View File

@@ -1,4 +1,3 @@
---
# Validation rules for stale action # Validation rules for stale action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: stale action: stale
description: A GitHub Action to close stale issues and pull requests. description: A GitHub Action to close stale issues and pull requests.

View File

@@ -1,4 +1,3 @@
---
# Validation rules for sync-labels action # Validation rules for sync-labels action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: sync-labels action: sync-labels
description: Sync labels from a YAML file to a GitHub repository description: Sync labels from a YAML file to a GitHub repository

View File

@@ -1,4 +1,3 @@
---
# Validation rules for terraform-lint-fix action # Validation rules for terraform-lint-fix action
# Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY # Generated by update-validators.py v1.0.0 - DO NOT EDIT MANUALLY
# Schema version: 1.0 # Schema version: 1.0
@@ -8,7 +7,6 @@
# Rules are automatically applied by validate-inputs action when this # Rules are automatically applied by validate-inputs action when this
# action is used. # action is used.
# #
schema_version: '1.0' schema_version: '1.0'
action: terraform-lint-fix action: terraform-lint-fix
description: Lints and fixes Terraform files with advanced validation and security checks. description: Lints and fixes Terraform files with advanced validation and security checks.

View File

@@ -311,9 +311,6 @@ class ValidationRuleGenerator:
"backoff-strategy": "backoff_strategy", "backoff-strategy": "backoff_strategy",
"shell": "shell_type", "shell": "shell_type",
}, },
"node-setup": {
"package-manager": "package_manager_enum",
},
"docker-publish": { "docker-publish": {
"registry": "registry_enum", "registry": "registry_enum",
"cache-mode": "cache_mode", "cache-mode": "cache_mode",

View File

@@ -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