Compare commits

...

5 Commits

Author SHA1 Message Date
github-actions[bot]
947f755987 chore: update action references to v2026 (f98ae7cd7d)
This commit updates all internal action references to point to the latest

v2026 tag SHA.
2026-03-02 09:14:52 +00:00
renovate[bot]
03eeb4c39f chore(deps): update astral-sh/setup-uv action (v7.3.0 → v7.3.1) (#473)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-02 03:04:57 +02:00
renovate[bot]
992b64a580 chore(deps)!: update hashicorp/setup-terraform (v3.1.2 → v4.0.0) (#471)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-02 02:35:56 +02:00
renovate[bot]
f114b11df1 chore(deps): lock file maintenance (#472)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-02 02:35:20 +02:00
bd59245cd7 fix(deps): replace step-security/retry and update action pins (#468)
* fix(deps): replace step-security/retry with nick-fields/retry

* chore(deps): update github action sha pins via pinact

* refactor: remove common-retry references from tests and validators

* chore: simplify description fallback and update action count

* docs: remove hardcoded test counts from memory and docs

Replace exact "769 tests" references with qualitative language
so these files don't go stale as test count grows.
2026-03-02 02:31:26 +02:00
28 changed files with 99 additions and 197 deletions

View File

@@ -17,7 +17,7 @@ runs:
using: composite using: composite
steps: steps:
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b # v7.3.0 uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 # v7.3.1
with: with:
enable-cache: true enable-cache: true

View File

@@ -80,7 +80,7 @@ jobs:
category: github-actions-tests category: github-actions-tests
- name: Upload unit test results - name: Upload unit test results
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: always() if: always()
with: with:
name: unit-test-results name: unit-test-results
@@ -133,7 +133,7 @@ jobs:
fi fi
- name: Upload integration test results - name: Upload integration test results
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: always() && steps.check-integration-reports.outputs.reports-found == 'true' if: always() && steps.check-integration-reports.outputs.reports-found == 'true'
with: with:
name: integration-test-results name: integration-test-results
@@ -167,7 +167,7 @@ jobs:
run: make test-coverage run: make test-coverage
- name: Upload coverage report - name: Upload coverage report
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with: with:
name: coverage-report name: coverage-report
path: _tests/coverage/ path: _tests/coverage/
@@ -263,7 +263,7 @@ jobs:
steps: steps:
- name: Download test results - name: Download test results
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with: with:
pattern: '*-test-results' pattern: '*-test-results'
merge-multiple: true merge-multiple: true

View File

@@ -5,28 +5,28 @@
- **Path**: /Users/ivuorinen/Code/ivuorinen/actions - **Path**: /Users/ivuorinen/Code/ivuorinen/actions
- **Branch**: main - **Branch**: main
- **External Usage**: `ivuorinen/actions/<action-name>@main` - **External Usage**: `ivuorinen/actions/<action-name>@main`
- **Total Actions**: 44 self-contained actions - **Total Actions**: 43 self-contained actions
- **Dogfooding**: Workflows use local actions (pr-lint, codeql-analysis, security-scan) - **Dogfooding**: Workflows use local actions (pr-lint, codeql-analysis, security-scan)
## Structure ## Structure
```text ```text
/ /
├── <action-dirs>/ # 44 self-contained actions ├── <action-dirs>/ # 43 self-contained actions
│ ├── action.yml # Action definition │ ├── action.yml # Action definition
│ ├── README.md # Auto-generated │ ├── README.md # Auto-generated
│ └── CustomValidator.py # Optional validator │ └── CustomValidator.py # Optional validator
├── validate-inputs/ # Centralized validation ├── validate-inputs/ # Centralized validation
│ ├── validators/ # 9 specialized modules │ ├── validators/ # 9 specialized modules
│ ├── scripts/ # Rule/test generators │ ├── scripts/ # Rule/test generators
│ └── tests/ # 769 pytest tests │ └── tests/ # pytest tests
├── _tests/ # ShellSpec framework ├── _tests/ # ShellSpec framework
├── _tools/ # Development utilities ├── _tools/ # Development utilities
├── .github/workflows/ # CI/CD workflows ├── .github/workflows/ # CI/CD workflows
└── Makefile # Build automation └── Makefile # Build automation
``` ```
## Action Categories (44 total) ## Action Categories (43 total)
**Setup (7)**: node-setup, set-git-config, php-version-detect, python-version-detect, python-version-detect-v2, go-version-detect, dotnet-version-detect **Setup (7)**: node-setup, set-git-config, php-version-detect, python-version-detect, python-version-detect-v2, go-version-detect, dotnet-version-detect
@@ -40,7 +40,7 @@
**Testing (3)**: php-tests, php-laravel-phpunit, php-composer **Testing (3)**: php-tests, php-laravel-phpunit, php-composer
**Repository (9)**: github-release, release-monthly, sync-labels, stale, compress-images, common-cache, common-file-check, common-retry, codeql-analysis **Repository (8)**: github-release, release-monthly, sync-labels, stale, compress-images, common-cache, common-file-check, codeql-analysis
**Utilities (3)**: version-file-parser, version-validator, validate-inputs **Utilities (3)**: version-file-parser, version-validator, validate-inputs
@@ -77,12 +77,12 @@ make test # All tests (pytest + ShellSpec)
## Testing Framework ## Testing Framework
- **ShellSpec**: GitHub Actions and shell scripts - **ShellSpec**: GitHub Actions and shell scripts
- **pytest**: Python validators (769 tests, 100% pass rate) - **pytest**: Python validators (100% pass rate)
- **Test Generator**: Automatic scaffolding for new actions - **Test Generator**: Automatic scaffolding for new actions
## Current Status ## Current Status
- ✅ All tests passing (769/769) - ✅ All tests passing
- ✅ Zero linting issues - ✅ Zero linting issues
- ✅ Modular validator architecture - ✅ Modular validator architecture
- ✅ Convention-based validation - ✅ Convention-based validation

View File

@@ -2,7 +2,7 @@
## Status: PRODUCTION READY ✅ ## Status: PRODUCTION READY ✅
- 769 tests passing (100%) - All tests passing (100%)
- Zero linting issues - Zero linting issues
- Modular architecture complete - Modular architecture complete
@@ -60,7 +60,7 @@ validate-inputs/
├── scripts/ ├── scripts/
│ ├── update-validators.py # Rule generator │ ├── update-validators.py # Rule generator
│ └── generate-tests.py # Test generator │ └── generate-tests.py # Test generator
└── tests/ # 769 pytest tests └── tests/ # pytest tests
<action>/CustomValidator.py # Action-specific validators <action>/CustomValidator.py # Action-specific validators
``` ```

View File

@@ -183,9 +183,6 @@ validate_input_python "docker-build" "tag" "v1.0.0" # success
validate_input_python "pre-commit" "config-file" "config.yml" # success validate_input_python "pre-commit" "config-file" "config.yml" # success
validate_input_python "pre-commit" "config-file" "../etc/pass" # failure validate_input_python "pre-commit" "config-file" "../etc/pass" # failure
# Injection detection
validate_input_python "common-retry" "command" "echo test" # success
validate_input_python "common-retry" "command" "rm -rf /; " # failure
``` ```
### Helper Functions from spec_helper.sh ### Helper Functions from spec_helper.sh
@@ -482,11 +479,6 @@ End
✅ **Always include**: ✅ **Always include**:
```bash ```bash
It "rejects command injection"
When call validate_input_python "common-retry" "command" "rm -rf /; "
The status should be failure
End
It "rejects path traversal" It "rejects path traversal"
When call validate_input_python "pre-commit" "config-file" "../etc/passwd" When call validate_input_python "pre-commit" "config-file" "../etc/passwd"
The status should be failure The status should be failure

View File

@@ -264,7 +264,7 @@ def get_input_property(action_file: str, input_name: str, property_check: str) -
if property_check == "description": if property_check == "description":
description = input_data.get("description", "") description = input_data.get("description", "")
return description if description else "no-description" return description or "no-description"
if property_check == "all_optional": if property_check == "all_optional":
# Check if all inputs are optional (none are required) # Check if all inputs are optional (none are required)

View File

@@ -337,7 +337,7 @@ class ValidationCore:
""" """
if not value: # Empty values are generally allowed, except for specific cases if not value: # Empty values are generally allowed, except for specific cases
# Some inputs should not be empty even if they're optional # Some inputs should not be empty even if they're optional
if action_name == "php-composer" and input_name in ["composer-version"]: if action_name == "php-composer" and input_name == "composer-version":
return False, f"Empty {input_name} is not allowed" return False, f"Empty {input_name} is not allowed"
return None, "" return None, ""
@@ -552,7 +552,7 @@ class ActionFileParser:
def _get_description_property(input_data: dict) -> str: def _get_description_property(input_data: dict) -> str:
"""Get the description property.""" """Get the description property."""
description = input_data.get("description", "") description = input_data.get("description", "")
return description if description else "no-description" return description or "no-description"
@staticmethod @staticmethod
def _get_all_optional_property(inputs: dict) -> str: def _get_all_optional_property(inputs: dict) -> str:

View File

@@ -92,9 +92,6 @@ setup_default_inputs() {
"go-build" | "go-lint") "go-build" | "go-lint")
[[ "$input_name" != "go-version" ]] && export INPUT_GO_VERSION="1.21" [[ "$input_name" != "go-version" ]] && export INPUT_GO_VERSION="1.21"
;; ;;
"common-retry")
[[ "$input_name" != "command" ]] && export INPUT_COMMAND="echo test"
;;
"dotnet-version-detect") "dotnet-version-detect")
[[ "$input_name" != "default-version" ]] && export INPUT_DEFAULT_VERSION="8.0" [[ "$input_name" != "default-version" ]] && export INPUT_DEFAULT_VERSION="8.0"
;; ;;
@@ -154,9 +151,6 @@ cleanup_default_inputs() {
"go-build" | "go-lint") "go-build" | "go-lint")
[[ "$input_name" != "go-version" ]] && unset INPUT_GO_VERSION [[ "$input_name" != "go-version" ]] && unset INPUT_GO_VERSION
;; ;;
"common-retry")
[[ "$input_name" != "command" ]] && unset INPUT_COMMAND
;;
"dotnet-version-detect") "dotnet-version-detect")
[[ "$input_name" != "default-version" ]] && unset INPUT_DEFAULT_VERSION [[ "$input_name" != "default-version" ]] && unset INPUT_DEFAULT_VERSION
;; ;;
@@ -239,12 +233,6 @@ shellspec_mock_action_run() {
"common-file-check") "common-file-check")
echo "found=true" >>"$GITHUB_OUTPUT" echo "found=true" >>"$GITHUB_OUTPUT"
;; ;;
"common-retry")
echo "success=true" >>"$GITHUB_OUTPUT"
echo "attempts=1" >>"$GITHUB_OUTPUT"
echo "exit-code=0" >>"$GITHUB_OUTPUT"
echo "duration=5" >>"$GITHUB_OUTPUT"
;;
"compress-images") "compress-images")
echo "images_compressed=true" >>"$GITHUB_OUTPUT" echo "images_compressed=true" >>"$GITHUB_OUTPUT"
printf "compression_report=## Compression Results\n- 3 images compressed\n- 25%% size reduction\n" >>"$GITHUB_OUTPUT" printf "compression_report=## Compression Results\n- 3 images compressed\n- 25%% size reduction\n" >>"$GITHUB_OUTPUT"

