Compare commits

...
Author SHA1 Message Date
28ec38735d chore: update known checksums for 0.16.1 (#397)
chore: update known checksums for 0.16.1

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-07-31 09:11:18 +02:00
project516andGitHub 2957f9e73d docs: unify ruff-action versions in README (#396) 2026-07-24 18:20:31 +00:00
5b168050b9 chore: update known checksums for 0.16.0 (#395)
chore: update known checksums for 0.16.0

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-07-24 06:30:28 +00:00
3bb5cd7c3c chore: update known checksums for 0.15.22 (#393)
chore: update known checksums for 0.15.22

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-07-17 06:19:01 +00:00
8d2a42ddf5 chore: update known checksums for 0.15.21 (#391)
chore: update known checksums for 0.15.21

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-07-13 09:04:22 +02:00
Kevin StillhammerandGitHub 278981a28c Add option to skip Astral mirror downloads (#387)
## Summary
- add `download-from-astral-mirror` input defaulting to `true`
- skip mirror URL rewriting and download directly from GitHub Releases
when disabled
- document the input and add unit coverage

Fixes #384

Refs: pi-session 019f31bc-bd1c-7276-9b4e-9734fa0aa367

## Testing
- npm run build
- npm run check
- npm run test:unit
2026-07-05 10:17:44 +00:00
Kevin StillhammerandGitHub c35f46c92b chore: roll up Dependabot updates (#386)
## Summary
- roll up remaining open Dependabot npm updates for @octokit/core and
@octokit/plugin-rest-endpoint-methods
- roll up remaining GitHub Actions pin updates for CodeQL, zizmor,
release-drafter, setup-node, and create-pull-request
- regenerate bundled dist files

## Validation
- npm run all

Refs: pi-session 019f31b8-93d9-7f9b-b3e9-5aaac6bab959
2026-07-05 12:04:11 +02:00
somazandGitHub f3db229c84 feat: support uv.lock as version-file (#379)
Adds `uv.lock` as a supported `version-file` format, alongside the
existing
`pyproject.toml` and `requirements.txt`. A `uv.lock` pins the exact
resolved
ruff version, so reading it gives a reproducible install that matches
the
project's lockfile — the single source of truth — instead of the
lower-bound /
range typically declared in `pyproject.toml`.

The parser reads the `[[package]]` entry whose `name` is `ruff` and
returns its
`version`. If ruff is absent or the file cannot be parsed, the action
warns and
falls back to `latest` (same behaviour as the other formats).

Validation:
- `npm run all` — tsc typecheck clean, biome clean, dist rebuilt, jest
65/65 pass
- Added unit tests (`__tests__/version/file-parser.test.ts`) + a
`uv.lock` fixture
- Added an integration job (`test-default-version-from-uv-lock`) that
runs the
  action against the fixture and asserts ruff 0.9.5 is installed

closes #375
2026-07-05 11:56:05 +02:00
Kevin StillhammerandGitHub 270e80dfe7 Fix wildcard src input (#368)
Fixes: #355
2026-07-05 11:55:02 +02:00
Kevin StillhammerandGitHub 5fedeebdb3 Add Dependabot rollup skill (#385)
## Summary
- add the dependabot-pr-rollup skill copied from setup-uv
- adapt the workflow notes for ruff-action's npm and GitHub Actions
Dependabot updates

## Testing
- npm run all

Refs: pi-session 019f317d-08f2-7aac-a6d5-56a44288d94c
2026-07-05 11:49:16 +02:00
99fe79f472 chore: update known checksums for 0.15.20 (#383)
chore: update known checksums for 0.15.20

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-06-26 08:39:54 +02:00
32ad1b993e chore: update known checksums for 0.15.19 (#382)
chore: update known checksums for 0.15.19

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-06-24 07:16:05 +00:00
f78e087041 chore: update known checksums for 0.15.18 (#381)
chore: update known checksums for 0.15.18

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-06-19 05:45:18 +00:00
2f88679623 chore: update known checksums for 0.15.17 (#380)
chore: update known checksums for 0.15.17

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-06-12 05:57:40 +00:00
b79a7ac759 chore: update known checksums for 0.15.16 (#378)
chore: update known checksums for 0.15.16

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-06-05 06:27:01 +00:00
30c0929868 chore: update known checksums for 0.15.15 (#377)
chore: update known checksums for 0.15.15

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-05-29 09:11:56 +00:00
b4bf7655a0 chore: update known checksums for 0.15.14 (#376)
chore: update known checksums for 0.15.14

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-05-22 05:57:48 +00:00
Frederick WagnerandGitHub 7f78e88b21 Use v4.0.0 in README.md (#371)
This change should reduce confusion from `@4` not working.
2026-05-20 13:18:52 +02:00
8c228c72ff chore: update known checksums for 0.15.13 (#372)
chore: update known checksums for 0.15.13

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-05-15 06:36:00 +00:00
Zanie BlueandGitHub 248b6d6da3 Update the release process to match setup-uv (#364) 2026-04-27 10:31:05 -05:00
ecaa98070e chore: update known checksums for 0.15.12 (#365)
chore: update known checksums for 0.15.12

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-04-25 07:00:01 +00:00
a9cfed68e4 chore: update known checksums for 0.15.11 (#360)
chore: update known checksums for 0.15.11

Co-authored-by: eifinger <1481961+eifinger@users.noreply.github.com>
2026-04-17 07:31:01 +00:00
Kevin StillhammerandGitHub eb44a0e99b Draft commitish releases (#359) 2026-04-16 20:31:36 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2915b93f0d Bump zizmorcore/zizmor-action from 0.5.2 to 0.5.3 (#356)
Bumps
[zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action)
from 0.5.2 to 0.5.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/zizmorcore/zizmor-action/releases">zizmorcore/zizmor-action's
releases</a>.</em></p>
<blockquote>
<h2>v0.5.3</h2>
<ul>
<li><code>1.24.0</code> and <code>1.24.1</code> are now available via
the action</li>
<li><code>1.24.1</code> is now the default version of zizmor used by the
action</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/zizmorcore/zizmor-action/commit/b1d7e1fb5de872772f31590499237e7cce841e8e"><code>b1d7e1f</code></a>
Sync zizmor versions (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/102">#102</a>)</li>
<li><a
href="https://github.com/zizmorcore/zizmor-action/commit/a195b57475917ddcb70845e5ffe1c3a15dbbdedc"><code>a195b57</code></a>
Sync zizmor versions (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/100">#100</a>)</li>
<li><a
href="https://github.com/zizmorcore/zizmor-action/commit/629d5d01fe5939a6aeae25c1bd1acd2cfa28e9b2"><code>629d5d0</code></a>
chore(deps): bump github/codeql-action in the github-actions group (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/99">#99</a>)</li>
<li><a
href="https://github.com/zizmorcore/zizmor-action/commit/453d591467e8199b1d5c6883b6ec5c22a12aac72"><code>453d591</code></a>
chore(deps): bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/98">#98</a>)</li>
<li><a
href="https://github.com/zizmorcore/zizmor-action/commit/ea2c18b942410df0b22bed3b94c361c407518d45"><code>ea2c18b</code></a>
Bump pins (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/97">#97</a>)</li>
<li>See full diff in <a
href="https://github.com/zizmorcore/zizmor-action/compare/71321a20a9ded102f6e9ce5718a2fcec2c4f70d8...b1d7e1fb5de872772f31590499237e7cce841e8e">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=zizmorcore/zizmor-action&package-manager=github_actions&previous-version=0.5.2&new-version=0.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-14 07:51:55 +02:00
30 changed files with 5769 additions and 778 deletions
@@ -0,0 +1,53 @@
---
name: dependabot-pr-rollup
description: Find open Dependabot PRs for ruff-action, compare each PR head to its base branch, replay only the remaining npm and GitHub Actions changes in a fresh worktree and branch, run repository validation, and optionally commit, push, and open a PR. Use when you want to batch or manually replicate active Dependabot updates.
license: MIT
compatibility: Requires git, git worktree, gh CLI auth, npm, and a GitHub repo with an origin remote.
---
# Dependabot PR Rollup
## When to use
Use this skill when the user wants to:
- find all open Dependabot PRs in this repo
- reproduce their net effect in one local branch
- validate the result with the repo's standard checks
- optionally commit, push, and open a PR
## Workflow
1. Inspect the current checkout state, but do not reuse a dirty worktree.
2. List open Dependabot PRs with `gh pr list --state open --author app/dependabot`.
3. For each PR, collect the title, base branch, head branch, changed files, and relevant diffs.
4. Compare each PR head against `origin/<base>` instead of trusting the PR title. Dependabot PRs can already be partially merged, superseded by newer versions, or have no remaining net effect.
5. Create a new worktree and branch from `origin/<base>`.
6. Reproduce only the remaining dependency changes in the new worktree.
- Inspect `package.json` before editing npm dependencies.
- Run `npm ci --ignore-scripts` before applying npm updates so dependency commands run from a clean install.
- Use `npm install ... --ignore-scripts` for direct npm dependency changes so `package-lock.json` stays in sync.
- Preserve whether an npm package is a `dependency` or `devDependency`.
- When updating `@biomejs/biome`, also update the Biome schema URL version in `biome.json` to match the installed Biome version.
- For GitHub Actions updates, apply the net workflow-file changes from the Dependabot PR heads after confirming they still apply cleanly to the selected base.
7. Run `npm run all`.
8. If requested, commit the changed source, lockfile, workflow files, and generated artifacts, then push and open a PR.
## Repo-specific notes
- Use `gh` for GitHub operations.
- Keep the user's original checkout untouched by working in a separate worktree.
- This repo has Dependabot configured for both `npm` and `github-actions`.
- In this repo, `npm run all` is the safest validation command because it runs build, check, package, and unit tests.
- `npm run check` may rewrite files with Biome; include those intentional formatting changes.
- If dependency changes affect bundled output, include the regenerated `dist/` files from `npm run package`.
## Report back
Always report:
- open Dependabot PRs found
- which PRs required no net changes
- new branch name
- new worktree path
- files changed
- `npm run all` result
- if applicable, commit SHA and PR URL
+3 -3
View File
@@ -45,7 +45,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0
uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
with:
languages: ${{ matrix.language }}
source-root: src
@@ -57,7 +57,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0
uses: github/codeql-action/autobuild@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -71,4 +71,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0
uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
+3 -1
View File
@@ -17,6 +17,8 @@ jobs:
pull-requests: read
steps:
- name: 🚀 Run Release Drafter
uses: release-drafter/release-drafter@5de93583980a40bd78603b6dfdcda5b4df377b32 # v7.2.0
uses: release-drafter/release-drafter@c2e2804cc59f45f57076a99af580d0fedb697927 # v7.3.0
with:
commitish: ${{ github.sha }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+63 -8
View File
@@ -11,31 +11,86 @@ on:
permissions: {}
jobs:
release:
name: Release
validate-release:
name: Validate release
runs-on: ubuntu-latest
environment: release
permissions:
contents: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Validate version
- name: Validate version and draft release
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ inputs.version }}
TAG: v${{ inputs.version }}
run: |
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
echo "::error::Version must match MAJOR.MINOR.PATCH (e.g., 8.1.0)"
exit 1
fi
RELEASE_JSON=$(gh release view "$TAG" --json isDraft,targetCommitish 2>&1) || {
echo "::error::No release found for $TAG"
exit 1
}
IS_DRAFT=$(echo "$RELEASE_JSON" | jq -r '.isDraft')
TARGET=$(echo "$RELEASE_JSON" | jq -r '.targetCommitish')
if [[ "$IS_DRAFT" != "true" ]]; then
echo "::error::Release $TAG already exists and is not a draft"
exit 1
fi
if [[ "$TARGET" != "$GITHUB_SHA" ]]; then
echo "::error::Draft release target ($TARGET) does not match current commit ($GITHUB_SHA)"
exit 1
fi
release-gate:
# N.B. This name should not change, it is used for downstream checks.
name: release-gate
needs:
- validate-release
runs-on: ubuntu-latest
environment:
name: release-gate
steps:
- run: echo "Release approved"
create-deployment:
name: create-deployment
needs:
- validate-release
- release-gate
runs-on: ubuntu-latest
environment:
name: release
steps:
- run: echo "Release deployment created"
release:
name: Release
needs:
- validate-release
- release-gate
- create-deployment
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Publish release
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ inputs.version }}
TAG: v${{ inputs.version }}
run: |
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
echo "::error::Version must match MAJOR.MINOR.PATCH (e.g., 8.1.0)"
exit 1
fi
RELEASE_JSON=$(gh release view "$TAG" --json isDraft,targetCommitish 2>&1) || {
echo "::error::No release found for $TAG"
exit 1
+52 -2
View File
@@ -24,8 +24,8 @@ jobs:
- name: Actionlint
uses: eifinger/actionlint-action@1fc89649be682d16ec5cf65ea16e269eb88d3982 # v1.10.2
- name: Run zizmor
uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: .nvmrc
cache: npm
@@ -280,6 +280,25 @@ jobs:
fi
env:
RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
test-default-version-from-uv-lock:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Use default version from uv.lock
id: ruff-action
uses: ./
with:
src: __tests__/fixtures/python-project
version-file: __tests__/fixtures/uv.lock
- name: Correct version gets installed
run: |
if [ "$RUFF_VERSION" != "0.9.5" ]; then
exit 1
fi
env:
RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
test-semver-range:
runs-on: ubuntu-latest
steps:
@@ -395,6 +414,34 @@ jobs:
fi
env:
CHECK_SHOULD_FAIL_OUTCOME: ${{ steps.check-should-fail.outcome }}
test-glob-src:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, windows-latest ]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Use glob pattern in src
uses: ./
with:
src: __tests__/fixtures/glob-project/**/*.py
test-glob-single-star-src:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, windows-latest ]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Use single-star glob pattern in src
uses: ./
with:
src: __tests__/fixtures/glob-single-star-project/foo/bar/*.py
test-multiple-src:
runs-on: ${{ matrix.os }}
strategy:
@@ -473,12 +520,15 @@ jobs:
- test-default-version-from-pyproject-optional-dependencies
- test-default-version-from-requirements
- test-default-version-from-requirements-with-hash
- test-default-version-from-uv-lock
- test-semver-range
- test-pep440-version-specifier
- test-checksum
- test-with-explicit-token
- test-args
- test-failure
- test-glob-src
- test-glob-single-star-src
- test-multiple-src
- test-parent-directory-pyproject
- test-custom-manifest-file
+2 -2
View File
@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: .nvmrc
cache: npm
@@ -25,7 +25,7 @@ jobs:
src/download/checksum/known-checksums.ts ${{ secrets.GITHUB_TOKEN }}
- run: npm ci --ignore-scripts && npm run all
- name: Create Pull Request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
commit-message: "chore: update known checksums"
title:
+52 -22
View File
@@ -32,8 +32,9 @@ anything `ruff` can (ex, fix).
| `version` | The version of Ruff to install. See [Install specific versions](#install-specific-versions) | discovered from `pyproject.toml`, else `latest` |
| `version-file` | The file to read the version from. See [Install a version from a specified version file](#install-a-version-from-a-specified-version-file) | None |
| `manifest-file` | URL to a custom Ruff manifest in the `astral-sh/versions` format. | None |
| `download-from-astral-mirror` | Download Ruff from the Astral mirror instead of directly from GitHub Releases. | `true` |
| `args` | The arguments to pass to the `ruff` command. See [Configuring Ruff] | `check` |
| `src` | The directory or single files to run `ruff` on. | [github.workspace] |
| `src` | Source path(s) to run `ruff` on. Supports glob patterns. | [github.workspace] |
| `checksum` | The sha256 checksum of the downloaded artifact. | None |
| `github-token` | The GitHub token to use when downloading Ruff release artifacts from GitHub. | `GITHUB_TOKEN` |
@@ -43,33 +44,60 @@ By default, Ruff version metadata is resolved from the
### Basic
```yaml
- uses: astral-sh/ruff-action@v3
- uses: astral-sh/ruff-action@v4.1.0
```
### Specify a different source directory
```yaml
- uses: astral-sh/ruff-action@v3
- uses: astral-sh/ruff-action@v4.1.0
with:
src: "./src"
```
### Specify multiple files
Separate multiple `src` values with whitespace.
```yaml
- uses: astral-sh/ruff-action@v3
- uses: astral-sh/ruff-action@v4.1.0
with:
src: >-
path/to/file1.py
path/to/file2.py
```
### Use glob patterns
Glob patterns (`*`, `?`, `[...]`, and `**`) are expanded by the action using
[`@actions/glob`](https://github.com/actions/toolkit/tree/main/packages/glob),
so they work consistently across Linux, macOS, and Windows runners. This action
does not emulate Bash, PowerShell, or other shell-specific glob expansion.
Hidden files and directories are skipped by default; target them explicitly, for
example with `.venv/**/*.py`, to include them. If a pattern does not match any
files, the original pattern is passed to Ruff so Ruff can report the missing
path. Literal glob metacharacters in file or directory names must be escaped
using `@actions/glob` syntax.
```yaml
- uses: astral-sh/ruff-action@v4.1.0
with:
src: "src/**/*.py"
```
> [!NOTE]
> When using multiple patterns, only the first is used to search for
> `pyproject.toml` to determine the Ruff version. Use the `version` input
> for explicit control. Large glob expansions may hit command-line length limits,
> especially on Windows.
### Use to install ruff
This action adds ruff to the PATH, so you can use it in subsequent steps.
```yaml
- uses: astral-sh/ruff-action@v3
- uses: astral-sh/ruff-action@v4.1.0
- run: ruff check --fix
- run: ruff format
```
@@ -80,7 +108,7 @@ you can use the `args` input to overwrite the default value (`check`):
```yaml
- name: Install ruff without running check or format
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
args: "--version"
```
@@ -88,7 +116,7 @@ you can use the `args` input to overwrite the default value (`check`):
### Use `ruff format`
```yaml
- uses: astral-sh/ruff-action@v3
- uses: astral-sh/ruff-action@v4.1.0
with:
args: "format --check --diff"
```
@@ -107,7 +135,7 @@ or no Ruff version is defined in `project.dependencies`, `project.optional-depen
```yaml
- name: Install the latest version of ruff
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
version: "latest"
```
@@ -116,7 +144,7 @@ or no Ruff version is defined in `project.dependencies`, `project.optional-depen
```yaml
- name: Install a specific version of ruff
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
version: "0.4.4"
```
@@ -129,21 +157,21 @@ to install the latest version that satisfies the range.
```yaml
- name: Install a semver range of ruff
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
version: ">=0.4.0"
```
```yaml
- name: Pinning a minor version of ruff
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
version: "0.4.x"
```
```yaml
- name: Install a pep440-specifier-satisfying version of ruff
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
version: ">=0.11.10,<0.12.0"
```
@@ -151,14 +179,14 @@ to install the latest version that satisfies the range.
#### Install a version from a specified version file
You can specify a file to read the version from.
Currently `pyproject.toml` and `requirements.txt` are supported. If the file cannot be parsed
or does not contain a Ruff version, the action warns and falls back to `latest`.
Currently `pyproject.toml`, `requirements.txt` and `uv.lock` are supported. If the file cannot
be parsed or does not contain a Ruff version, the action warns and falls back to `latest`.
```yaml
- name: Install a version from a specified version file
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
version-file: "my-path/to/pyproject.toml-or-requirements.txt"
version-file: "my-path/to/pyproject.toml-requirements.txt-or-uv.lock"
```
Version resolution precedence is:
@@ -175,7 +203,7 @@ This affects both version resolution and artifact selection.
```yaml
- name: Install Ruff from a custom manifest
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
version: "latest"
manifest-file: "https://example.com/ruff.ndjson"
@@ -189,7 +217,7 @@ are automatically verified by this action. The sha256 hashes can be found on the
```yaml
- name: Install a specific version and validate the checksum
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
version: "0.7.4"
checksum: "0de731c669b9ece77e799ac3f4a160c30849752714d9775c94cc4cfaf326860c"
@@ -197,10 +225,12 @@ are automatically verified by this action. The sha256 hashes can be found on the
### GitHub authentication token
By default, this action resolves available uv versions from
[`astral-sh/versions`](https://github.com/astral-sh/versions) and downloads release artifacts from `https://releases.astral.sh`. If this fails this action falls back to downloading from the GitHub releases page of the ruff repository.
By default, this action resolves available Ruff versions from
[`astral-sh/versions`](https://github.com/astral-sh/versions) and downloads release artifacts from `https://releases.astral.sh`. If this fails this action falls back to downloading from the GitHub releases page of the Ruff repository.
You can provide a token via `github-token` to authenticate those downloads. By default, the
Set `download-from-astral-mirror` to `false` to skip the Astral mirror and download directly from GitHub Releases.
You can provide a token via `github-token` to authenticate GitHub Releases downloads. By default, the
`GITHUB_TOKEN` secret is used, which is automatically provided by GitHub Actions.
If the default
@@ -209,7 +239,7 @@ are not sufficient, you can provide a custom GitHub token with the necessary per
```yaml
- name: Install the latest version of ruff with a custom GitHub token
uses: astral-sh/ruff-action@v3
uses: astral-sh/ruff-action@v4.1.0
with:
github-token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
```
@@ -357,6 +357,32 @@ describe("download-version", () => {
expect(mockDownloadTool).toHaveBeenCalledTimes(1);
});
it("skips the Astral mirror when downloadFromAstralMirror is false", async () => {
mockGetArtifact.mockResolvedValue({
archiveFormat: "tar.gz",
checksum: "abc123",
downloadUrl:
"https://github.com/astral-sh/ruff/releases/download/0.15.8/ruff-x86_64-unknown-linux-gnu.tar.gz",
});
await downloadVersion(
"unknown-linux-gnu",
"x86_64",
"0.15.8",
undefined,
"token",
undefined,
false,
);
expect(mockDownloadTool).toHaveBeenCalledWith(
"https://github.com/astral-sh/ruff/releases/download/0.15.8/ruff-x86_64-unknown-linux-gnu.tar.gz",
undefined,
"token",
);
expect(mockDownloadTool).toHaveBeenCalledTimes(1);
});
it("uses manifest-file checksum metadata when checksum input is unset", async () => {
mockGetArtifact.mockResolvedValue({
archiveFormat: "tar.gz",
@@ -0,0 +1,13 @@
[project]
name = "pyython-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"ruff==0.6.2",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
@@ -0,0 +1 @@
print("hello")
@@ -0,0 +1 @@
print("deeper")
@@ -0,0 +1 @@
print("check me")
@@ -0,0 +1,2 @@
# This file should be ignored when using foo/bar/*.py glob
print("ignore me")
@@ -0,0 +1,13 @@
[project]
name = "glob-single-star-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"ruff==0.6.2",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
+20
View File
@@ -0,0 +1,20 @@
version = 1
revision = 1
requires-python = ">=3.11"
[[package]]
name = "example-project"
version = "0.1.0"
source = { editable = "." }
dependencies = [
{ name = "ruff" },
]
[package.metadata]
requires-dist = [{ name = "ruff", specifier = ">=0.9.0" }]
[[package]]
name = "ruff"
version = "0.9.5"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/source/r/ruff/ruff-0.9.5.tar.gz", hash = "sha256:11aecd7a633932875ab3cb05a484c99970b9d52606ce9ea912b690b02653d56c", size = 3634177 }
+374
View File
@@ -0,0 +1,374 @@
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import { afterEach, describe, expect, it, jest } from "@jest/globals";
jest.unstable_mockModule("@actions/core", () => ({
debug: jest.fn(),
info: jest.fn(),
}));
const {
expandSourceInput,
getSourceBasePath,
getVersionSourceDirectory,
splitInput,
} = await import("../../src/utils/source-input");
const { findPyprojectToml } = await import("../../src/utils/pyproject-finder");
let tempDir: string | undefined;
afterEach(async () => {
if (tempDir !== undefined) {
await fs.rm(tempDir, { force: true, recursive: true });
tempDir = undefined;
}
});
async function createTempProject(): Promise<string> {
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "ruff-action-source-"));
await fs.mkdir(path.join(tempDir, "src", "package", "nested"), {
recursive: true,
});
await fs.writeFile(path.join(tempDir, "src", "package", "__init__.py"), "");
await fs.writeFile(path.join(tempDir, "src", "package", "main.py"), "");
await fs.writeFile(
path.join(tempDir, "src", "package", "nested", "mod.py"),
"",
);
await fs.writeFile(path.join(tempDir, "src", "package", "notes.txt"), "");
await fs.mkdir(path.join(tempDir, "src", "pkg[legacy]"), {
recursive: true,
});
await fs.writeFile(path.join(tempDir, "src", "pkg[legacy]", "main.py"), "");
await fs.mkdir(path.join(tempDir, "src", "pkgl"), { recursive: true });
await fs.writeFile(path.join(tempDir, "src", "pkgl", "main.py"), "");
return tempDir;
}
describe("splitInput", () => {
it("splits whitespace-delimited inputs", () => {
expect(splitInput(" check --fix\n--diff ")).toEqual([
"check",
"--fix",
"--diff",
]);
});
it("returns an empty array for empty input", () => {
expect(splitInput(" \n\t ")).toEqual([]);
});
});
describe("expandSourceInput", () => {
it("leaves non-glob sources unchanged", async () => {
await expect(expandSourceInput("src file.py")).resolves.toEqual([
"src",
"file.py",
]);
});
it("expands recursive globs without relying on shell behavior", async () => {
const projectDir = await createTempProject();
const pattern = path.join(projectDir, "src", "**", "*.py");
await expect(expandSourceInput(pattern)).resolves.toEqual([
path.join(projectDir, "src", "package", "__init__.py"),
path.join(projectDir, "src", "package", "main.py"),
path.join(projectDir, "src", "package", "nested", "mod.py"),
path.join(projectDir, "src", "pkg[legacy]", "main.py"),
path.join(projectDir, "src", "pkgl", "main.py"),
]);
});
it("preserves relative source patterns as relative paths", async () => {
const projectDir = await createTempProject();
const originalCwd = process.cwd();
try {
process.chdir(projectDir);
await expect(expandSourceInput("src/**/*.py")).resolves.toEqual([
path.join("src", "package", "__init__.py"),
path.join("src", "package", "main.py"),
path.join("src", "package", "nested", "mod.py"),
path.join("src", "pkg[legacy]", "main.py"),
path.join("src", "pkgl", "main.py"),
]);
} finally {
process.chdir(originalCwd);
}
});
it("maps relative root glob matches to . instead of an empty argument", async () => {
const projectDir = await createTempProject();
const originalCwd = process.cwd();
try {
process.chdir(projectDir);
for (const pattern of ["**", "**/", "./**"]) {
const sources = await expandSourceInput(pattern);
expect(sources).toContain(".");
expect(sources).not.toContain("");
}
} finally {
process.chdir(originalCwd);
}
});
it("excludes hidden paths by default while allowing explicit hidden patterns", async () => {
const projectDir = await createTempProject();
const originalCwd = process.cwd();
await fs.mkdir(path.join(projectDir, ".venv"));
await fs.writeFile(path.join(projectDir, ".venv", "ignored.py"), "");
await fs.mkdir(path.join(projectDir, ".tox"));
await fs.writeFile(path.join(projectDir, ".tox", "ignored.py"), "");
try {
process.chdir(projectDir);
const defaultSources = await expandSourceInput("**/*.py");
expect(defaultSources).not.toContain(path.join(".venv", "ignored.py"));
expect(defaultSources).not.toContain(path.join(".tox", "ignored.py"));
await expect(expandSourceInput(".venv/**/*.py")).resolves.toEqual([
path.join(".venv", "ignored.py"),
]);
} finally {
process.chdir(originalCwd);
}
});
it("preserves unmatched globs for Ruff to report", async () => {
const projectDir = await createTempProject();
const pattern = path.join(projectDir, "src", "**", "missing-*.py");
await expect(expandSourceInput(pattern)).resolves.toEqual([pattern]);
});
it("expands multiple sources in input order", async () => {
const projectDir = await createTempProject();
const first = path.join(projectDir, "src", "package", "main.py");
const second = path.join(projectDir, "src", "package", "nested", "*.py");
await expect(expandSourceInput(`${first} ${second}`)).resolves.toEqual([
first,
path.join(projectDir, "src", "package", "nested", "mod.py"),
]);
});
it("uses @actions/glob syntax for paths that contain glob metacharacters", async () => {
const projectDir = await createTempProject();
await expect(
expandSourceInput(path.join(projectDir, "src", "pkg[legacy]")),
).resolves.toEqual([path.join(projectDir, "src", "pkgl")]);
await expect(
expandSourceInput(path.join(projectDir, "src", "pkg[legacy]", "*.py")),
).resolves.toEqual([path.join(projectDir, "src", "pkgl", "main.py")]);
});
it("supports @actions/glob escaping for literal glob metacharacters", async () => {
const projectDir = await createTempProject();
const pattern = path.join(projectDir, "src", "pkg[[]legacy]", "*.py");
await expect(expandSourceInput(pattern)).resolves.toEqual([
path.join(projectDir, "src", "pkg[legacy]", "main.py"),
]);
});
it("does not traverse symlinked directories", async () => {
const projectDir = await createTempProject();
const externalDir = path.join(projectDir, "external");
const symlinkPath = path.join(projectDir, "src", "linked");
await fs.mkdir(externalDir);
await fs.writeFile(path.join(externalDir, "external.py"), "");
await fs.symlink(externalDir, symlinkPath, "dir");
const sources = await expandSourceInput(
path.join(projectDir, "src", "**", "*.py"),
);
expect(sources).not.toContain(path.join(symlinkPath, "external.py"));
});
it("still expands missing paths that contain glob metacharacters", async () => {
const projectDir = await createTempProject();
const pattern = path.join(projectDir, "src", "pkg[l]");
await expect(expandSourceInput(pattern)).resolves.toEqual([
path.join(projectDir, "src", "pkgl"),
]);
});
});
describe("getVersionSourceDirectory", () => {
it("does not scan src globs when version input is explicit", async () => {
await expect(
getVersionSourceDirectory("../**/*.py", "0.1.0", undefined),
).resolves.toBe(".");
});
it("does not scan src globs when version-file input is explicit", async () => {
await expect(
getVersionSourceDirectory("../**/*.py", undefined, "pyproject.toml"),
).resolves.toBe(".");
});
it("uses source discovery when no version input is explicit", async () => {
await expect(
getVersionSourceDirectory("../**/*.py", undefined, undefined),
).rejects.toThrow("Invalid pattern '../**/*.py'");
});
});
describe("getSourceBasePath", () => {
it("returns the directory for a plain path", async () => {
await expect(getSourceBasePath("my-project")).resolves.toBe("my-project");
});
it("returns the directory for a dotted path", async () => {
await expect(getSourceBasePath("./src")).resolves.toBe("./src");
});
it("preserves filesystem root paths", async () => {
const root = path.parse(process.cwd()).root;
await expect(getSourceBasePath(root)).resolves.toBe(root);
});
it("strips glob pattern and returns parent directory", async () => {
await expect(getSourceBasePath("src/**/*.py")).resolves.toBe("src");
});
it("returns . for a top-level glob", async () => {
await expect(getSourceBasePath("*.py")).resolves.toBe(".");
});
it("returns . for empty string", async () => {
await expect(getSourceBasePath("")).resolves.toBe(".");
});
it("uses only the first whitespace-delimited token", async () => {
await expect(getSourceBasePath("sub1/*.py sub2/")).resolves.toBe("sub1");
});
it("handles trailing slash in prefix", async () => {
await expect(getSourceBasePath("sub/*.py")).resolves.toBe("sub");
});
it("uses the parent directory when a glob appears in a filename", async () => {
await expect(getSourceBasePath("src/file*.py")).resolves.toBe("src");
});
it("handles ? glob", async () => {
await expect(getSourceBasePath("file?.py")).resolves.toBe(".");
});
it("handles bracket glob", async () => {
await expect(getSourceBasePath("file[0-9].py")).resolves.toBe(".");
});
it("uses @actions/glob syntax for base paths with glob metacharacters", async () => {
const projectDir = await createTempProject();
const originalCwd = process.cwd();
try {
process.chdir(projectDir);
await expect(getSourceBasePath("src/pkg[legacy]")).resolves.toBe(
path.join("src", "pkgl"),
);
await expect(getSourceBasePath("src/pkg[legacy]/*.py")).resolves.toBe(
path.join("src", "pkgl", "main.py"),
);
} finally {
process.chdir(originalCwd);
}
});
it("supports @actions/glob escaping for version discovery from literal glob metacharacters", async () => {
const projectDir = await createTempProject();
const originalCwd = process.cwd();
const pyprojectPath = path.join(
projectDir,
"src",
"pkg[legacy]",
"pyproject.toml",
);
await fs.writeFile(
pyprojectPath,
"[project]\ndependencies = ['ruff==0.6.2']\n",
);
try {
process.chdir(projectDir);
const sourceBasePath = await getSourceBasePath(
"src/pkg[[]legacy]/main.py",
);
expect(findPyprojectToml(sourceBasePath, projectDir)).toBe(
await fs.realpath(pyprojectPath),
);
} finally {
process.chdir(originalCwd);
}
});
it("uses the first expanded glob match for version discovery", async () => {
const projectDir = await createTempProject();
const originalCwd = process.cwd();
const pyprojectPath = path.join(
projectDir,
"packages",
"foo",
"pyproject.toml",
);
await fs.mkdir(path.join(projectDir, "packages", "foo", "src"), {
recursive: true,
});
await fs.writeFile(
pyprojectPath,
"[project]\ndependencies = ['ruff==0.10.0']\n",
);
await fs.writeFile(
path.join(projectDir, "packages", "foo", "src", "module.py"),
"",
);
try {
process.chdir(projectDir);
const sourceBasePath = await getSourceBasePath("packages/*/src/**/*.py");
expect(sourceBasePath).toBe(
path.join("packages", "foo", "src", "module.py"),
);
const workspaceRoot = await fs.realpath(projectDir);
expect(findPyprojectToml(sourceBasePath, workspaceRoot)).toBe(
await fs.realpath(pyprojectPath),
);
} finally {
process.chdir(originalCwd);
}
});
it("uses the unmatched glob fallback when version-discovery glob has no matches", async () => {
const projectDir = await createTempProject();
const originalCwd = process.cwd();
await fs.mkdir(path.join(projectDir, "packages"));
try {
process.chdir(projectDir);
await expect(getSourceBasePath("packages/*/src/**/*.py")).resolves.toBe(
"packages",
);
} finally {
process.chdir(originalCwd);
}
});
it("does not treat brace expansion as glob syntax", async () => {
await expect(getSourceBasePath("src/{a,b}/*.py")).resolves.toBe(
"src/{a,b}",
);
});
});
+26 -3
View File
@@ -9,9 +9,11 @@ jest.unstable_mockModule("@actions/core", () => ({
warning,
}));
const { findRuffVersionInSpec, getRuffVersionFromFile } = await import(
"../../src/version/file-parser"
);
const {
findRuffVersionInSpec,
getRuffVersionFromFile,
getRuffVersionFromUvLockContent,
} = await import("../../src/version/file-parser");
describe("file-parser", () => {
beforeEach(() => {
@@ -124,5 +126,26 @@ describe("file-parser", () => {
);
expect(result).toBe("~0.8.2");
});
it("reads the version from uv.lock", () => {
const result = getRuffVersionFromFile("__tests__/fixtures/uv.lock");
expect(result).toBe("0.9.5");
});
});
describe("getRuffVersionFromUvLockContent", () => {
it("extracts the ruff version from uv.lock content", () => {
const result = getRuffVersionFromUvLockContent(
'[[package]]\nname = "other"\nversion = "1.0.0"\n\n[[package]]\nname = "ruff"\nversion = "0.9.5"\n',
);
expect(result).toBe("0.9.5");
});
it("returns undefined when ruff is not in uv.lock", () => {
const result = getRuffVersionFromUvLockContent(
'[[package]]\nname = "other"\nversion = "1.0.0"\n',
);
expect(result).toBeUndefined();
});
});
});
+6 -2
View File
@@ -7,7 +7,7 @@ inputs:
required: false
default: "check"
src:
description: "Source to run Ruff. Defaults to the current directory."
description: "Source path(s) or @actions/glob pattern(s) to run Ruff on. Defaults to the current workspace."
required: false
default: ${{ github.workspace }}
version:
@@ -15,7 +15,7 @@ inputs:
required: false
default: ""
version-file:
description: "Path to a pyproject.toml or requirements.txt file to read the version from. If parsing fails, the action warns and falls back to `latest`."
description: "Path to a pyproject.toml, requirements.txt or uv.lock file to read the version from. If parsing fails, the action warns and falls back to `latest`."
required: false
checksum:
description: "The checksum of the ruff version to install"
@@ -23,6 +23,10 @@ inputs:
manifest-file:
description: "URL to a custom manifest file in the astral-sh/versions format."
required: false
download-from-astral-mirror:
description: "Download Ruff from the Astral mirror instead of directly from GitHub Releases."
required: false
default: "true"
github-token:
description:
"Used for authenticated downloads of Ruff release artifacts from GitHub."
Generated Vendored
+3387 -499
View File
File diff suppressed because it is too large Load Diff
+744 -162
View File
File diff suppressed because it is too large Load Diff
+193 -52
View File
@@ -11,10 +11,11 @@
"dependencies": {
"@actions/core": "^3.0.0",
"@actions/exec": "^3.0.0",
"@actions/glob": "^0.7.0",
"@actions/tool-cache": "^4.0.0",
"@octokit/core": "^7.0.3",
"@octokit/core": "^7.0.6",
"@octokit/plugin-paginate-rest": "^13.1.1",
"@octokit/plugin-rest-endpoint-methods": "^16.0.0",
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
"@renovatebot/pep440": "^4.2.1",
"smol-toml": "^1.6.0",
"undici": "^6.24.1"
@@ -51,6 +52,52 @@
"@actions/io": "^3.0.2"
}
},
"node_modules/@actions/glob": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.7.0.tgz",
"integrity": "sha512-+7s3wM+cXapDLmLL1NVWHawqcJOZzXZy2df/VhNn8DnZtS/x83iTCKaUn9F0llur4h3CII0AilvKKH4CMPL8Gw==",
"license": "MIT",
"dependencies": {
"@actions/core": "^3.0.0",
"minimatch": "^10.2.5"
}
},
"node_modules/@actions/glob/node_modules/balanced-match": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
"license": "MIT",
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/@actions/glob/node_modules/brace-expansion": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
"integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/@actions/glob/node_modules/minimatch": {
"version": "10.2.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
"integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
"license": "BlueOak-1.0.0",
"dependencies": {
"brace-expansion": "^5.0.5"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@actions/http-client": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
@@ -2688,16 +2735,16 @@
}
},
"node_modules/@octokit/core": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.3.tgz",
"integrity": "sha512-oNXsh2ywth5aowwIa7RKtawnkdH6LgU1ztfP9AIUCQCvzysB+WeU8o2kyyosDPwBZutPpjZDKPQGIzzrfTWweQ==",
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz",
"integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==",
"license": "MIT",
"dependencies": {
"@octokit/auth-token": "^6.0.0",
"@octokit/graphql": "^9.0.1",
"@octokit/request": "^10.0.2",
"@octokit/request-error": "^7.0.0",
"@octokit/types": "^14.0.0",
"@octokit/graphql": "^9.0.3",
"@octokit/request": "^10.0.6",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"before-after-hook": "^4.0.0",
"universal-user-agent": "^7.0.0"
},
@@ -2705,33 +2752,78 @@
"node": ">= 20"
}
},
"node_modules/@octokit/endpoint": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.0.tgz",
"integrity": "sha512-hoYicJZaqISMAI3JfaDr1qMNi48OctWuOih1m80bkYow/ayPw6Jj52tqWJ6GEoFTk1gBqfanSoI1iY99Z5+ekQ==",
"node_modules/@octokit/core/node_modules/@octokit/openapi-types": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
"license": "MIT"
},
"node_modules/@octokit/core/node_modules/@octokit/types": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^14.0.0",
"@octokit/openapi-types": "^27.0.0"
}
},
"node_modules/@octokit/endpoint": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz",
"integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/graphql": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.1.tgz",
"integrity": "sha512-j1nQNU1ZxNFx2ZtKmL4sMrs4egy5h65OMDmSbVyuCzjOcwsHq6EaYjOTGXPQxgfiN8dJ4CriYHk6zF050WEULg==",
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
"license": "MIT"
},
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"license": "MIT",
"dependencies": {
"@octokit/request": "^10.0.2",
"@octokit/types": "^14.0.0",
"@octokit/openapi-types": "^27.0.0"
}
},
"node_modules/@octokit/graphql": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz",
"integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==",
"license": "MIT",
"dependencies": {
"@octokit/request": "^10.0.6",
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
"license": "MIT"
},
"node_modules/@octokit/graphql/node_modules/@octokit/types": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^27.0.0"
}
},
"node_modules/@octokit/openapi-types": {
"version": "25.1.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz",
@@ -2754,12 +2846,12 @@
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-16.0.0.tgz",
"integrity": "sha512-kJVUQk6/dx/gRNLWUnAWKFs1kVPn5O5CYZyssyEoNYaFedqZxsfYs7DwI3d67hGz4qOwaJ1dpm07hOAD1BXx6g==",
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz",
"integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^14.1.0"
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
@@ -2768,16 +2860,32 @@
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/request": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.3.tgz",
"integrity": "sha512-V6jhKokg35vk098iBqp2FBKunk3kMTXlmq+PtbV9Gl3TfskWlebSofU9uunVKhUN7xl+0+i5vt0TGTG8/p/7HA==",
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
"license": "MIT"
},
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^11.0.0",
"@octokit/request-error": "^7.0.0",
"@octokit/types": "^14.0.0",
"fast-content-type-parse": "^3.0.0",
"@octokit/openapi-types": "^27.0.0"
}
},
"node_modules/@octokit/request": {
"version": "10.0.11",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.11.tgz",
"integrity": "sha512-+s7HUxjfFqOMS9VlIwDffq0MikjSAK0gSpG73W+meAvVAvX4MBrHYTK5Bj3Uot55qFT4gzUtfzE4mGWY4Br8/Q==",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^11.0.3",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"content-type": "^2.0.0",
"json-with-bigint": "^3.5.3",
"universal-user-agent": "^7.0.2"
},
"engines": {
@@ -2785,17 +2893,47 @@
}
},
"node_modules/@octokit/request-error": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.0.0.tgz",
"integrity": "sha512-KRA7VTGdVyJlh0cP5Tf94hTiYVVqmt2f3I6mnimmaVz4UG3gQV/k4mDJlJv3X67iX6rmN7gSHCF8ssqeMnmhZg==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
"integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^14.0.0"
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
"license": "MIT"
},
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^27.0.0"
}
},
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
"license": "MIT"
},
"node_modules/@octokit/request/node_modules/@octokit/types": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^27.0.0"
}
},
"node_modules/@octokit/types": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz",
@@ -3772,6 +3910,19 @@
"dev": true,
"license": "MIT"
},
"node_modules/content-type": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
"integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -4028,22 +4179,6 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/fast-content-type-parse": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
"integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "MIT"
},
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -6814,6 +6949,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/json-with-bigint": {
"version": "3.5.8",
"resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.8.tgz",
"integrity": "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==",
"license": "MIT"
},
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+3 -2
View File
@@ -30,10 +30,11 @@
"dependencies": {
"@actions/core": "^3.0.0",
"@actions/exec": "^3.0.0",
"@actions/glob": "^0.7.0",
"@actions/tool-cache": "^4.0.0",
"@octokit/core": "^7.0.3",
"@octokit/core": "^7.0.6",
"@octokit/plugin-paginate-rest": "^13.1.1",
"@octokit/plugin-rest-endpoint-methods": "^16.0.0",
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
"@renovatebot/pep440": "^4.2.1",
"smol-toml": "^1.6.0",
"undici": "^6.24.1"
+476
View File
@@ -1,5 +1,481 @@
// AUTOGENERATED_DO_NOT_EDIT
export const KNOWN_CHECKSUMS: { [key: string]: string } = {
"aarch64-apple-darwin-0.16.1":
"a8df4e8e9f22e3b0ae0b9f165ddaafb7e34df692197a6c1a361e7426f90681d5",
"aarch64-pc-windows-msvc-0.16.1":
"9d591931196e46338183b2b0307f126f2071b0543ed90ad3e8d8187278ba954b",
"aarch64-unknown-linux-gnu-0.16.1":
"52b67c61ca7355a535dfab77f87a4a3ae3550191bead41c70aadded8b5dd33a4",
"aarch64-unknown-linux-musl-0.16.1":
"5929d9f37fc518a3825f33a76ad8092c0555ca045ca1dbf5e680038a402c840c",
"arm-unknown-linux-musleabihf-0.16.1":
"6159e52f130dde9332a21a73ce022fbf19331baf19c0b561834ef02821e2c39c",
"armv7-unknown-linux-gnueabihf-0.16.1":
"78d06e22c0eb1ee88d87f7f22868a5261c6301c6c1a6a6a685bcd2a0c94e66a0",
"armv7-unknown-linux-musleabihf-0.16.1":
"0b781ee2243716cab3e4523443fa0b73b90ee487ac6d61c7717bcacf39abf6e6",
"i686-pc-windows-msvc-0.16.1":
"dd912980ccb50c13ff727014125927e4720ec6f6e0402ee6f5aeb44ab8df078a",
"i686-unknown-linux-gnu-0.16.1":
"b78c5f4635d6037deea63e7c68152982e220f23e62eea09d81563fc082fd6ee1",
"i686-unknown-linux-musl-0.16.1":
"4ab0197bfb5b42ac01c8a5725317f8a73592f0e95a057ae50ba1602c5bb18bda",
"powerpc64le-unknown-linux-gnu-0.16.1":
"db72f14ff9a96b12064af6a5ae18cacfc19ce555e30b636fff3239d830b17829",
"riscv64gc-unknown-linux-gnu-0.16.1":
"2b2a71b3af2b0d7147e5dacb883a3a308d74437929162e897b30deb10a503b44",
"s390x-unknown-linux-gnu-0.16.1":
"dd9a0a1e6e88a38a1ef41f695c5dfd473e3c2e70721f44fd3cac50152c726875",
"x86_64-apple-darwin-0.16.1":
"00396fb9db4cb04e07ad277e6b10d845e6767f0a2aae67e1a57aa65fa01334f0",
"x86_64-pc-windows-msvc-0.16.1":
"f37898d133acba7df8cbd130abc3b58b98243d7f3ab751087193dde8887955c4",
"x86_64-unknown-linux-gnu-0.16.1":
"7e1cc9b3da4911bb2c98c076302fd8997d822fac74dd8f1e30371701e70a4c56",
"x86_64-unknown-linux-musl-0.16.1":
"23469683052cd2db1589f15032dd1751b2a3f212062e9fc901b0776d25fb36bc",
"aarch64-apple-darwin-0.16.0":
"ce6564491a2cc4b0659f45ee174dbef17e4dec24e03a9c03d313b5430bc21099",
"aarch64-pc-windows-msvc-0.16.0":
"5f7356bdd186a2af97e3dcd4422b481fd107ae0867cc04a2a8c150441ccd15b6",
"aarch64-unknown-linux-gnu-0.16.0":
"879d4f0ca1a7f21a4afc6ef9345118b8a75aa2bc4aae9e41e0474994d0ef0a4f",
"aarch64-unknown-linux-musl-0.16.0":
"7a6add3d38768dfa00c6d3853e9bd940b5526f3fbb76f02b1fe77ec0653f1e0e",
"arm-unknown-linux-musleabihf-0.16.0":
"a3edf70c0c265bee17b9173d332643ce5bab9ee575938555c0b2e035d3b6b6bc",
"armv7-unknown-linux-gnueabihf-0.16.0":
"6eb7ab8baf7ff9cb61e73c6c0615a637b15e8246652cd9c4d36182b5d912e641",
"armv7-unknown-linux-musleabihf-0.16.0":
"c74b5763fc29b788b06349f78752c929501106614571d52ea11434678e162744",
"i686-pc-windows-msvc-0.16.0":
"73bc7921afd23c28657a52f037760e2d12eb9aa285f56b94ce4034c100747b3a",
"i686-unknown-linux-gnu-0.16.0":
"2c22c34005beed261b7de1bd1c58e1aee5f72c66491a53bde9a456a288eb8cd8",
"i686-unknown-linux-musl-0.16.0":
"f2b38ddae2b54adf7b00237c190309f40368a64a69cb1e554a50643bb5b6703a",
"powerpc64le-unknown-linux-gnu-0.16.0":
"55eb2e715fd4b89661bd99163c8422a2829f1d790bb388fa431f7c410864b7e9",
"riscv64gc-unknown-linux-gnu-0.16.0":
"80eedc31c6f02c1ff9ea8828e7a99e7cae93bc67e8835d27c80590392d30089b",
"s390x-unknown-linux-gnu-0.16.0":
"520abb2a2baf1e639dd582b590895f055bbb7aaa0d9c574a25239ed83ffb6381",
"x86_64-apple-darwin-0.16.0":
"3d9ef6228c4eeb26d593c398b2dc5250e0f6d6425933db2993fcf30d49c78b69",
"x86_64-pc-windows-msvc-0.16.0":
"c5d1185c47261f86361d03b547da25be79120226a6f1721d623b2aba9d27668b",
"x86_64-unknown-linux-gnu-0.16.0":
"98001c995a134d95f9bc83106a7f94b552971b583f1c0ab75fb656a881e13865",
"x86_64-unknown-linux-musl-0.16.0":
"2138b7bc58ff877f5bba09aea4cc984ad5699433b6a3f811003527b8cff8e9ad",
"aarch64-apple-darwin-0.15.22":
"a2881af26fd1d19f4932c4ddf1e70b4e0efcf48513c5dae082564e03f0b467a3",
"aarch64-pc-windows-msvc-0.15.22":
"76a57fe257602c386499437071a16abb1ee51fff68c8b4c28b0bf8a0d9f7aa34",
"aarch64-unknown-linux-gnu-0.15.22":
"54ec426d839d7cea1096e9ea1c5486fd2f3df62ee6cfd71dc090b18f99bebd90",
"aarch64-unknown-linux-musl-0.15.22":
"88feb2dc2fafb92482185201f4d483134fbaab10370c79512d3dd372f1d3f28b",
"arm-unknown-linux-musleabihf-0.15.22":
"dfc790d7d1bb5c3ea2162ebfec45262e88c8f78903709ca54e15b1d21ac1c7b6",
"armv7-unknown-linux-gnueabihf-0.15.22":
"b31c1f0e3b2c24372a58d09a45889fd350a02f4b7cbf39ce239b0f3fa6635479",
"armv7-unknown-linux-musleabihf-0.15.22":
"c948d4cec399959773d6ac04fc92794d44dbf6a23d3a4e0411ef7d51afe7f494",
"i686-pc-windows-msvc-0.15.22":
"a30a9a9aa89f582d12b14a10235de48a08656539fe1c5949ab915130718073b6",
"i686-unknown-linux-gnu-0.15.22":
"e9af79223f3cdbd64dce693bd8ed1d52dec7408eb43c510f19e280b13679bf62",
"i686-unknown-linux-musl-0.15.22":
"fbfc808162931f6bc30c641eaf6f568880fa230f915f3e7bd89912e6b275be65",
"powerpc64le-unknown-linux-gnu-0.15.22":
"3760b7a4d2f5141ad4186c54545b77d93e7b05ecbcce8fd633b564ec215a8595",
"riscv64gc-unknown-linux-gnu-0.15.22":
"b411cea3bec3c2d6c01ceb6425a613cc91e3b1b6542d1661902d224c343dc550",
"s390x-unknown-linux-gnu-0.15.22":
"5493483cecb481eece55b2565d91395a24c51af62d43c380246fde1cb9d3b56a",
"x86_64-apple-darwin-0.15.22":
"687a9ceb88ab85dab061026d5017218225a481121b1a40862cc8f92b56f18090",
"x86_64-pc-windows-msvc-0.15.22":
"6e5419593984941405e9add902e89c6ea4af87d97919ac5ef82e1bc4e43bbd8d",
"x86_64-unknown-linux-gnu-0.15.22":
"d535a4be6504146e757eff67b992f11a293a7a108be22e2a5898b32c32565996",
"x86_64-unknown-linux-musl-0.15.22":
"853462df618fb9f156a9f04d9d899d9e5a9e1a43fbffaec72df4bb159348e71b",
"aarch64-apple-darwin-0.15.21":
"0452f9d5da6e8051d332cf21ae82a608d8e2cfeec5a71a46ffa9e50adbb2381d",
"aarch64-pc-windows-msvc-0.15.21":
"52f05487f1e9e5c4d20b06e3659104507f23ef184e5b194c600fba945226e196",
"aarch64-unknown-linux-gnu-0.15.21":
"9846136be7fe5b70351d5bde22fd21d4b3ab55b07c9793fdf190040b296ee9a3",
"aarch64-unknown-linux-musl-0.15.21":
"2ec7c0077431f96f74c3c72aea6505e902bc2ff47127653c8de1389ee30a3cb3",
"arm-unknown-linux-musleabihf-0.15.21":
"7c7f7a917119513f6c98a27fd2539a6fc0443aec70866c07b46763f2ba4bb802",
"armv7-unknown-linux-gnueabihf-0.15.21":
"e491d6b6fd77e6e878b55589b67db3ec5f2769908fb7db5e6c67ad468499da44",
"armv7-unknown-linux-musleabihf-0.15.21":
"63816c926e66942ae9d3774be5cb07f895805a64afed915045d330c07523f270",
"i686-pc-windows-msvc-0.15.21":
"a5bd8669602b50559cea879c391eca5a265a2759e77dec082cdab998660bf998",
"i686-unknown-linux-gnu-0.15.21":
"5e9f9df0736c021a68315a1d4c2fe23e8f7035d78223004491ca3a780a1bb1bc",
"i686-unknown-linux-musl-0.15.21":
"239062dd642ab4a3d3daea9d1f9a87296318b415cef3e6bc3c48c4a47127d8c8",
"powerpc64le-unknown-linux-gnu-0.15.21":
"d450f2dbfdfe31ef63f433c9c62273fb5692f0f44d545569f9c66c7ceb2b19d1",
"riscv64gc-unknown-linux-gnu-0.15.21":
"28067c07327533bdc9e94e1ff9e8446cd60f3bcd8c90dd6f302a0e5061870c05",
"s390x-unknown-linux-gnu-0.15.21":
"5cd4bcc992155993ebda0363db0261f40b0119f1c781ad2e9502ba404df67bb5",
"x86_64-apple-darwin-0.15.21":
"7e6ff3bd585b5b7c47634c957ac84fb5806d3c7ab4ef0e5ec1c53ce272f489da",
"x86_64-pc-windows-msvc-0.15.21":
"035c59abfd7bd1102e0b656f5771e6ae7a712a45ef54b5ab575541c7ff7d1eb0",
"x86_64-unknown-linux-gnu-0.15.21":
"7ddba1886f39ba918587f9ca37de9651008726834811c19ee83991705bd3e56b",
"x86_64-unknown-linux-musl-0.15.21":
"7e157ff9a2e13676118c587e6db0ec02d040e415b21014346d230e64789c0e78",
"aarch64-apple-darwin-0.15.20":
"cb41c48690c113dc08470e64103ce65ca15249c6ce3495d3ac792b329a83e8c1",
"aarch64-pc-windows-msvc-0.15.20":
"6472417dfa49885bab36b92286cf933497bade1a30c816e6aa92e3adc684131b",
"aarch64-unknown-linux-gnu-0.15.20":
"f915de3ab6d31a49f4c57b1f97129f359f9348c162ea03acfa07011ba79e1197",
"aarch64-unknown-linux-musl-0.15.20":
"2e06ebae862dce74eb7b084081621f2d4183e18e60cb074e7906f862869fa1b6",
"arm-unknown-linux-musleabihf-0.15.20":
"3fab24c45421c992c1a32da52473319969ad66069fa7b8ef96632e9f6edb48cc",
"armv7-unknown-linux-gnueabihf-0.15.20":
"032288e4fc032c0c6e7d790bdc3272beac8e35870fc3153b94804e906b73b489",
"armv7-unknown-linux-musleabihf-0.15.20":
"40a085563d348fb7ce3536ac5d422a3c8efd901218138397e02515f5498d993e",
"i686-pc-windows-msvc-0.15.20":
"9f575c9b1d7c7304535ff6e271e15adb71e89c57381fbc14be91c741e70cabe7",
"i686-unknown-linux-gnu-0.15.20":
"918f5e2f8d5cc8881388ae2f8b1faaebc6a6d93f325cc203e245782374ae74da",
"i686-unknown-linux-musl-0.15.20":
"c06588ab67ed9b89bf8e9a7e8cfde5ed39afb2cc0050b89e4f05e8705be39ccd",
"powerpc64le-unknown-linux-gnu-0.15.20":
"6005f0dbcf9526737e998b0e9643b45705a2a14196bcdf57522a1eb4c1e92606",
"riscv64gc-unknown-linux-gnu-0.15.20":
"f050ed3b244aed95998865608e6c5c07ddc871a8cba7b4bd167212ba35d7b3a2",
"s390x-unknown-linux-gnu-0.15.20":
"e10200d1436f39bba9b041d8f4ed86762ce799344f0af3cf625bd398713f4d5b",
"x86_64-apple-darwin-0.15.20":
"36b91219b3aae00464e2a4fa361766abd47d0402ac88fbe6da5de44285738386",
"x86_64-pc-windows-msvc-0.15.20":
"835fdea5b8d4e13d2cc49439006aa1fbe9b67a89371f03871fc7f70a0cf10516",
"x86_64-unknown-linux-gnu-0.15.20":
"df8e74862d4cd4fdac11faf3048789896ff9898a0cacb98497df20d0a1cc7bb4",
"x86_64-unknown-linux-musl-0.15.20":
"0715560b2402024b529a4ffd6ea7d3814a090eb255a6216259fb192823be3ad8",
"aarch64-apple-darwin-0.15.19":
"c7253342f2ffbe2a0eaadaacd3424c3a24331b0307e57cc54031bc7ccd35d83a",
"aarch64-pc-windows-msvc-0.15.19":
"66e3014fe7ae4424a0e7c48b524ab03e8e39a51012ba5acf656c3771fed24c0a",
"aarch64-unknown-linux-gnu-0.15.19":
"b00f8c17424c0abea8f87ca52880b864d10ae8e5c5d09ee61730a80ee3874a97",
"aarch64-unknown-linux-musl-0.15.19":
"d6945815c5b2b32d01483e1d59ac7d2e744df0a20272680b2290c3e5e4ce5020",
"arm-unknown-linux-musleabihf-0.15.19":
"a533fbfe66f4ee6318d4c49b315c83b2dae9e474e1a66cb89148a12574654bd1",
"armv7-unknown-linux-gnueabihf-0.15.19":
"3acea3a3808e724412d9abf898bd9228c6417bd9641168394a5db98c06669302",
"armv7-unknown-linux-musleabihf-0.15.19":
"1fd42881a29964d884d822b4b3aacf5661aba43c95ce6b333defdab468ba57c5",
"i686-pc-windows-msvc-0.15.19":
"6f89edb30cae3ba71176bdeb2a94d2ec6f2ddf3a647da61c45adf9b28efabd67",
"i686-unknown-linux-gnu-0.15.19":
"82b0a2793f9bc1205f6ac2ecf8b2cfdd4fab450b7b63688d030c1276d477b0df",
"i686-unknown-linux-musl-0.15.19":
"75876128126ceccd1374059b3aea2415c48aa735c8a0e3c16e2c48bff589f16b",
"powerpc64le-unknown-linux-gnu-0.15.19":
"ce4548a179737c1e633cadd879124d762ebe6a850b6f6619467db2f822f42df1",
"riscv64gc-unknown-linux-gnu-0.15.19":
"0032c5458e4515b1f3aea15cef4870d43a49bee55345994ee598e0e7ebed166d",
"s390x-unknown-linux-gnu-0.15.19":
"86a9df0baa93b3e000283d0e019f52b7e684ae9a27cd07f3a985d159b8f1772a",
"x86_64-apple-darwin-0.15.19":
"aaf50afd2a76be2674b8dd24b305e42a33a99269c2c43e334f6a940b29ca291c",
"x86_64-pc-windows-msvc-0.15.19":
"e996f09c5aa5b00675318f0cdb59628633a202219d9c929736c5dcaaad2a6c4d",
"x86_64-unknown-linux-gnu-0.15.19":
"0bfabff71f317e0e3b8c363043b888f045eff092073d5d9bd0ac7f8ede465711",
"x86_64-unknown-linux-musl-0.15.19":
"682158b99b14ce60b62e7b4585100a11ebd5716355efe4048760690eda21fb99",
"aarch64-apple-darwin-0.15.18":
"f0cc66c2df37f2a11c99a85b59b8fde21b37f61df062404a0afaed387b56dad0",
"aarch64-pc-windows-msvc-0.15.18":
"344835d508df8bd5fd30a2941a7cee95b9b4f0f6342886b5d52b89571614c0d2",
"aarch64-unknown-linux-gnu-0.15.18":
"c9636879455e940fc92edb95dd6e475d683da833987d1f0c147f39e521ae98a2",
"aarch64-unknown-linux-musl-0.15.18":
"941eb7a7b8bc11f195a08393bb45def1656003031cff89af3805ca89cfd066b4",
"arm-unknown-linux-musleabihf-0.15.18":
"e70e827e863e0c5efea70661c61fafc068ec630ecac529ac8921d6c83ba5bae2",
"armv7-unknown-linux-gnueabihf-0.15.18":
"7cbdcb38059ad6c4cad1ea61e7411eb550510c8688a045aa4aee7aff3c743dc3",
"armv7-unknown-linux-musleabihf-0.15.18":
"24e9f8ae7ca03639871299a9a55439593564ed6d6572dbc3649aa0d3bf35da19",
"i686-pc-windows-msvc-0.15.18":
"d33ccad071478e3faa106506a53c0a62780abbb6d8c3c1ed29a36d4ec6a13168",
"i686-unknown-linux-gnu-0.15.18":
"8ee90592d7b22bbb81c7ebbd08adcc7ba66154046e8539d793bfcb9b4e681dd1",
"i686-unknown-linux-musl-0.15.18":
"9854c1fd59e876d229075f81dee88fb29f88bdc1aed9bca5e899810dd640db33",
"powerpc64le-unknown-linux-gnu-0.15.18":
"6efa78ce85071f72f37f77fcdc51b39fd75efd795baaf1fe1d85a3d7cb1a2c1a",
"riscv64gc-unknown-linux-gnu-0.15.18":
"d9b15d6fcd2931b0d88c8e56fd49f67ce7d1d362ad4b2623678849da5638f423",
"s390x-unknown-linux-gnu-0.15.18":
"5699eba448816315ce7fb9489512f7823d5dc872d997641dbbc984c07a8a4799",
"x86_64-apple-darwin-0.15.18":
"229d2c192718fde76794185ab9339515b75a55cc1337e4ca9d60309e2c506900",
"x86_64-pc-windows-msvc-0.15.18":
"2c38db5fef5984c93db7bdc395c20c5c3470fafdd8deb72150db4d2da7870d07",
"x86_64-unknown-linux-gnu-0.15.18":
"1ffb1d5e04e60347be17c514cbb19303d6d8c75f629060ed481a150337dbf060",
"x86_64-unknown-linux-musl-0.15.18":
"9ca54aec52cfdbe1e708cc975e41e3e736a2c1ebe76668575efe09e0701465c8",
"aarch64-apple-darwin-0.15.17":
"81f372886fb7a0056949356c615fa689a091cf79b0b54ed914c810cdbc6d85e9",
"aarch64-pc-windows-msvc-0.15.17":
"827124e08fe4633e76a3186fb9e881485faf2057d8c12dd98924474d8b7d4493",
"aarch64-unknown-linux-gnu-0.15.17":
"71593a6ca85cfede1743b9163aa4531a273f0eed6ae6c99d26ffe2af51bb5a3d",
"aarch64-unknown-linux-musl-0.15.17":
"211d610dd81ef472d3b1404b28eaa19a62cb41ab9374584847307b97821a4ab8",
"arm-unknown-linux-musleabihf-0.15.17":
"0ad5f2c15c85f334e846396c261dc18c850ed8288c8ca58fbf736783fb38ff48",
"armv7-unknown-linux-gnueabihf-0.15.17":
"6a6abb8e81ee6e9fc1d389e39986698dcd2c97c98f983e6d0b1466791f9ebd64",
"armv7-unknown-linux-musleabihf-0.15.17":
"97e60f2f92df99b4a80a12fe97316e2f403336515e7719d61d9fae6cca9c84fa",
"i686-pc-windows-msvc-0.15.17":
"50b5ba7faa811d38993b3cde5d038480fa76c5af6b4183bfc28c9ad863c47a6b",
"i686-unknown-linux-gnu-0.15.17":
"105dbbb8d898cb7ffb5f5464af3126d4be7dd1a1e58d802d482bb7a3b9712393",
"i686-unknown-linux-musl-0.15.17":
"8803e601e51bb4e0fb6747272339394014d8447f231effb414e7937b9ea12888",
"powerpc64le-unknown-linux-gnu-0.15.17":
"202fc52df8cc69d8ffdadc9bc4f68af987f9991bf153d676db3e116aa7f82e89",
"riscv64gc-unknown-linux-gnu-0.15.17":
"cdd72afde5bbfc119fee54f215696db870aeb4893ae3c134c8dc83af3a69d9c0",
"s390x-unknown-linux-gnu-0.15.17":
"f73297ab1ed5b1bb733a04ad4bc87a30b0a8c16843d7b0981b8b9e1a3495ea3f",
"x86_64-apple-darwin-0.15.17":
"5522e517bd67ee8c2cb0d6a8298388d8edc8621a0bc5dc773f65e06c953693f6",
"x86_64-pc-windows-msvc-0.15.17":
"08b6cb2bd20f3d19e3cf6e768d8d8105c8337de1c52e90c7dc1deea483d68c86",
"x86_64-unknown-linux-gnu-0.15.17":
"7bca4641db4b0256d20f3a8c38057725e0982965639f5f9a0fb2f9aece4b7c4f",
"x86_64-unknown-linux-musl-0.15.17":
"cbf85fc152b7fc25cb27f0233b325e9c72cb26965152050164e7608b72515189",
"aarch64-apple-darwin-0.15.16":
"9deb6c4c38c9324bfd98ea4efb40946aae99a987e7f9d1308a1291f14f6b46e2",
"aarch64-pc-windows-msvc-0.15.16":
"d2654d546fa03618e4ce39a568e78a0ccda71319928832266009b286f57354f8",
"aarch64-unknown-linux-gnu-0.15.16":
"a39b83af7288da13c013a789af1a4f875562ba09fc8011a2825a4883cb3a97a9",
"aarch64-unknown-linux-musl-0.15.16":
"3b39fc2608e12c554d42f6950a5ea131db8d8a0736c8949b3581c361f9f011d4",
"arm-unknown-linux-musleabihf-0.15.16":
"30d04d1f068a443fe6a919a9f0a77a3e59deab515b6b60c07a678d94332d444b",
"armv7-unknown-linux-gnueabihf-0.15.16":
"1f32fb51a347b70faa7d248ed524954736a79d3fd00887f79ee8c22004c8cca5",
"armv7-unknown-linux-musleabihf-0.15.16":
"5d14928f26c14bb40c7ec0b9db1f7e05e6e6b21ffd499dafcd77d0575fa796d2",
"i686-pc-windows-msvc-0.15.16":
"a68887cad08f7cf47e3753b1c84add837a64d9070102f43ec29d2a9fc8ed144a",
"i686-unknown-linux-gnu-0.15.16":
"3afb75f98244d7aec2532b5140da8ec9f2f9422ae27d7ba42bd6f8b20d76547e",
"i686-unknown-linux-musl-0.15.16":
"6fa9f045b0893456476836333410af37e52c32ecd511046d177802aeed42b2aa",
"powerpc64le-unknown-linux-gnu-0.15.16":
"adeee21392ed843e1e30e64a1b238d844c00385ac983fbc231b786cfe5d3bee7",
"riscv64gc-unknown-linux-gnu-0.15.16":
"e8e04a9d0664bd78e5164be9376091dbeefc455cdb684814a949dd7ebf5daa88",
"s390x-unknown-linux-gnu-0.15.16":
"2bd5e6a045f19a593b269d362c07b4bcc68b57b73d2ada1eecf3618d0cde0237",
"x86_64-apple-darwin-0.15.16":
"a8a7a60182f66b5995bd16e1831cf013e89558edf52135a1b6646f155f491f98",
"x86_64-pc-windows-msvc-0.15.16":
"b6c843fa84afb37af9d665a418324782ae18ea3dd1de775abfd7cf17f9431f85",
"x86_64-unknown-linux-gnu-0.15.16":
"b949a853b208b0f818a150fb06490487db585a15becaeda28483dd662939030a",
"x86_64-unknown-linux-musl-0.15.16":
"f52d90f8a6b1b3ad7d74301c3c796652e851d8f05b6ba26d139f05f4838cf412",
"aarch64-apple-darwin-0.15.15":
"2f7063e09d3c2af019b56f4fc6548199851e9387f359d696111af312adfe7619",
"aarch64-pc-windows-msvc-0.15.15":
"801067abc7c499bda61ff7308a271f7b5258c1a9f90abb081d9ac099cee20720",
"aarch64-unknown-linux-gnu-0.15.15":
"d334ae13383977fdaf754e6ea3d85c7b3ccbd510c713463eca73d0cd7151fe12",
"aarch64-unknown-linux-musl-0.15.15":
"46ea2750c0f21dab01f853d55a521a5f388f8573dab698735effdc6a94c9b293",
"arm-unknown-linux-musleabihf-0.15.15":
"daaf7d2b228c6b60ec30a3fefe37552d1b2ad50fc47d416dfbe04e80c78e4017",
"armv7-unknown-linux-gnueabihf-0.15.15":
"752ed1eef8c0b3550c21e9682a4eb873dfe1e08e0c23ad59a1ff57212e2665b2",
"armv7-unknown-linux-musleabihf-0.15.15":
"dda544c4890d46ec5d0b4a553087036ba9c50df6f566c54b38f8612185cd49c9",
"i686-pc-windows-msvc-0.15.15":
"57abdd72d19a6dc81e1583b40fcc5c88584cbee4406e257c8002e4ab4f825429",
"i686-unknown-linux-gnu-0.15.15":
"0c9ea8fa37a517cd833c8cdc26646ae2321d0f1f5f4359b00c3ae14b39c09f5b",
"i686-unknown-linux-musl-0.15.15":
"37a77abef48e92d43755c268ae04cc395538f630a9f295de9d2afd401965551d",
"powerpc64le-unknown-linux-gnu-0.15.15":
"ea7ba10a14ec3ef32275359cb8200775b6875f949352df3438f0c8de5b4ab514",
"riscv64gc-unknown-linux-gnu-0.15.15":
"486c47b6441134b0f8e31cd4b5e12cc8d4501e5c19ea1d68523c60b7300d4344",
"s390x-unknown-linux-gnu-0.15.15":
"d1834ddb58e5e73c6aa4c080bc3e1da4f4789150bb2d1d74824ff1bb52d5ddf9",
"x86_64-apple-darwin-0.15.15":
"e43d7c03701c7a436e18da455baf29e4be3379fb70887c4dc65091dfa73c1747",
"x86_64-pc-windows-msvc-0.15.15":
"c336db29a9e9234310212bc0d0bec1f722ec44f8a62c77b3f96a300282c6ff6d",
"x86_64-unknown-linux-gnu-0.15.15":
"2c50f95a0f553731c87f8dc413465aa06059a0dc21dfe16786682db95ffeb9dc",
"x86_64-unknown-linux-musl-0.15.15":
"c09b24fdec07d8ea73f7cbb32c38eb4f36f52298ac445dccf763171c898d8fc0",
"aarch64-apple-darwin-0.15.14":
"953243859467ed3f4f2bc6c11e241cd42a11ed42605b33d971dc2b174772da7d",
"aarch64-pc-windows-msvc-0.15.14":
"2f7a3fc221ca307c441306eb8f66740bfa129835a921862d124474080311933e",
"aarch64-unknown-linux-gnu-0.15.14":
"9740a687b333e5e9b3764a9d09001268bd841c93140a0766ddceef53fd1ccd87",
"aarch64-unknown-linux-musl-0.15.14":
"1693dfc1f402a81b32ff4fee5f8b494857a1a857a2b8d63cad88d9d39c201297",
"arm-unknown-linux-musleabihf-0.15.14":
"3107f1e38cd07aad9567b1eba6fcce3d7f7af2c011dc665c9f733c650e92f1c7",
"armv7-unknown-linux-gnueabihf-0.15.14":
"f198a9b46f860d1eba5fdd869fe12611f1828a564bd55b00a70cd8ade791717b",
"armv7-unknown-linux-musleabihf-0.15.14":
"2cb7aa2aa1b3f0762e69a76d0e636f39d9a87f554c24a705c2b9c05b0bb824e0",
"i686-pc-windows-msvc-0.15.14":
"c746d60bccd1a38e78893f683bb8b3043e1c6cd4ebe7fc4d7c11ead639808634",
"i686-unknown-linux-gnu-0.15.14":
"34f99c35d9efbb4491f252ba565edc5051a879371829ee05b9f8b96432dff466",
"i686-unknown-linux-musl-0.15.14":
"bb8b59953ccfb08a60c07666e07c1b830c4907ac8d0036bdef416ee614dd5fc7",
"powerpc64le-unknown-linux-gnu-0.15.14":
"a25f2979686c99d47c1c4fb4a7676e015ac492682fdff7b05c078e253bd22c70",
"riscv64gc-unknown-linux-gnu-0.15.14":
"757f852cfd037bae48186bbb78bf683197a21599d3c0f063c2f7d3be6f3a5d80",
"s390x-unknown-linux-gnu-0.15.14":
"d8dcf7282d04eb44bb0717892605c46d9a26d35c641819cdef77b3a6b9b6213a",
"x86_64-apple-darwin-0.15.14":
"537f569780fc71f63238f1f43dc04285b24fddbc6eea7219a9a18f408bdd869d",
"x86_64-pc-windows-msvc-0.15.14":
"c589a77b0e112c374e9a5e0c42a7fb18d8725c5322ae261e343f66d1c87f0a5e",
"x86_64-unknown-linux-gnu-0.15.14":
"e9fe1bb63fb8950cf8596d069f5c61b5a962bdd6c75edbdd2c8320871c40d6dd",
"x86_64-unknown-linux-musl-0.15.14":
"e380c9cf14764b7134434c49d445d13c6e3db732cfd18d72c4bc2316a6dbb82e",
"aarch64-apple-darwin-0.15.13":
"66ab3abeeba319266612e675dfbe0ca9c63f1e5f6ca3c6174482b0b088b8f6ff",
"aarch64-pc-windows-msvc-0.15.13":
"b16d436afac64f8032831d2f7874fe5fa6b1b238bfae97924d2233904372deed",
"aarch64-unknown-linux-gnu-0.15.13":
"8b8ee2a0f7e9ace1a734b2993ab2bfd68112d8a9c151ffa3025dbccaed4da52f",
"aarch64-unknown-linux-musl-0.15.13":
"1084d8038eeb51f55c7b7c9779bb37e5f53b28b987767df61333e9d0da7b2701",
"arm-unknown-linux-musleabihf-0.15.13":
"2b5b01e5e4ea6b72d75f20b7eac05305b29057e983c42839d62a7a5b9059867a",
"armv7-unknown-linux-gnueabihf-0.15.13":
"e579f3068d8011dc8fb845e3939407facb2fb129a5bc31c7db216a5a0e9e15d6",
"armv7-unknown-linux-musleabihf-0.15.13":
"d470b0fa4ba9cf94675dd8769f44bcdd16970fa6d8f48c34eb576299638a0742",
"i686-pc-windows-msvc-0.15.13":
"418907ac98fed6d3a4011d9c3f4b6bc525d4572aa926368f7b37311bb163b15c",
"i686-unknown-linux-gnu-0.15.13":
"8f7dc9bf2f7e1cbb6cbcb009d3759614085a32658271aff97eec6f51fa456eab",
"i686-unknown-linux-musl-0.15.13":
"0ea01a5614197f7058af27fd067ae8a178f6d2e3ce3114bf22f74921289cd38a",
"powerpc64le-unknown-linux-gnu-0.15.13":
"bd07a50f51069f130c8a66472260a6acc88a81735f92c40b5c735119f4155cc2",
"riscv64gc-unknown-linux-gnu-0.15.13":
"e689a47ef17dd49c75d957b11f95b0bc102d8240817e209c0fea2907ea638a71",
"s390x-unknown-linux-gnu-0.15.13":
"879a0888431b78fce4bd934d794921723d549c558021b8f7b3fb952be05abf53",
"x86_64-apple-darwin-0.15.13":
"3ff692a61d5231ea6c94e6dafc575f87582a089d1281fac6b31cef2b4f2e4b6b",
"x86_64-pc-windows-msvc-0.15.13":
"59892c6773df805effe7928e69796447585b42af54310cb6f1552536b746c39a",
"x86_64-unknown-linux-gnu-0.15.13":
"fd09d74c60963714b9b0fbda226c669e85624e5a8488398b3e0d0b5ee7684dd1",
"x86_64-unknown-linux-musl-0.15.13":
"66ac0b0582c8d24badc210b8e933e9aa0ad6707414e236409c9b9ad638972fb9",
"aarch64-apple-darwin-0.15.12":
"bd59107e125f9c9f64a75be13b6ff21bf7cbc61c4b9529bbb75c8184e3dd6c3c",
"aarch64-pc-windows-msvc-0.15.12":
"310a94d0c708691905d7614385732a2cbdede0979b93b81c01d55ab9de7ae754",
"aarch64-unknown-linux-gnu-0.15.12":
"4dcd4cd8beb525d04294eeab67d84d199cce2c44b66858978ca729b694fe29ff",
"aarch64-unknown-linux-musl-0.15.12":
"8996fe01814d00480c81da2b8ce9e8274f63eb07992318f082f7071772699635",
"arm-unknown-linux-musleabihf-0.15.12":
"aca8dadd6bd0e7c2192bbe5cbb39efdd5bbca47460c0ef73e6102a8c858890c6",
"armv7-unknown-linux-gnueabihf-0.15.12":
"3b8278e41d29ecac9f9ae07d95f8dc6707c45a28322503ea48d8c0cae53056b4",
"armv7-unknown-linux-musleabihf-0.15.12":
"d60776dd376f82f8bbbf346e1fbb81ef844a6445068b0594e36102c1121f57e9",
"i686-pc-windows-msvc-0.15.12":
"a466127b868dc22095dc717856cc94f283a01ccffa3a9814d35b5d42661e73be",
"i686-unknown-linux-gnu-0.15.12":
"64c4c076d6cc45f65b058bf5e2c3dd3150f80964a5a47f76c4245cdaa40ff7bb",
"i686-unknown-linux-musl-0.15.12":
"44462b0989328e7f7bbf4396e6d18152909ffeb43f49991e5b2f9fb28738af6d",
"powerpc64le-unknown-linux-gnu-0.15.12":
"36d42837ce7526663c707572c91615f4b1457c5d22f6ec4f96ea8921f83cc38d",
"riscv64gc-unknown-linux-gnu-0.15.12":
"69e5f9d477ea238f7fd00c2ac39ea78a3d7c7369124f62620a8c8a6b195d4f3a",
"s390x-unknown-linux-gnu-0.15.12":
"a612eaae54928a170403de322ab659d82fc233a3d1bb0337c8c39b48e9e5b41f",
"x86_64-apple-darwin-0.15.12":
"f88b6ad8338ad7acf83497e4bc2f2b5d3cac46c3e71363b7263c1bb9027c9b37",
"x86_64-pc-windows-msvc-0.15.12":
"d378033392042377491ef2541457af47cc4652c4e984639c95413b0c4876b0f1",
"x86_64-unknown-linux-gnu-0.15.12":
"5e26a7811f7db364864ace00cced53003556a37b63f3c987e340b18207776f1c",
"x86_64-unknown-linux-musl-0.15.12":
"e0b074f722f87efe2e09de3a77820a012d1417ebabbd308cccdf6b98ba8d4bb3",
"aarch64-apple-darwin-0.15.11":
"89cd4370b5c5d7ab01f436bd5d878293c9858e4e964a3da3013c49549198dc8b",
"aarch64-pc-windows-msvc-0.15.11":
"35ee4e8f0e784100aa1f3325705f2a764319d673fbeb8ba74ce169d4da13a675",
"aarch64-unknown-linux-gnu-0.15.11":
"6c7004eb732951ecce2059b3d5ef93010f8410ececaf96c24dbac41155780eee",
"aarch64-unknown-linux-musl-0.15.11":
"4d196496a51d4bbefc4a2a65049364c920b470afd320befa20516e59d1c065e2",
"arm-unknown-linux-musleabihf-0.15.11":
"caf1d8a5fbeb85389f9aa354bb9e5444f8d16ce7c6e5483681ef83ec6f9f7aa5",
"armv7-unknown-linux-gnueabihf-0.15.11":
"c8733ca5191f6503853a1f908e005ce9f2984ed58623f7544c56c28ce5d737db",
"armv7-unknown-linux-musleabihf-0.15.11":
"758d7fa7f7258dce3074a17432d6425bd6eec3be0a0558bf46729bbcf011cae7",
"i686-pc-windows-msvc-0.15.11":
"4af40e2bd1c6044ab1e0cb94ed836773237a4d88697a72c0babb16aede6e352f",
"i686-unknown-linux-gnu-0.15.11":
"db2c037d01bef8a5bc790f10fb7bfe82d97d287b5cda88acdd3a8d0bfcf20069",
"i686-unknown-linux-musl-0.15.11":
"c0c8456deb03520b4c8cea4f7dcd6e1fbaaa810a751b031fa79db09c41eae800",
"powerpc64le-unknown-linux-gnu-0.15.11":
"d68248684191d453897040fe5aab170a5bea7298fdaf0796f6eafa17d820e3cf",
"riscv64gc-unknown-linux-gnu-0.15.11":
"33beb06489d7b4b8295c0a696ef2125afe6f31e8e9355ae61bff6aa46b118702",
"s390x-unknown-linux-gnu-0.15.11":
"8b20efbb2a004fa27be6fda2c821a82d55cfaae5a0878ad210a12d976e3f0b60",
"x86_64-apple-darwin-0.15.11":
"c6f2c36fc5f3d14ffc2db1e205aa69756de485771f39848afe848c16b8a1a648",
"x86_64-pc-windows-msvc-0.15.11":
"d1f76eac07c279aafc594d9ba4c6f658f7cb433002aeeadbe2959229fc368881",
"x86_64-unknown-linux-gnu-0.15.11":
"8018f4c746c98e3a4128295c5da294d8b04c2bb14e1868e2da6fd02faf93ebe4",
"x86_64-unknown-linux-musl-0.15.11":
"ea286f17b66054a3aac2672158b9ac194030d89043ff108357edd9b20123219a",
"aarch64-apple-darwin-0.15.10":
"77c1df502dcfaaec52c6ce203b504b8554c88ab66ac01313410fa68ad9aafd5b",
"aarch64-pc-windows-msvc-0.15.10":
+10 -1
View File
@@ -35,6 +35,7 @@ export async function downloadVersion(
checksum: string | undefined,
githubToken: string,
manifestUrl?: string,
downloadFromAstralMirror = true,
): Promise<{ version: string; cachedToolDir: string }> {
const artifact = await getArtifact(version, arch, platform, manifestUrl);
@@ -57,6 +58,7 @@ export async function downloadVersion(
arch,
version,
getDownloadToken(artifact.downloadUrl, githubToken),
downloadFromAstralMirror,
);
await validateChecksum(
resolvedChecksum,
@@ -83,6 +85,10 @@ export async function downloadVersion(
return { cachedToolDir, version };
}
/**
* Rewrite a GitHub Releases URL to the Astral mirror.
* Returns `undefined` if the URL does not match the expected GitHub prefix.
*/
export function rewriteToMirror(url: string): string | undefined {
if (!url.startsWith(GITHUB_RELEASES_PREFIX)) {
return undefined;
@@ -97,8 +103,11 @@ async function downloadArtifact(
arch: Architecture,
version: string,
githubToken: string | undefined,
downloadFromAstralMirror: boolean,
): Promise<string> {
const mirrorUrl = rewriteToMirror(downloadUrl);
const mirrorUrl = downloadFromAstralMirror
? rewriteToMirror(downloadUrl)
: undefined;
const resolvedDownloadUrl = mirrorUrl ?? downloadUrl;
try {
+24 -10
View File
@@ -9,6 +9,7 @@ import {
import {
args,
checkSum,
downloadFromAstralMirror,
githubToken,
manifestFile,
src,
@@ -21,6 +22,11 @@ import {
getPlatform,
type Platform,
} from "./utils/platforms";
import {
expandSourceInput,
getVersionSourceDirectory,
splitInput,
} from "./utils/source-input";
import { resolveRuffVersion } from "./version/resolve";
async function run(): Promise<void> {
@@ -34,7 +40,13 @@ async function run(): Promise<void> {
if (arch === undefined) {
throw new Error(`Unsupported architecture: ${process.arch}`);
}
const setupResult = await setupRuff(platform, arch, checkSum, githubToken);
const setupResult = await setupRuff(
platform,
arch,
checkSum,
githubToken,
downloadFromAstralMirror,
);
addRuffToPath(setupResult.ruffDir);
setOutputFormat();
@@ -42,11 +54,7 @@ async function run(): Promise<void> {
core.setOutput("ruff-version", setupResult.version);
core.info(`Successfully installed ruff version ${setupResult.version}`);
await runRuff(
path.join(setupResult.ruffDir, "ruff"),
args.split(" "),
src.split(" "),
);
await runRuff(path.join(setupResult.ruffDir, "ruff"), args, src);
process.exit(0);
} catch (err) {
@@ -59,6 +67,7 @@ async function setupRuff(
arch: Architecture,
checkSum: string | undefined,
githubToken: string,
downloadFromAstralMirror: boolean,
): Promise<{ ruffDir: string; version: string }> {
const resolvedVersion = await determineVersion();
const manifestUrl = manifestFile || undefined;
@@ -83,6 +92,7 @@ async function setupRuff(
checkSum,
githubToken,
manifestUrl,
downloadFromAstralMirror,
);
return {
@@ -94,7 +104,11 @@ async function setupRuff(
async function determineVersion(): Promise<string> {
return await resolveRuffVersion({
manifestFile: manifestFile || undefined,
sourceDirectory: src,
sourceDirectory: await getVersionSourceDirectory(
src,
version,
versionFileInput,
),
version,
versionFile: versionFileInput,
workspaceRoot: process.env.GITHUB_WORKSPACE || ".",
@@ -125,10 +139,10 @@ function getActionRoot(): string {
async function runRuff(
ruffExecutablePath: string,
args: string[],
src: string[],
args: string,
src: string,
): Promise<void> {
const execArgs = [...args, ...src];
const execArgs = [...splitInput(args), ...(await expandSourceInput(src))];
await exec.exec(ruffExecutablePath, execArgs);
}
+11
View File
@@ -7,3 +7,14 @@ export const args = core.getInput("args");
export const src = core.getInput("src");
export const versionFile = core.getInput("version-file");
export const manifestFile = core.getInput("manifest-file");
export const downloadFromAstralMirror = getBooleanInput(
"download-from-astral-mirror",
true,
);
function getBooleanInput(name: string, defaultValue: boolean): boolean {
if (core.getInput(name) === "") {
return defaultValue;
}
return core.getBooleanInput(name);
}
+20 -4
View File
@@ -3,19 +3,22 @@ import * as path from "node:path";
import * as core from "@actions/core";
/**
* Search for a pyproject.toml file starting from the given directory
* Search for a pyproject.toml file starting from the given source path
* and traversing upwards through parent directories until reaching
* the GitHub workspace root.
*
* @param startDir The directory to start the search from (e.g., the src input)
* If the source path points to a file, the search begins in that file's
* parent directory.
*
* @param startPath The source path to start the search from (file or directory)
* @param workspaceRoot The GitHub workspace directory (GITHUB_WORKSPACE)
* @returns The path to the found pyproject.toml, or undefined if not found
*/
export function findPyprojectToml(
startDir: string,
startPath: string,
workspaceRoot: string,
): string | undefined {
let currentDir = path.resolve(startDir);
let currentDir = resolveStartDirectory(startPath);
const resolvedWorkspaceRoot = path.resolve(workspaceRoot);
while (true) {
@@ -42,6 +45,19 @@ export function findPyprojectToml(
}
}
function resolveStartDirectory(startPath: string): string {
const resolvedStartPath = path.resolve(startPath);
if (!fs.existsSync(resolvedStartPath)) {
return resolvedStartPath;
}
const stats = fs.statSync(resolvedStartPath);
return stats.isDirectory()
? resolvedStartPath
: path.dirname(resolvedStartPath);
}
/**
* Check if a given path is within or equal to the workspace root.
*
+161
View File
@@ -0,0 +1,161 @@
import * as fs from "node:fs/promises";
import * as path from "node:path";
import * as glob from "@actions/glob";
const GLOB_PATTERN = /[*?[]/;
/**
* Split an action input into whitespace-delimited tokens.
*
* The action has historically documented both `args` and `src` as plain
* whitespace-delimited inputs. Keep that behavior instead of invoking a shell.
*/
export function splitInput(input: string): string[] {
return input.trim().split(/\s+/).filter(Boolean);
}
/**
* Expand glob patterns from the `src` input in a cross-platform way.
*
* Glob syntax is defined by @actions/glob. This action does not emulate shell
* expansion. Unmatched patterns are preserved so Ruff can report the missing
* path.
*/
export async function expandSourceInput(srcInput: string): Promise<string[]> {
const sources = splitInput(srcInput);
if (sources.length === 0) {
return [];
}
const expandedSources: string[] = [];
for (const source of sources) {
if (!hasGlobPattern(source)) {
expandedSources.push(source);
continue;
}
const matches = await globMatches(source);
expandedSources.push(...(matches.length > 0 ? matches : [source]));
}
return expandedSources;
}
/**
* Resolve the starting path for version discovery from the `src` input.
*
* Takes the first whitespace-delimited token. Literal paths are preserved. Glob
* patterns use their first sorted match when available, so pyproject.toml
* discovery starts from a path Ruff will actually check. Unmatched globs fall
* back to @actions/glob's search path.
*/
export async function getVersionSourceDirectory(
srcInput: string,
versionInput: string | undefined,
versionFileInput: string | undefined,
): Promise<string> {
if (hasInput(versionInput) || hasInput(versionFileInput)) {
return ".";
}
return await getSourceBasePath(srcInput);
}
export async function getSourceBasePath(srcInput: string): Promise<string> {
const firstSource = splitInput(srcInput)[0] ?? ".";
if (!hasGlobPattern(firstSource)) {
return stripTrailingSeparators(firstSource);
}
const globber = await createGlobber(firstSource);
const matches = (await globber.glob()).sort();
if (matches.length > 0) {
return (
(await preserveSourcePathStyle(firstSource, [matches[0] ?? "."]))[0] ??
"."
);
}
const searchPaths = globber.getSearchPaths().sort();
if (searchPaths.length > 0) {
return (
(
await preserveSourcePathStyle(firstSource, [searchPaths[0] ?? "."])
)[0] ?? "."
);
}
return ".";
}
function hasInput(input: string | undefined): boolean {
return input !== undefined && input.trim() !== "";
}
function hasGlobPattern(source: string): boolean {
return GLOB_PATTERN.test(source);
}
function stripTrailingSeparators(source: string): string {
const root = path.parse(source).root;
const strippedSource = source.replace(/[/\\]+$/, "");
if (root !== "" && strippedSource.length < root.length) {
return root;
}
return strippedSource || root || ".";
}
async function globMatches(pattern: string): Promise<string[]> {
const globber = await createGlobber(pattern);
const matches = await globber.glob();
return await preserveSourcePathStyle(pattern, matches.sort());
}
async function createGlobber(pattern: string): Promise<glob.Globber> {
return await glob.create(normalizeGlobPattern(pattern), {
excludeHiddenFiles: !explicitlyTargetsHiddenPath(pattern),
followSymbolicLinks: false,
implicitDescendants: false,
});
}
async function preserveSourcePathStyle(
pattern: string,
matches: string[],
): Promise<string[]> {
if (path.isAbsolute(pattern)) {
return matches;
}
const cwd = await fs.realpath(process.cwd());
return matches.map((match) => path.relative(cwd, match) || ".");
}
function explicitlyTargetsHiddenPath(pattern: string): boolean {
return splitSourcePath(pattern).some(isHiddenPathSegment);
}
function splitSourcePath(source: string): string[] {
const root = path.parse(source).root;
const relativePath = source.slice(root.length);
const separatorPattern = process.platform === "win32" ? /[/\\]+/ : /\/+/;
return relativePath.split(separatorPattern).filter(Boolean);
}
function isHiddenPathSegment(segment: string): boolean {
return segment.startsWith(".") && segment !== "." && segment !== "..";
}
function normalizeGlobPattern(pattern: string): string {
if (process.platform !== "win32") {
return pattern;
}
return pattern.replace(/\\/g, "/");
}
+24
View File
@@ -24,6 +24,10 @@ interface Pyproject {
};
}
interface UvLock {
package?: Array<{ name?: string; version?: string }>;
}
const VERSION_FILE_PARSERS: VersionFileParser[] = [
{
format: "pyproject.toml",
@@ -33,6 +37,14 @@ const VERSION_FILE_PARSERS: VersionFileParser[] = [
},
supports: (filePath) => filePath.endsWith("pyproject.toml"),
},
{
format: "uv.lock",
parse: (filePath) => {
const fileContent = fs.readFileSync(filePath, "utf-8");
return getRuffVersionFromUvLockContent(fileContent);
},
supports: (filePath) => filePath.endsWith("uv.lock"),
},
{
format: "requirements",
parse: (filePath) => {
@@ -132,6 +144,18 @@ export function parsePyprojectContent(pyprojectContent: string): Pyproject {
return toml.parse(pyprojectContent) as Pyproject;
}
export function getRuffVersionFromUvLockContent(
uvLockContent: string,
): string | undefined {
const uvLock = toml.parse(uvLockContent) as UvLock;
const ruffPackage = (uvLock.package || []).find((pkg) => pkg.name === "ruff");
if (ruffPackage?.version === undefined) {
return undefined;
}
core.info(`Found ruff version in uv.lock: ${ruffPackage.version}`);
return ruffPackage.version;
}
function getVersionFileParser(filePath: string): VersionFileParser | undefined {
return VERSION_FILE_PARSERS.find((parser) => parser.supports(filePath));
}
+1 -1
View File
@@ -4,7 +4,7 @@ export type VersionSource =
| "pyproject.toml"
| "default";
export type VersionFileFormat = "pyproject.toml" | "requirements";
export type VersionFileFormat = "pyproject.toml" | "requirements" | "uv.lock";
export interface ParsedVersionFile {
format: VersionFileFormat;