From 7a82f1f7e476a4dd16763f7fc514d89e7dc93a40 Mon Sep 17 00:00:00 2001 From: Kevin Stillhammer Date: Mon, 23 Dec 2024 11:07:46 +0100 Subject: [PATCH] Default to ruff-version from pyproject.toml (#30) Closes: #9 Changes the default behavior to: - Search for a pyproject.toml in the repo root - Search in project.dependencies and dependency-groups.dev for ruff - If none is found use latest Support for requirements.txt files can be added later --- .github/workflows/test.yml | 38 ++++++++++++++- README.md | 44 +++++++++++------ .../README.md | 0 .../pyproject.toml | 15 ++++++ .../__init__.py | 2 + .../hello_world.py | 1 + .../fixtures/python-project/pyproject.toml | 2 +- action.yml | 7 ++- dist/ruff-action/index.js | Bin 1416546 -> 1531108 bytes package-lock.json | 8 ++- package.json | 3 +- src/download/download-version.ts | 15 ++---- src/ruff-action.ts | 46 ++++++++++++++---- src/utils/inputs.ts | 1 + src/utils/pyproject.ts | 30 ++++++++++++ 15 files changed, 168 insertions(+), 44 deletions(-) create mode 100644 __tests__/fixtures/pyproject-dependency-dev-project/README.md create mode 100644 __tests__/fixtures/pyproject-dependency-dev-project/pyproject.toml create mode 100644 __tests__/fixtures/pyproject-dependency-dev-project/src/pyproject_dependency_dev_project/__init__.py create mode 100644 __tests__/fixtures/pyproject-dependency-dev-project/src/pyproject_dependency_dev_project/hello_world.py create mode 100644 src/utils/pyproject.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ef5926..dfa0f22 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,17 +28,18 @@ jobs: - name: Make sure no changes from linters are detected run: | git diff --exit-code - test-default-version: + test-latest-version: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest, macos-14, windows-latest] steps: - uses: actions/checkout@v4 - - name: Use default version + - name: Use latest version uses: ./ with: src: __tests__/fixtures/python-project + version: latest test-specific-version: runs-on: ubuntu-latest strategy: @@ -51,6 +52,39 @@ jobs: with: version: ${{ matrix.ruff-version }} src: __tests__/fixtures/python-project + test-default-version-from-pyproject: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use default version from pyproject.toml + id: ruff-action + uses: ./ + with: + src: __tests__/fixtures/python-project + - name: Correct version gets installed + run: | + if [ "$RUFF_VERSION" != "0.6.2" ]; then + exit 1 + fi + env: + RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }} + test-default-version-from-pyproject-dev-group: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use default version from pyproject.toml dev group + id: ruff-action + uses: ./ + with: + src: __tests__/fixtures/pyproject-dependency-dev-project + version-file: __tests__/fixtures/pyproject-dependency-dev-project/pyproject.toml + - name: Correct version gets installed + run: | + if [ "$RUFF_VERSION" != "0.8.3" ]; then + exit 1 + fi + env: + RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }} test-semver-range: runs-on: ubuntu-latest steps: diff --git a/README.md b/README.md index a12d31c..e50cf47 100644 --- a/README.md +++ b/README.md @@ -19,19 +19,21 @@ fix). - [Install the latest version (default)](#install-the-latest-version-default) - [Install a specific version](#install-a-specific-version) - [Install a version by supplying a semver range](#install-a-version-by-supplying-a-semver-range) + - [Install a version from a specified version file](#install-a-version-from-a-specified-version-file) - [Validate checksum](#validate-checksum) - [GitHub authentication token](#github-authentication-token) - [Outputs](#outputs) ## Usage -| Input | Description | Default | -|----------------|---------------------------------------------------------------------------------------------|--------------------| -| `version` | The version of Ruff to install. See [Install specific versions](#install-specific-versions) | `latest` | -| `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] | -| `checksum` | The sha256 checksum of the downloaded executable. | None | -| `github-token` | The GitHub token to use for authentication. | `GITHUB_TOKEN` | +| Input | Description | Default | +|----------------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------------| +| `version` | The version of Ruff to install. See [Install specific versions](#install-specific-versions) | `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 | +| `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] | +| `checksum` | The sha256 checksum of the downloaded executable. | None | +| `github-token` | The GitHub token to use for authentication. | `GITHUB_TOKEN` | ### Basic @@ -77,7 +79,11 @@ This action adds ruff to the PATH, so you can use it in subsequent steps. ### Install specific versions -#### Install the latest version (default) +By default this action looks for a pyproject.toml file in the root of the repository to determine +the ruff version to install. If no pyproject.toml file is found, or no ruff version is defined in +either `dependencies` or `dependency-groups.dev` the latest version is installed. + +#### Install the latest version ```yaml - name: Install the latest version of ruff @@ -86,13 +92,7 @@ This action adds ruff to the PATH, so you can use it in subsequent steps. version: "latest" ``` -> [!TIP] -> -> Using `latest` requires to download the ruff executable on every run, which incurs a cost -> (especially on self-hosted runners). As a best practice, consider pinning the version to a -> specific release. - -### Install a specific version +#### Install a specific version ```yaml - name: Install a specific version of ruff @@ -101,7 +101,7 @@ This action adds ruff to the PATH, so you can use it in subsequent steps. version: "0.4.4" ``` -### Install a version by supplying a semver range +#### Install a version by supplying a semver range You can specify a [semver range](https://github.com/npm/node-semver?tab=readme-ov-file#ranges) to install the latest version that satisfies the range. @@ -120,6 +120,18 @@ to install the latest version that satisfies the range. version: "0.4.x" ``` +#### Install a version from a specified version file + +You can specify a file to read the version from. +Currently `pyproject.toml` is supported. + +```yaml +- name: Install a version from a specified version file + uses: astral-sh/ruff-action@v2 + with: + version-file: "my-path/to/pyproject.toml" +``` + ### Validate checksum You can specify a checksum to validate the downloaded executable. Checksums up to the default version diff --git a/__tests__/fixtures/pyproject-dependency-dev-project/README.md b/__tests__/fixtures/pyproject-dependency-dev-project/README.md new file mode 100644 index 0000000..e69de29 diff --git a/__tests__/fixtures/pyproject-dependency-dev-project/pyproject.toml b/__tests__/fixtures/pyproject-dependency-dev-project/pyproject.toml new file mode 100644 index 0000000..b6ce798 --- /dev/null +++ b/__tests__/fixtures/pyproject-dependency-dev-project/pyproject.toml @@ -0,0 +1,15 @@ +[project] +name = "pyproject-dependency-dev-project" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" + +[dependency-groups] +dev = [ + "ruff==0.8.3" +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" diff --git a/__tests__/fixtures/pyproject-dependency-dev-project/src/pyproject_dependency_dev_project/__init__.py b/__tests__/fixtures/pyproject-dependency-dev-project/src/pyproject_dependency_dev_project/__init__.py new file mode 100644 index 0000000..feca748 --- /dev/null +++ b/__tests__/fixtures/pyproject-dependency-dev-project/src/pyproject_dependency_dev_project/__init__.py @@ -0,0 +1,2 @@ +def hello() -> str: + return "Hello from python-project!" diff --git a/__tests__/fixtures/pyproject-dependency-dev-project/src/pyproject_dependency_dev_project/hello_world.py b/__tests__/fixtures/pyproject-dependency-dev-project/src/pyproject_dependency_dev_project/hello_world.py new file mode 100644 index 0000000..f1a1813 --- /dev/null +++ b/__tests__/fixtures/pyproject-dependency-dev-project/src/pyproject_dependency_dev_project/hello_world.py @@ -0,0 +1 @@ +print("Hello world!") diff --git a/__tests__/fixtures/python-project/pyproject.toml b/__tests__/fixtures/python-project/pyproject.toml index 66377ba..f8999d3 100644 --- a/__tests__/fixtures/python-project/pyproject.toml +++ b/__tests__/fixtures/python-project/pyproject.toml @@ -5,7 +5,7 @@ description = "Add your description here" readme = "README.md" requires-python = ">=3.12" dependencies = [ - "ruff>=0.6.2", + "ruff==0.6.2", ] [build-system] diff --git a/action.yml b/action.yml index 91b0cbb..72ca55e 100644 --- a/action.yml +++ b/action.yml @@ -11,9 +11,12 @@ inputs: required: false default: ${{ github.workspace }} version: - description: "The version of Ruff to use, e.g., `0.6.0` Defaults to the latest version." + description: "The version of Ruff to use, e.g., `0.6.0` Defaults to the version in pyproject.toml or 'latest'." + required: false + default: "" + version-file: + description: "Path to a pyproject.toml or requirements.txt file to read the version from." required: false - default: "latest" checksum: description: "The checksum of the ruff version to install" required: false diff --git a/dist/ruff-action/index.js b/dist/ruff-action/index.js index 9f31d51b159f1d75fb4908f3b6056f8dc20e5caa..41a9d13b5bae133ee6f2a222b51f5ef5bd4af52f 100644 GIT binary patch delta 93278 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 p4GqZc*EB@Ax2e5ef9LC6y8$T9uRG^|?=QCfv delta 291 zcmaE|GxpK0u!a`K7N!>F7M3ln;oa?bt=NH>1Bf|+m3^uT diff --git a/package-lock.json b/package-lock.json index 73390f0..8abe58d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", - "@actions/tool-cache": "^2.0.1" + "@actions/tool-cache": "^2.0.1", + "toml": "^3.0.0" }, "devDependencies": { "@biomejs/biome": "1.9.4", @@ -453,6 +454,11 @@ "semver": "bin/semver.js" } }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + }, "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", diff --git a/package.json b/package.json index c485fb9..bee93b8 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", - "@actions/tool-cache": "^2.0.1" + "@actions/tool-cache": "^2.0.1", + "toml": "^3.0.0" }, "devDependencies": { "@biomejs/biome": "1.9.4", diff --git a/src/download/download-version.ts b/src/download/download-version.ts index bb3fd0d..4b9b7c6 100644 --- a/src/download/download-version.ts +++ b/src/download/download-version.ts @@ -29,13 +29,12 @@ export async function downloadVersion( checkSum: string | undefined, githubToken: string, ): Promise<{ version: string; cachedToolDir: string }> { - const resolvedVersion = await resolveVersion(version, githubToken); const artifact = `ruff-${arch}-${platform}`; let extension = ".tar.gz"; if (platform === "pc-windows-msvc") { extension = ".zip"; } - const downloadUrl = `https://github.com/${OWNER}/${REPO}/releases/download/${resolvedVersion}/${artifact}${extension}`; + const downloadUrl = `https://github.com/${OWNER}/${REPO}/releases/download/${version}/${artifact}${extension}`; core.info(`Downloading ruff from "${downloadUrl}" ...`); const downloadPath = await tc.downloadTool( @@ -43,13 +42,7 @@ export async function downloadVersion( undefined, githubToken, ); - await validateChecksum( - checkSum, - downloadPath, - arch, - platform, - resolvedVersion, - ); + await validateChecksum(checkSum, downloadPath, arch, platform, version); let ruffDir: string; if (platform === "pc-windows-msvc") { @@ -64,10 +57,10 @@ export async function downloadVersion( const cachedToolDir = await tc.cacheDir( ruffDir, TOOL_CACHE_NAME, - resolvedVersion, + version, arch, ); - return { version: resolvedVersion, cachedToolDir }; + return { version: version, cachedToolDir }; } export async function resolveVersion( diff --git a/src/ruff-action.ts b/src/ruff-action.ts index 38424f0..fb5e3e8 100644 --- a/src/ruff-action.ts +++ b/src/ruff-action.ts @@ -13,7 +13,16 @@ import { getPlatform, type Platform, } from "./utils/platforms"; -import { args, checkSum, githubToken, src, version } from "./utils/inputs"; +import { + args, + checkSum, + githubToken, + src, + version, + versionFile as versionFileInput, +} from "./utils/inputs"; +import { getRuffVersionFromPyproject } from "./utils/pyproject"; +import * as fs from "node:fs"; async function run(): Promise { const platform = getPlatform(); @@ -26,13 +35,7 @@ async function run(): Promise { if (arch === undefined) { throw new Error(`Unsupported architecture: ${process.arch}`); } - const setupResult = await setupRuff( - platform, - arch, - version, - checkSum, - githubToken, - ); + const setupResult = await setupRuff(platform, arch, checkSum, githubToken); addRuffToPath(setupResult.ruffDir); setOutputFormat(); @@ -55,11 +58,10 @@ async function run(): Promise { async function setupRuff( platform: Platform, arch: Architecture, - versionInput: string, checkSum: string | undefined, githubToken: string, ): Promise<{ ruffDir: string; version: string }> { - const resolvedVersion = await resolveVersion(versionInput, githubToken); + const resolvedVersion = await determineVersion(); const toolCacheResult = tryGetFromToolCache(arch, resolvedVersion); if (toolCacheResult.installedPath) { core.info(`Found ruffDir in tool-cache for ${toolCacheResult.version}`); @@ -83,6 +85,30 @@ async function setupRuff( }; } +async function determineVersion(): Promise { + if (versionFileInput !== "" && version !== "") { + throw Error("It is not allowed to specify both version and version-file"); + } + if (version !== "") { + return await resolveVersion(version, githubToken); + } + if (versionFileInput !== "") { + const versionFromPyproject = getRuffVersionFromPyproject(versionFileInput); + if (versionFromPyproject === undefined) { + core.warning( + "Could not parse version from supplied pyproject.toml. Using latest version.", + ); + return await resolveVersion("latest", githubToken); + } + } + const pyProjectPath = path.join(src, "pyproject.toml"); + if (!fs.existsSync(pyProjectPath)) { + return await resolveVersion("latest", githubToken); + } + const versionFromPyproject = getRuffVersionFromPyproject(pyProjectPath); + return await resolveVersion(versionFromPyproject || "latest", githubToken); +} + function addRuffToPath(cachedPath: string): void { core.addPath(cachedPath); core.info(`Added ${cachedPath} to the path`); diff --git a/src/utils/inputs.ts b/src/utils/inputs.ts index 26b9a29..6b59b93 100644 --- a/src/utils/inputs.ts +++ b/src/utils/inputs.ts @@ -5,3 +5,4 @@ export const checkSum = core.getInput("checksum"); export const githubToken = core.getInput("github-token"); export const args = core.getInput("args"); export const src = core.getInput("src"); +export const versionFile = core.getInput("version-file"); diff --git a/src/utils/pyproject.ts b/src/utils/pyproject.ts new file mode 100644 index 0000000..ad0c778 --- /dev/null +++ b/src/utils/pyproject.ts @@ -0,0 +1,30 @@ +import * as fs from "node:fs"; +import * as core from "@actions/core"; +import * as toml from "toml"; + +export function getRuffVersionFromPyproject( + filePath: string, +): string | undefined { + const pyprojectContent = fs.readFileSync(filePath, "utf-8"); + const pyproject = toml.parse(pyprojectContent); + + const dependencies: string[] = pyproject.project?.dependencies || []; + const devDependencies: string[] = pyproject["dependency-groups"]?.dev || []; + + const ruffVersionDefinition = + dependencies.find((dep: string) => dep.startsWith("ruff")) || + devDependencies.find((dep: string) => dep.startsWith("ruff")); + + if (ruffVersionDefinition) { + const ruffVersion = ruffVersionDefinition + .match(/^ruff([^A-Z0-9._-]+.*)$/)?.[1] + .trim(); + if (ruffVersion?.startsWith("==")) { + return ruffVersion.slice(2); + } + core.info(`Found ruff version in pyproject.toml: ${ruffVersion}`); + return ruffVersion; + } + + return undefined; +}