View File

@@ -45,7 +45,7 @@ runs:
steps: steps:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: 'ansible-lint-fix' action-type: 'ansible-lint-fix'
token: ${{ inputs.token }} token: ${{ inputs.token }}
@@ -83,7 +83,7 @@ runs:
- name: Install ansible-lint - name: Install ansible-lint
id: install-ansible-lint id: install-ansible-lint
if: steps.check-files.outputs.files_found == 'true' if: steps.check-files.outputs.files_found == 'true'
uses: step-security/retry@e1d59ce1f574b32f0915e3a8df055cfe9f99be5d # v3.0.4 uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with: with:
timeout_minutes: 5 timeout_minutes: 5
max_attempts: ${{ inputs.max-retries }} max_attempts: ${{ inputs.max-retries }}

View File

@@ -107,7 +107,7 @@ runs:
using: composite using: composite
steps: steps:
- name: Validate inputs - name: Validate inputs
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: codeql-analysis action-type: codeql-analysis
language: ${{ inputs.language }} language: ${{ inputs.language }}

View File

@@ -155,7 +155,7 @@ runs:
cache-dependency-path: '**/packages.lock.json' cache-dependency-path: '**/packages.lock.json'
- name: Restore Dependencies - name: Restore Dependencies
uses: step-security/retry@e1d59ce1f574b32f0915e3a8df055cfe9f99be5d # v3.0.4 uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with: with:
timeout_minutes: 10 timeout_minutes: 10
max_attempts: ${{ inputs.max-retries }} max_attempts: ${{ inputs.max-retries }}
@@ -203,7 +203,7 @@ runs:
- name: Upload Test Results - name: Upload Test Results
if: always() if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with: with:
name: csharp-test-results name: csharp-test-results
path: | path: |

