Compare commits

...
6 Commits
11 changed files with 153 additions and 74 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
- name: Compare the expected and actual dist/ directories
run: |
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. See status below:"
echo "::error::Detected uncommitted changes after build. Run 'npm run build' and commit the changes."
git diff --text -v
exit 1
fi
+35 -1
View File
@@ -26,7 +26,7 @@ jobs:
npm run all
- name: Make sure no changes from linters are detected
run: |
git diff --exit-code
git diff --exit-code || (echo "::error::Please run 'npm run all' to fix the issues" && exit 1)
test-latest-version:
runs-on: ${{ matrix.os }}
strategy:
@@ -51,6 +51,23 @@ jobs:
with:
version: ${{ matrix.ruff-version }}
src: __tests__/fixtures/python-project
test-version-from-version-file-pyproject:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use version from pyproject.toml
id: ruff-action
uses: ./
with:
src: __tests__/fixtures/python-project
version-file: __tests__/fixtures/pyproject.toml
- name: Correct version gets installed
run: |
if [ "$RUFF_VERSION" != "0.9.3" ]; then
exit 1
fi
env:
RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
test-default-version-from-pyproject:
runs-on: ubuntu-latest
steps:
@@ -118,6 +135,23 @@ jobs:
fi
env:
RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
test-default-version-from-requirements:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use default version from requirements.txt
id: ruff-action
uses: ./
with:
src: __tests__/fixtures/python-project
version-file: __tests__/fixtures/requirements.txt
- name: Correct version gets installed
run: |
if [ "$RUFF_VERSION" != "0.9.0" ]; then
exit 1
fi
env:
RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
test-semver-range:
runs-on: ubuntu-latest
steps:
@@ -1,6 +1,8 @@
name: "Update known checksums"
on:
workflow_dispatch:
schedule:
- cron: "0 4 * * *" # Run every day at 4am UTC
jobs:
build:
+2 -2
View File
@@ -124,13 +124,13 @@ 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` is supported.
Currently `pyproject.toml` and `requirements.txt` are supported.
```yaml
- name: Install a version from a specified version file
uses: astral-sh/ruff-action@v3
with:
version-file: "my-path/to/pyproject.toml"
version-file: "my-path/to/pyproject.toml-or-requirements.txt"
```
### Validate checksum
+13
View File
@@ -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.9.3",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
+1
View File
@@ -0,0 +1 @@
ruff==0.9.0
Generated Vendored
+39 -26
View File
@@ -30387,6 +30387,7 @@ async function downloadVersion(platform, arch, version, checkSum, githubToken) {
return { version: version, cachedToolDir };
}
async function resolveVersion(versionInput, githubToken) {
core.debug(`Resolving ${versionInput}...`);
const version = versionInput === "latest"
? await getLatestVersion(githubToken)
: versionInput;
@@ -30399,6 +30400,7 @@ async function resolveVersion(versionInput, githubToken) {
if (resolvedVersion === "") {
throw new Error(`No version found for ${version}`);
}
core.debug(`Resolved version: ${resolvedVersion}`);
return resolvedVersion;
}
async function getAvailableVersions(githubToken) {
@@ -30552,17 +30554,21 @@ async function determineVersion() {
return await (0, download_version_1.resolveVersion)(inputs_1.version, inputs_1.githubToken);
}
if (inputs_1.versionFile !== "") {
const versionFromPyproject = (0, pyproject_1.getRuffVersionFromPyproject)(inputs_1.versionFile);
const versionFromPyproject = (0, pyproject_1.getRuffVersionFromRequirementsFile)(inputs_1.versionFile);
if (versionFromPyproject === undefined) {
core.warning("Could not parse version from supplied pyproject.toml. Using latest version.");
return await (0, download_version_1.resolveVersion)("latest", inputs_1.githubToken);
core.warning(`Could not parse version from ${inputs_1.versionFile}. Using latest version.`);
}
return await (0, download_version_1.resolveVersion)(versionFromPyproject || "latest", inputs_1.githubToken);
}
const pyProjectPath = path.join(inputs_1.src, "pyproject.toml");
if (!fs.existsSync(pyProjectPath)) {
core.info(`Could not find ${pyProjectPath}. Using latest version.`);
return await (0, download_version_1.resolveVersion)("latest", inputs_1.githubToken);
}
const versionFromPyproject = (0, pyproject_1.getRuffVersionFromPyproject)(pyProjectPath);
const versionFromPyproject = (0, pyproject_1.getRuffVersionFromRequirementsFile)(pyProjectPath);
if (versionFromPyproject === undefined) {
core.warning(`Could not parse version from ${pyProjectPath}. Using latest version.`);
}
return await (0, download_version_1.resolveVersion)(versionFromPyproject || "latest", inputs_1.githubToken);
}
function addRuffToPath(cachedPath) {
@@ -30725,31 +30731,11 @@ var __importStar = (this && this.__importStar) || (function () {
};
})();
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getRuffVersionFromPyproject = getRuffVersionFromPyproject;
exports.getRuffVersionFromRequirementsFile = getRuffVersionFromRequirementsFile;
const fs = __importStar(__nccwpck_require__(3024));
const core = __importStar(__nccwpck_require__(7484));
const toml = __importStar(__nccwpck_require__(7106));
function getRuffVersionFromPyproject(filePath) {
if (!fs.existsSync(filePath)) {
core.warning(`Could not find file: ${filePath}`);
return undefined;
}
const pyprojectContent = fs.readFileSync(filePath, "utf-8");
let pyproject;
try {
pyproject = toml.parse(pyprojectContent);
}
catch (err) {
const message = err.message;
core.warning(`Error while parsing ${filePath}: ${message}`);
return undefined;
}
const dependencies = pyproject?.project?.dependencies || [];
const optionalDependencies = Object.values(pyproject?.project?.["optional-dependencies"] || {}).flat();
const devDependencies = Object.values(pyproject?.["dependency-groups"] || {})
.flat()
.filter((item) => typeof item === "string");
const allDependencies = dependencies.concat(optionalDependencies, devDependencies);
function getRuffVersionFromAllDependencies(allDependencies) {
const ruffVersionDefinition = allDependencies.find((dep) => dep.startsWith("ruff"));
if (ruffVersionDefinition) {
const ruffVersion = ruffVersionDefinition
@@ -30763,6 +30749,33 @@ function getRuffVersionFromPyproject(filePath) {
}
return undefined;
}
function parsePyproject(pyprojectContent) {
const pyproject = toml.parse(pyprojectContent);
const dependencies = pyproject?.project?.dependencies || [];
const optionalDependencies = Object.values(pyproject?.project?.["optional-dependencies"] || {}).flat();
const devDependencies = Object.values(pyproject?.["dependency-groups"] || {})
.flat()
.filter((item) => typeof item === "string");
return getRuffVersionFromAllDependencies(dependencies.concat(optionalDependencies, devDependencies));
}
function getRuffVersionFromRequirementsFile(filePath) {
if (!fs.existsSync(filePath)) {
core.warning(`Could not find file: ${filePath}`);
return undefined;
}
const pyprojectContent = fs.readFileSync(filePath, "utf-8");
if (filePath.endsWith(".txt")) {
return getRuffVersionFromAllDependencies(pyprojectContent.split("\n"));
}
try {
return parsePyproject(pyprojectContent);
}
catch (err) {
const message = err.message;
core.warning(`Error while parsing ${filePath}: ${message}`);
return undefined;
}
}
/***/ }),
+1 -1
View File
@@ -12,7 +12,7 @@
"package": "ncc build -o dist/ruff-action src/ruff-action.ts && ncc build -o dist/update-known-checksums src/update-known-checksums.ts",
"act": "act pull_request -W .github/workflows/test.yml --container-architecture linux/amd64 -s GITHUB_TOKEN=\"$(gh auth token)\"",
"update-known-checksums": "RUNNER_TEMP=known_checksums node dist/update-known-checksums/index.js src/download/checksum/known-checksums.ts \"$(gh auth token)\"",
"all": "npm run build && npm run format && npm run lint && npm run package"
"all": "npm install && npm run build && npm run format && npm run lint && npm run package"
},
"repository": {
"type": "git",
+2
View File
@@ -71,6 +71,7 @@ export async function resolveVersion(
versionInput: string,
githubToken: string,
): Promise<string> {
core.debug(`Resolving ${versionInput}...`);
const version =
versionInput === "latest"
? await getLatestVersion(githubToken)
@@ -84,6 +85,7 @@ export async function resolveVersion(
if (resolvedVersion === "") {
throw new Error(`No version found for ${version}`);
}
core.debug(`Resolved version: ${resolvedVersion}`);
return resolvedVersion;
}
+13 -5
View File
@@ -21,7 +21,7 @@ import {
version,
versionFile as versionFileInput,
} from "./utils/inputs";
import { getRuffVersionFromPyproject } from "./utils/pyproject";
import { getRuffVersionFromRequirementsFile } from "./utils/pyproject";
import * as fs from "node:fs";
async function run(): Promise<void> {
@@ -93,19 +93,27 @@ async function determineVersion(): Promise<string> {
return await resolveVersion(version, githubToken);
}
if (versionFileInput !== "") {
const versionFromPyproject = getRuffVersionFromPyproject(versionFileInput);
const versionFromPyproject =
getRuffVersionFromRequirementsFile(versionFileInput);
if (versionFromPyproject === undefined) {
core.warning(
"Could not parse version from supplied pyproject.toml. Using latest version.",
`Could not parse version from ${versionFileInput}. Using latest version.`,
);
return await resolveVersion("latest", githubToken);
}
return await resolveVersion(versionFromPyproject || "latest", githubToken);
}
const pyProjectPath = path.join(src, "pyproject.toml");
if (!fs.existsSync(pyProjectPath)) {
core.info(`Could not find ${pyProjectPath}. Using latest version.`);
return await resolveVersion("latest", githubToken);
}
const versionFromPyproject = getRuffVersionFromPyproject(pyProjectPath);
const versionFromPyproject =
getRuffVersionFromRequirementsFile(pyProjectPath);
if (versionFromPyproject === undefined) {
core.warning(
`Could not parse version from ${pyProjectPath}. Using latest version.`,
);
}
return await resolveVersion(versionFromPyproject || "latest", githubToken);
}
+44 -38
View File
@@ -2,45 +2,9 @@ import * as fs from "node:fs";
import * as core from "@actions/core";
import * as toml from "smol-toml";
export function getRuffVersionFromPyproject(
filePath: string,
function getRuffVersionFromAllDependencies(
allDependencies: string[],
): string | undefined {
if (!fs.existsSync(filePath)) {
core.warning(`Could not find file: ${filePath}`);
return undefined;
}
const pyprojectContent = fs.readFileSync(filePath, "utf-8");
let pyproject:
| {
project?: {
dependencies?: string[];
"optional-dependencies"?: Map<string, string[]>;
};
"dependency-groups"?: Map<string, Array<string | object>>;
}
| undefined;
try {
pyproject = toml.parse(pyprojectContent);
} catch (err) {
const message = (err as Error).message;
core.warning(`Error while parsing ${filePath}: ${message}`);
return undefined;
}
const dependencies: string[] = pyproject?.project?.dependencies || [];
const optionalDependencies: string[] = Object.values(
pyproject?.project?.["optional-dependencies"] || {},
).flat();
const devDependencies: string[] = Object.values(
pyproject?.["dependency-groups"] || {},
)
.flat()
.filter((item: string | object) => typeof item === "string");
const allDependencies: string[] = dependencies.concat(
optionalDependencies,
devDependencies,
);
const ruffVersionDefinition = allDependencies.find((dep: string) =>
dep.startsWith("ruff"),
);
@@ -58,3 +22,45 @@ export function getRuffVersionFromPyproject(
return undefined;
}
function parsePyproject(pyprojectContent: string): string | undefined {
const pyproject: {
project?: {
dependencies?: string[];
"optional-dependencies"?: Map<string, string[]>;
};
"dependency-groups"?: Map<string, Array<string | object>>;
} = toml.parse(pyprojectContent);
const dependencies: string[] = pyproject?.project?.dependencies || [];
const optionalDependencies: string[] = Object.values(
pyproject?.project?.["optional-dependencies"] || {},
).flat();
const devDependencies: string[] = Object.values(
pyproject?.["dependency-groups"] || {},
)
.flat()
.filter((item: string | object) => typeof item === "string");
return getRuffVersionFromAllDependencies(
dependencies.concat(optionalDependencies, devDependencies),
);
}
export function getRuffVersionFromRequirementsFile(
filePath: string,
): string | undefined {
if (!fs.existsSync(filePath)) {
core.warning(`Could not find file: ${filePath}`);
return undefined;
}
const pyprojectContent = fs.readFileSync(filePath, "utf-8");
if (filePath.endsWith(".txt")) {
return getRuffVersionFromAllDependencies(pyprojectContent.split("\n"));
}
try {
return parsePyproject(pyprojectContent);
} catch (err) {
const message = (err as Error).message;
core.warning(`Error while parsing ${filePath}: ${message}`);
return undefined;
}
}