mirror of
https://github.com/astral-sh/setup-uv.git
synced 2026-01-27 06:02:04 +00:00
Compare commits
2 Commits
update-kno
...
zsol/jj-uq
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71191068af | ||
|
|
450788bda3 |
5120
dist/save-cache/index.js
generated
vendored
5120
dist/save-cache/index.js
generated
vendored
File diff suppressed because it is too large
Load Diff
9462
dist/setup/index.js
generated
vendored
9462
dist/setup/index.js
generated
vendored
File diff suppressed because it is too large
Load Diff
20
dist/update-known-versions/index.js
generated
vendored
20
dist/update-known-versions/index.js
generated
vendored
@@ -32482,8 +32482,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.REMOTE_MANIFEST_URL = void 0;
|
||||||
exports.getLatestKnownVersion = getLatestKnownVersion;
|
exports.getLatestKnownVersion = getLatestKnownVersion;
|
||||||
exports.getDownloadUrl = getDownloadUrl;
|
exports.getDownloadUrl = getDownloadUrl;
|
||||||
|
exports.getAvailableVersionsFromManifest = getAvailableVersionsFromManifest;
|
||||||
exports.updateVersionManifest = updateVersionManifest;
|
exports.updateVersionManifest = updateVersionManifest;
|
||||||
const node_fs_1 = __nccwpck_require__(3024);
|
const node_fs_1 = __nccwpck_require__(3024);
|
||||||
const node_path_1 = __nccwpck_require__(6760);
|
const node_path_1 = __nccwpck_require__(6760);
|
||||||
@@ -32491,6 +32493,9 @@ const core = __importStar(__nccwpck_require__(7484));
|
|||||||
const semver = __importStar(__nccwpck_require__(9318));
|
const semver = __importStar(__nccwpck_require__(9318));
|
||||||
const fetch_1 = __nccwpck_require__(3385);
|
const fetch_1 = __nccwpck_require__(3385);
|
||||||
const localManifestFile = (0, node_path_1.join)(__dirname, "..", "..", "version-manifest.json");
|
const localManifestFile = (0, node_path_1.join)(__dirname, "..", "..", "version-manifest.json");
|
||||||
|
exports.REMOTE_MANIFEST_URL = "https://raw.githubusercontent.com/astral-sh/setup-uv/main/version-manifest.json";
|
||||||
|
// Cache for manifest entries to avoid re-fetching
|
||||||
|
const manifestCache = new Map();
|
||||||
async function getLatestKnownVersion(manifestUrl) {
|
async function getLatestKnownVersion(manifestUrl) {
|
||||||
const manifestEntries = await getManifestEntries(manifestUrl);
|
const manifestEntries = await getManifestEntries(manifestUrl);
|
||||||
return manifestEntries.reduce((a, b) => semver.gt(a.version, b.version) ? a : b).version;
|
return manifestEntries.reduce((a, b) => semver.gt(a.version, b.version) ? a : b).version;
|
||||||
@@ -32502,7 +32507,18 @@ async function getDownloadUrl(manifestUrl, version, arch, platform) {
|
|||||||
entry.platform === platform);
|
entry.platform === platform);
|
||||||
return entry ? entry.downloadUrl : undefined;
|
return entry ? entry.downloadUrl : undefined;
|
||||||
}
|
}
|
||||||
|
async function getAvailableVersionsFromManifest(manifestUrl) {
|
||||||
|
const manifestEntries = await getManifestEntries(manifestUrl);
|
||||||
|
return [...new Set(manifestEntries.map((entry) => entry.version))];
|
||||||
|
}
|
||||||
async function getManifestEntries(manifestUrl) {
|
async function getManifestEntries(manifestUrl) {
|
||||||
|
const cacheKey = manifestUrl ?? "local";
|
||||||
|
// Return cached entries if available
|
||||||
|
const cached = manifestCache.get(cacheKey);
|
||||||
|
if (cached !== undefined) {
|
||||||
|
core.debug(`Using cached manifest entries for: ${cacheKey}`);
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
let data;
|
let data;
|
||||||
if (manifestUrl !== undefined) {
|
if (manifestUrl !== undefined) {
|
||||||
core.info(`Fetching manifest-file from: ${manifestUrl}`);
|
core.info(`Fetching manifest-file from: ${manifestUrl}`);
|
||||||
@@ -32517,7 +32533,9 @@ async function getManifestEntries(manifestUrl) {
|
|||||||
const fileContent = await node_fs_1.promises.readFile(localManifestFile);
|
const fileContent = await node_fs_1.promises.readFile(localManifestFile);
|
||||||
data = fileContent.toString();
|
data = fileContent.toString();
|
||||||
}
|
}
|
||||||
return JSON.parse(data);
|
const entries = JSON.parse(data);
|
||||||
|
manifestCache.set(cacheKey, entries);
|
||||||
|
return entries;
|
||||||
}
|
}
|
||||||
async function updateVersionManifest(manifestUrl, downloadUrls) {
|
async function updateVersionManifest(manifestUrl, downloadUrls) {
|
||||||
const manifest = [];
|
const manifest = [];
|
||||||
|
|||||||
@@ -2,21 +2,18 @@ import { promises as fs } from "node:fs";
|
|||||||
import * as path from "node:path";
|
import * as path from "node:path";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import * as tc from "@actions/tool-cache";
|
import * as tc from "@actions/tool-cache";
|
||||||
import type { Endpoints } from "@octokit/types";
|
|
||||||
import * as pep440 from "@renovatebot/pep440";
|
import * as pep440 from "@renovatebot/pep440";
|
||||||
import * as semver from "semver";
|
import * as semver from "semver";
|
||||||
import { OWNER, REPO, TOOL_CACHE_NAME } from "../utils/constants";
|
import { OWNER, REPO, TOOL_CACHE_NAME } from "../utils/constants";
|
||||||
import { Octokit } from "../utils/octokit";
|
|
||||||
import type { Architecture, Platform } from "../utils/platforms";
|
import type { Architecture, Platform } from "../utils/platforms";
|
||||||
import { validateChecksum } from "./checksum/checksum";
|
import { validateChecksum } from "./checksum/checksum";
|
||||||
import {
|
import {
|
||||||
|
getAvailableVersionsFromManifest,
|
||||||
getDownloadUrl,
|
getDownloadUrl,
|
||||||
getLatestKnownVersion as getLatestVersionInManifest,
|
getLatestKnownVersion as getLatestVersionInManifest,
|
||||||
|
REMOTE_MANIFEST_URL,
|
||||||
} from "./version-manifest";
|
} from "./version-manifest";
|
||||||
|
|
||||||
type Release =
|
|
||||||
Endpoints["GET /repos/{owner}/{repo}/releases"]["response"]["data"][number];
|
|
||||||
|
|
||||||
export function tryGetFromToolCache(
|
export function tryGetFromToolCache(
|
||||||
arch: Architecture,
|
arch: Architecture,
|
||||||
version: string,
|
version: string,
|
||||||
@@ -61,27 +58,36 @@ export async function downloadVersionFromManifest(
|
|||||||
checkSum: string | undefined,
|
checkSum: string | undefined,
|
||||||
githubToken: string,
|
githubToken: string,
|
||||||
): Promise<{ version: string; cachedToolDir: string }> {
|
): Promise<{ version: string; cachedToolDir: string }> {
|
||||||
const downloadUrl = await getDownloadUrl(
|
// If no user-provided manifest, try remote manifest first (will use cache if already fetched)
|
||||||
manifestUrl,
|
// then fall back to bundled manifest
|
||||||
version,
|
const manifestSources =
|
||||||
arch,
|
manifestUrl !== undefined
|
||||||
platform,
|
? [manifestUrl]
|
||||||
);
|
: [REMOTE_MANIFEST_URL, undefined];
|
||||||
if (!downloadUrl) {
|
|
||||||
core.info(
|
for (const source of manifestSources) {
|
||||||
`manifest-file does not contain version ${version}, arch ${arch}, platform ${platform}. Falling back to GitHub releases.`,
|
try {
|
||||||
);
|
const downloadUrl = await getDownloadUrl(source, version, arch, platform);
|
||||||
return await downloadVersionFromGithub(
|
if (downloadUrl) {
|
||||||
platform,
|
return await downloadVersion(
|
||||||
arch,
|
downloadUrl,
|
||||||
version,
|
`uv-${arch}-${platform}`,
|
||||||
checkSum,
|
platform,
|
||||||
githubToken,
|
arch,
|
||||||
);
|
version,
|
||||||
|
checkSum,
|
||||||
|
githubToken,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
core.debug(`Failed to get download URL from manifest ${source}: ${err}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return await downloadVersion(
|
|
||||||
downloadUrl,
|
core.info(
|
||||||
`uv-${arch}-${platform}`,
|
`Manifest does not contain version ${version}, arch ${arch}, platform ${platform}. Falling back to GitHub releases.`,
|
||||||
|
);
|
||||||
|
return await downloadVersionFromGithub(
|
||||||
platform,
|
platform,
|
||||||
arch,
|
arch,
|
||||||
version,
|
version,
|
||||||
@@ -143,7 +149,6 @@ function getExtension(platform: Platform): string {
|
|||||||
export async function resolveVersion(
|
export async function resolveVersion(
|
||||||
versionInput: string,
|
versionInput: string,
|
||||||
manifestFile: string | undefined,
|
manifestFile: string | undefined,
|
||||||
githubToken: string,
|
|
||||||
resolutionStrategy: "highest" | "lowest" = "highest",
|
resolutionStrategy: "highest" | "lowest" = "highest",
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
core.debug(`Resolving version: ${versionInput}`);
|
core.debug(`Resolving version: ${versionInput}`);
|
||||||
@@ -163,7 +168,7 @@ export async function resolveVersion(
|
|||||||
} else {
|
} else {
|
||||||
version =
|
version =
|
||||||
versionInput === "latest" || resolveVersionSpecifierToLatest
|
versionInput === "latest" || resolveVersionSpecifierToLatest
|
||||||
? await getLatestVersion(githubToken)
|
? await getLatestVersion()
|
||||||
: versionInput;
|
: versionInput;
|
||||||
}
|
}
|
||||||
if (tc.isExplicitVersion(version)) {
|
if (tc.isExplicitVersion(version)) {
|
||||||
@@ -175,7 +180,7 @@ export async function resolveVersion(
|
|||||||
}
|
}
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
const availableVersions = await getAvailableVersions(githubToken);
|
const availableVersions = await getAvailableVersions();
|
||||||
core.debug(`Available versions: ${availableVersions}`);
|
core.debug(`Available versions: ${availableVersions}`);
|
||||||
const resolvedVersion =
|
const resolvedVersion =
|
||||||
resolutionStrategy === "lowest"
|
resolutionStrategy === "lowest"
|
||||||
@@ -187,79 +192,37 @@ export async function resolveVersion(
|
|||||||
return resolvedVersion;
|
return resolvedVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAvailableVersions(githubToken: string): Promise<string[]> {
|
async function getAvailableVersions(): Promise<string[]> {
|
||||||
core.info("Getting available versions from GitHub API...");
|
// 1. Try remote manifest first (no rate limits, always current)
|
||||||
try {
|
try {
|
||||||
const octokit = new Octokit({
|
core.info("Getting available versions from remote manifest...");
|
||||||
auth: githubToken,
|
const versions =
|
||||||
});
|
await getAvailableVersionsFromManifest(REMOTE_MANIFEST_URL);
|
||||||
return await getReleaseTagNames(octokit);
|
core.debug(`Found ${versions.length} versions from remote manifest`);
|
||||||
|
return versions;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if ((err as Error).message.includes("Bad credentials")) {
|
core.debug(`Remote manifest lookup failed: ${err}`);
|
||||||
core.info(
|
|
||||||
"No (valid) GitHub token provided. Falling back to anonymous. Requests might be rate limited.",
|
|
||||||
);
|
|
||||||
const octokit = new Octokit();
|
|
||||||
return await getReleaseTagNames(octokit);
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. Fall back to bundled manifest (no network, may be stale)
|
||||||
|
core.info("Getting available versions from bundled manifest...");
|
||||||
|
return await getAvailableVersionsFromManifest(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getReleaseTagNames(octokit: Octokit): Promise<string[]> {
|
async function getLatestVersion() {
|
||||||
const response: Release[] = await octokit.paginate(
|
// 1. Try remote manifest first (no rate limits, always current)
|
||||||
octokit.rest.repos.listReleases,
|
|
||||||
{
|
|
||||||
owner: OWNER,
|
|
||||||
repo: REPO,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const releaseTagNames = response.map((release) => release.tag_name);
|
|
||||||
if (releaseTagNames.length === 0) {
|
|
||||||
throw Error(
|
|
||||||
"Github API request failed while getting releases. Check the GitHub status page for outages. Try again later.",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return releaseTagNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getLatestVersion(githubToken: string) {
|
|
||||||
core.info("Getting latest version from GitHub API...");
|
|
||||||
const octokit = new Octokit({
|
|
||||||
auth: githubToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
let latestRelease: { tag_name: string } | undefined;
|
|
||||||
try {
|
try {
|
||||||
latestRelease = await getLatestRelease(octokit);
|
core.info("Getting latest version from remote manifest...");
|
||||||
|
const version = await getLatestVersionInManifest(REMOTE_MANIFEST_URL);
|
||||||
|
core.debug(`Latest version from remote manifest: ${version}`);
|
||||||
|
return version;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if ((err as Error).message.includes("Bad credentials")) {
|
core.debug(`Remote manifest lookup failed: ${err}`);
|
||||||
core.info(
|
|
||||||
"No (valid) GitHub token provided. Falling back to anonymous. Requests might be rate limited.",
|
|
||||||
);
|
|
||||||
const octokit = new Octokit();
|
|
||||||
latestRelease = await getLatestRelease(octokit);
|
|
||||||
} else {
|
|
||||||
core.error(
|
|
||||||
"Github API request failed while getting latest release. Check the GitHub status page for outages. Try again later.",
|
|
||||||
);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!latestRelease) {
|
// 2. Fall back to bundled manifest (no network, may be stale)
|
||||||
throw new Error("Could not determine latest release.");
|
core.info("Getting latest version from bundled manifest...");
|
||||||
}
|
return await getLatestVersionInManifest(undefined);
|
||||||
core.debug(`Latest version: ${latestRelease.tag_name}`);
|
|
||||||
return latestRelease.tag_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getLatestRelease(octokit: Octokit) {
|
|
||||||
const { data: latestRelease } = await octokit.rest.repos.getLatestRelease({
|
|
||||||
owner: OWNER,
|
|
||||||
repo: REPO,
|
|
||||||
});
|
|
||||||
return latestRelease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function maxSatisfying(
|
function maxSatisfying(
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ import * as semver from "semver";
|
|||||||
import { fetch } from "../utils/fetch";
|
import { fetch } from "../utils/fetch";
|
||||||
|
|
||||||
const localManifestFile = join(__dirname, "..", "..", "version-manifest.json");
|
const localManifestFile = join(__dirname, "..", "..", "version-manifest.json");
|
||||||
|
export const REMOTE_MANIFEST_URL =
|
||||||
|
"https://raw.githubusercontent.com/astral-sh/setup-uv/main/version-manifest.json";
|
||||||
|
|
||||||
|
// Cache for manifest entries to avoid re-fetching
|
||||||
|
const manifestCache = new Map<string, ManifestEntry[]>();
|
||||||
|
|
||||||
interface ManifestEntry {
|
interface ManifestEntry {
|
||||||
version: string;
|
version: string;
|
||||||
@@ -39,9 +44,25 @@ export async function getDownloadUrl(
|
|||||||
return entry ? entry.downloadUrl : undefined;
|
return entry ? entry.downloadUrl : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getAvailableVersionsFromManifest(
|
||||||
|
manifestUrl: string | undefined,
|
||||||
|
): Promise<string[]> {
|
||||||
|
const manifestEntries = await getManifestEntries(manifestUrl);
|
||||||
|
return [...new Set(manifestEntries.map((entry) => entry.version))];
|
||||||
|
}
|
||||||
|
|
||||||
async function getManifestEntries(
|
async function getManifestEntries(
|
||||||
manifestUrl: string | undefined,
|
manifestUrl: string | undefined,
|
||||||
): Promise<ManifestEntry[]> {
|
): Promise<ManifestEntry[]> {
|
||||||
|
const cacheKey = manifestUrl ?? "local";
|
||||||
|
|
||||||
|
// Return cached entries if available
|
||||||
|
const cached = manifestCache.get(cacheKey);
|
||||||
|
if (cached !== undefined) {
|
||||||
|
core.debug(`Using cached manifest entries for: ${cacheKey}`);
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
let data: string;
|
let data: string;
|
||||||
if (manifestUrl !== undefined) {
|
if (manifestUrl !== undefined) {
|
||||||
core.info(`Fetching manifest-file from: ${manifestUrl}`);
|
core.info(`Fetching manifest-file from: ${manifestUrl}`);
|
||||||
@@ -58,7 +79,9 @@ async function getManifestEntries(
|
|||||||
data = fileContent.toString();
|
data = fileContent.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON.parse(data);
|
const entries: ManifestEntry[] = JSON.parse(data);
|
||||||
|
manifestCache.set(cacheKey, entries);
|
||||||
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateVersionManifest(
|
export async function updateVersionManifest(
|
||||||
|
|||||||
@@ -157,12 +157,7 @@ async function determineVersion(
|
|||||||
manifestFile: string | undefined,
|
manifestFile: string | undefined,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
if (versionInput !== "") {
|
if (versionInput !== "") {
|
||||||
return await resolveVersion(
|
return await resolveVersion(versionInput, manifestFile, resolutionStrategy);
|
||||||
versionInput,
|
|
||||||
manifestFile,
|
|
||||||
githubToken,
|
|
||||||
resolutionStrategy,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (versionFileInput !== "") {
|
if (versionFileInput !== "") {
|
||||||
const versionFromFile = getUvVersionFromFile(versionFileInput);
|
const versionFromFile = getUvVersionFromFile(versionFileInput);
|
||||||
@@ -174,7 +169,6 @@ async function determineVersion(
|
|||||||
return await resolveVersion(
|
return await resolveVersion(
|
||||||
versionFromFile,
|
versionFromFile,
|
||||||
manifestFile,
|
manifestFile,
|
||||||
githubToken,
|
|
||||||
resolutionStrategy,
|
resolutionStrategy,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -192,7 +186,6 @@ async function determineVersion(
|
|||||||
return await resolveVersion(
|
return await resolveVersion(
|
||||||
versionFromUvToml || versionFromPyproject || "latest",
|
versionFromUvToml || versionFromPyproject || "latest",
|
||||||
manifestFile,
|
manifestFile,
|
||||||
githubToken,
|
|
||||||
resolutionStrategy,
|
resolutionStrategy,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user