View File

@@ -55,7 +55,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: 'csharp-publish' action-type: 'csharp-publish'
token: ${{ inputs.token }} token: ${{ inputs.token }}
@@ -169,7 +169,7 @@ runs:
cache-dependency-path: '**/packages.lock.json' cache-dependency-path: '**/packages.lock.json'
- name: Restore Dependencies - name: Restore Dependencies
uses: step-security/retry@e1d59ce1f574b32f0915e3a8df055cfe9f99be5d # v3.0.4 uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with: with:
timeout_minutes: 10 timeout_minutes: 10
max_attempts: ${{ inputs.max-retries }} max_attempts: ${{ inputs.max-retries }}

View File

@@ -147,7 +147,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: 'docker-build' action-type: 'docker-build'
image-name: ${{ inputs.image-name }} image-name: ${{ inputs.image-name }}

View File

@@ -159,13 +159,13 @@ runs:
echo "Final detected Go version: $detected_version" >&2 echo "Final detected Go version: $detected_version" >&2
- name: Setup Go - name: Setup Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with: with:
go-version: ${{ steps.detect-go-version.outputs.detected-version }} go-version: ${{ steps.detect-go-version.outputs.detected-version }}
cache: true cache: true
- name: Download Dependencies - name: Download Dependencies
uses: step-security/retry@e1d59ce1f574b32f0915e3a8df055cfe9f99be5d # v3.0.4 uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with: with:
timeout_minutes: 10 timeout_minutes: 10
max_attempts: ${{ inputs.max-retries }} max_attempts: ${{ inputs.max-retries }}
@@ -253,7 +253,7 @@ runs:
- name: Upload Build Artifacts - name: Upload Build Artifacts
if: always() if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with: with:
name: go-build-artifacts name: go-build-artifacts
path: | path: |

View File

@@ -205,7 +205,7 @@ runs:
validate_linter_list "$DISABLE_LINTERS" "disable-linters" validate_linter_list "$DISABLE_LINTERS" "disable-linters"
- name: Setup Go - name: Setup Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with: with:
go-version: ${{ inputs.go-version }} go-version: ${{ inputs.go-version }}
cache: true cache: true

40
package-lock.json generated
View File

@@ -185,9 +185,9 @@
} }
}, },
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "5.0.3", "version": "5.0.4",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
"integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -422,16 +422,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/dir-glob/node_modules/path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -823,9 +813,9 @@
} }
}, },
"node_modules/katex": { "node_modules/katex": {
"version": "0.16.32", "version": "0.16.33",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.32.tgz", "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.33.tgz",
"integrity": "sha512-ac0FzkRJlpw4WyH3Zu/OgU9LmPKqjHr6O2BxfSrBt8uJ1BhvH2YK3oJ4ut/K+O+6qQt2MGpdbn0MrffVEnnUDQ==", "integrity": "sha512-q3N5u+1sY9Bu7T4nlXoiRBXWfwSefNGoKeOwekV+gw0cAXQlz2Ww6BLcmBxVDeXBMUDQv6fK5bcNaJLxob3ZQA==",
"dev": true, "dev": true,
"funding": [ "funding": [
"https://opencollective.com/katex", "https://opencollective.com/katex",
@@ -1768,6 +1758,16 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/picomatch": { "node_modules/picomatch": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@@ -2034,13 +2034,13 @@
} }
}, },
"node_modules/strip-ansi": { "node_modules/strip-ansi": {
"version": "7.1.2", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ansi-regex": "^6.0.1" "ansi-regex": "^6.2.2"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=12"

View File

@@ -376,7 +376,7 @@ runs:
composer clear-cache composer clear-cache
- name: Install Composer Dependencies - name: Install Composer Dependencies
uses: step-security/retry@e1d59ce1f574b32f0915e3a8df055cfe9f99be5d # v3.0.4 uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with: with:
timeout_minutes: 10 timeout_minutes: 10
max_attempts: ${{ inputs.max-retries }} max_attempts: ${{ inputs.max-retries }}

View File

@@ -40,7 +40,7 @@ runs:
steps: steps:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: pr-lint action-type: pr-lint
token: ${{ inputs.token }} token: ${{ inputs.token }}
@@ -621,7 +621,7 @@ runs:
- name: Setup Go - name: Setup Go
if: steps.detect-go.outputs.found == 'true' if: steps.detect-go.outputs.found == 'true'
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with: with:
go-version: ${{ steps.go-version.outputs.detected-version }} go-version: ${{ steps.go-version.outputs.detected-version }}
cache: true cache: true
@@ -677,7 +677,7 @@ runs:
# Upload MegaLinter artifacts # Upload MegaLinter artifacts
- name: Archive production artifacts - name: Archive production artifacts
if: success() || failure() if: success() || failure()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with: with:
name: MegaLinter reports name: MegaLinter reports
include-hidden-files: 'true' include-hidden-files: 'true'

View File

@@ -49,7 +49,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: 'pre-commit' action-type: 'pre-commit'
token: ${{ inputs.token }} token: ${{ inputs.token }}

View File

@@ -64,7 +64,7 @@ runs:
steps: steps:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: 'python-lint-fix' action-type: 'python-lint-fix'
token: ${{ inputs.token }} token: ${{ inputs.token }}

View File

@@ -65,7 +65,7 @@ runs:
steps: steps:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: security-scan action-type: security-scan
gitleaks-license: ${{ inputs.gitleaks-license }} gitleaks-license: ${{ inputs.gitleaks-license }}
@@ -175,7 +175,7 @@ runs:
- name: Archive security reports - name: Archive security reports
if: always() if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with: with:
name: security-reports-${{ github.run_id }} name: security-reports-${{ github.run_id }}
path: | path: |

View File

@@ -43,7 +43,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: 'stale' action-type: 'stale'
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}

View File

@@ -78,7 +78,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@5cc7373a22402ee8985376bc713f00e09b5b2edb uses: ivuorinen/actions/validate-inputs@f98ae7cd7d0feb1f9d6b01de0addbb11414cfc73
with: with:
action-type: 'terraform-lint-fix' action-type: 'terraform-lint-fix'
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}
@@ -128,7 +128,7 @@ runs:
- name: Setup Terraform - name: Setup Terraform
if: steps.check-files.outputs.found == 'true' if: steps.check-files.outputs.found == 'true'
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v4.0.0
with: with:
terraform_version: ${{ inputs.terraform-version }} terraform_version: ${{ inputs.terraform-version }}
terraform_wrapper: false terraform_wrapper: false

