mirror of
https://github.com/astral-sh/setup-uv.git
synced 2026-01-13 06:52:16 +00:00
If a manifest-file is supplied the default value of the version input (latest) will get the latest version available in the manifest. That might not be the actual latest version available in the official uv repo.
225 lines
6.3 KiB
TypeScript
225 lines
6.3 KiB
TypeScript
import * as core from "@actions/core";
|
|
import * as path from "node:path";
|
|
import {
|
|
tryGetFromToolCache,
|
|
resolveVersion,
|
|
downloadVersionFromGithub,
|
|
downloadVersionFromManifest,
|
|
} from "./download/download-version";
|
|
import { restoreCache } from "./cache/restore-cache";
|
|
|
|
import {
|
|
type Architecture,
|
|
getArch,
|
|
getPlatform,
|
|
type Platform,
|
|
} from "./utils/platforms";
|
|
import {
|
|
activateEnvironment as activateEnvironmentInput,
|
|
cacheLocalPath,
|
|
checkSum,
|
|
ignoreEmptyWorkdir,
|
|
enableCache,
|
|
githubToken,
|
|
pythonVersion,
|
|
toolBinDir,
|
|
toolDir,
|
|
version as versionInput,
|
|
workingDirectory,
|
|
serverUrl,
|
|
manifestFile,
|
|
} from "./utils/inputs";
|
|
import * as exec from "@actions/exec";
|
|
import fs from "node:fs";
|
|
import { getUvVersionFromConfigFile } from "./utils/config-file";
|
|
|
|
async function run(): Promise<void> {
|
|
detectEmptyWorkdir();
|
|
const platform = await getPlatform();
|
|
const arch = getArch();
|
|
|
|
try {
|
|
if (platform === undefined) {
|
|
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
}
|
|
if (arch === undefined) {
|
|
throw new Error(`Unsupported architecture: ${process.arch}`);
|
|
}
|
|
const setupResult = await setupUv(platform, arch, checkSum, githubToken);
|
|
|
|
addToolBinToPath();
|
|
addUvToPathAndOutput(setupResult.uvDir);
|
|
setToolDir();
|
|
setupPython();
|
|
await activateEnvironment();
|
|
addMatchers();
|
|
setCacheDir(cacheLocalPath);
|
|
|
|
core.setOutput("uv-version", setupResult.version);
|
|
core.info(`Successfully installed uv version ${setupResult.version}`);
|
|
|
|
if (enableCache) {
|
|
await restoreCache();
|
|
}
|
|
process.exit(0);
|
|
} catch (err) {
|
|
core.setFailed((err as Error).message);
|
|
}
|
|
}
|
|
|
|
function detectEmptyWorkdir(): void {
|
|
if (fs.readdirSync(".").length === 0) {
|
|
if (ignoreEmptyWorkdir) {
|
|
core.info(
|
|
"Empty workdir detected. Ignoring because ignore-empty-workdir is enabled",
|
|
);
|
|
} else {
|
|
core.warning(
|
|
"Empty workdir detected. This may cause unexpected behavior. You can enable ignore-empty-workdir to mute this warning.",
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function setupUv(
|
|
platform: Platform,
|
|
arch: Architecture,
|
|
checkSum: string | undefined,
|
|
githubToken: string,
|
|
): Promise<{ uvDir: string; version: string }> {
|
|
const resolvedVersion = await determineVersion(manifestFile);
|
|
const toolCacheResult = tryGetFromToolCache(arch, resolvedVersion);
|
|
if (toolCacheResult.installedPath) {
|
|
core.info(`Found uv in tool-cache for ${toolCacheResult.version}`);
|
|
return {
|
|
uvDir: toolCacheResult.installedPath,
|
|
version: toolCacheResult.version,
|
|
};
|
|
}
|
|
|
|
let downloadVersionResult: { version: string; cachedToolDir: string };
|
|
if (serverUrl !== "https://github.com") {
|
|
core.warning(
|
|
"The input server-url is deprecated. Please use manifest-file instead.",
|
|
);
|
|
downloadVersionResult = await downloadVersionFromGithub(
|
|
serverUrl,
|
|
platform,
|
|
arch,
|
|
resolvedVersion,
|
|
checkSum,
|
|
githubToken,
|
|
);
|
|
} else {
|
|
downloadVersionResult = await downloadVersionFromManifest(
|
|
manifestFile,
|
|
platform,
|
|
arch,
|
|
resolvedVersion,
|
|
checkSum,
|
|
githubToken,
|
|
);
|
|
}
|
|
|
|
return {
|
|
uvDir: downloadVersionResult.cachedToolDir,
|
|
version: downloadVersionResult.version,
|
|
};
|
|
}
|
|
|
|
async function determineVersion(
|
|
manifestFile: string | undefined,
|
|
): Promise<string> {
|
|
if (versionInput !== "") {
|
|
return await resolveVersion(versionInput, manifestFile, githubToken);
|
|
}
|
|
const versionFromUvToml = getUvVersionFromConfigFile(
|
|
`${workingDirectory}${path.sep}uv.toml`,
|
|
);
|
|
const versionFromPyproject = getUvVersionFromConfigFile(
|
|
`${workingDirectory}${path.sep}pyproject.toml`,
|
|
);
|
|
if (versionFromUvToml === undefined && versionFromPyproject === undefined) {
|
|
core.info(
|
|
"Could not determine uv version from uv.toml or pyproject.toml. Falling back to latest.",
|
|
);
|
|
}
|
|
return await resolveVersion(
|
|
versionFromUvToml || versionFromPyproject || "latest",
|
|
manifestFile,
|
|
githubToken,
|
|
);
|
|
}
|
|
|
|
function addUvToPathAndOutput(cachedPath: string): void {
|
|
core.setOutput("uv-path", `${cachedPath}${path.sep}uv`);
|
|
core.setOutput("uvx-path", `${cachedPath}${path.sep}uvx`);
|
|
core.addPath(cachedPath);
|
|
core.info(`Added ${cachedPath} to the path`);
|
|
}
|
|
|
|
function addToolBinToPath(): void {
|
|
if (toolBinDir !== undefined) {
|
|
core.exportVariable("UV_TOOL_BIN_DIR", toolBinDir);
|
|
core.info(`Set UV_TOOL_BIN_DIR to ${toolBinDir}`);
|
|
core.addPath(toolBinDir);
|
|
core.info(`Added ${toolBinDir} to the path`);
|
|
} else {
|
|
if (process.env.XDG_BIN_HOME !== undefined) {
|
|
core.addPath(process.env.XDG_BIN_HOME);
|
|
core.info(`Added ${process.env.XDG_BIN_HOME} to the path`);
|
|
} else if (process.env.XDG_DATA_HOME !== undefined) {
|
|
core.addPath(`${process.env.XDG_DATA_HOME}/../bin`);
|
|
core.info(`Added ${process.env.XDG_DATA_HOME}/../bin to the path`);
|
|
} else {
|
|
core.addPath(`${process.env.HOME}/.local/bin`);
|
|
core.info(`Added ${process.env.HOME}/.local/bin to the path`);
|
|
}
|
|
}
|
|
}
|
|
|
|
function setToolDir(): void {
|
|
if (toolDir !== undefined) {
|
|
core.exportVariable("UV_TOOL_DIR", toolDir);
|
|
core.info(`Set UV_TOOL_DIR to ${toolDir}`);
|
|
}
|
|
}
|
|
|
|
function setupPython(): void {
|
|
if (pythonVersion !== "") {
|
|
core.exportVariable("UV_PYTHON", pythonVersion);
|
|
core.info(`Set UV_PYTHON to ${pythonVersion}`);
|
|
}
|
|
}
|
|
|
|
async function activateEnvironment(): Promise<void> {
|
|
if (activateEnvironmentInput) {
|
|
const execArgs = ["venv", ".venv", "--directory", workingDirectory];
|
|
|
|
core.info("Activating python venv...");
|
|
await exec.exec("uv", execArgs);
|
|
|
|
let venvBinPath = `${workingDirectory}${path.sep}.venv${path.sep}bin`;
|
|
if (process.platform === "win32") {
|
|
venvBinPath = `${workingDirectory}${path.sep}.venv${path.sep}Scripts`;
|
|
}
|
|
core.addPath(path.resolve(venvBinPath));
|
|
core.exportVariable(
|
|
"VIRTUAL_ENV",
|
|
path.resolve(`${workingDirectory}${path.sep}.venv`),
|
|
);
|
|
}
|
|
}
|
|
|
|
function setCacheDir(cacheLocalPath: string): void {
|
|
core.exportVariable("UV_CACHE_DIR", cacheLocalPath);
|
|
core.info(`Set UV_CACHE_DIR to ${cacheLocalPath}`);
|
|
}
|
|
|
|
function addMatchers(): void {
|
|
const matchersPath = path.join(__dirname, `..${path.sep}..`, ".github");
|
|
core.info(`##[add-matcher]${path.join(matchersPath, "python.json")}`);
|
|
}
|
|
|
|
run();
|