mirror of
https://github.com/ivuorinen/actions.git
synced 2026-03-08 02:56:34 +00:00
Compare commits
15 Commits
v2026.03.0
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f995f89a21 | |||
|
|
242ecca8f0 | ||
|
|
97105fc2a9 | ||
|
|
e9deac2a01 | ||
|
|
480c06b83b | ||
|
|
07ce8df887 | ||
|
|
0f29424163 | ||
|
|
ce81e51641 | ||
|
|
261323db29 | ||
|
|
c679f0c863 | ||
|
|
128b2f1713 | ||
|
|
08393e8063 | ||
|
|
ed9f205433 | ||
|
|
ae4ad9ec80 | ||
|
|
455267f892 |
30
.claude/agents/action-validator.md
Normal file
30
.claude/agents/action-validator.md
Normal file
@@ -0,0 +1,30 @@
|
||||
You review action.yml files against the repository's critical prevention rules.
|
||||
|
||||
Check each action.yml file for these violations:
|
||||
|
||||
1. All external action refs are SHA-pinned (not @main/@v1)
|
||||
2. All internal action refs use `ivuorinen/actions/name@SHA` format
|
||||
3. Shell scripts use `set -eu` (POSIX, not bash)
|
||||
4. Steps with referenced outputs have `id:` fields
|
||||
5. Tool availability checked before use (`command -v`)
|
||||
6. Variables properly quoted (`"$var"`)
|
||||
7. `$GITHUB_OUTPUT` uses `printf`, not `echo`
|
||||
8. No nested `${{ }}` in quoted YAML strings
|
||||
9. Token inputs use `${{ github.token }}` default
|
||||
10. Fallbacks provided for tools not on all runners
|
||||
|
||||
Run `actionlint` on each file. Report violations with file path, line, and fix suggestion.
|
||||
|
||||
To find all action.yml files:
|
||||
|
||||
```bash
|
||||
find . -name "action.yml" -not -path "./.git/*"
|
||||
```
|
||||
|
||||
For each file, read it and check against all 10 rules. Then run:
|
||||
|
||||
```bash
|
||||
actionlint <file>
|
||||
```
|
||||
|
||||
Output a summary table of violations found, grouped by action.
|
||||
33
.claude/agents/test-coverage-reviewer.md
Normal file
33
.claude/agents/test-coverage-reviewer.md
Normal file
@@ -0,0 +1,33 @@
|
||||
You review test coverage for GitHub Actions in this monorepo.
|
||||
|
||||
For each action:
|
||||
|
||||
1. Read the action.yml to understand inputs, outputs, and steps
|
||||
2. Read the corresponding test files in `_tests/unit/<action-name>/`
|
||||
3. Check if all inputs have validation tests
|
||||
4. Check if error paths are tested (missing required inputs, invalid values)
|
||||
5. Check if shell scripts have edge case tests (spaces in paths, empty strings, special chars)
|
||||
6. Report coverage gaps with specific test suggestions
|
||||
|
||||
To find all actions and their tests:
|
||||
|
||||
```bash
|
||||
ls -d */action.yml | sed 's|/action.yml||'
|
||||
ls -d _tests/unit/*/
|
||||
```
|
||||
|
||||
Compare the two lists to find actions without any tests.
|
||||
|
||||
For each action with tests, check coverage of:
|
||||
|
||||
- All required inputs validated
|
||||
- All optional inputs with defaults tested
|
||||
- Error conditions (missing inputs, invalid formats)
|
||||
- Edge cases in shell logic (empty strings, special characters, spaces in paths)
|
||||
- Output values verified
|
||||
|
||||
Output a coverage report with:
|
||||
|
||||
- Actions with no tests (critical)
|
||||
- Actions with partial coverage (list missing test cases)
|
||||
- Actions with good coverage (brief confirmation)
|
||||
21
.claude/hooks/block-rules-yml.sh
Executable file
21
.claude/hooks/block-rules-yml.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# Read JSON input from stdin to get the file path
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "Error: jq is required but not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INPUT=$(cat)
|
||||
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.filePath // empty')
|
||||
|
||||
if [ -z "$FILE_PATH" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case "$FILE_PATH" in
|
||||
*/rules.yml)
|
||||
echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"rules.yml files are auto-generated. Run make update-validators instead."}}'
|
||||
;;
|
||||
esac
|
||||
46
.claude/hooks/post-edit-write.sh
Executable file
46
.claude/hooks/post-edit-write.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# Read JSON input from stdin to get the file path
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "Error: jq is required but not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INPUT=$(cat)
|
||||
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.filePath // empty')
|
||||
|
||||
if [ -z "$FILE_PATH" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case "$FILE_PATH" in
|
||||
*/rules.yml)
|
||||
# rules.yml should not be reached here (blocked by PreToolUse),
|
||||
# but skip formatting just in case
|
||||
exit 0
|
||||
;;
|
||||
*.py)
|
||||
ruff format --quiet "$FILE_PATH" 2>/dev/null || true
|
||||
ruff check --fix --quiet "$FILE_PATH" 2>/dev/null || true
|
||||
;;
|
||||
*.sh)
|
||||
shfmt -w "$FILE_PATH" 2>/dev/null || true
|
||||
shellcheck "$FILE_PATH" 2>&1 || true
|
||||
;;
|
||||
*.yml | *.yaml | *.json)
|
||||
npx prettier --write "$FILE_PATH" 2>/dev/null || true
|
||||
;;
|
||||
*.md)
|
||||
npx prettier --write "$FILE_PATH" 2>/dev/null || true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Run actionlint on action.yml files
|
||||
case "$FILE_PATH" in
|
||||
*/action.yml)
|
||||
if command -v actionlint >/dev/null 2>&1; then
|
||||
actionlint "$FILE_PATH" 2>&1 || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
26
.claude/settings.json
Normal file
26
.claude/settings.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-rules-yml.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/post-edit-write.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
40
.claude/skills/check-pins/SKILL.md
Normal file
40
.claude/skills/check-pins/SKILL.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: check-pins
|
||||
description: Verify all action references are properly SHA-pinned
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Check SHA-Pinned Action References
|
||||
|
||||
## 1. Check version references
|
||||
|
||||
```bash
|
||||
make check-version-refs
|
||||
```
|
||||
|
||||
This verifies that all `ivuorinen/actions/*` references in `action.yml` files use SHA-pinned commits.
|
||||
|
||||
## 2. Check local references
|
||||
|
||||
```bash
|
||||
make check-local-refs
|
||||
```
|
||||
|
||||
This verifies that test workflows use `./action-name` format (local references are allowed in tests).
|
||||
|
||||
## 3. Interpret results
|
||||
|
||||
**Violations to fix:**
|
||||
|
||||
- `@main` or `@v*` references in `action.yml` files must be replaced with full SHA commits
|
||||
- `./action-name` in `action.yml` (non-test) files must use `ivuorinen/actions/action-name@<SHA>`
|
||||
- External actions must be pinned to SHA commits, not version tags
|
||||
|
||||
**How to get the SHA for pinning:**
|
||||
|
||||
```bash
|
||||
# After pushing, get the SHA of the latest commit on the remote
|
||||
git rev-parse origin/main
|
||||
```
|
||||
|
||||
Use a SHA that exists on the remote. Local-only commits won't resolve when the action is used externally.
|
||||
60
.claude/skills/new-action/SKILL.md
Normal file
60
.claude/skills/new-action/SKILL.md
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
name: new-action
|
||||
description: Scaffold a new GitHub Action with all required files
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Scaffold a New GitHub Action
|
||||
|
||||
## 1. Gather information
|
||||
|
||||
Ask the user for:
|
||||
|
||||
- **Action name** (kebab-case, e.g. `my-new-action`)
|
||||
- **Description** (one line)
|
||||
- **Category** (setup, linting, testing, build, publishing, repository, utility)
|
||||
- **Inputs** (name, description, required, default for each)
|
||||
- **What it does** (shell commands, composite steps, etc.)
|
||||
|
||||
## 2. Create directory and action.yml
|
||||
|
||||
Create `<action-name>/action.yml` following the existing action patterns:
|
||||
|
||||
- Use `composite` runs type
|
||||
- Include `set -eu` in shell scripts (POSIX sh, not bash)
|
||||
- Use `${{ github.token }}` for token defaults
|
||||
- Pin all external action references to SHA commits
|
||||
- Pin internal action references using `ivuorinen/actions/action-name@<SHA>`
|
||||
- Add `id:` to steps whose outputs are referenced
|
||||
|
||||
## 3. Generate validation rules
|
||||
|
||||
```bash
|
||||
make update-validators
|
||||
```
|
||||
|
||||
This generates `<action-name>/rules.yml` from the action's inputs.
|
||||
|
||||
## 4. Generate test scaffolding
|
||||
|
||||
```bash
|
||||
make generate-tests
|
||||
```
|
||||
|
||||
## 5. Generate README
|
||||
|
||||
```bash
|
||||
make docs
|
||||
```
|
||||
|
||||
## 6. Run validation
|
||||
|
||||
```bash
|
||||
make all
|
||||
```
|
||||
|
||||
Fix any issues before considering the action complete.
|
||||
|
||||
## 7. Update repository overview
|
||||
|
||||
Remind the user to update the Serena memory `repository_overview` if they use Serena.
|
||||
57
.claude/skills/release/SKILL.md
Normal file
57
.claude/skills/release/SKILL.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
name: release
|
||||
description: Create a new CalVer release with validation checks
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Release Workflow
|
||||
|
||||
Follow these steps to create a new CalVer release:
|
||||
|
||||
## 1. Pre-flight checks
|
||||
|
||||
Run the full validation pipeline:
|
||||
|
||||
```bash
|
||||
make all
|
||||
```
|
||||
|
||||
If any step fails, fix the issues before proceeding.
|
||||
|
||||
## 2. Check version references
|
||||
|
||||
Verify all action references are properly pinned:
|
||||
|
||||
```bash
|
||||
make check-version-refs
|
||||
make check-local-refs
|
||||
```
|
||||
|
||||
## 3. Prepare the release
|
||||
|
||||
Run release preparation (updates version references):
|
||||
|
||||
```bash
|
||||
make release-prep
|
||||
```
|
||||
|
||||
Review the changes with `git diff`.
|
||||
|
||||
## 4. Confirm with user
|
||||
|
||||
Ask the user to confirm:
|
||||
|
||||
- The version number (defaults to `vYYYY.MM.DD` based on today's date)
|
||||
- That all changes look correct
|
||||
|
||||
## 5. Create the release
|
||||
|
||||
```bash
|
||||
make release VERSION=vYYYY.MM.DD
|
||||
```
|
||||
|
||||
Replace `vYYYY.MM.DD` with the confirmed version.
|
||||
|
||||
## 6. Verify
|
||||
|
||||
Show the user the created tag and any output from the release process.
|
||||
34
.claude/skills/test-action/SKILL.md
Normal file
34
.claude/skills/test-action/SKILL.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: test-action
|
||||
description: Run tests for a specific GitHub Action by name
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Test a Specific Action
|
||||
|
||||
## 1. Identify the action
|
||||
|
||||
Ask the user which action to test if not already specified.
|
||||
List available actions if needed:
|
||||
|
||||
```bash
|
||||
ls -d */action.yml | sed 's|/action.yml||'
|
||||
```
|
||||
|
||||
## 2. Run tests
|
||||
|
||||
```bash
|
||||
make test-action ACTION=<action-name>
|
||||
```
|
||||
|
||||
## 3. Display results
|
||||
|
||||
Show the test output. If tests fail, read the relevant test files in `_tests/unit/<action-name>/` and the action's `action.yml` to help diagnose the issue.
|
||||
|
||||
## 4. Coverage (optional)
|
||||
|
||||
If the user wants coverage information:
|
||||
|
||||
```bash
|
||||
make test-coverage
|
||||
```
|
||||
51
.claude/skills/validate/SKILL.md
Normal file
51
.claude/skills/validate/SKILL.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: validate
|
||||
description: Run full validation pipeline (docs, format, lint, precommit)
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Full Validation Pipeline
|
||||
|
||||
Run the complete validation pipeline:
|
||||
|
||||
```bash
|
||||
make all
|
||||
```
|
||||
|
||||
This runs in order: `install-tools` -> `update-validators` -> `docs` -> `update-catalog` -> `format` -> `lint` -> `precommit`
|
||||
|
||||
**Note:** `make test` must be run separately.
|
||||
|
||||
## If validation fails
|
||||
|
||||
### Formatting issues
|
||||
|
||||
```bash
|
||||
make format
|
||||
```
|
||||
|
||||
Then re-run `make all`.
|
||||
|
||||
### Linting issues
|
||||
|
||||
- **actionlint**: Check action.yml syntax, step IDs, expression usage
|
||||
- **shellcheck**: POSIX compliance, quoting, variable usage
|
||||
- **ruff**: Python style and errors
|
||||
- **markdownlint**: Markdown formatting
|
||||
- **prettier**: YAML/JSON/MD formatting
|
||||
|
||||
### Test failures
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
Read the failing test output and fix the underlying action or test.
|
||||
|
||||
### Documentation drift
|
||||
|
||||
```bash
|
||||
make docs
|
||||
```
|
||||
|
||||
Regenerates READMEs from action.yml files.
|
||||
@@ -31,7 +31,7 @@ runs:
|
||||
run: uv sync --frozen
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version: '24'
|
||||
cache: npm
|
||||
|
||||
8
.github/workflows/action-security.yml
vendored
8
.github/workflows/action-security.yml
vendored
@@ -17,10 +17,7 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
pull-requests: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
@@ -29,6 +26,9 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
pull-requests: read
|
||||
security-events: write
|
||||
statuses: write
|
||||
issues: write
|
||||
|
||||
11
.github/workflows/build-testing-image.yml
vendored
11
.github/workflows/build-testing-image.yml
vendored
@@ -23,15 +23,16 @@ on:
|
||||
default: 'latest'
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
name: Build and Push Testing Image
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -49,7 +50,7 @@ jobs:
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository_owner }}/actions
|
||||
tags: |
|
||||
@@ -59,7 +60,7 @@ jobs:
|
||||
type=raw,value=${{ github.event.inputs.tag }},enable=${{ github.event.inputs.tag != '' }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
|
||||
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
|
||||
with:
|
||||
context: _tools/docker-testing-tools
|
||||
file: _tools/docker-testing-tools/Dockerfile
|
||||
|
||||
7
.github/workflows/codeql-new.yml
vendored
7
.github/workflows/codeql-new.yml
vendored
@@ -13,17 +13,16 @@ on:
|
||||
- cron: '30 1 * * 0' # Run at 1:30 AM UTC every Sunday
|
||||
merge_group:
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
7
.github/workflows/dependency-review.yml
vendored
7
.github/workflows/dependency-review.yml
vendored
@@ -4,14 +4,15 @@ name: 'Dependency Review'
|
||||
on:
|
||||
- pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
dependency-review:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e # v6-beta
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@05fe4576374b728f0c523d6a13d64c25081e0803 # v4.8.3
|
||||
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
|
||||
|
||||
3
.github/workflows/issue-stats.yml
vendored
3
.github/workflows/issue-stats.yml
vendored
@@ -5,8 +5,7 @@ on:
|
||||
schedule:
|
||||
- cron: '3 2 1 * *'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
2
.github/workflows/new-release.yml
vendored
2
.github/workflows/new-release.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
schedule:
|
||||
- cron: '0 21 * * *' # 00:00 at Europe/Helsinki
|
||||
|
||||
permissions: read-all
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
new-daily-release:
|
||||
|
||||
6
.github/workflows/pr-lint.yml
vendored
6
.github/workflows/pr-lint.yml
vendored
@@ -37,9 +37,7 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read # Required for private dependencies
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
megalinter:
|
||||
@@ -74,7 +72,7 @@ jobs:
|
||||
|
||||
- name: Upload SARIF Report
|
||||
if: always() && hashFiles('megalinter-reports/sarif/*.sarif')
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: megalinter-reports/sarif
|
||||
category: megalinter
|
||||
|
||||
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@@ -7,8 +7,7 @@ on:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
|
||||
11
.github/workflows/security-suite.yml
vendored
11
.github/workflows/security-suite.yml
vendored
@@ -18,11 +18,7 @@ on:
|
||||
- '**/*.yaml'
|
||||
- '.github/workflows/**'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
actions: read
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
||||
@@ -32,6 +28,11 @@ jobs:
|
||||
security-analysis:
|
||||
name: Security Analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
actions: read
|
||||
|
||||
steps:
|
||||
- name: Checkout PR
|
||||
|
||||
5
.github/workflows/stale.yml
vendored
5
.github/workflows/stale.yml
vendored
@@ -8,10 +8,7 @@ on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
statuses: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
3
.github/workflows/sync-labels.yml
vendored
3
.github/workflows/sync-labels.yml
vendored
@@ -22,7 +22,7 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: read-all
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
labels:
|
||||
@@ -31,6 +31,7 @@ jobs:
|
||||
timeout-minutes: 10
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
|
||||
2
.github/workflows/test-actions.yml
vendored
2
.github/workflows/test-actions.yml
vendored
@@ -73,7 +73,7 @@ jobs:
|
||||
if: always()
|
||||
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
if: always() && hashFiles('_tests/reports/test-results.sarif') != ''
|
||||
with:
|
||||
sarif_file: _tests/reports/test-results.sarif
|
||||
|
||||
9
.github/workflows/version-maintenance.yml
vendored
9
.github/workflows/version-maintenance.yml
vendored
@@ -12,15 +12,16 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
check-and-update:
|
||||
name: Check Version References
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
|
||||
@@ -14,7 +14,7 @@ repos:
|
||||
types: [markdown, python, yaml]
|
||||
files: ^(docs/.*|README\.md|CONTRIBUTING\.md|CHANGELOG\.md|.*\.py|.*\.ya?ml)$
|
||||
- repo: https://github.com/astral-sh/uv-pre-commit
|
||||
rev: 0.10.7
|
||||
rev: 0.10.8
|
||||
hooks:
|
||||
- id: uv-lock
|
||||
- id: uv-sync
|
||||
@@ -55,7 +55,7 @@ repos:
|
||||
- id: yamllint
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.15.4
|
||||
rev: v0.15.5
|
||||
hooks:
|
||||
# Run the linter with auto-fix
|
||||
- id: ruff-check
|
||||
@@ -84,7 +84,7 @@ repos:
|
||||
args: ['-shellcheck=']
|
||||
|
||||
- repo: https://github.com/bridgecrewio/checkov.git
|
||||
rev: '3.2.506'
|
||||
rev: '3.2.507'
|
||||
hooks:
|
||||
- id: checkov
|
||||
args:
|
||||
|
||||
10
CLAUDE.md
10
CLAUDE.md
@@ -25,12 +25,22 @@
|
||||
### Folders
|
||||
|
||||
- `.serena/` – Internal config (do not edit)
|
||||
- `.claude/hooks/` – Claude Code hook scripts (auto-format, lint, block rules.yml edits)
|
||||
- `.claude/skills/` – Claude Code skills (`/release`, `/test-action`, `/new-action`, `/validate`, `/check-pins`)
|
||||
- `.claude/agents/` – Claude Code subagents (action-validator, test-coverage-reviewer)
|
||||
- `.github/` – Workflows/templates
|
||||
- `_tests/` – ShellSpec tests
|
||||
- `_tools/` – Helper tools
|
||||
- `validate-inputs/` – Python validation system + tests
|
||||
- `*/rules.yml` – Auto-generated validation rules
|
||||
|
||||
### Claude Code Hooks
|
||||
|
||||
**Auto-formatting**: PostToolUse hooks auto-format files on Edit/Write (ruff for .py, shfmt for .sh, prettier for .yml/.yaml/.json/.md, actionlint for action.yml)
|
||||
**Blocked edits**: PreToolUse hook blocks direct edits to `rules.yml` (auto-generated, use `make update-validators`)
|
||||
**Hook schema**: `matcher` is a regex string matching tool names (e.g. `"Edit|Write"`), not an object. File filtering done in hook scripts via stdin JSON (`jq -r '.tool_input.file_path'`)
|
||||
**Reference**: `$CLAUDE_PROJECT_DIR` for project-relative paths in hook commands
|
||||
|
||||
### Memory System
|
||||
|
||||
**Location**: `.serena/memories/` (9 consolidated memories for context)
|
||||
|
||||
2
Makefile
2
Makefile
@@ -210,7 +210,7 @@ bump-major-version: ## Replace one major version with another (usage: make bump-
|
||||
@sh _tools/bump-major-version.sh "$(OLD)" "$(NEW)"
|
||||
@echo "$(GREEN)✅ Major version bumped$(RESET)"
|
||||
|
||||
check-version-refs: ## List all current SHA-pinned action references
|
||||
check-version-refs: ## Verify all action references are SHA-pinned
|
||||
@echo "$(BLUE)🔍 Checking action references...$(RESET)"
|
||||
@sh _tools/check-version-refs.sh
|
||||
|
||||
|
||||
@@ -23,19 +23,43 @@ for tool in find grep sed printf sort cut tr wc; do
|
||||
fi
|
||||
done
|
||||
|
||||
# --- Validation pass: detect non-SHA-pinned references ---
|
||||
violations_file=$(safe_mktemp)
|
||||
trap 'rm -f "$violations_file"' EXIT
|
||||
|
||||
find . -maxdepth 2 -name "action.yml" -path "*/action.yml" \
|
||||
! -path "./_*" ! -path "./.github/*" \
|
||||
-exec grep -nE '^\s+uses:\s+ivuorinen/actions/' {} /dev/null \; \
|
||||
>"$violations_file"
|
||||
|
||||
violations_found=false
|
||||
while IFS= read -r match; do
|
||||
if ! printf '%s\n' "$match" | grep -qE '@[0-9a-f]{40}'; then
|
||||
if [ "$violations_found" = false ]; then
|
||||
msg_error "Non-SHA-pinned action references found:"
|
||||
violations_found=true
|
||||
fi
|
||||
printf ' %s\n' "$match" >&2
|
||||
fi
|
||||
done <"$violations_file"
|
||||
|
||||
if [ "$violations_found" = true ]; then
|
||||
rm -f "$violations_file"
|
||||
exit 1
|
||||
fi
|
||||
rm -f "$violations_file"
|
||||
|
||||
printf '%b' "${BLUE}Current SHA-pinned action references:${NC}\n"
|
||||
printf '\n'
|
||||
|
||||
# Create temp files for processing
|
||||
temp_file=$(safe_mktemp)
|
||||
trap 'rm -f "$temp_file"' EXIT
|
||||
|
||||
temp_input=$(safe_mktemp)
|
||||
trap 'rm -f "$temp_file" "$temp_input"' EXIT
|
||||
|
||||
# Find all action references and collect SHA|action pairs
|
||||
# Use input redirection to avoid subshell issues with pipeline
|
||||
find . -maxdepth 2 -name "action.yml" -path "*/action.yml" ! -path "./_*" ! -path "./.github/*" -exec grep -h "uses: ivuorinen/actions/" {} \; > "$temp_input"
|
||||
find . -maxdepth 2 -name "action.yml" -path "*/action.yml" ! -path "./_*" ! -path "./.github/*" -exec grep -h "uses: ivuorinen/actions/" {} \; >"$temp_input"
|
||||
|
||||
while IFS= read -r line; do
|
||||
# Extract action name and SHA using sed
|
||||
@@ -43,9 +67,9 @@ while IFS= read -r line; do
|
||||
sha=$(echo "$line" | sed -n 's|.*@\([a-f0-9]\{40\}\).*|\1|p')
|
||||
|
||||
if [ -n "$action" ] && [ -n "$sha" ]; then
|
||||
printf '%s\n' "$sha|$action" >> "$temp_file"
|
||||
printf '%s\n' "$sha|$action" >>"$temp_file"
|
||||
fi
|
||||
done < "$temp_input"
|
||||
done <"$temp_input"
|
||||
|
||||
# Check if we found any references
|
||||
if [ ! -s "$temp_file" ]; then
|
||||
@@ -54,7 +78,7 @@ if [ ! -s "$temp_file" ]; then
|
||||
fi
|
||||
|
||||
# Sort by SHA and group
|
||||
sort "$temp_file" | uniq > "${temp_file}.sorted"
|
||||
sort "$temp_file" | uniq >"${temp_file}.sorted"
|
||||
mv "${temp_file}.sorted" "$temp_file"
|
||||
|
||||
# Count unique SHAs
|
||||
@@ -95,7 +119,7 @@ while IFS='|' read -r sha action; do
|
||||
# Add to current SHA group
|
||||
actions_list="$actions_list, $action"
|
||||
fi
|
||||
done < "$temp_file"
|
||||
done <"$temp_file"
|
||||
|
||||
# Print last SHA group
|
||||
if [ -n "$current_sha" ]; then
|
||||
|
||||
@@ -130,6 +130,6 @@ runs:
|
||||
|
||||
- name: Upload SARIF Report
|
||||
if: steps.check-files.outputs.files_found == 'true'
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: ansible-lint.sarif
|
||||
|
||||
@@ -181,7 +181,7 @@ runs:
|
||||
echo "Detected package manager: $package_manager"
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
@@ -212,7 +212,7 @@ runs:
|
||||
|
||||
- name: Setup Bun
|
||||
if: steps.detect-pm.outputs.package-manager == 'bun'
|
||||
uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2
|
||||
uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2.1.3
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
@@ -331,7 +331,7 @@ runs:
|
||||
|
||||
- name: Upload SARIF Report
|
||||
if: inputs.mode == 'check' && always()
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: biome-report.sarif
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ runs:
|
||||
echo "Using build mode: $build_mode"
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
languages: ${{ inputs.language }}
|
||||
queries: ${{ inputs.queries }}
|
||||
@@ -199,12 +199,12 @@ runs:
|
||||
threads: ${{ inputs.threads }}
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/autobuild@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
if: ${{ steps.set-build-mode.outputs.build-mode == 'autobuild' }}
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
id: analysis
|
||||
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/analyze@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
category: ${{ steps.set-category.outputs.category }}
|
||||
upload: ${{ inputs.upload-results }}
|
||||
|
||||
@@ -148,7 +148,7 @@ runs:
|
||||
echo "Final detected .NET version: $detected_version" >&2
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
|
||||
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
|
||||
with:
|
||||
dotnet-version: ${{ steps.detect-dotnet-version.outputs.detected-version }}
|
||||
cache: true
|
||||
|
||||
@@ -164,7 +164,7 @@ runs:
|
||||
echo "Final detected .NET version: $detected_version" >&2
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
|
||||
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
|
||||
with:
|
||||
dotnet-version: ${{ steps.detect-dotnet-version.outputs.detected-version }}
|
||||
cache: true
|
||||
@@ -206,6 +206,6 @@ runs:
|
||||
fi
|
||||
|
||||
- name: Upload SARIF Report
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: dotnet-format.sarif
|
||||
|
||||
@@ -162,7 +162,7 @@ runs:
|
||||
echo "Final detected .NET version: $detected_version" >&2
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0
|
||||
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
|
||||
with:
|
||||
dotnet-version: ${{ inputs.dotnet-version || steps.detect-dotnet-version.outputs.detected-version }}
|
||||
cache: true
|
||||
|
||||
@@ -536,7 +536,7 @@ runs:
|
||||
- name: Scan Image for Vulnerabilities
|
||||
id: scan
|
||||
if: inputs.scan-image == 'true' && inputs.dry-run != 'true'
|
||||
uses: aquasecurity/trivy-action@e368e328979b113139d6f9068e03accaed98a518 # 0.34.1
|
||||
uses: aquasecurity/trivy-action@97e0b3872f55f89b95b2f65b3dbab56962816478 # 0.34.2
|
||||
with:
|
||||
scan-type: 'image'
|
||||
image-ref: ${{ steps.image-name.outputs.name }}:${{ inputs.tag }}
|
||||
|
||||
@@ -280,7 +280,7 @@ runs:
|
||||
|
||||
- name: Build and Push Docker Image
|
||||
id: build
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
|
||||
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
|
||||
with:
|
||||
context: ${{ inputs.context }}
|
||||
file: ${{ inputs.dockerfile }}
|
||||
|
||||
@@ -288,7 +288,7 @@ runs:
|
||||
echo "Detected package manager: $package_manager"
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
@@ -319,7 +319,7 @@ runs:
|
||||
|
||||
- name: Setup Bun
|
||||
if: steps.detect-pm.outputs.package-manager == 'bun'
|
||||
uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2
|
||||
uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2.1.3
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
@@ -457,7 +457,7 @@ runs:
|
||||
|
||||
- name: Upload SARIF Report
|
||||
if: inputs.mode == 'check' && inputs.report-format == 'sarif' && always()
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: ${{ inputs.working-directory }}/eslint-results.sarif
|
||||
|
||||
|
||||
@@ -414,7 +414,7 @@ runs:
|
||||
|
||||
- name: Upload Lint Results
|
||||
if: always() && inputs.report-format == 'sarif'
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: ${{ inputs.working-directory }}/reports/golangci-lint.sarif
|
||||
category: golangci-lint
|
||||
|
||||
@@ -121,7 +121,7 @@ runs:
|
||||
echo "Detected package manager: $package_manager"
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
@@ -152,7 +152,7 @@ runs:
|
||||
|
||||
- name: Setup Bun
|
||||
if: steps.detect-pm.outputs.package-manager == 'bun'
|
||||
uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2
|
||||
uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2.1.3
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ runs:
|
||||
|
||||
- name: Setup Node.js
|
||||
if: steps.detect-node.outputs.found == 'true'
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
@@ -156,7 +156,7 @@ runs:
|
||||
|
||||
- name: Setup Bun
|
||||
if: steps.detect-node.outputs.found == 'true' && steps.detect-pm.outputs.package-manager == 'bun'
|
||||
uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2
|
||||
uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2.1.3
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ runs:
|
||||
echo "Detected package manager: $package_manager"
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
@@ -305,7 +305,7 @@ runs:
|
||||
|
||||
- name: Setup Bun
|
||||
if: steps.detect-pm.outputs.package-manager == 'bun'
|
||||
uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2
|
||||
uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2.1.3
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
|
||||
@@ -370,7 +370,7 @@ runs:
|
||||
|
||||
- name: Upload SARIF Report
|
||||
if: steps.check-files.outputs.result == 'found'
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: ${{ inputs.working-directory }}/reports/flake8.sarif
|
||||
category: 'python-lint'
|
||||
|
||||
@@ -99,7 +99,7 @@ runs:
|
||||
|
||||
- name: Run actionlint
|
||||
if: steps.check-configs.outputs.run_actionlint == 'true'
|
||||
uses: raven-actions/actionlint@e01d1ea33dd6a5ed517d95b4c0c357560ac6f518 # v2.1.1
|
||||
uses: raven-actions/actionlint@205b530c5d9fa8f44ae9ed59f341a0db994aa6f8 # v2.1.2
|
||||
with:
|
||||
cache: true
|
||||
fail-on-error: true
|
||||
@@ -161,14 +161,14 @@ runs:
|
||||
|
||||
- name: Upload Trivy results
|
||||
if: steps.verify-sarif.outputs.has_trivy == 'true'
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
category: 'trivy'
|
||||
|
||||
- name: Upload Gitleaks results
|
||||
if: steps.verify-sarif.outputs.has_gitleaks == 'true'
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: 'gitleaks-report.sarif'
|
||||
category: 'gitleaks'
|
||||
|
||||
@@ -256,7 +256,7 @@ runs:
|
||||
|
||||
- name: Upload SARIF Report
|
||||
if: steps.check-files.outputs.found == 'true' && inputs.format == 'sarif'
|
||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
with:
|
||||
sarif_file: ${{ env.VALIDATED_WORKING_DIR }}/reports/tflint.sarif
|
||||
category: terraform-lint
|
||||
|
||||
38
uv.lock
generated
38
uv.lock
generated
@@ -299,27 +299,27 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.15.4"
|
||||
version = "0.15.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
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" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/77/9b/840e0039e65fcf12758adf684d2289024d6140cde9268cc59887dc55189c/ruff-0.15.5.tar.gz", hash = "sha256:7c3601d3b6d76dce18c5c824fc8d06f4eef33d6df0c21ec7799510cde0f159a2", size = 4574214, upload-time = "2026-03-05T20:06:34.946Z" }
|
||||
wheels = [
|
||||
{ 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/20/5369c3ce21588c708bcbe517a8fbe1a8dfdb5dfd5137e14790b1da71612c/ruff-0.15.5-py3-none-linux_armv6l.whl", hash = "sha256:4ae44c42281f42e3b06b988e442d344a5b9b72450ff3c892e30d11b29a96a57c", size = 10478185, upload-time = "2026-03-05T20:06:29.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/ed/e81dd668547da281e5dce710cf0bc60193f8d3d43833e8241d006720e42b/ruff-0.15.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6edd3792d408ebcf61adabc01822da687579a1a023f297618ac27a5b51ef0080", size = 10859201, upload-time = "2026-03-05T20:06:32.632Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/8f/533075f00aaf19b07c5cd6aa6e5d89424b06b3b3f4583bfa9c640a079059/ruff-0.15.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:89f463f7c8205a9f8dea9d658d59eff49db05f88f89cc3047fb1a02d9f344010", size = 10184752, upload-time = "2026-03-05T20:06:40.312Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/0e/ba49e2c3fa0395b3152bad634c7432f7edfc509c133b8f4529053ff024fb/ruff-0.15.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba786a8295c6574c1116704cf0b9e6563de3432ac888d8f83685654fe528fd65", size = 10534857, upload-time = "2026-03-05T20:06:19.581Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/71/39234440f27a226475a0659561adb0d784b4d247dfe7f43ffc12dd02e288/ruff-0.15.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd4b801e57955fe9f02b31d20375ab3a5c4415f2e5105b79fb94cf2642c91440", size = 10309120, upload-time = "2026-03-05T20:06:00.435Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/87/4140aa86a93df032156982b726f4952aaec4a883bb98cb6ef73c347da253/ruff-0.15.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391f7c73388f3d8c11b794dbbc2959a5b5afe66642c142a6effa90b45f6f5204", size = 11047428, upload-time = "2026-03-05T20:05:51.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/f7/4953e7e3287676f78fbe85e3a0ca414c5ca81237b7575bdadc00229ac240/ruff-0.15.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dc18f30302e379fe1e998548b0f5e9f4dff907f52f73ad6da419ea9c19d66c8", size = 11914251, upload-time = "2026-03-05T20:06:22.887Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/46/0f7c865c10cf896ccf5a939c3e84e1cfaeed608ff5249584799a74d33835/ruff-0.15.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc6e7f90087e2d27f98dc34ed1b3ab7c8f0d273cc5431415454e22c0bd2a681", size = 11333801, upload-time = "2026-03-05T20:05:57.168Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/01/a10fe54b653061585e655f5286c2662ebddb68831ed3eaebfb0eb08c0a16/ruff-0.15.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1cb7169f53c1ddb06e71a9aebd7e98fc0fea936b39afb36d8e86d36ecc2636a", size = 11206821, upload-time = "2026-03-05T20:06:03.441Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/0d/2132ceaf20c5e8699aa83da2706ecb5c5dcdf78b453f77edca7fb70f8a93/ruff-0.15.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:9b037924500a31ee17389b5c8c4d88874cc6ea8e42f12e9c61a3d754ff72f1ca", size = 11133326, upload-time = "2026-03-05T20:06:25.655Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/cb/2e5259a7eb2a0f87c08c0fe5bf5825a1e4b90883a52685524596bfc93072/ruff-0.15.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65bb414e5b4eadd95a8c1e4804f6772bbe8995889f203a01f77ddf2d790929dd", size = 10510820, upload-time = "2026-03-05T20:06:37.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/20/b67ce78f9e6c59ffbdb5b4503d0090e749b5f2d31b599b554698a80d861c/ruff-0.15.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d20aa469ae3b57033519c559e9bc9cd9e782842e39be05b50e852c7c981fa01d", size = 10302395, upload-time = "2026-03-05T20:05:54.504Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/e5/719f1acccd31b720d477751558ed74e9c88134adcc377e5e886af89d3072/ruff-0.15.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:15388dd28c9161cdb8eda68993533acc870aa4e646a0a277aa166de9ad5a8752", size = 10754069, upload-time = "2026-03-05T20:06:06.422Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/9c/d1db14469e32d98f3ca27079dbd30b7b44dbb5317d06ab36718dee3baf03/ruff-0.15.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b30da330cbd03bed0c21420b6b953158f60c74c54c5f4c1dabbdf3a57bf355d2", size = 11304315, upload-time = "2026-03-05T20:06:10.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/3a/950367aee7c69027f4f422059227b290ed780366b6aecee5de5039d50fa8/ruff-0.15.5-py3-none-win32.whl", hash = "sha256:732e5ee1f98ba5b3679029989a06ca39a950cced52143a0ea82a2102cb592b74", size = 10551676, upload-time = "2026-03-05T20:06:13.705Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/00/bf077a505b4e649bdd3c47ff8ec967735ce2544c8e4a43aba42ee9bf935d/ruff-0.15.5-py3-none-win_amd64.whl", hash = "sha256:821d41c5fa9e19117616c35eaa3f4b75046ec76c65e7ae20a333e9a8696bc7fe", size = 11678972, upload-time = "2026-03-05T20:06:45.379Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/4e/cd76eca6db6115604b7626668e891c9dd03330384082e33662fb0f113614/ruff-0.15.5-py3-none-win_arm64.whl", hash = "sha256:b498d1c60d2fe5c10c45ec3f698901065772730b411f164ae270bb6bfcc4740b", size = 10965572, upload-time = "2026-03-05T20:06:16.984Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
38
validate-inputs/uv.lock
generated
38
validate-inputs/uv.lock
generated
@@ -631,27 +631,27 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.15.4"
|
||||
version = "0.15.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
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" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/77/9b/840e0039e65fcf12758adf684d2289024d6140cde9268cc59887dc55189c/ruff-0.15.5.tar.gz", hash = "sha256:7c3601d3b6d76dce18c5c824fc8d06f4eef33d6df0c21ec7799510cde0f159a2", size = 4574214, upload-time = "2026-03-05T20:06:34.946Z" }
|
||||
wheels = [
|
||||
{ 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/20/5369c3ce21588c708bcbe517a8fbe1a8dfdb5dfd5137e14790b1da71612c/ruff-0.15.5-py3-none-linux_armv6l.whl", hash = "sha256:4ae44c42281f42e3b06b988e442d344a5b9b72450ff3c892e30d11b29a96a57c", size = 10478185, upload-time = "2026-03-05T20:06:29.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/ed/e81dd668547da281e5dce710cf0bc60193f8d3d43833e8241d006720e42b/ruff-0.15.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6edd3792d408ebcf61adabc01822da687579a1a023f297618ac27a5b51ef0080", size = 10859201, upload-time = "2026-03-05T20:06:32.632Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/8f/533075f00aaf19b07c5cd6aa6e5d89424b06b3b3f4583bfa9c640a079059/ruff-0.15.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:89f463f7c8205a9f8dea9d658d59eff49db05f88f89cc3047fb1a02d9f344010", size = 10184752, upload-time = "2026-03-05T20:06:40.312Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/0e/ba49e2c3fa0395b3152bad634c7432f7edfc509c133b8f4529053ff024fb/ruff-0.15.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba786a8295c6574c1116704cf0b9e6563de3432ac888d8f83685654fe528fd65", size = 10534857, upload-time = "2026-03-05T20:06:19.581Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/71/39234440f27a226475a0659561adb0d784b4d247dfe7f43ffc12dd02e288/ruff-0.15.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd4b801e57955fe9f02b31d20375ab3a5c4415f2e5105b79fb94cf2642c91440", size = 10309120, upload-time = "2026-03-05T20:06:00.435Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/87/4140aa86a93df032156982b726f4952aaec4a883bb98cb6ef73c347da253/ruff-0.15.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391f7c73388f3d8c11b794dbbc2959a5b5afe66642c142a6effa90b45f6f5204", size = 11047428, upload-time = "2026-03-05T20:05:51.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/f7/4953e7e3287676f78fbe85e3a0ca414c5ca81237b7575bdadc00229ac240/ruff-0.15.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dc18f30302e379fe1e998548b0f5e9f4dff907f52f73ad6da419ea9c19d66c8", size = 11914251, upload-time = "2026-03-05T20:06:22.887Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/46/0f7c865c10cf896ccf5a939c3e84e1cfaeed608ff5249584799a74d33835/ruff-0.15.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc6e7f90087e2d27f98dc34ed1b3ab7c8f0d273cc5431415454e22c0bd2a681", size = 11333801, upload-time = "2026-03-05T20:05:57.168Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/01/a10fe54b653061585e655f5286c2662ebddb68831ed3eaebfb0eb08c0a16/ruff-0.15.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1cb7169f53c1ddb06e71a9aebd7e98fc0fea936b39afb36d8e86d36ecc2636a", size = 11206821, upload-time = "2026-03-05T20:06:03.441Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/0d/2132ceaf20c5e8699aa83da2706ecb5c5dcdf78b453f77edca7fb70f8a93/ruff-0.15.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:9b037924500a31ee17389b5c8c4d88874cc6ea8e42f12e9c61a3d754ff72f1ca", size = 11133326, upload-time = "2026-03-05T20:06:25.655Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/cb/2e5259a7eb2a0f87c08c0fe5bf5825a1e4b90883a52685524596bfc93072/ruff-0.15.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65bb414e5b4eadd95a8c1e4804f6772bbe8995889f203a01f77ddf2d790929dd", size = 10510820, upload-time = "2026-03-05T20:06:37.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/20/b67ce78f9e6c59ffbdb5b4503d0090e749b5f2d31b599b554698a80d861c/ruff-0.15.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d20aa469ae3b57033519c559e9bc9cd9e782842e39be05b50e852c7c981fa01d", size = 10302395, upload-time = "2026-03-05T20:05:54.504Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/e5/719f1acccd31b720d477751558ed74e9c88134adcc377e5e886af89d3072/ruff-0.15.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:15388dd28c9161cdb8eda68993533acc870aa4e646a0a277aa166de9ad5a8752", size = 10754069, upload-time = "2026-03-05T20:06:06.422Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/9c/d1db14469e32d98f3ca27079dbd30b7b44dbb5317d06ab36718dee3baf03/ruff-0.15.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b30da330cbd03bed0c21420b6b953158f60c74c54c5f4c1dabbdf3a57bf355d2", size = 11304315, upload-time = "2026-03-05T20:06:10.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/3a/950367aee7c69027f4f422059227b290ed780366b6aecee5de5039d50fa8/ruff-0.15.5-py3-none-win32.whl", hash = "sha256:732e5ee1f98ba5b3679029989a06ca39a950cced52143a0ea82a2102cb592b74", size = 10551676, upload-time = "2026-03-05T20:06:13.705Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/00/bf077a505b4e649bdd3c47ff8ec967735ce2544c8e4a43aba42ee9bf935d/ruff-0.15.5-py3-none-win_amd64.whl", hash = "sha256:821d41c5fa9e19117616c35eaa3f4b75046ec76c65e7ae20a333e9a8696bc7fe", size = 11678972, upload-time = "2026-03-05T20:06:45.379Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/4e/cd76eca6db6115604b7626668e891c9dd03330384082e33662fb0f113614/ruff-0.15.5-py3-none-win_arm64.whl", hash = "sha256:b498d1c60d2fe5c10c45ec3f698901065772730b411f164ae270bb6bfcc4740b", size = 10965572, upload-time = "2026-03-05T20:06:16.984Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in New Issue
Block a user