38
uv.lock generated
View File

@@ -299,27 +299,27 @@ wheels = [
[[package]] [[package]]
name = "ruff" name = "ruff"
version = "0.15.2" version = "0.15.4"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/06/04/eab13a954e763b0606f460443fcbf6bb5a0faf06890ea3754ff16523dce5/ruff-0.15.2.tar.gz", hash = "sha256:14b965afee0969e68bb871eba625343b8673375f457af4abe98553e8bbb98342", size = 4558148, upload-time = "2026-02-19T22:32:20.271Z" } sdist = { url = "https://files.pythonhosted.org/packages/da/31/d6e536cdebb6568ae75a7f00e4b4819ae0ad2640c3604c305a0428680b0c/ruff-0.15.4.tar.gz", hash = "sha256:3412195319e42d634470cc97aa9803d07e9d5c9223b99bcb1518f0c725f26ae1", size = 4569550, upload-time = "2026-02-26T20:04:14.959Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/2f/70/3a4dc6d09b13cb3e695f28307e5d889b2e1a66b7af9c5e257e796695b0e6/ruff-0.15.2-py3-none-linux_armv6l.whl", hash = "sha256:120691a6fdae2f16d65435648160f5b81a9625288f75544dc40637436b5d3c0d", size = 10430565, upload-time = "2026-02-19T22:32:41.824Z" }, { url = "https://files.pythonhosted.org/packages/f2/82/c11a03cfec3a4d26a0ea1e571f0f44be5993b923f905eeddfc397c13d360/ruff-0.15.4-py3-none-linux_armv6l.whl", hash = "sha256:a1810931c41606c686bae8b5b9a8072adac2f611bb433c0ba476acba17a332e0", size = 10453333, upload-time = "2026-02-26T20:04:20.093Z" },
{ url = "https://files.pythonhosted.org/packages/71/0b/bb8457b56185ece1305c666dc895832946d24055be90692381c31d57466d/ruff-0.15.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a89056d831256099658b6bba4037ac6dd06f49d194199215befe2bb10457ea5e", size = 10820354, upload-time = "2026-02-19T22:32:07.366Z" }, { url = "https://files.pythonhosted.org/packages/ce/5d/6a1f271f6e31dffb31855996493641edc3eef8077b883eaf007a2f1c2976/ruff-0.15.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5a1632c66672b8b4d3e1d1782859e98d6e0b4e70829530666644286600a33992", size = 10853356, upload-time = "2026-02-26T20:04:05.808Z" },
{ url = "https://files.pythonhosted.org/packages/2d/c1/e0532d7f9c9e0b14c46f61b14afd563298b8b83f337b6789ddd987e46121/ruff-0.15.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e36dee3a64be0ebd23c86ffa3aa3fd3ac9a712ff295e192243f814a830b6bd87", size = 10170767, upload-time = "2026-02-19T22:32:13.188Z" }, { url = "https://files.pythonhosted.org/packages/b1/d8/0fab9f8842b83b1a9c2bf81b85063f65e93fb512e60effa95b0be49bfc54/ruff-0.15.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a4386ba2cd6c0f4ff75252845906acc7c7c8e1ac567b7bc3d373686ac8c222ba", size = 10187434, upload-time = "2026-02-26T20:03:54.656Z" },
{ url = "https://files.pythonhosted.org/packages/47/e8/da1aa341d3af017a21c7a62fb5ec31d4e7ad0a93ab80e3a508316efbcb23/ruff-0.15.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9fb47b6d9764677f8c0a193c0943ce9a05d6763523f132325af8a858eadc2b9", size = 10529591, upload-time = "2026-02-19T22:32:02.547Z" }, { url = "https://files.pythonhosted.org/packages/85/cc/cc220fd9394eff5db8d94dec199eec56dd6c9f3651d8869d024867a91030/ruff-0.15.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2496488bdfd3732747558b6f95ae427ff066d1fcd054daf75f5a50674411e75", size = 10535456, upload-time = "2026-02-26T20:03:52.738Z" },
{ url = "https://files.pythonhosted.org/packages/93/74/184fbf38e9f3510231fbc5e437e808f0b48c42d1df9434b208821efcd8d6/ruff-0.15.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f376990f9d0d6442ea9014b19621d8f2aaf2b8e39fdbfc79220b7f0c596c9b80", size = 10260771, upload-time = "2026-02-19T22:32:36.938Z" }, { url = "https://files.pythonhosted.org/packages/fa/0f/bced38fa5cf24373ec767713c8e4cadc90247f3863605fb030e597878661/ruff-0.15.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3f1c4893841ff2d54cbda1b2860fa3260173df5ddd7b95d370186f8a5e66a4ac", size = 10287772, upload-time = "2026-02-26T20:04:08.138Z" },
{ url = "https://files.pythonhosted.org/packages/05/ac/605c20b8e059a0bc4b42360414baa4892ff278cec1c91fff4be0dceedefd/ruff-0.15.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2dcc987551952d73cbf5c88d9fdee815618d497e4df86cd4c4824cc59d5dd75f", size = 11045791, upload-time = "2026-02-19T22:32:31.642Z" }, { url = "https://files.pythonhosted.org/packages/2b/90/58a1802d84fed15f8f281925b21ab3cecd813bde52a8ca033a4de8ab0e7a/ruff-0.15.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:820b8766bd65503b6c30aaa6331e8ef3a6e564f7999c844e9a547c40179e440a", size = 11049051, upload-time = "2026-02-26T20:04:03.53Z" },
{ url = "https://files.pythonhosted.org/packages/fd/52/db6e419908f45a894924d410ac77d64bdd98ff86901d833364251bd08e22/ruff-0.15.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:42a47fd785cbe8c01b9ff45031af875d101b040ad8f4de7bbb716487c74c9a77", size = 11879271, upload-time = "2026-02-19T22:32:29.305Z" }, { url = "https://files.pythonhosted.org/packages/d2/ac/b7ad36703c35f3866584564dc15f12f91cb1a26a897dc2fd13d7cb3ae1af/ruff-0.15.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9fb74bab47139c1751f900f857fa503987253c3ef89129b24ed375e72873e85", size = 11890494, upload-time = "2026-02-26T20:04:10.497Z" },
{ url = "https://files.pythonhosted.org/packages/3e/d8/7992b18f2008bdc9231d0f10b16df7dda964dbf639e2b8b4c1b4e91b83af/ruff-0.15.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbe9f49354866e575b4c6943856989f966421870e85cd2ac94dccb0a9dcb2fea", size = 11303707, upload-time = "2026-02-19T22:32:22.492Z" }, { url = "https://files.pythonhosted.org/packages/93/3d/3eb2f47a39a8b0da99faf9c54d3eb24720add1e886a5309d4d1be73a6380/ruff-0.15.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f80c98765949c518142b3a50a5db89343aa90f2c2bf7799de9986498ae6176db", size = 11326221, upload-time = "2026-02-26T20:04:12.84Z" },
{ url = "https://files.pythonhosted.org/packages/d7/02/849b46184bcfdd4b64cde61752cc9a146c54759ed036edd11857e9b8443b/ruff-0.15.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7a672c82b5f9887576087d97be5ce439f04bbaf548ee987b92d3a7dede41d3a", size = 11149151, upload-time = "2026-02-19T22:32:44.234Z" }, { url = "https://files.pythonhosted.org/packages/ff/90/bf134f4c1e5243e62690e09d63c55df948a74084c8ac3e48a88468314da6/ruff-0.15.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:451a2e224151729b3b6c9ffb36aed9091b2996fe4bdbd11f47e27d8f2e8888ec", size = 11168459, upload-time = "2026-02-26T20:04:00.969Z" },
{ url = "https://files.pythonhosted.org/packages/70/04/f5284e388bab60d1d3b99614a5a9aeb03e0f333847e2429bebd2aaa1feec/ruff-0.15.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:72ecc64f46f7019e2bcc3cdc05d4a7da958b629a5ab7033195e11a438403d956", size = 11091132, upload-time = "2026-02-19T22:32:24.691Z" }, { url = "https://files.pythonhosted.org/packages/b5/e5/a64d27688789b06b5d55162aafc32059bb8c989c61a5139a36e1368285eb/ruff-0.15.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a8f157f2e583c513c4f5f896163a93198297371f34c04220daf40d133fdd4f7f", size = 11104366, upload-time = "2026-02-26T20:03:48.099Z" },
{ url = "https://files.pythonhosted.org/packages/fa/ae/88d844a21110e14d92cf73d57363fab59b727ebeabe78009b9ccb23500af/ruff-0.15.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:8dcf243b15b561c655c1ef2f2b0050e5d50db37fe90115507f6ff37d865dc8b4", size = 10504717, upload-time = "2026-02-19T22:32:26.75Z" }, { url = "https://files.pythonhosted.org/packages/f1/f6/32d1dcb66a2559763fc3027bdd65836cad9eb09d90f2ed6a63d8e9252b02/ruff-0.15.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:917cc68503357021f541e69b35361c99387cdbbf99bd0ea4aa6f28ca99ff5338", size = 10510887, upload-time = "2026-02-26T20:03:45.771Z" },
{ url = "https://files.pythonhosted.org/packages/64/27/867076a6ada7f2b9c8292884ab44d08fd2ba71bd2b5364d4136f3cd537e1/ruff-0.15.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dab6941c862c05739774677c6273166d2510d254dac0695c0e3f5efa1b5585de", size = 10263122, upload-time = "2026-02-19T22:32:10.036Z" }, { url = "https://files.pythonhosted.org/packages/ff/92/22d1ced50971c5b6433aed166fcef8c9343f567a94cf2b9d9089f6aa80fe/ruff-0.15.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e9737c8161da79fd7cfec19f1e35620375bd8b2a50c3e77fa3d2c16f574105cc", size = 10285939, upload-time = "2026-02-26T20:04:22.42Z" },
{ url = "https://files.pythonhosted.org/packages/e7/ef/faf9321d550f8ebf0c6373696e70d1758e20ccdc3951ad7af00c0956be7c/ruff-0.15.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1b9164f57fc36058e9a6806eb92af185b0697c9fe4c7c52caa431c6554521e5c", size = 10735295, upload-time = "2026-02-19T22:32:39.227Z" }, { url = "https://files.pythonhosted.org/packages/e6/f4/7c20aec3143837641a02509a4668fb146a642fd1211846634edc17eb5563/ruff-0.15.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:291258c917539e18f6ba40482fe31d6f5ac023994ee11d7bdafd716f2aab8a68", size = 10765471, upload-time = "2026-02-26T20:03:58.924Z" },
{ url = "https://files.pythonhosted.org/packages/2f/55/e8089fec62e050ba84d71b70e7834b97709ca9b7aba10c1a0b196e493f97/ruff-0.15.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:80d24fcae24d42659db7e335b9e1531697a7102c19185b8dc4a028b952865fd8", size = 11241641, upload-time = "2026-02-19T22:32:34.617Z" }, { url = "https://files.pythonhosted.org/packages/d0/09/6d2f7586f09a16120aebdff8f64d962d7c4348313c77ebb29c566cefc357/ruff-0.15.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3f83c45911da6f2cd5936c436cf86b9f09f09165f033a99dcf7477e34041cbc3", size = 11263382, upload-time = "2026-02-26T20:04:24.424Z" },
{ url = "https://files.pythonhosted.org/packages/23/01/1c30526460f4d23222d0fabd5888868262fd0e2b71a00570ca26483cd993/ruff-0.15.2-py3-none-win32.whl", hash = "sha256:fd5ff9e5f519a7e1bd99cbe8daa324010a74f5e2ebc97c6242c08f26f3714f6f", size = 10507885, upload-time = "2026-02-19T22:32:15.635Z" }, { url = "https://files.pythonhosted.org/packages/1b/fa/2ef715a1cd329ef47c1a050e10dee91a9054b7ce2fcfdd6a06d139afb7ec/ruff-0.15.4-py3-none-win32.whl", hash = "sha256:65594a2d557d4ee9f02834fcdf0a28daa8b3b9f6cb2cb93846025a36db47ef22", size = 10506664, upload-time = "2026-02-26T20:03:50.56Z" },
{ url = "https://files.pythonhosted.org/packages/5c/10/3d18e3bbdf8fc50bbb4ac3cc45970aa5a9753c5cb51bf9ed9a3cd8b79fa3/ruff-0.15.2-py3-none-win_amd64.whl", hash = "sha256:d20014e3dfa400f3ff84830dfb5755ece2de45ab62ecea4af6b7262d0fb4f7c5", size = 11623725, upload-time = "2026-02-19T22:32:04.947Z" }, { url = "https://files.pythonhosted.org/packages/d0/a8/c688ef7e29983976820d18710f955751d9f4d4eb69df658af3d006e2ba3e/ruff-0.15.4-py3-none-win_amd64.whl", hash = "sha256:04196ad44f0df220c2ece5b0e959c2f37c777375ec744397d21d15b50a75264f", size = 11651048, upload-time = "2026-02-26T20:04:17.191Z" },
{ url = "https://files.pythonhosted.org/packages/6d/78/097c0798b1dab9f8affe73da9642bb4500e098cb27fd8dc9724816ac747b/ruff-0.15.2-py3-none-win_arm64.whl", hash = "sha256:cabddc5822acdc8f7b5527b36ceac55cc51eec7b1946e60181de8fe83ca8876e", size = 10941649, upload-time = "2026-02-19T22:32:18.108Z" }, { url = "https://files.pythonhosted.org/packages/3e/0a/9e1be9035b37448ce2e68c978f0591da94389ade5a5abafa4cf99985d1b2/ruff-0.15.4-py3-none-win_arm64.whl", hash = "sha256:60d5177e8cfc70e51b9c5fad936c634872a74209f934c1e79107d11787ad5453", size = 10966776, upload-time = "2026-02-26T20:03:56.908Z" },
] ]
[[package]] [[package]]

View File

@@ -332,7 +332,7 @@ class CustomValidator(BaseValidator):
## Quality Metrics ## Quality Metrics
- **Test Coverage**: 100% (769 tests) - **Test Coverage**: 100%
- **Validators**: 9 specialized + unlimited custom - **Validators**: 9 specialized + unlimited custom
- **Performance**: < 10ms typical validation time - **Performance**: < 10ms typical validation time
- **Zero Dependencies**: Uses only Python stdlib + PyYAML - **Zero Dependencies**: Uses only Python stdlib + PyYAML

View File

@@ -310,10 +310,6 @@ class ValidationRuleGenerator:
"common-file-check": { "common-file-check": {
"file-pattern": "file_path", "file-pattern": "file_path",
}, },
"common-retry": {
"backoff-strategy": "backoff_strategy",
"shell": "shell_type",
},
"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 common-retry 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 / "common-retry"
sys.path.insert(0, str(action_path))
# pylint: disable=wrong-import-position
from CustomValidator import CustomValidator
class TestCustomCommonRetryValidator:
"""Test cases for common-retry custom validator."""
def setup_method(self):
"""Set up test fixtures."""
self.validator = CustomValidator("common-retry")
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 common-retry
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 common-retry
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 common-retry
def test_validation_rules(self):
"""Test validation rules."""
rules = self.validator.get_validation_rules()
assert isinstance(rules, dict)
# TODO: Assert specific validation rules for common-retry
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

View File

@@ -631,27 +631,27 @@ wheels = [
[[package]] [[package]]
name = "ruff" name = "ruff"
version = "0.15.2" version = "0.15.4"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/06/04/eab13a954e763b0606f460443fcbf6bb5a0faf06890ea3754ff16523dce5/ruff-0.15.2.tar.gz", hash = "sha256:14b965afee0969e68bb871eba625343b8673375f457af4abe98553e8bbb98342", size = 4558148, upload-time = "2026-02-19T22:32:20.271Z" } sdist = { url = "https://files.pythonhosted.org/packages/da/31/d6e536cdebb6568ae75a7f00e4b4819ae0ad2640c3604c305a0428680b0c/ruff-0.15.4.tar.gz", hash = "sha256:3412195319e42d634470cc97aa9803d07e9d5c9223b99bcb1518f0c725f26ae1", size = 4569550, upload-time = "2026-02-26T20:04:14.959Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/2f/70/3a4dc6d09b13cb3e695f28307e5d889b2e1a66b7af9c5e257e796695b0e6/ruff-0.15.2-py3-none-linux_armv6l.whl", hash = "sha256:120691a6fdae2f16d65435648160f5b81a9625288f75544dc40637436b5d3c0d", size = 10430565, upload-time = "2026-02-19T22:32:41.824Z" }, { url = "https://files.pythonhosted.org/packages/f2/82/c11a03cfec3a4d26a0ea1e571f0f44be5993b923f905eeddfc397c13d360/ruff-0.15.4-py3-none-linux_armv6l.whl", hash = "sha256:a1810931c41606c686bae8b5b9a8072adac2f611bb433c0ba476acba17a332e0", size = 10453333, upload-time = "2026-02-26T20:04:20.093Z" },
{ url = "https://files.pythonhosted.org/packages/71/0b/bb8457b56185ece1305c666dc895832946d24055be90692381c31d57466d/ruff-0.15.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a89056d831256099658b6bba4037ac6dd06f49d194199215befe2bb10457ea5e", size = 10820354, upload-time = "2026-02-19T22:32:07.366Z" }, { url = "https://files.pythonhosted.org/packages/ce/5d/6a1f271f6e31dffb31855996493641edc3eef8077b883eaf007a2f1c2976/ruff-0.15.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5a1632c66672b8b4d3e1d1782859e98d6e0b4e70829530666644286600a33992", size = 10853356, upload-time = "2026-02-26T20:04:05.808Z" },
{ url = "https://files.pythonhosted.org/packages/2d/c1/e0532d7f9c9e0b14c46f61b14afd563298b8b83f337b6789ddd987e46121/ruff-0.15.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e36dee3a64be0ebd23c86ffa3aa3fd3ac9a712ff295e192243f814a830b6bd87", size = 10170767, upload-time = "2026-02-19T22:32:13.188Z" }, { url = "https://files.pythonhosted.org/packages/b1/d8/0fab9f8842b83b1a9c2bf81b85063f65e93fb512e60effa95b0be49bfc54/ruff-0.15.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a4386ba2cd6c0f4ff75252845906acc7c7c8e1ac567b7bc3d373686ac8c222ba", size = 10187434, upload-time = "2026-02-26T20:03:54.656Z" },
{ url = "https://files.pythonhosted.org/packages/47/e8/da1aa341d3af017a21c7a62fb5ec31d4e7ad0a93ab80e3a508316efbcb23/ruff-0.15.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9fb47b6d9764677f8c0a193c0943ce9a05d6763523f132325af8a858eadc2b9", size = 10529591, upload-time = "2026-02-19T22:32:02.547Z" }, { url = "https://files.pythonhosted.org/packages/85/cc/cc220fd9394eff5db8d94dec199eec56dd6c9f3651d8869d024867a91030/ruff-0.15.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2496488bdfd3732747558b6f95ae427ff066d1fcd054daf75f5a50674411e75", size = 10535456, upload-time = "2026-02-26T20:03:52.738Z" },
{ url = "https://files.pythonhosted.org/packages/93/74/184fbf38e9f3510231fbc5e437e808f0b48c42d1df9434b208821efcd8d6/ruff-0.15.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f376990f9d0d6442ea9014b19621d8f2aaf2b8e39fdbfc79220b7f0c596c9b80", size = 10260771, upload-time = "2026-02-19T22:32:36.938Z" }, { url = "https://files.pythonhosted.org/packages/fa/0f/bced38fa5cf24373ec767713c8e4cadc90247f3863605fb030e597878661/ruff-0.15.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3f1c4893841ff2d54cbda1b2860fa3260173df5ddd7b95d370186f8a5e66a4ac", size = 10287772, upload-time = "2026-02-26T20:04:08.138Z" },
{ url = "https://files.pythonhosted.org/packages/05/ac/605c20b8e059a0bc4b42360414baa4892ff278cec1c91fff4be0dceedefd/ruff-0.15.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2dcc987551952d73cbf5c88d9fdee815618d497e4df86cd4c4824cc59d5dd75f", size = 11045791, upload-time = "2026-02-19T22:32:31.642Z" }, { url = "https://files.pythonhosted.org/packages/2b/90/58a1802d84fed15f8f281925b21ab3cecd813bde52a8ca033a4de8ab0e7a/ruff-0.15.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:820b8766bd65503b6c30aaa6331e8ef3a6e564f7999c844e9a547c40179e440a", size = 11049051, upload-time = "2026-02-26T20:04:03.53Z" },
{ url = "https://files.pythonhosted.org/packages/fd/52/db6e419908f45a894924d410ac77d64bdd98ff86901d833364251bd08e22/ruff-0.15.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:42a47fd785cbe8c01b9ff45031af875d101b040ad8f4de7bbb716487c74c9a77", size = 11879271, upload-time = "2026-02-19T22:32:29.305Z" }, { url = "https://files.pythonhosted.org/packages/d2/ac/b7ad36703c35f3866584564dc15f12f91cb1a26a897dc2fd13d7cb3ae1af/ruff-0.15.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9fb74bab47139c1751f900f857fa503987253c3ef89129b24ed375e72873e85", size = 11890494, upload-time = "2026-02-26T20:04:10.497Z" },
{ url = "https://files.pythonhosted.org/packages/3e/d8/7992b18f2008bdc9231d0f10b16df7dda964dbf639e2b8b4c1b4e91b83af/ruff-0.15.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbe9f49354866e575b4c6943856989f966421870e85cd2ac94dccb0a9dcb2fea", size = 11303707, upload-time = "2026-02-19T22:32:22.492Z" }, { url = "https://files.pythonhosted.org/packages/93/3d/3eb2f47a39a8b0da99faf9c54d3eb24720add1e886a5309d4d1be73a6380/ruff-0.15.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f80c98765949c518142b3a50a5db89343aa90f2c2bf7799de9986498ae6176db", size = 11326221, upload-time = "2026-02-26T20:04:12.84Z" },
{ url = "https://files.pythonhosted.org/packages/d7/02/849b46184bcfdd4b64cde61752cc9a146c54759ed036edd11857e9b8443b/ruff-0.15.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7a672c82b5f9887576087d97be5ce439f04bbaf548ee987b92d3a7dede41d3a", size = 11149151, upload-time = "2026-02-19T22:32:44.234Z" }, { url = "https://files.pythonhosted.org/packages/ff/90/bf134f4c1e5243e62690e09d63c55df948a74084c8ac3e48a88468314da6/ruff-0.15.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:451a2e224151729b3b6c9ffb36aed9091b2996fe4bdbd11f47e27d8f2e8888ec", size = 11168459, upload-time = "2026-02-26T20:04:00.969Z" },
{ url = "https://files.pythonhosted.org/packages/70/04/f5284e388bab60d1d3b99614a5a9aeb03e0f333847e2429bebd2aaa1feec/ruff-0.15.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:72ecc64f46f7019e2bcc3cdc05d4a7da958b629a5ab7033195e11a438403d956", size = 11091132, upload-time = "2026-02-19T22:32:24.691Z" }, { url = "https://files.pythonhosted.org/packages/b5/e5/a64d27688789b06b5d55162aafc32059bb8c989c61a5139a36e1368285eb/ruff-0.15.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a8f157f2e583c513c4f5f896163a93198297371f34c04220daf40d133fdd4f7f", size = 11104366, upload-time = "2026-02-26T20:03:48.099Z" },
{ url = "https://files.pythonhosted.org/packages/fa/ae/88d844a21110e14d92cf73d57363fab59b727ebeabe78009b9ccb23500af/ruff-0.15.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:8dcf243b15b561c655c1ef2f2b0050e5d50db37fe90115507f6ff37d865dc8b4", size = 10504717, upload-time = "2026-02-19T22:32:26.75Z" }, { url = "https://files.pythonhosted.org/packages/f1/f6/32d1dcb66a2559763fc3027bdd65836cad9eb09d90f2ed6a63d8e9252b02/ruff-0.15.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:917cc68503357021f541e69b35361c99387cdbbf99bd0ea4aa6f28ca99ff5338", size = 10510887, upload-time = "2026-02-26T20:03:45.771Z" },
{ url = "https://files.pythonhosted.org/packages/64/27/867076a6ada7f2b9c8292884ab44d08fd2ba71bd2b5364d4136f3cd537e1/ruff-0.15.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dab6941c862c05739774677c6273166d2510d254dac0695c0e3f5efa1b5585de", size = 10263122, upload-time = "2026-02-19T22:32:10.036Z" }, { url = "https://files.pythonhosted.org/packages/ff/92/22d1ced50971c5b6433aed166fcef8c9343f567a94cf2b9d9089f6aa80fe/ruff-0.15.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e9737c8161da79fd7cfec19f1e35620375bd8b2a50c3e77fa3d2c16f574105cc", size = 10285939, upload-time = "2026-02-26T20:04:22.42Z" },
{ url = "https://files.pythonhosted.org/packages/e7/ef/faf9321d550f8ebf0c6373696e70d1758e20ccdc3951ad7af00c0956be7c/ruff-0.15.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1b9164f57fc36058e9a6806eb92af185b0697c9fe4c7c52caa431c6554521e5c", size = 10735295, upload-time = "2026-02-19T22:32:39.227Z" }, { url = "https://files.pythonhosted.org/packages/e6/f4/7c20aec3143837641a02509a4668fb146a642fd1211846634edc17eb5563/ruff-0.15.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:291258c917539e18f6ba40482fe31d6f5ac023994ee11d7bdafd716f2aab8a68", size = 10765471, upload-time = "2026-02-26T20:03:58.924Z" },
{ url = "https://files.pythonhosted.org/packages/2f/55/e8089fec62e050ba84d71b70e7834b97709ca9b7aba10c1a0b196e493f97/ruff-0.15.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:80d24fcae24d42659db7e335b9e1531697a7102c19185b8dc4a028b952865fd8", size = 11241641, upload-time = "2026-02-19T22:32:34.617Z" }, { url = "https://files.pythonhosted.org/packages/d0/09/6d2f7586f09a16120aebdff8f64d962d7c4348313c77ebb29c566cefc357/ruff-0.15.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3f83c45911da6f2cd5936c436cf86b9f09f09165f033a99dcf7477e34041cbc3", size = 11263382, upload-time = "2026-02-26T20:04:24.424Z" },
{ url = "https://files.pythonhosted.org/packages/23/01/1c30526460f4d23222d0fabd5888868262fd0e2b71a00570ca26483cd993/ruff-0.15.2-py3-none-win32.whl", hash = "sha256:fd5ff9e5f519a7e1bd99cbe8daa324010a74f5e2ebc97c6242c08f26f3714f6f", size = 10507885, upload-time = "2026-02-19T22:32:15.635Z" }, { url = "https://files.pythonhosted.org/packages/1b/fa/2ef715a1cd329ef47c1a050e10dee91a9054b7ce2fcfdd6a06d139afb7ec/ruff-0.15.4-py3-none-win32.whl", hash = "sha256:65594a2d557d4ee9f02834fcdf0a28daa8b3b9f6cb2cb93846025a36db47ef22", size = 10506664, upload-time = "2026-02-26T20:03:50.56Z" },
{ url = "https://files.pythonhosted.org/packages/5c/10/3d18e3bbdf8fc50bbb4ac3cc45970aa5a9753c5cb51bf9ed9a3cd8b79fa3/ruff-0.15.2-py3-none-win_amd64.whl", hash = "sha256:d20014e3dfa400f3ff84830dfb5755ece2de45ab62ecea4af6b7262d0fb4f7c5", size = 11623725, upload-time = "2026-02-19T22:32:04.947Z" }, { url = "https://files.pythonhosted.org/packages/d0/a8/c688ef7e29983976820d18710f955751d9f4d4eb69df658af3d006e2ba3e/ruff-0.15.4-py3-none-win_amd64.whl", hash = "sha256:04196ad44f0df220c2ece5b0e959c2f37c777375ec744397d21d15b50a75264f", size = 11651048, upload-time = "2026-02-26T20:04:17.191Z" },
{ url = "https://files.pythonhosted.org/packages/6d/78/097c0798b1dab9f8affe73da9642bb4500e098cb27fd8dc9724816ac747b/ruff-0.15.2-py3-none-win_arm64.whl", hash = "sha256:cabddc5822acdc8f7b5527b36ceac55cc51eec7b1946e60181de8fe83ca8876e", size = 10941649, upload-time = "2026-02-19T22:32:18.108Z" }, { url = "https://files.pythonhosted.org/packages/3e/0a/9e1be9035b37448ce2e68c978f0591da94389ade5a5abafa4cf99985d1b2/ruff-0.15.4-py3-none-win_arm64.whl", hash = "sha256:60d5177e8cfc70e51b9c5fad936c634872a74209f934c1e79107d11787ad5453", size = 10966776, upload-time = "2026-02-26T20:03:56.908Z" },
] ]
[[package]] [[package]]