mirror of
https://github.com/astral-sh/setup-uv.git
synced 2025-12-17 11:05:59 +00:00
Compare commits
11 Commits
copilot/ad
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f94e1fdb8a | ||
|
|
9f2a67fea1 | ||
|
|
65bae315f3 | ||
|
|
3ccd0fd498 | ||
|
|
ce6dbd84e1 | ||
|
|
2382069a66 | ||
|
|
b1daf91f4e | ||
|
|
3259c6206f | ||
|
|
bf8e8ed895 | ||
|
|
9c6b5e9fb5 | ||
|
|
a5129e99f4 |
44
.github/copilot-instructions.md
vendored
44
.github/copilot-instructions.md
vendored
@@ -4,9 +4,13 @@ This document provides essential information for GitHub Copilot coding agents wo
|
|||||||
|
|
||||||
## Repository Overview
|
## Repository Overview
|
||||||
|
|
||||||
**setup-uv** is a GitHub Action that sets up the [uv](https://docs.astral.sh/uv/) Python package installer in GitHub Actions workflows. It's a TypeScript-based action that downloads uv binaries, manages caching, handles version resolution, and configures the environment for subsequent workflow steps.
|
**setup-uv** is a GitHub Action that sets up the [uv](https://docs.astral.sh/uv/)
|
||||||
|
Python package installer in GitHub Actions workflows.
|
||||||
|
It's a TypeScript-based action that downloads uv binaries, manages caching, handles version resolution,
|
||||||
|
and configures the environment for subsequent workflow steps.
|
||||||
|
|
||||||
### Key Features
|
### Key Features
|
||||||
|
|
||||||
- Downloads and installs specific uv versions from GitHub releases
|
- Downloads and installs specific uv versions from GitHub releases
|
||||||
- Supports version resolution from config files (pyproject.toml, uv.toml, .tool-versions)
|
- Supports version resolution from config files (pyproject.toml, uv.toml, .tool-versions)
|
||||||
- Implements intelligent caching for both uv cache and Python installations
|
- Implements intelligent caching for both uv cache and Python installations
|
||||||
@@ -22,6 +26,7 @@ This document provides essential information for GitHub Copilot coding agents wo
|
|||||||
**Key Dependencies**: @actions/core, @actions/cache, @actions/tool-cache, @octokit/core
|
**Key Dependencies**: @actions/core, @actions/cache, @actions/tool-cache, @octokit/core
|
||||||
|
|
||||||
### Core Architecture
|
### Core Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
├── setup-uv.ts # Main entry point and orchestration
|
├── setup-uv.ts # Main entry point and orchestration
|
||||||
@@ -34,6 +39,7 @@ src/
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Key Files and Locations
|
### Key Files and Locations
|
||||||
|
|
||||||
- **Action Definition**: `action.yml` - Defines all inputs/outputs and entry points
|
- **Action Definition**: `action.yml` - Defines all inputs/outputs and entry points
|
||||||
- **Main Source**: `src/setup-uv.ts` - Primary action logic
|
- **Main Source**: `src/setup-uv.ts` - Primary action logic
|
||||||
- **Configuration**: `biome.json` (linting), `tsconfig.json` (TypeScript), `jest.config.js` (testing)
|
- **Configuration**: `biome.json` (linting), `tsconfig.json` (TypeScript), `jest.config.js` (testing)
|
||||||
@@ -44,53 +50,66 @@ src/
|
|||||||
## Build and Development Process
|
## Build and Development Process
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- Node.js 24+ (matches GitHub Actions runtime)
|
- Node.js 24+ (matches GitHub Actions runtime)
|
||||||
- npm (included with Node.js)
|
- npm (included with Node.js)
|
||||||
|
|
||||||
### Essential Commands (ALWAYS run in this order)
|
### Essential Commands (ALWAYS run in this order)
|
||||||
|
|
||||||
#### 1. Install Dependencies
|
#### 1. Install Dependencies
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
**Timing**: ~20-30 seconds
|
**Timing**: ~20-30 seconds
|
||||||
**Note**: Always run this first after cloning or when package.json changes
|
**Note**: Always run this first after cloning or when package.json changes
|
||||||
|
|
||||||
#### 2. Build TypeScript
|
#### 2. Build TypeScript
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
**Timing**: ~5-10 seconds
|
**Timing**: ~5-10 seconds
|
||||||
**Purpose**: Compiles TypeScript source to JavaScript in `lib/` directory
|
**Purpose**: Compiles TypeScript source to JavaScript in `lib/` directory
|
||||||
|
|
||||||
#### 3. Lint and Format Code
|
#### 3. Lint and Format Code
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run check
|
npm run check
|
||||||
```
|
```
|
||||||
|
|
||||||
**Timing**: ~2-5 seconds
|
**Timing**: ~2-5 seconds
|
||||||
**Tool**: Biome (replaces ESLint/Prettier)
|
**Tool**: Biome (replaces ESLint/Prettier)
|
||||||
**Auto-fixes**: Formatting, import organization, basic linting issues
|
**Auto-fixes**: Formatting, import organization, basic linting issues
|
||||||
|
|
||||||
#### 4. Package for Distribution
|
#### 4. Package for Distribution
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run package
|
npm run package
|
||||||
```
|
```
|
||||||
|
|
||||||
**Timing**: ~20-30 seconds
|
**Timing**: ~20-30 seconds
|
||||||
**Purpose**: Creates bundled distributions in `dist/` using @vercel/ncc
|
**Purpose**: Creates bundled distributions in `dist/` using @vercel/ncc
|
||||||
**Critical**: This step MUST be run before committing - the `dist/` files are used by GitHub Actions
|
**Critical**: This step MUST be run before committing - the `dist/` files are used by GitHub Actions
|
||||||
|
|
||||||
#### 5. Run Tests
|
#### 5. Run Tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm test
|
npm test
|
||||||
```
|
```
|
||||||
|
|
||||||
**Timing**: ~10-15 seconds
|
**Timing**: ~10-15 seconds
|
||||||
**Framework**: Jest with TypeScript support
|
**Framework**: Jest with TypeScript support
|
||||||
**Coverage**: Unit tests for version resolution, input parsing, checksum validation
|
**Coverage**: Unit tests for version resolution, input parsing, checksum validation
|
||||||
|
|
||||||
#### 6. Complete Validation (Recommended)
|
#### 6. Complete Validation (Recommended)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run all
|
npm run all
|
||||||
```
|
```
|
||||||
|
|
||||||
**Timing**: ~60-90 seconds
|
**Timing**: ~60-90 seconds
|
||||||
**Purpose**: Runs build → check → package → test in sequence
|
**Purpose**: Runs build → check → package → test in sequence
|
||||||
**Use**: Before making pull requests or when unsure about build state
|
**Use**: Before making pull requests or when unsure about build state
|
||||||
@@ -106,11 +125,13 @@ npm run all
|
|||||||
## Testing Strategy
|
## Testing Strategy
|
||||||
|
|
||||||
### Unit Tests
|
### Unit Tests
|
||||||
|
|
||||||
- **Location**: `__tests__/` directory
|
- **Location**: `__tests__/` directory
|
||||||
- **Framework**: Jest with ts-jest transformer
|
- **Framework**: Jest with ts-jest transformer
|
||||||
- **Coverage**: Version resolution, input parsing, checksum validation, utility functions
|
- **Coverage**: Version resolution, input parsing, checksum validation, utility functions
|
||||||
|
|
||||||
### Integration Tests
|
### Integration Tests
|
||||||
|
|
||||||
- **Location**: `.github/workflows/test.yml`
|
- **Location**: `.github/workflows/test.yml`
|
||||||
- **Scope**: Full end-to-end testing across multiple platforms and scenarios
|
- **Scope**: Full end-to-end testing across multiple platforms and scenarios
|
||||||
- **Key Test Categories**:
|
- **Key Test Categories**:
|
||||||
@@ -121,6 +142,7 @@ npm run all
|
|||||||
- Error handling and edge cases
|
- Error handling and edge cases
|
||||||
|
|
||||||
### Test Fixtures
|
### Test Fixtures
|
||||||
|
|
||||||
Located in `__tests__/fixtures/`, these provide sample projects with different configurations:
|
Located in `__tests__/fixtures/`, these provide sample projects with different configurations:
|
||||||
- `pyproject-toml-project/` - Standard Python project with uv version specification
|
- `pyproject-toml-project/` - Standard Python project with uv version specification
|
||||||
- `uv-toml-project/` - Project using uv.toml configuration
|
- `uv-toml-project/` - Project using uv.toml configuration
|
||||||
@@ -132,9 +154,10 @@ Located in `__tests__/fixtures/`, these provide sample projects with different c
|
|||||||
### GitHub Workflows
|
### GitHub Workflows
|
||||||
|
|
||||||
#### Primary Test Suite (`.github/workflows/test.yml`)
|
#### Primary Test Suite (`.github/workflows/test.yml`)
|
||||||
|
|
||||||
- **Triggers**: PRs, pushes to main, manual dispatch
|
- **Triggers**: PRs, pushes to main, manual dispatch
|
||||||
- **Matrix**: Multiple OS (Ubuntu, macOS, Windows), architecture (x64, ARM), and configuration combinations
|
- **Matrix**: Multiple OS (Ubuntu, macOS, Windows), architecture (x64, ARM), and configuration combinations
|
||||||
- **Duration**: ~20-30 minutes for full matrix
|
- **Duration**: ~5 minutes for full matrix
|
||||||
- **Key Validations**:
|
- **Key Validations**:
|
||||||
- Cross-platform installation and functionality
|
- Cross-platform installation and functionality
|
||||||
- Cache behavior and performance
|
- Cache behavior and performance
|
||||||
@@ -143,11 +166,13 @@ Located in `__tests__/fixtures/`, these provide sample projects with different c
|
|||||||
- Problem matcher functionality
|
- Problem matcher functionality
|
||||||
|
|
||||||
#### Maintenance Workflows
|
#### Maintenance Workflows
|
||||||
|
|
||||||
- **CodeQL Analysis**: Security scanning on pushes/PRs
|
- **CodeQL Analysis**: Security scanning on pushes/PRs
|
||||||
- **Update Known Versions**: Daily job to sync with latest uv releases
|
- **Update Known Versions**: Daily job to sync with latest uv releases
|
||||||
- **Dependabot**: Automated dependency updates
|
- **Dependabot**: Automated dependency updates
|
||||||
|
|
||||||
### Pre-commit Validation
|
### Pre-commit Validation
|
||||||
|
|
||||||
The CI runs these checks that you should run locally:
|
The CI runs these checks that you should run locally:
|
||||||
1. `npm run all` - Complete build and test suite
|
1. `npm run all` - Complete build and test suite
|
||||||
2. ActionLint - GitHub Actions workflow validation
|
2. ActionLint - GitHub Actions workflow validation
|
||||||
@@ -156,15 +181,20 @@ The CI runs these checks that you should run locally:
|
|||||||
## Key Configuration Files
|
## Key Configuration Files
|
||||||
|
|
||||||
### Action Configuration (`action.yml`)
|
### Action Configuration (`action.yml`)
|
||||||
Defines 20+ inputs including version specifications, cache settings, tool directories, and environment options. This file is the authoritative source for understanding available action parameters.
|
|
||||||
|
Defines 20+ inputs including version specifications,
|
||||||
|
cache settings, tool directories, and environment options.
|
||||||
|
This file is the authoritative source for understanding available action parameters.
|
||||||
|
|
||||||
### TypeScript Configuration (`tsconfig.json`)
|
### TypeScript Configuration (`tsconfig.json`)
|
||||||
|
|
||||||
- Target: ES2024
|
- Target: ES2024
|
||||||
- Module: nodenext (Node.js modules)
|
- Module: nodenext (Node.js modules)
|
||||||
- Strict mode enabled
|
- Strict mode enabled
|
||||||
- Output directory: `lib/`
|
- Output directory: `lib/`
|
||||||
|
|
||||||
### Linting Configuration (`biome.json`)
|
### Linting Configuration (`biome.json`)
|
||||||
|
|
||||||
- Formatter and linter combined
|
- Formatter and linter combined
|
||||||
- Enforces consistent code style
|
- Enforces consistent code style
|
||||||
- Automatically organizes imports and sorts object keys
|
- Automatically organizes imports and sorts object keys
|
||||||
@@ -172,6 +202,7 @@ Defines 20+ inputs including version specifications, cache settings, tool direct
|
|||||||
## Common Development Patterns
|
## Common Development Patterns
|
||||||
|
|
||||||
### Making Code Changes
|
### Making Code Changes
|
||||||
|
|
||||||
1. Edit TypeScript source files in `src/`
|
1. Edit TypeScript source files in `src/`
|
||||||
2. Run `npm run build` to compile
|
2. Run `npm run build` to compile
|
||||||
3. Run `npm run check` to format and lint
|
3. Run `npm run check` to format and lint
|
||||||
@@ -180,18 +211,22 @@ Defines 20+ inputs including version specifications, cache settings, tool direct
|
|||||||
6. Commit all changes including `dist/` files
|
6. Commit all changes including `dist/` files
|
||||||
|
|
||||||
### Adding New Features
|
### Adding New Features
|
||||||
|
|
||||||
- Follow existing patterns in `src/utils/inputs.ts` for new action inputs
|
- Follow existing patterns in `src/utils/inputs.ts` for new action inputs
|
||||||
- Update `action.yml` to declare new inputs/outputs
|
- Update `action.yml` to declare new inputs/outputs
|
||||||
- Add corresponding tests in `__tests__/`
|
- Add corresponding tests in `__tests__/`
|
||||||
|
- Add a test in `.github/workflows/test.yml` if it affects integration
|
||||||
- Update README.md with usage examples
|
- Update README.md with usage examples
|
||||||
|
|
||||||
### Cache-Related Changes
|
### Cache-Related Changes
|
||||||
|
|
||||||
- Cache logic is complex and affects performance significantly
|
- Cache logic is complex and affects performance significantly
|
||||||
- Test with multiple cache scenarios (hit, miss, invalidation)
|
- Test with multiple cache scenarios (hit, miss, invalidation)
|
||||||
- Consider impact on both GitHub-hosted and self-hosted runners
|
- Consider impact on both GitHub-hosted and self-hosted runners
|
||||||
- Validate cache key generation and dependency detection
|
- Validate cache key generation and dependency detection
|
||||||
|
|
||||||
### Version Resolution Changes
|
### Version Resolution Changes
|
||||||
|
|
||||||
- Version resolution supports multiple file formats and precedence rules
|
- Version resolution supports multiple file formats and precedence rules
|
||||||
- Test with fixtures in `__tests__/fixtures/`
|
- Test with fixtures in `__tests__/fixtures/`
|
||||||
- Consider backward compatibility with existing projects
|
- Consider backward compatibility with existing projects
|
||||||
@@ -200,16 +235,19 @@ Defines 20+ inputs including version specifications, cache settings, tool direct
|
|||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Build Failures
|
### Build Failures
|
||||||
|
|
||||||
- **"Module not found"**: Run `npm install` to ensure dependencies are installed
|
- **"Module not found"**: Run `npm install` to ensure dependencies are installed
|
||||||
- **TypeScript errors**: Check `tsconfig.json` and ensure all imports are valid
|
- **TypeScript errors**: Check `tsconfig.json` and ensure all imports are valid
|
||||||
- **Test failures**: Check if test fixtures have been modified or if logic changes broke assumptions
|
- **Test failures**: Check if test fixtures have been modified or if logic changes broke assumptions
|
||||||
|
|
||||||
### Action Failures in Workflows
|
### Action Failures in Workflows
|
||||||
|
|
||||||
- **Changes not taking effect**: Ensure `npm run package` was run and `dist/` files committed
|
- **Changes not taking effect**: Ensure `npm run package` was run and `dist/` files committed
|
||||||
- **Version resolution issues**: Check version specification format and file existence
|
- **Version resolution issues**: Check version specification format and file existence
|
||||||
- **Cache problems**: Verify cache key generation and dependency glob patterns
|
- **Cache problems**: Verify cache key generation and dependency glob patterns
|
||||||
|
|
||||||
### Common Gotchas
|
### Common Gotchas
|
||||||
|
|
||||||
- **Forgetting to package**: Code changes won't work without running `npm run package`
|
- **Forgetting to package**: Code changes won't work without running `npm run package`
|
||||||
- **Platform differences**: Windows paths use backslashes, test cross-platform behavior
|
- **Platform differences**: Windows paths use backslashes, test cross-platform behavior
|
||||||
- **Cache invalidation**: Cache keys are sensitive to dependency file changes
|
- **Cache invalidation**: Cache keys are sensitive to dependency file changes
|
||||||
|
|||||||
16
.github/scripts/check-all-tests-passed-needs.js
vendored
16
.github/scripts/check-all-tests-passed-needs.js
vendored
@@ -1,16 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
var fs = require("node:fs");
|
|
||||||
var yaml = require("js-yaml");
|
|
||||||
var workflow = yaml.load(fs.readFileSync("../workflows/test.yml", "utf8"));
|
|
||||||
var jobs = Object.keys(workflow.jobs);
|
|
||||||
var allTestsPassed = workflow.jobs["all-tests-passed"];
|
|
||||||
var needs = allTestsPassed.needs || [];
|
|
||||||
var expectedNeeds = jobs.filter(function (j) { return j !== "all-tests-passed"; });
|
|
||||||
var missing = expectedNeeds.filter(function (j) { return !needs.includes(j); });
|
|
||||||
if (missing.length > 0) {
|
|
||||||
console.error("Missing jobs in all-tests-passed needs: ".concat(missing.join(", ")));
|
|
||||||
console.info("Please add the missing jobs to the needs section of all-tests-passed in test.yml.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
console.log("All jobs in test.yml are in the needs section of all-tests-passed.");
|
|
||||||
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
|||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
|
uses: github/codeql-action/init@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # v4.30.8
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
source-root: src
|
source-root: src
|
||||||
@@ -59,7 +59,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# 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)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
|
uses: github/codeql-action/autobuild@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # v4.30.8
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@@ -73,4 +73,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
|
uses: github/codeql-action/analyze@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # v4.30.8
|
||||||
|
|||||||
16
.github/workflows/test.yml
vendored
16
.github/workflows/test.yml
vendored
@@ -25,10 +25,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Actionlint
|
- name: Actionlint
|
||||||
uses: eifinger/actionlint-action@23c85443d840cd73bbecb9cddfc933cc21649a38 # v1.9.1
|
uses: eifinger/actionlint-action@03ff1f78c0670b71017616a37170f327df932030 # v1.9.2
|
||||||
- name: Run zizmor
|
- name: Run zizmor
|
||||||
uses: zizmorcore/zizmor-action@e673c3917a1aef3c65c972347ed84ccd013ecda4 # v0.2.0
|
uses: zizmorcore/zizmor-action@e673c3917a1aef3c65c972347ed84ccd013ecda4 # v0.2.0
|
||||||
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||||
with:
|
with:
|
||||||
node-version: "24"
|
node-version: "24"
|
||||||
- run: |
|
- run: |
|
||||||
@@ -111,15 +111,25 @@ jobs:
|
|||||||
expected-version: "0.3.5"
|
expected-version: "0.3.5"
|
||||||
- version-input: ">=0.4.25,<0.5"
|
- version-input: ">=0.4.25,<0.5"
|
||||||
expected-version: "0.4.30"
|
expected-version: "0.4.30"
|
||||||
|
- version-input: ">=0.4.25,<0.5"
|
||||||
|
expected-version: "0.4.25"
|
||||||
|
resolution-strategy: "lowest"
|
||||||
|
- version-input: ">=0.1,<0.2"
|
||||||
|
expected-version: "0.1.45"
|
||||||
|
resolution-strategy: "highest"
|
||||||
|
- version-input: ">=0.1.0,<0.2"
|
||||||
|
expected-version: "0.1.0"
|
||||||
|
resolution-strategy: "lowest"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Install version ${{ matrix.input.version-input }}
|
- name: Install version ${{ matrix.input.version-input }} with strategy ${{ matrix.input.resolution-strategy || 'highest' }}
|
||||||
id: setup-uv
|
id: setup-uv
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
version: ${{ matrix.input.version-input }}
|
version: ${{ matrix.input.version-input }}
|
||||||
|
resolution-strategy: ${{ matrix.input.resolution-strategy || 'highest' }}
|
||||||
- name: Correct version gets installed
|
- name: Correct version gets installed
|
||||||
run: |
|
run: |
|
||||||
if [ "$(uv --version)" != "uv ${{ matrix.input.expected-version }}" ]; then
|
if [ "$(uv --version)" != "uv ${{ matrix.input.expected-version }}" ]; then
|
||||||
|
|||||||
2
.github/workflows/update-known-versions.yml
vendored
2
.github/workflows/update-known-versions.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: true
|
persist-credentials: true
|
||||||
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||||
with:
|
with:
|
||||||
node-version: "20"
|
node-version: "20"
|
||||||
- name: Update known versions
|
- name: Update known versions
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -100,3 +100,6 @@ lib/**/*
|
|||||||
|
|
||||||
# Idea IDEs (PyCharm, WebStorm, IntelliJ, etc)
|
# Idea IDEs (PyCharm, WebStorm, IntelliJ, etc)
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
# Compiled scripts
|
||||||
|
.github/scripts/*.js
|
||||||
|
|||||||
544
README.md
544
README.md
@@ -12,28 +12,11 @@ Set up your GitHub Actions workflow with a specific version of [uv](https://docs
|
|||||||
|
|
||||||
- [Usage](#usage)
|
- [Usage](#usage)
|
||||||
- [Install a required-version or latest (default)](#install-a-required-version-or-latest-default)
|
- [Install a required-version or latest (default)](#install-a-required-version-or-latest-default)
|
||||||
- [Install the latest version](#install-the-latest-version)
|
- [Inputs](#inputs)
|
||||||
- [Install a specific version](#install-a-specific-version)
|
- [Outputs](#outputs)
|
||||||
- [Install a version by supplying a semver range or pep440 specifier](#install-a-version-by-supplying-a-semver-range-or-pep440-specifier)
|
|
||||||
- [Install a version defined in a requirements or config file](#install-a-version-defined-in-a-requirements-or-config-file)
|
|
||||||
- [Python version](#python-version)
|
- [Python version](#python-version)
|
||||||
- [Activate environment](#activate-environment)
|
|
||||||
- [Working directory](#working-directory)
|
- [Working directory](#working-directory)
|
||||||
- [Validate checksum](#validate-checksum)
|
- [Advanced Configuration](#advanced-configuration)
|
||||||
- [Enable Caching](#enable-caching)
|
|
||||||
- [Cache dependency glob](#cache-dependency-glob)
|
|
||||||
- [Restore cache](#restore-cache)
|
|
||||||
- [Save cache](#save-cache)
|
|
||||||
- [Local cache path](#local-cache-path)
|
|
||||||
- [Disable cache pruning](#disable-cache-pruning)
|
|
||||||
- [Cache Python installs](#cache-python-installs)
|
|
||||||
- [Ignore nothing to cache](#ignore-nothing-to-cache)
|
|
||||||
- [GitHub authentication token](#github-authentication-token)
|
|
||||||
- [UV_TOOL_DIR](#uv_tool_dir)
|
|
||||||
- [UV_TOOL_BIN_DIR](#uv_tool_bin_dir)
|
|
||||||
- [Tilde Expansion](#tilde-expansion)
|
|
||||||
- [Manifest file](#manifest-file)
|
|
||||||
- [Add problem matchers](#add-problem-matchers)
|
|
||||||
- [How it works](#how-it-works)
|
- [How it works](#how-it-works)
|
||||||
- [FAQ](#faq)
|
- [FAQ](#faq)
|
||||||
|
|
||||||
@@ -52,65 +35,96 @@ in a `uv.toml` or `pyproject.toml` file in the repository root. If none is found
|
|||||||
For an example workflow, see
|
For an example workflow, see
|
||||||
[here](https://github.com/charliermarsh/autobot/blob/e42c66659bf97b90ca9ff305a19cc99952d0d43f/.github/workflows/ci.yaml).
|
[here](https://github.com/charliermarsh/autobot/blob/e42c66659bf97b90ca9ff305a19cc99952d0d43f/.github/workflows/ci.yaml).
|
||||||
|
|
||||||
### Install the latest version
|
### Inputs
|
||||||
|
|
||||||
|
All inputs and their defaults.
|
||||||
|
Have a look under [Advanced Configuration](#advanced-configuration) for detailed documentation on most of them.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Install the latest version of uv
|
- name: Install uv with all available options
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v6
|
||||||
with:
|
with:
|
||||||
version: "latest"
|
# The version of uv to install (default: searches for version in config files, then latest)
|
||||||
|
version: ""
|
||||||
|
|
||||||
|
# Path to a file containing the version of uv to install (default: searches uv.toml then pyproject.toml)
|
||||||
|
version-file: ""
|
||||||
|
|
||||||
|
# Resolution strategy when resolving version ranges: 'highest' or 'lowest'
|
||||||
|
resolution-strategy: "highest"
|
||||||
|
|
||||||
|
# The version of Python to set UV_PYTHON to
|
||||||
|
python-version: ""
|
||||||
|
|
||||||
|
# Use uv venv to activate a venv ready to be used by later steps
|
||||||
|
activate-environment: "false"
|
||||||
|
|
||||||
|
# The directory to execute all commands in and look for files such as pyproject.toml
|
||||||
|
working-directory: ""
|
||||||
|
|
||||||
|
# The checksum of the uv version to install
|
||||||
|
checksum: ""
|
||||||
|
|
||||||
|
# Used to increase the rate limit when retrieving versions and downloading uv
|
||||||
|
github-token: ${{ github.token }}
|
||||||
|
|
||||||
|
# Enable uploading of the uv cache: true, false, or auto (enabled on GitHub-hosted runners, disabled on self-hosted runners)
|
||||||
|
enable-cache: "auto"
|
||||||
|
|
||||||
|
# Glob pattern to match files relative to the repository root to control the cache
|
||||||
|
cache-dependency-glob: |
|
||||||
|
**/*requirements*.txt
|
||||||
|
**/*requirements*.in
|
||||||
|
**/*constraints*.txt
|
||||||
|
**/*constraints*.in
|
||||||
|
**/pyproject.toml
|
||||||
|
**/uv.lock
|
||||||
|
**/*.py.lock
|
||||||
|
|
||||||
|
# Whether to restore the cache if found
|
||||||
|
restore-cache: "true"
|
||||||
|
|
||||||
|
# Whether to save the cache after the run
|
||||||
|
save-cache: "true"
|
||||||
|
|
||||||
|
# Suffix for the cache key
|
||||||
|
cache-suffix: ""
|
||||||
|
|
||||||
|
# Local path to store the cache (default: "" - uses system temp directory)
|
||||||
|
cache-local-path: ""
|
||||||
|
|
||||||
|
# Prune cache before saving
|
||||||
|
prune-cache: "true"
|
||||||
|
|
||||||
|
# Upload managed Python installations to the GitHub Actions cache
|
||||||
|
cache-python: "false"
|
||||||
|
|
||||||
|
# Ignore when nothing is found to cache
|
||||||
|
ignore-nothing-to-cache: "false"
|
||||||
|
|
||||||
|
# Ignore when the working directory is empty
|
||||||
|
ignore-empty-workdir: "false"
|
||||||
|
|
||||||
|
# Custom path to set UV_TOOL_DIR to
|
||||||
|
tool-dir: ""
|
||||||
|
|
||||||
|
# Custom path to set UV_TOOL_BIN_DIR to
|
||||||
|
tool-bin-dir: ""
|
||||||
|
|
||||||
|
# URL to the manifest file containing available versions and download URLs
|
||||||
|
manifest-file: ""
|
||||||
|
|
||||||
|
# Add problem matchers
|
||||||
|
add-problem-matchers: "true"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install a specific version
|
### Outputs
|
||||||
|
|
||||||
```yaml
|
- `uv-version`: The installed uv version. Useful when using latest.
|
||||||
- name: Install a specific version of uv
|
- `uv-path`: The path to the installed uv binary.
|
||||||
uses: astral-sh/setup-uv@v6
|
- `uvx-path`: The path to the installed uvx binary.
|
||||||
with:
|
- `cache-hit`: A boolean value to indicate a cache entry was found.
|
||||||
version: "0.4.4"
|
- `venv`: Path to the activated venv if activate-environment is true.
|
||||||
```
|
|
||||||
|
|
||||||
### Install a version by supplying a semver range or pep440 specifier
|
|
||||||
|
|
||||||
You can specify a [semver range](https://github.com/npm/node-semver?tab=readme-ov-file#ranges)
|
|
||||||
or [pep440 specifier](https://peps.python.org/pep-0440/#version-specifiers)
|
|
||||||
to install the latest version that satisfies the range.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install a semver range of uv
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
version: ">=0.4.0"
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Pinning a minor version of uv
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
version: "0.4.x"
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install a pep440-specifier-satisfying version of uv
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
version: ">=0.4.25,<0.5"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Install a version defined in a requirements or config file
|
|
||||||
|
|
||||||
You can use the `version-file` input to specify a file that contains the version of uv to install.
|
|
||||||
This can either be a `pyproject.toml` or `uv.toml` file which defines a `required-version` or
|
|
||||||
uv defined as a dependency in `pyproject.toml` or `requirements.txt`.
|
|
||||||
|
|
||||||
[asdf](https://asdf-vm.com/) `.tool-versions` is also supported, but without the `ref` syntax.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install uv based on the version defined in pyproject.toml
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
version-file: "pyproject.toml"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Python version
|
### Python version
|
||||||
|
|
||||||
@@ -145,29 +159,6 @@ jobs:
|
|||||||
run: uv run --frozen pytest
|
run: uv run --frozen pytest
|
||||||
```
|
```
|
||||||
|
|
||||||
### Activate environment
|
|
||||||
|
|
||||||
You can set `activate-environment` to `true` to automatically activate a venv.
|
|
||||||
This allows directly using it in later steps:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install the latest version of uv and activate the environment
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
activate-environment: true
|
|
||||||
- run: uv pip install pip
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!WARNING]
|
|
||||||
>
|
|
||||||
> Activating the environment adds your dependencies to the `PATH`, which could break some workflows.
|
|
||||||
> For example, if you have a dependency which requires uv, e.g., `hatch`, activating the
|
|
||||||
> environment will shadow the `uv` binary installed by this action and may result in a different uv
|
|
||||||
> version being used.
|
|
||||||
>
|
|
||||||
> We do not recommend using this setting for most use-cases. Instead, use `uv run` to execute
|
|
||||||
> commands in the environment.
|
|
||||||
|
|
||||||
### Working directory
|
### Working directory
|
||||||
|
|
||||||
You can set the working directory with the `working-directory` input.
|
You can set the working directory with the `working-directory` input.
|
||||||
@@ -183,346 +174,14 @@ It also controls where [the venv gets created](#activate-environment).
|
|||||||
working-directory: my/subproject/dir
|
working-directory: my/subproject/dir
|
||||||
```
|
```
|
||||||
|
|
||||||
### Validate checksum
|
## Advanced Configuration
|
||||||
|
|
||||||
You can specify a checksum to validate the downloaded executable. Checksums up to the default version
|
For more advanced configuration options, see our detailed documentation:
|
||||||
are automatically verified by this action. The sha256 hashes can be found on the
|
|
||||||
[releases page](https://github.com/astral-sh/uv/releases) of the uv repo.
|
|
||||||
|
|
||||||
```yaml
|
- **[Advanced Version Configuration](docs/advanced-version-configuration.md)** - Resolution strategies and version files
|
||||||
- name: Install a specific version and validate the checksum
|
- **[Caching](docs/caching.md)** - Complete guide to caching configuration
|
||||||
uses: astral-sh/setup-uv@v6
|
- **[Environment and Tools](docs/environment-and-tools.md)** - Environment activation, tool directories, authentication, and environment variables
|
||||||
with:
|
- **[Customization](docs/customization.md)** - Checksum validation, custom manifests, and problem matchers
|
||||||
version: "0.3.1"
|
|
||||||
checksum: "e11b01402ab645392c7ad6044db63d37e4fd1e745e015306993b07695ea5f9f8"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enable caching
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> The cache is pruned before it is uploaded to the GitHub Actions cache. This can lead to
|
|
||||||
> a small or empty cache. See [Disable cache pruning](#disable-cache-pruning) for more details.
|
|
||||||
|
|
||||||
If you enable caching, the [uv cache](https://docs.astral.sh/uv/concepts/cache/) will be uploaded to
|
|
||||||
the GitHub Actions cache. This can speed up runs that reuse the cache by several minutes.
|
|
||||||
Caching is enabled by default on GitHub-hosted runners.
|
|
||||||
|
|
||||||
> [!TIP]
|
|
||||||
>
|
|
||||||
> On self-hosted runners this is usually not needed since the cache generated by uv on the runner's
|
|
||||||
> filesystem is not removed after a run. For more details see [Local cache path](#local-cache-path).
|
|
||||||
|
|
||||||
You can optionally define a custom cache key suffix.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Enable caching and define a custom cache key suffix
|
|
||||||
id: setup-uv
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
cache-suffix: "optional-suffix"
|
|
||||||
```
|
|
||||||
|
|
||||||
When the cache was successfully restored, the output `cache-hit` will be set to `true` and you can
|
|
||||||
use it in subsequent steps. For example, to use the cache in the above case:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Do something if the cache was restored
|
|
||||||
if: steps.setup-uv.outputs.cache-hit == 'true'
|
|
||||||
run: echo "Cache was restored"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Cache dependency glob
|
|
||||||
|
|
||||||
If you want to control when the GitHub Actions cache is invalidated, specify a glob pattern with the
|
|
||||||
`cache-dependency-glob` input. The GitHub Actions cache will be invalidated if any file matching the glob pattern
|
|
||||||
changes. If you use relative paths, they are relative to the repository root.
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
>
|
|
||||||
> You can look up supported patterns [here](https://github.com/actions/toolkit/tree/main/packages/glob#patterns)
|
|
||||||
>
|
|
||||||
> The default is
|
|
||||||
> ```yaml
|
|
||||||
> cache-dependency-glob: |
|
|
||||||
> **/*requirements*.txt
|
|
||||||
> **/*requirements*.in
|
|
||||||
> **/*constraints*.txt
|
|
||||||
> **/*constraints*.in
|
|
||||||
> **/pyproject.toml
|
|
||||||
> **/uv.lock
|
|
||||||
> **/*.py.lock
|
|
||||||
> ```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Define a cache dependency glob
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: "**/pyproject.toml"
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Define a list of cache dependency globs
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: |
|
|
||||||
**/requirements*.txt
|
|
||||||
**/pyproject.toml
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Define an absolute cache dependency glob
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: "/tmp/my-folder/requirements*.txt"
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Never invalidate the cache
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: ""
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Restore cache
|
|
||||||
|
|
||||||
Restoring an existing cache can be enabled or disabled with the `restore-cache` input.
|
|
||||||
By default, the cache will be restored.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Don't restore an existing cache
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
restore-cache: false
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Save cache
|
|
||||||
|
|
||||||
You can also disable saving the cache after the run with the `save-cache` input.
|
|
||||||
This can be useful to save cache storage when you know you will not use the cache of the run again.
|
|
||||||
By default, the cache will be saved.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Don't save the cache after the run
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
save-cache: false
|
|
||||||
```
|
|
||||||
|
|
||||||
### Local cache path
|
|
||||||
|
|
||||||
If caching is enabled, this action controls where uv stores its cache on the runner's filesystem
|
|
||||||
by setting `UV_CACHE_DIR`.
|
|
||||||
|
|
||||||
It defaults to `setup-uv-cache` in the `TMP` dir, `D:\a\_temp\uv-tool-dir` on Windows and
|
|
||||||
`/tmp/setup-uv-cache` on Linux/macOS. You can change the default by specifying the path with the
|
|
||||||
`cache-local-path` input.
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> If the environment variable `UV_CACHE_DIR` is already set this action will not override it.
|
|
||||||
> If you configured [cache-dir](https://docs.astral.sh/uv/reference/settings/#cache-dir) in your
|
|
||||||
> config file then it is also respected and this action will not set `UV_CACHE_DIR`.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Define a custom uv cache path
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
cache-local-path: "/path/to/cache"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Disable cache pruning
|
|
||||||
|
|
||||||
By default, the uv cache is pruned after every run, removing pre-built wheels, but retaining any
|
|
||||||
wheels that were built from source. On GitHub-hosted runners, it's typically faster to omit those
|
|
||||||
pre-built wheels from the cache (and instead re-download them from the registry on each run).
|
|
||||||
However, on self-hosted or local runners, preserving the cache may be more efficient. See
|
|
||||||
the [documentation](https://docs.astral.sh/uv/concepts/cache/#caching-in-continuous-integration) for
|
|
||||||
more information.
|
|
||||||
|
|
||||||
If you want to persist the entire cache across runs, disable cache pruning with the `prune-cache`
|
|
||||||
input.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Don't prune the cache before saving it
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
prune-cache: false
|
|
||||||
```
|
|
||||||
|
|
||||||
### Cache Python installs
|
|
||||||
|
|
||||||
By default, the Python install dir (`uv python dir` / `UV_PYTHON_INSTALL_DIR`) is not cached,
|
|
||||||
for the same reason that the dependency cache is pruned.
|
|
||||||
If you want to cache Python installs along with your dependencies, set the `cache-python` input to `true`.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Cache Python installs
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
cache-python: true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ignore nothing to cache
|
|
||||||
|
|
||||||
By default, the action will fail if caching is enabled but there is nothing to upload (the uv cache directory does not exist).
|
|
||||||
If you want to ignore this, set the `ignore-nothing-to-cache` input to `true`.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Ignore nothing to cache
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
enable-cache: true
|
|
||||||
ignore-nothing-to-cache: true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ignore empty workdir
|
|
||||||
|
|
||||||
By default, the action will warn if the workdir is empty, because this is usually the case when
|
|
||||||
`actions/checkout` is configured to run after `setup-uv`, which is not supported.
|
|
||||||
|
|
||||||
If you want to ignore this, set the `ignore-empty-workdir` input to `true`.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Ignore empty workdir
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
ignore-empty-workdir: true
|
|
||||||
```
|
|
||||||
|
|
||||||
### GitHub authentication token
|
|
||||||
|
|
||||||
This action uses the GitHub API to fetch the uv release artifacts. To avoid hitting the GitHub API
|
|
||||||
rate limit too quickly, an authentication token can be provided via the `github-token` input. By
|
|
||||||
default, the `GITHUB_TOKEN` secret is used, which is automatically provided by GitHub Actions.
|
|
||||||
|
|
||||||
If the default
|
|
||||||
[permissions for the GitHub token](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
|
|
||||||
are not sufficient, you can provide a custom GitHub token with the necessary permissions.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install the latest version of uv with a custom GitHub token
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
|
|
||||||
```
|
|
||||||
|
|
||||||
### UV_TOOL_DIR
|
|
||||||
|
|
||||||
On Windows `UV_TOOL_DIR` is set to `uv-tool-dir` in the `TMP` dir (e.g. `D:\a\_temp\uv-tool-dir`).
|
|
||||||
On GitHub hosted runners this is on the much faster `D:` drive.
|
|
||||||
|
|
||||||
On all other platforms the tool environments are placed in the
|
|
||||||
[default location](https://docs.astral.sh/uv/concepts/tools/#tools-directory).
|
|
||||||
|
|
||||||
If you want to change this behaviour (especially on self-hosted runners) you can use the `tool-dir`
|
|
||||||
input:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install the latest version of uv with a custom tool dir
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
tool-dir: "/path/to/tool/dir"
|
|
||||||
```
|
|
||||||
|
|
||||||
### UV_TOOL_BIN_DIR
|
|
||||||
|
|
||||||
On Windows `UV_TOOL_BIN_DIR` is set to `uv-tool-bin-dir` in the `TMP` dir (e.g.
|
|
||||||
`D:\a\_temp\uv-tool-bin-dir`). On GitHub hosted runners this is on the much faster `D:` drive. This
|
|
||||||
path is also automatically added to the PATH.
|
|
||||||
|
|
||||||
On all other platforms the tool binaries get installed to the
|
|
||||||
[default location](https://docs.astral.sh/uv/concepts/tools/#the-bin-directory).
|
|
||||||
|
|
||||||
If you want to change this behaviour (especially on self-hosted runners) you can use the
|
|
||||||
`tool-bin-dir` input:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install the latest version of uv with a custom tool bin dir
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
tool-bin-dir: "/path/to/tool-bin/dir"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tilde Expansion
|
|
||||||
|
|
||||||
This action supports expanding the `~` character to the user's home directory for the following inputs:
|
|
||||||
|
|
||||||
- `version-file`
|
|
||||||
- `cache-local-path`
|
|
||||||
- `tool-dir`
|
|
||||||
- `tool-bin-dir`
|
|
||||||
- `cache-dependency-glob`
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Expand the tilde character
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
cache-local-path: "~/path/to/cache"
|
|
||||||
tool-dir: "~/path/to/tool/dir"
|
|
||||||
tool-bin-dir: "~/path/to/tool-bin/dir"
|
|
||||||
cache-dependency-glob: "~/my-cache-buster"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manifest file
|
|
||||||
|
|
||||||
The `manifest-file` input allows you to specify a JSON manifest that lists available uv versions,
|
|
||||||
architectures, and their download URLs. By default, this action uses the manifest file contained
|
|
||||||
in this repository, which is automatically updated with each release of uv.
|
|
||||||
|
|
||||||
The manifest file contains an array of objects, each describing a version,
|
|
||||||
architecture, platform, and the corresponding download URL. For example:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"version": "0.7.13",
|
|
||||||
"artifactName": "uv-aarch64-apple-darwin.tar.gz",
|
|
||||||
"arch": "aarch64",
|
|
||||||
"platform": "apple-darwin",
|
|
||||||
"downloadUrl": "https://github.com/astral-sh/uv/releases/download/0.7.13/uv-aarch64-apple-darwin.tar.gz"
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
You can supply a custom manifest file URL to define additional versions,
|
|
||||||
architectures, or different download URLs.
|
|
||||||
This is useful if you maintain your own uv builds or want to override the default sources.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Use a custom manifest file
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
manifest-file: "https://example.com/my-custom-manifest.json"
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> When you use a custom manifest file and do not set the `version` input, its default value is `latest`.
|
|
||||||
> This means the action will install the latest version available in the custom manifest file.
|
|
||||||
> This is different from the default behavior of installing the latest version from the official uv releases.
|
|
||||||
|
|
||||||
### Add problem matchers
|
|
||||||
|
|
||||||
This action automatically adds
|
|
||||||
[problem matchers](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md)
|
|
||||||
for python errors.
|
|
||||||
|
|
||||||
You can disable this by setting the `add-problem-matchers` input to `false`.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install the latest version of uv without problem matchers
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
with:
|
|
||||||
add-problem-matchers: false
|
|
||||||
```
|
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
@@ -589,14 +248,13 @@ output:
|
|||||||
|
|
||||||
**Yes!**
|
**Yes!**
|
||||||
|
|
||||||
The cache key gets computed by using the [cache-dependency-glob](#cache-dependency-glob).
|
The cache key gets computed by using the cache-dependency-glob (see [Caching documentation](docs/caching.md)).
|
||||||
|
|
||||||
If you
|
If you have jobs which use the same dependency definitions from `requirements.txt` or
|
||||||
have jobs which use the same dependency definitions from `requirements.txt` or
|
|
||||||
`pyproject.toml` but different
|
`pyproject.toml` but different
|
||||||
[resolution strategies](https://docs.astral.sh/uv/concepts/resolution/#resolution-strategy),
|
[resolution strategies](https://docs.astral.sh/uv/concepts/resolution/#resolution-strategy),
|
||||||
each job will have different dependencies or dependency versions.
|
each job will have different dependencies or dependency versions.
|
||||||
But if you do not add the resolution strategy as a [cache-suffix](#enable-caching),
|
But if you do not add the resolution strategy as a cache-suffix (see [Caching documentation](docs/caching.md)),
|
||||||
they will have the same cache key.
|
they will have the same cache key.
|
||||||
|
|
||||||
This means the first job which starts uploading its cache will win and all other job will fail
|
This means the first job which starts uploading its cache will win and all other job will fail
|
||||||
@@ -609,15 +267,15 @@ You might see errors like
|
|||||||
### Why do I see warnings like `No GitHub Actions cache found for key`
|
### Why do I see warnings like `No GitHub Actions cache found for key`
|
||||||
|
|
||||||
When a workflow runs for the first time on a branch and has a new cache key, because the
|
When a workflow runs for the first time on a branch and has a new cache key, because the
|
||||||
[cache-dependency-glob](#cache-dependency-glob) found changed files (changed dependencies),
|
cache-dependency-glob (see [Caching documentation](docs/caching.md)) found changed files (changed dependencies),
|
||||||
the cache will not be found and the warning `No GitHub Actions cache found for key` will be printed.
|
the cache will not be found and the warning `No GitHub Actions cache found for key` will be printed.
|
||||||
|
|
||||||
While this might be irritating at first, it is expected behaviour and the cache will be created
|
While this might be irritating at first, it is expected behaviour and the cache will be created
|
||||||
and reused in later workflows.
|
and reused in later workflows.
|
||||||
|
|
||||||
The reason for the warning is, that we have to way to know if this is the first run of a new
|
The reason for the warning is, that we have to way to know if this is the first run of a new
|
||||||
cache key or the user accidentally misconfigured the [cache-dependency-glob](#cache-dependency-glob)
|
cache key or the user accidentally misconfigured the cache-dependency-glob
|
||||||
or [cache-suffix](#enable-caching) and the cache never gets used.
|
or cache-suffix (see [Caching documentation](docs/caching.md)) and the cache never gets used.
|
||||||
|
|
||||||
### Do I have to run `actions/checkout` before or after `setup-uv`?
|
### Do I have to run `actions/checkout` before or after `setup-uv`?
|
||||||
|
|
||||||
@@ -642,11 +300,11 @@ if an uploaded cache exists for this key.
|
|||||||
If yes (e.g. contents of `uv.lock` did not change since last run) the dependencies in the cache
|
If yes (e.g. contents of `uv.lock` did not change since last run) the dependencies in the cache
|
||||||
are up to date and the cache will be downloaded and used.
|
are up to date and the cache will be downloaded and used.
|
||||||
|
|
||||||
Details on determining which files will lead to different caches can be read under
|
Details on determining which files will lead to different caches can be read in the
|
||||||
[cache-dependency-glob](#cache-dependency-glob)
|
[Caching documentation](docs/caching.md).
|
||||||
|
|
||||||
Some dependencies will never be uploaded to the cache and will be downloaded again on each run
|
Some dependencies will never be uploaded to the cache and will be downloaded again on each run
|
||||||
as described in [disable-cache-pruning](#disable-cache-pruning)
|
as described in the [Caching documentation](docs/caching.md).
|
||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ inputs:
|
|||||||
add-problem-matchers:
|
add-problem-matchers:
|
||||||
description: "Add problem matchers."
|
description: "Add problem matchers."
|
||||||
default: "true"
|
default: "true"
|
||||||
|
resolution-strategy:
|
||||||
|
description: "Resolution strategy to use when resolving version ranges. 'highest' uses the latest compatible version, 'lowest' uses the oldest compatible version."
|
||||||
|
default: "highest"
|
||||||
outputs:
|
outputs:
|
||||||
uv-version:
|
uv-version:
|
||||||
description: "The installed uv version. Useful when using latest."
|
description: "The installed uv version. Useful when using latest."
|
||||||
|
|||||||
63
dist/save-cache/index.js
generated
vendored
63
dist/save-cache/index.js
generated
vendored
@@ -39,7 +39,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.saveCache = exports.restoreCache = exports.isFeatureAvailable = exports.ReserveCacheError = exports.ValidationError = void 0;
|
exports.saveCache = exports.restoreCache = exports.isFeatureAvailable = exports.FinalizeCacheError = exports.ReserveCacheError = exports.ValidationError = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(7484));
|
const core = __importStar(__nccwpck_require__(7484));
|
||||||
const path = __importStar(__nccwpck_require__(6928));
|
const path = __importStar(__nccwpck_require__(6928));
|
||||||
const utils = __importStar(__nccwpck_require__(8299));
|
const utils = __importStar(__nccwpck_require__(8299));
|
||||||
@@ -47,7 +47,6 @@ const cacheHttpClient = __importStar(__nccwpck_require__(3171));
|
|||||||
const cacheTwirpClient = __importStar(__nccwpck_require__(6819));
|
const cacheTwirpClient = __importStar(__nccwpck_require__(6819));
|
||||||
const config_1 = __nccwpck_require__(7606);
|
const config_1 = __nccwpck_require__(7606);
|
||||||
const tar_1 = __nccwpck_require__(5321);
|
const tar_1 = __nccwpck_require__(5321);
|
||||||
const constants_1 = __nccwpck_require__(8287);
|
|
||||||
const http_client_1 = __nccwpck_require__(4844);
|
const http_client_1 = __nccwpck_require__(4844);
|
||||||
class ValidationError extends Error {
|
class ValidationError extends Error {
|
||||||
constructor(message) {
|
constructor(message) {
|
||||||
@@ -65,6 +64,14 @@ class ReserveCacheError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.ReserveCacheError = ReserveCacheError;
|
exports.ReserveCacheError = ReserveCacheError;
|
||||||
|
class FinalizeCacheError extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message);
|
||||||
|
this.name = 'FinalizeCacheError';
|
||||||
|
Object.setPrototypeOf(this, FinalizeCacheError.prototype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.FinalizeCacheError = FinalizeCacheError;
|
||||||
function checkPaths(paths) {
|
function checkPaths(paths) {
|
||||||
if (!paths || paths.length === 0) {
|
if (!paths || paths.length === 0) {
|
||||||
throw new ValidationError(`Path Validation Error: At least one directory or file path is required`);
|
throw new ValidationError(`Path Validation Error: At least one directory or file path is required`);
|
||||||
@@ -441,10 +448,6 @@ function saveCacheV2(paths, key, options, enableCrossOsArchive = false) {
|
|||||||
}
|
}
|
||||||
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath);
|
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath);
|
||||||
core.debug(`File Size: ${archiveFileSize}`);
|
core.debug(`File Size: ${archiveFileSize}`);
|
||||||
// For GHES, this check will take place in ReserveCache API with enterprise file size limit
|
|
||||||
if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) {
|
|
||||||
throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`);
|
|
||||||
}
|
|
||||||
// Set the archive size in the options, will be used to display the upload progress
|
// Set the archive size in the options, will be used to display the upload progress
|
||||||
options.archiveSizeBytes = archiveFileSize;
|
options.archiveSizeBytes = archiveFileSize;
|
||||||
core.debug('Reserving Cache');
|
core.debug('Reserving Cache');
|
||||||
@@ -457,7 +460,10 @@ function saveCacheV2(paths, key, options, enableCrossOsArchive = false) {
|
|||||||
try {
|
try {
|
||||||
const response = yield twirpClient.CreateCacheEntry(request);
|
const response = yield twirpClient.CreateCacheEntry(request);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Response was not ok');
|
if (response.message) {
|
||||||
|
core.warning(`Cache reservation failed: ${response.message}`);
|
||||||
|
}
|
||||||
|
throw new Error(response.message || 'Response was not ok');
|
||||||
}
|
}
|
||||||
signedUploadUrl = response.signedUploadUrl;
|
signedUploadUrl = response.signedUploadUrl;
|
||||||
}
|
}
|
||||||
@@ -475,6 +481,9 @@ function saveCacheV2(paths, key, options, enableCrossOsArchive = false) {
|
|||||||
const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest);
|
const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest);
|
||||||
core.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`);
|
core.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`);
|
||||||
if (!finalizeResponse.ok) {
|
if (!finalizeResponse.ok) {
|
||||||
|
if (finalizeResponse.message) {
|
||||||
|
throw new FinalizeCacheError(finalizeResponse.message);
|
||||||
|
}
|
||||||
throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`);
|
throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`);
|
||||||
}
|
}
|
||||||
cacheId = parseInt(finalizeResponse.entryId);
|
cacheId = parseInt(finalizeResponse.entryId);
|
||||||
@@ -487,6 +496,9 @@ function saveCacheV2(paths, key, options, enableCrossOsArchive = false) {
|
|||||||
else if (typedError.name === ReserveCacheError.name) {
|
else if (typedError.name === ReserveCacheError.name) {
|
||||||
core.info(`Failed to save: ${typedError.message}`);
|
core.info(`Failed to save: ${typedError.message}`);
|
||||||
}
|
}
|
||||||
|
else if (typedError.name === FinalizeCacheError.name) {
|
||||||
|
core.warning(typedError.message);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// Log server errors (5xx) as errors, all other errors as warnings
|
// Log server errors (5xx) as errors, all other errors as warnings
|
||||||
if (typedError instanceof http_client_1.HttpClientError &&
|
if (typedError instanceof http_client_1.HttpClientError &&
|
||||||
@@ -598,11 +610,12 @@ class CreateCacheEntryResponse$Type extends runtime_5.MessageType {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super("github.actions.results.api.v1.CreateCacheEntryResponse", [
|
super("github.actions.results.api.v1.CreateCacheEntryResponse", [
|
||||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||||
{ no: 2, name: "signed_upload_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
{ no: 2, name: "signed_upload_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||||
|
{ no: 3, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
create(value) {
|
create(value) {
|
||||||
const message = { ok: false, signedUploadUrl: "" };
|
const message = { ok: false, signedUploadUrl: "", message: "" };
|
||||||
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
||||||
if (value !== undefined)
|
if (value !== undefined)
|
||||||
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
||||||
@@ -619,6 +632,9 @@ class CreateCacheEntryResponse$Type extends runtime_5.MessageType {
|
|||||||
case /* string signed_upload_url */ 2:
|
case /* string signed_upload_url */ 2:
|
||||||
message.signedUploadUrl = reader.string();
|
message.signedUploadUrl = reader.string();
|
||||||
break;
|
break;
|
||||||
|
case /* string message */ 3:
|
||||||
|
message.message = reader.string();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
let u = options.readUnknownField;
|
let u = options.readUnknownField;
|
||||||
if (u === "throw")
|
if (u === "throw")
|
||||||
@@ -637,6 +653,9 @@ class CreateCacheEntryResponse$Type extends runtime_5.MessageType {
|
|||||||
/* string signed_upload_url = 2; */
|
/* string signed_upload_url = 2; */
|
||||||
if (message.signedUploadUrl !== "")
|
if (message.signedUploadUrl !== "")
|
||||||
writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl);
|
writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl);
|
||||||
|
/* string message = 3; */
|
||||||
|
if (message.message !== "")
|
||||||
|
writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message);
|
||||||
let u = options.writeUnknownFields;
|
let u = options.writeUnknownFields;
|
||||||
if (u !== false)
|
if (u !== false)
|
||||||
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||||
@@ -720,11 +739,12 @@ class FinalizeCacheEntryUploadResponse$Type extends runtime_5.MessageType {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super("github.actions.results.api.v1.FinalizeCacheEntryUploadResponse", [
|
super("github.actions.results.api.v1.FinalizeCacheEntryUploadResponse", [
|
||||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||||
{ no: 2, name: "entry_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ }
|
{ no: 2, name: "entry_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ },
|
||||||
|
{ no: 3, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
create(value) {
|
create(value) {
|
||||||
const message = { ok: false, entryId: "0" };
|
const message = { ok: false, entryId: "0", message: "" };
|
||||||
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
||||||
if (value !== undefined)
|
if (value !== undefined)
|
||||||
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
||||||
@@ -741,6 +761,9 @@ class FinalizeCacheEntryUploadResponse$Type extends runtime_5.MessageType {
|
|||||||
case /* int64 entry_id */ 2:
|
case /* int64 entry_id */ 2:
|
||||||
message.entryId = reader.int64().toString();
|
message.entryId = reader.int64().toString();
|
||||||
break;
|
break;
|
||||||
|
case /* string message */ 3:
|
||||||
|
message.message = reader.string();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
let u = options.readUnknownField;
|
let u = options.readUnknownField;
|
||||||
if (u === "throw")
|
if (u === "throw")
|
||||||
@@ -759,6 +782,9 @@ class FinalizeCacheEntryUploadResponse$Type extends runtime_5.MessageType {
|
|||||||
/* int64 entry_id = 2; */
|
/* int64 entry_id = 2; */
|
||||||
if (message.entryId !== "0")
|
if (message.entryId !== "0")
|
||||||
writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId);
|
writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId);
|
||||||
|
/* string message = 3; */
|
||||||
|
if (message.message !== "")
|
||||||
|
writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message);
|
||||||
let u = options.writeUnknownFields;
|
let u = options.writeUnknownFields;
|
||||||
if (u !== false)
|
if (u !== false)
|
||||||
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||||
@@ -91010,7 +91036,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.addProblemMatchers = exports.manifestFile = exports.githubToken = exports.pythonDir = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.cachePython = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.saveCache = exports.restoreCache = exports.enableCache = exports.checkSum = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = exports.workingDirectory = void 0;
|
exports.resolutionStrategy = exports.addProblemMatchers = exports.manifestFile = exports.githubToken = exports.pythonDir = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.cachePython = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.saveCache = exports.restoreCache = exports.enableCache = exports.checkSum = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = exports.workingDirectory = void 0;
|
||||||
exports.getUvPythonDir = getUvPythonDir;
|
exports.getUvPythonDir = getUvPythonDir;
|
||||||
const node_path_1 = __importDefault(__nccwpck_require__(6760));
|
const node_path_1 = __importDefault(__nccwpck_require__(6760));
|
||||||
const core = __importStar(__nccwpck_require__(7484));
|
const core = __importStar(__nccwpck_require__(7484));
|
||||||
@@ -91037,6 +91063,7 @@ exports.pythonDir = getUvPythonDir();
|
|||||||
exports.githubToken = core.getInput("github-token");
|
exports.githubToken = core.getInput("github-token");
|
||||||
exports.manifestFile = getManifestFile();
|
exports.manifestFile = getManifestFile();
|
||||||
exports.addProblemMatchers = core.getInput("add-problem-matchers") === "true";
|
exports.addProblemMatchers = core.getInput("add-problem-matchers") === "true";
|
||||||
|
exports.resolutionStrategy = getResolutionStrategy();
|
||||||
function getVersionFile() {
|
function getVersionFile() {
|
||||||
const versionFileInput = core.getInput("version-file");
|
const versionFileInput = core.getInput("version-file");
|
||||||
if (versionFileInput !== "") {
|
if (versionFileInput !== "") {
|
||||||
@@ -91173,6 +91200,16 @@ function getManifestFile() {
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
function getResolutionStrategy() {
|
||||||
|
const resolutionStrategyInput = core.getInput("resolution-strategy");
|
||||||
|
if (resolutionStrategyInput === "lowest") {
|
||||||
|
return "lowest";
|
||||||
|
}
|
||||||
|
if (resolutionStrategyInput === "highest" || resolutionStrategyInput === "") {
|
||||||
|
return "highest";
|
||||||
|
}
|
||||||
|
throw new Error(`Invalid resolution-strategy: ${resolutionStrategyInput}. Must be 'highest' or 'lowest'.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -94097,7 +94134,7 @@ var index_default = { parse, stringify, TomlDate, TomlError };
|
|||||||
/***/ ((module) => {
|
/***/ ((module) => {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"4.0.5","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.11.1","@actions/exec":"^1.0.1","@actions/glob":"^0.1.0","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^2.1.1","@actions/io":"^1.0.1","@azure/abort-controller":"^1.1.0","@azure/ms-rest-js":"^2.6.0","@azure/storage-blob":"^12.13.0","semver":"^6.3.1"},"devDependencies":{"@types/node":"^22.13.9","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"}}');
|
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"4.1.0","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.11.1","@actions/exec":"^1.0.1","@actions/glob":"^0.1.0","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^2.1.1","@actions/io":"^1.0.1","@azure/abort-controller":"^1.1.0","@azure/ms-rest-js":"^2.6.0","@azure/storage-blob":"^12.13.0","semver":"^6.3.1"},"devDependencies":{"@types/node":"^22.13.9","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"}}');
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
|
|||||||
105
dist/setup/index.js
generated
vendored
105
dist/setup/index.js
generated
vendored
@@ -39,7 +39,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.saveCache = exports.restoreCache = exports.isFeatureAvailable = exports.ReserveCacheError = exports.ValidationError = void 0;
|
exports.saveCache = exports.restoreCache = exports.isFeatureAvailable = exports.FinalizeCacheError = exports.ReserveCacheError = exports.ValidationError = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(37484));
|
const core = __importStar(__nccwpck_require__(37484));
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
const path = __importStar(__nccwpck_require__(16928));
|
||||||
const utils = __importStar(__nccwpck_require__(98299));
|
const utils = __importStar(__nccwpck_require__(98299));
|
||||||
@@ -47,7 +47,6 @@ const cacheHttpClient = __importStar(__nccwpck_require__(73171));
|
|||||||
const cacheTwirpClient = __importStar(__nccwpck_require__(96819));
|
const cacheTwirpClient = __importStar(__nccwpck_require__(96819));
|
||||||
const config_1 = __nccwpck_require__(17606);
|
const config_1 = __nccwpck_require__(17606);
|
||||||
const tar_1 = __nccwpck_require__(95321);
|
const tar_1 = __nccwpck_require__(95321);
|
||||||
const constants_1 = __nccwpck_require__(58287);
|
|
||||||
const http_client_1 = __nccwpck_require__(54844);
|
const http_client_1 = __nccwpck_require__(54844);
|
||||||
class ValidationError extends Error {
|
class ValidationError extends Error {
|
||||||
constructor(message) {
|
constructor(message) {
|
||||||
@@ -65,6 +64,14 @@ class ReserveCacheError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.ReserveCacheError = ReserveCacheError;
|
exports.ReserveCacheError = ReserveCacheError;
|
||||||
|
class FinalizeCacheError extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message);
|
||||||
|
this.name = 'FinalizeCacheError';
|
||||||
|
Object.setPrototypeOf(this, FinalizeCacheError.prototype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.FinalizeCacheError = FinalizeCacheError;
|
||||||
function checkPaths(paths) {
|
function checkPaths(paths) {
|
||||||
if (!paths || paths.length === 0) {
|
if (!paths || paths.length === 0) {
|
||||||
throw new ValidationError(`Path Validation Error: At least one directory or file path is required`);
|
throw new ValidationError(`Path Validation Error: At least one directory or file path is required`);
|
||||||
@@ -441,10 +448,6 @@ function saveCacheV2(paths, key, options, enableCrossOsArchive = false) {
|
|||||||
}
|
}
|
||||||
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath);
|
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath);
|
||||||
core.debug(`File Size: ${archiveFileSize}`);
|
core.debug(`File Size: ${archiveFileSize}`);
|
||||||
// For GHES, this check will take place in ReserveCache API with enterprise file size limit
|
|
||||||
if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) {
|
|
||||||
throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`);
|
|
||||||
}
|
|
||||||
// Set the archive size in the options, will be used to display the upload progress
|
// Set the archive size in the options, will be used to display the upload progress
|
||||||
options.archiveSizeBytes = archiveFileSize;
|
options.archiveSizeBytes = archiveFileSize;
|
||||||
core.debug('Reserving Cache');
|
core.debug('Reserving Cache');
|
||||||
@@ -457,7 +460,10 @@ function saveCacheV2(paths, key, options, enableCrossOsArchive = false) {
|
|||||||
try {
|
try {
|
||||||
const response = yield twirpClient.CreateCacheEntry(request);
|
const response = yield twirpClient.CreateCacheEntry(request);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Response was not ok');
|
if (response.message) {
|
||||||
|
core.warning(`Cache reservation failed: ${response.message}`);
|
||||||
|
}
|
||||||
|
throw new Error(response.message || 'Response was not ok');
|
||||||
}
|
}
|
||||||
signedUploadUrl = response.signedUploadUrl;
|
signedUploadUrl = response.signedUploadUrl;
|
||||||
}
|
}
|
||||||
@@ -475,6 +481,9 @@ function saveCacheV2(paths, key, options, enableCrossOsArchive = false) {
|
|||||||
const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest);
|
const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest);
|
||||||
core.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`);
|
core.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`);
|
||||||
if (!finalizeResponse.ok) {
|
if (!finalizeResponse.ok) {
|
||||||
|
if (finalizeResponse.message) {
|
||||||
|
throw new FinalizeCacheError(finalizeResponse.message);
|
||||||
|
}
|
||||||
throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`);
|
throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`);
|
||||||
}
|
}
|
||||||
cacheId = parseInt(finalizeResponse.entryId);
|
cacheId = parseInt(finalizeResponse.entryId);
|
||||||
@@ -487,6 +496,9 @@ function saveCacheV2(paths, key, options, enableCrossOsArchive = false) {
|
|||||||
else if (typedError.name === ReserveCacheError.name) {
|
else if (typedError.name === ReserveCacheError.name) {
|
||||||
core.info(`Failed to save: ${typedError.message}`);
|
core.info(`Failed to save: ${typedError.message}`);
|
||||||
}
|
}
|
||||||
|
else if (typedError.name === FinalizeCacheError.name) {
|
||||||
|
core.warning(typedError.message);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// Log server errors (5xx) as errors, all other errors as warnings
|
// Log server errors (5xx) as errors, all other errors as warnings
|
||||||
if (typedError instanceof http_client_1.HttpClientError &&
|
if (typedError instanceof http_client_1.HttpClientError &&
|
||||||
@@ -598,11 +610,12 @@ class CreateCacheEntryResponse$Type extends runtime_5.MessageType {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super("github.actions.results.api.v1.CreateCacheEntryResponse", [
|
super("github.actions.results.api.v1.CreateCacheEntryResponse", [
|
||||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||||
{ no: 2, name: "signed_upload_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
{ no: 2, name: "signed_upload_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||||
|
{ no: 3, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
create(value) {
|
create(value) {
|
||||||
const message = { ok: false, signedUploadUrl: "" };
|
const message = { ok: false, signedUploadUrl: "", message: "" };
|
||||||
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
||||||
if (value !== undefined)
|
if (value !== undefined)
|
||||||
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
||||||
@@ -619,6 +632,9 @@ class CreateCacheEntryResponse$Type extends runtime_5.MessageType {
|
|||||||
case /* string signed_upload_url */ 2:
|
case /* string signed_upload_url */ 2:
|
||||||
message.signedUploadUrl = reader.string();
|
message.signedUploadUrl = reader.string();
|
||||||
break;
|
break;
|
||||||
|
case /* string message */ 3:
|
||||||
|
message.message = reader.string();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
let u = options.readUnknownField;
|
let u = options.readUnknownField;
|
||||||
if (u === "throw")
|
if (u === "throw")
|
||||||
@@ -637,6 +653,9 @@ class CreateCacheEntryResponse$Type extends runtime_5.MessageType {
|
|||||||
/* string signed_upload_url = 2; */
|
/* string signed_upload_url = 2; */
|
||||||
if (message.signedUploadUrl !== "")
|
if (message.signedUploadUrl !== "")
|
||||||
writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl);
|
writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl);
|
||||||
|
/* string message = 3; */
|
||||||
|
if (message.message !== "")
|
||||||
|
writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message);
|
||||||
let u = options.writeUnknownFields;
|
let u = options.writeUnknownFields;
|
||||||
if (u !== false)
|
if (u !== false)
|
||||||
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||||
@@ -720,11 +739,12 @@ class FinalizeCacheEntryUploadResponse$Type extends runtime_5.MessageType {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super("github.actions.results.api.v1.FinalizeCacheEntryUploadResponse", [
|
super("github.actions.results.api.v1.FinalizeCacheEntryUploadResponse", [
|
||||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||||
{ no: 2, name: "entry_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ }
|
{ no: 2, name: "entry_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ },
|
||||||
|
{ no: 3, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
create(value) {
|
create(value) {
|
||||||
const message = { ok: false, entryId: "0" };
|
const message = { ok: false, entryId: "0", message: "" };
|
||||||
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
||||||
if (value !== undefined)
|
if (value !== undefined)
|
||||||
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
||||||
@@ -741,6 +761,9 @@ class FinalizeCacheEntryUploadResponse$Type extends runtime_5.MessageType {
|
|||||||
case /* int64 entry_id */ 2:
|
case /* int64 entry_id */ 2:
|
||||||
message.entryId = reader.int64().toString();
|
message.entryId = reader.int64().toString();
|
||||||
break;
|
break;
|
||||||
|
case /* string message */ 3:
|
||||||
|
message.message = reader.string();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
let u = options.readUnknownField;
|
let u = options.readUnknownField;
|
||||||
if (u === "throw")
|
if (u === "throw")
|
||||||
@@ -759,6 +782,9 @@ class FinalizeCacheEntryUploadResponse$Type extends runtime_5.MessageType {
|
|||||||
/* int64 entry_id = 2; */
|
/* int64 entry_id = 2; */
|
||||||
if (message.entryId !== "0")
|
if (message.entryId !== "0")
|
||||||
writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId);
|
writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId);
|
||||||
|
/* string message = 3; */
|
||||||
|
if (message.message !== "")
|
||||||
|
writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message);
|
||||||
let u = options.writeUnknownFields;
|
let u = options.writeUnknownFields;
|
||||||
if (u !== false)
|
if (u !== false)
|
||||||
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||||
@@ -129114,6 +129140,7 @@ const path = __importStar(__nccwpck_require__(76760));
|
|||||||
const core = __importStar(__nccwpck_require__(37484));
|
const core = __importStar(__nccwpck_require__(37484));
|
||||||
const tc = __importStar(__nccwpck_require__(33472));
|
const tc = __importStar(__nccwpck_require__(33472));
|
||||||
const pep440 = __importStar(__nccwpck_require__(63297));
|
const pep440 = __importStar(__nccwpck_require__(63297));
|
||||||
|
const semver = __importStar(__nccwpck_require__(39318));
|
||||||
const constants_1 = __nccwpck_require__(56156);
|
const constants_1 = __nccwpck_require__(56156);
|
||||||
const octokit_1 = __nccwpck_require__(73352);
|
const octokit_1 = __nccwpck_require__(73352);
|
||||||
const checksum_1 = __nccwpck_require__(17772);
|
const checksum_1 = __nccwpck_require__(17772);
|
||||||
@@ -129165,7 +129192,7 @@ async function downloadVersion(downloadUrl, artifactName, platform, arch, versio
|
|||||||
function getExtension(platform) {
|
function getExtension(platform) {
|
||||||
return platform === "pc-windows-msvc" ? ".zip" : ".tar.gz";
|
return platform === "pc-windows-msvc" ? ".zip" : ".tar.gz";
|
||||||
}
|
}
|
||||||
async function resolveVersion(versionInput, manifestFile, githubToken) {
|
async function resolveVersion(versionInput, manifestFile, githubToken, resolutionStrategy = "highest") {
|
||||||
core.debug(`Resolving version: ${versionInput}`);
|
core.debug(`Resolving version: ${versionInput}`);
|
||||||
let version;
|
let version;
|
||||||
const isSimpleMinimumVersionSpecifier = versionInput.includes(">") && !versionInput.includes(",");
|
const isSimpleMinimumVersionSpecifier = versionInput.includes(">") && !versionInput.includes(",");
|
||||||
@@ -129195,7 +129222,9 @@ async function resolveVersion(versionInput, manifestFile, githubToken) {
|
|||||||
}
|
}
|
||||||
const availableVersions = await getAvailableVersions(githubToken);
|
const availableVersions = await getAvailableVersions(githubToken);
|
||||||
core.debug(`Available versions: ${availableVersions}`);
|
core.debug(`Available versions: ${availableVersions}`);
|
||||||
const resolvedVersion = maxSatisfying(availableVersions, version);
|
const resolvedVersion = resolutionStrategy === "lowest"
|
||||||
|
? minSatisfying(availableVersions, version)
|
||||||
|
: maxSatisfying(availableVersions, version);
|
||||||
if (resolvedVersion === undefined) {
|
if (resolvedVersion === undefined) {
|
||||||
throw new Error(`No version found for ${version}`);
|
throw new Error(`No version found for ${version}`);
|
||||||
}
|
}
|
||||||
@@ -129275,6 +129304,21 @@ function maxSatisfying(versions, version) {
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
function minSatisfying(versions, version) {
|
||||||
|
// For semver, we need to use a different approach since tc.evaluateVersions only returns max
|
||||||
|
// Let's use semver directly for min satisfying
|
||||||
|
const minSemver = semver.minSatisfying(versions, version);
|
||||||
|
if (minSemver !== null) {
|
||||||
|
core.debug(`Found a version that satisfies the semver range: ${minSemver}`);
|
||||||
|
return minSemver;
|
||||||
|
}
|
||||||
|
const minPep440 = pep440.minSatisfying(versions, version);
|
||||||
|
if (minPep440 !== null) {
|
||||||
|
core.debug(`Found a version that satisfies the pep440 specifier: ${minPep440}`);
|
||||||
|
return minPep440;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -129556,7 +129600,8 @@ async function run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function detectEmptyWorkdir() {
|
function detectEmptyWorkdir() {
|
||||||
if (node_fs_1.default.readdirSync(".").length === 0) {
|
const dirToCheck = inputs_1.workingDirectory || ".";
|
||||||
|
if (node_fs_1.default.readdirSync(dirToCheck).length === 0) {
|
||||||
if (inputs_1.ignoreEmptyWorkdir) {
|
if (inputs_1.ignoreEmptyWorkdir) {
|
||||||
core.info("Empty workdir detected. Ignoring because ignore-empty-workdir is enabled");
|
core.info("Empty workdir detected. Ignoring because ignore-empty-workdir is enabled");
|
||||||
}
|
}
|
||||||
@@ -129583,21 +129628,21 @@ async function setupUv(platform, arch, checkSum, githubToken) {
|
|||||||
}
|
}
|
||||||
async function determineVersion(manifestFile) {
|
async function determineVersion(manifestFile) {
|
||||||
if (inputs_1.version !== "") {
|
if (inputs_1.version !== "") {
|
||||||
return await (0, download_version_1.resolveVersion)(inputs_1.version, manifestFile, inputs_1.githubToken);
|
return await (0, download_version_1.resolveVersion)(inputs_1.version, manifestFile, inputs_1.githubToken, inputs_1.resolutionStrategy);
|
||||||
}
|
}
|
||||||
if (inputs_1.versionFile !== "") {
|
if (inputs_1.versionFile !== "") {
|
||||||
const versionFromFile = (0, resolve_1.getUvVersionFromFile)(inputs_1.versionFile);
|
const versionFromFile = (0, resolve_1.getUvVersionFromFile)(inputs_1.versionFile);
|
||||||
if (versionFromFile === undefined) {
|
if (versionFromFile === undefined) {
|
||||||
throw new Error(`Could not determine uv version from file: ${inputs_1.versionFile}`);
|
throw new Error(`Could not determine uv version from file: ${inputs_1.versionFile}`);
|
||||||
}
|
}
|
||||||
return await (0, download_version_1.resolveVersion)(versionFromFile, manifestFile, inputs_1.githubToken);
|
return await (0, download_version_1.resolveVersion)(versionFromFile, manifestFile, inputs_1.githubToken, inputs_1.resolutionStrategy);
|
||||||
}
|
}
|
||||||
const versionFromUvToml = (0, resolve_1.getUvVersionFromFile)(`${inputs_1.workingDirectory}${path.sep}uv.toml`);
|
const versionFromUvToml = (0, resolve_1.getUvVersionFromFile)(`${inputs_1.workingDirectory}${path.sep}uv.toml`);
|
||||||
const versionFromPyproject = (0, resolve_1.getUvVersionFromFile)(`${inputs_1.workingDirectory}${path.sep}pyproject.toml`);
|
const versionFromPyproject = (0, resolve_1.getUvVersionFromFile)(`${inputs_1.workingDirectory}${path.sep}pyproject.toml`);
|
||||||
if (versionFromUvToml === undefined && versionFromPyproject === undefined) {
|
if (versionFromUvToml === undefined && versionFromPyproject === undefined) {
|
||||||
core.info("Could not determine uv version from uv.toml or pyproject.toml. Falling back to latest.");
|
core.info("Could not determine uv version from uv.toml or pyproject.toml. Falling back to latest.");
|
||||||
}
|
}
|
||||||
return await (0, download_version_1.resolveVersion)(versionFromUvToml || versionFromPyproject || "latest", manifestFile, inputs_1.githubToken);
|
return await (0, download_version_1.resolveVersion)(versionFromUvToml || versionFromPyproject || "latest", manifestFile, inputs_1.githubToken, inputs_1.resolutionStrategy);
|
||||||
}
|
}
|
||||||
function addUvToPathAndOutput(cachedPath) {
|
function addUvToPathAndOutput(cachedPath) {
|
||||||
core.setOutput("uv-path", `${cachedPath}${path.sep}uv`);
|
core.setOutput("uv-path", `${cachedPath}${path.sep}uv`);
|
||||||
@@ -129853,7 +129898,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.addProblemMatchers = exports.manifestFile = exports.githubToken = exports.pythonDir = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.cachePython = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.saveCache = exports.restoreCache = exports.enableCache = exports.checkSum = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = exports.workingDirectory = void 0;
|
exports.resolutionStrategy = exports.addProblemMatchers = exports.manifestFile = exports.githubToken = exports.pythonDir = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.cachePython = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.saveCache = exports.restoreCache = exports.enableCache = exports.checkSum = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = exports.workingDirectory = void 0;
|
||||||
exports.getUvPythonDir = getUvPythonDir;
|
exports.getUvPythonDir = getUvPythonDir;
|
||||||
const node_path_1 = __importDefault(__nccwpck_require__(76760));
|
const node_path_1 = __importDefault(__nccwpck_require__(76760));
|
||||||
const core = __importStar(__nccwpck_require__(37484));
|
const core = __importStar(__nccwpck_require__(37484));
|
||||||
@@ -129880,6 +129925,7 @@ exports.pythonDir = getUvPythonDir();
|
|||||||
exports.githubToken = core.getInput("github-token");
|
exports.githubToken = core.getInput("github-token");
|
||||||
exports.manifestFile = getManifestFile();
|
exports.manifestFile = getManifestFile();
|
||||||
exports.addProblemMatchers = core.getInput("add-problem-matchers") === "true";
|
exports.addProblemMatchers = core.getInput("add-problem-matchers") === "true";
|
||||||
|
exports.resolutionStrategy = getResolutionStrategy();
|
||||||
function getVersionFile() {
|
function getVersionFile() {
|
||||||
const versionFileInput = core.getInput("version-file");
|
const versionFileInput = core.getInput("version-file");
|
||||||
if (versionFileInput !== "") {
|
if (versionFileInput !== "") {
|
||||||
@@ -130016,6 +130062,16 @@ function getManifestFile() {
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
function getResolutionStrategy() {
|
||||||
|
const resolutionStrategyInput = core.getInput("resolution-strategy");
|
||||||
|
if (resolutionStrategyInput === "lowest") {
|
||||||
|
return "lowest";
|
||||||
|
}
|
||||||
|
if (resolutionStrategyInput === "highest" || resolutionStrategyInput === "") {
|
||||||
|
return "highest";
|
||||||
|
}
|
||||||
|
throw new Error(`Invalid resolution-strategy: ${resolutionStrategyInput}. Must be 'highest' or 'lowest'.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -134756,9 +134812,11 @@ var paginatingEndpoints = [
|
|||||||
"GET /networks/{owner}/{repo}/events",
|
"GET /networks/{owner}/{repo}/events",
|
||||||
"GET /notifications",
|
"GET /notifications",
|
||||||
"GET /organizations",
|
"GET /organizations",
|
||||||
|
"GET /organizations/{org}/dependabot/repository-access",
|
||||||
"GET /orgs/{org}/actions/cache/usage-by-repository",
|
"GET /orgs/{org}/actions/cache/usage-by-repository",
|
||||||
"GET /orgs/{org}/actions/hosted-runners",
|
"GET /orgs/{org}/actions/hosted-runners",
|
||||||
"GET /orgs/{org}/actions/permissions/repositories",
|
"GET /orgs/{org}/actions/permissions/repositories",
|
||||||
|
"GET /orgs/{org}/actions/permissions/self-hosted-runners/repositories",
|
||||||
"GET /orgs/{org}/actions/runner-groups",
|
"GET /orgs/{org}/actions/runner-groups",
|
||||||
"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/hosted-runners",
|
"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/hosted-runners",
|
||||||
"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories",
|
"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories",
|
||||||
@@ -134808,6 +134866,9 @@ var paginatingEndpoints = [
|
|||||||
"GET /orgs/{org}/personal-access-tokens/{pat_id}/repositories",
|
"GET /orgs/{org}/personal-access-tokens/{pat_id}/repositories",
|
||||||
"GET /orgs/{org}/private-registries",
|
"GET /orgs/{org}/private-registries",
|
||||||
"GET /orgs/{org}/projects",
|
"GET /orgs/{org}/projects",
|
||||||
|
"GET /orgs/{org}/projectsV2",
|
||||||
|
"GET /orgs/{org}/projectsV2/{project_number}/fields",
|
||||||
|
"GET /orgs/{org}/projectsV2/{project_number}/items",
|
||||||
"GET /orgs/{org}/properties/values",
|
"GET /orgs/{org}/properties/values",
|
||||||
"GET /orgs/{org}/public_members",
|
"GET /orgs/{org}/public_members",
|
||||||
"GET /orgs/{org}/repos",
|
"GET /orgs/{org}/repos",
|
||||||
@@ -134828,7 +134889,6 @@ var paginatingEndpoints = [
|
|||||||
"GET /orgs/{org}/teams/{team_slug}/projects",
|
"GET /orgs/{org}/teams/{team_slug}/projects",
|
||||||
"GET /orgs/{org}/teams/{team_slug}/repos",
|
"GET /orgs/{org}/teams/{team_slug}/repos",
|
||||||
"GET /orgs/{org}/teams/{team_slug}/teams",
|
"GET /orgs/{org}/teams/{team_slug}/teams",
|
||||||
"GET /projects/columns/{column_id}/cards",
|
|
||||||
"GET /projects/{project_id}/collaborators",
|
"GET /projects/{project_id}/collaborators",
|
||||||
"GET /projects/{project_id}/columns",
|
"GET /projects/{project_id}/columns",
|
||||||
"GET /repos/{owner}/{repo}/actions/artifacts",
|
"GET /repos/{owner}/{repo}/actions/artifacts",
|
||||||
@@ -134888,6 +134948,8 @@ var paginatingEndpoints = [
|
|||||||
"GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions",
|
"GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions",
|
||||||
"GET /repos/{owner}/{repo}/issues/events",
|
"GET /repos/{owner}/{repo}/issues/events",
|
||||||
"GET /repos/{owner}/{repo}/issues/{issue_number}/comments",
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/comments",
|
||||||
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by",
|
||||||
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocking",
|
||||||
"GET /repos/{owner}/{repo}/issues/{issue_number}/events",
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/events",
|
||||||
"GET /repos/{owner}/{repo}/issues/{issue_number}/labels",
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/labels",
|
||||||
"GET /repos/{owner}/{repo}/issues/{issue_number}/reactions",
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/reactions",
|
||||||
@@ -134968,6 +135030,8 @@ var paginatingEndpoints = [
|
|||||||
"GET /user/subscriptions",
|
"GET /user/subscriptions",
|
||||||
"GET /user/teams",
|
"GET /user/teams",
|
||||||
"GET /users",
|
"GET /users",
|
||||||
|
"GET /users/{user_id}/projectsV2/{project_number}/fields",
|
||||||
|
"GET /users/{user_id}/projectsV2/{project_number}/items",
|
||||||
"GET /users/{username}/attestations/{subject_digest}",
|
"GET /users/{username}/attestations/{subject_digest}",
|
||||||
"GET /users/{username}/events",
|
"GET /users/{username}/events",
|
||||||
"GET /users/{username}/events/orgs/{org}",
|
"GET /users/{username}/events/orgs/{org}",
|
||||||
@@ -134980,6 +135044,7 @@ var paginatingEndpoints = [
|
|||||||
"GET /users/{username}/orgs",
|
"GET /users/{username}/orgs",
|
||||||
"GET /users/{username}/packages",
|
"GET /users/{username}/packages",
|
||||||
"GET /users/{username}/projects",
|
"GET /users/{username}/projects",
|
||||||
|
"GET /users/{username}/projectsV2",
|
||||||
"GET /users/{username}/received_events",
|
"GET /users/{username}/received_events",
|
||||||
"GET /users/{username}/received_events/public",
|
"GET /users/{username}/received_events/public",
|
||||||
"GET /users/{username}/repos",
|
"GET /users/{username}/repos",
|
||||||
@@ -137378,7 +137443,7 @@ legacyRestEndpointMethods.VERSION = VERSION;
|
|||||||
/***/ ((module) => {
|
/***/ ((module) => {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"4.0.5","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.11.1","@actions/exec":"^1.0.1","@actions/glob":"^0.1.0","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^2.1.1","@actions/io":"^1.0.1","@azure/abort-controller":"^1.1.0","@azure/ms-rest-js":"^2.6.0","@azure/storage-blob":"^12.13.0","semver":"^6.3.1"},"devDependencies":{"@types/node":"^22.13.9","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"}}');
|
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"4.1.0","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.11.1","@actions/exec":"^1.0.1","@actions/glob":"^0.1.0","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^2.1.1","@actions/io":"^1.0.1","@azure/abort-controller":"^1.1.0","@azure/ms-rest-js":"^2.6.0","@azure/storage-blob":"^12.13.0","semver":"^6.3.1"},"devDependencies":{"@types/node":"^22.13.9","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"}}');
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
|
|||||||
11
dist/update-known-versions/index.js
generated
vendored
11
dist/update-known-versions/index.js
generated
vendored
@@ -69397,9 +69397,11 @@ var paginatingEndpoints = [
|
|||||||
"GET /networks/{owner}/{repo}/events",
|
"GET /networks/{owner}/{repo}/events",
|
||||||
"GET /notifications",
|
"GET /notifications",
|
||||||
"GET /organizations",
|
"GET /organizations",
|
||||||
|
"GET /organizations/{org}/dependabot/repository-access",
|
||||||
"GET /orgs/{org}/actions/cache/usage-by-repository",
|
"GET /orgs/{org}/actions/cache/usage-by-repository",
|
||||||
"GET /orgs/{org}/actions/hosted-runners",
|
"GET /orgs/{org}/actions/hosted-runners",
|
||||||
"GET /orgs/{org}/actions/permissions/repositories",
|
"GET /orgs/{org}/actions/permissions/repositories",
|
||||||
|
"GET /orgs/{org}/actions/permissions/self-hosted-runners/repositories",
|
||||||
"GET /orgs/{org}/actions/runner-groups",
|
"GET /orgs/{org}/actions/runner-groups",
|
||||||
"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/hosted-runners",
|
"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/hosted-runners",
|
||||||
"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories",
|
"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories",
|
||||||
@@ -69449,6 +69451,9 @@ var paginatingEndpoints = [
|
|||||||
"GET /orgs/{org}/personal-access-tokens/{pat_id}/repositories",
|
"GET /orgs/{org}/personal-access-tokens/{pat_id}/repositories",
|
||||||
"GET /orgs/{org}/private-registries",
|
"GET /orgs/{org}/private-registries",
|
||||||
"GET /orgs/{org}/projects",
|
"GET /orgs/{org}/projects",
|
||||||
|
"GET /orgs/{org}/projectsV2",
|
||||||
|
"GET /orgs/{org}/projectsV2/{project_number}/fields",
|
||||||
|
"GET /orgs/{org}/projectsV2/{project_number}/items",
|
||||||
"GET /orgs/{org}/properties/values",
|
"GET /orgs/{org}/properties/values",
|
||||||
"GET /orgs/{org}/public_members",
|
"GET /orgs/{org}/public_members",
|
||||||
"GET /orgs/{org}/repos",
|
"GET /orgs/{org}/repos",
|
||||||
@@ -69469,7 +69474,6 @@ var paginatingEndpoints = [
|
|||||||
"GET /orgs/{org}/teams/{team_slug}/projects",
|
"GET /orgs/{org}/teams/{team_slug}/projects",
|
||||||
"GET /orgs/{org}/teams/{team_slug}/repos",
|
"GET /orgs/{org}/teams/{team_slug}/repos",
|
||||||
"GET /orgs/{org}/teams/{team_slug}/teams",
|
"GET /orgs/{org}/teams/{team_slug}/teams",
|
||||||
"GET /projects/columns/{column_id}/cards",
|
|
||||||
"GET /projects/{project_id}/collaborators",
|
"GET /projects/{project_id}/collaborators",
|
||||||
"GET /projects/{project_id}/columns",
|
"GET /projects/{project_id}/columns",
|
||||||
"GET /repos/{owner}/{repo}/actions/artifacts",
|
"GET /repos/{owner}/{repo}/actions/artifacts",
|
||||||
@@ -69529,6 +69533,8 @@ var paginatingEndpoints = [
|
|||||||
"GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions",
|
"GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions",
|
||||||
"GET /repos/{owner}/{repo}/issues/events",
|
"GET /repos/{owner}/{repo}/issues/events",
|
||||||
"GET /repos/{owner}/{repo}/issues/{issue_number}/comments",
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/comments",
|
||||||
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by",
|
||||||
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocking",
|
||||||
"GET /repos/{owner}/{repo}/issues/{issue_number}/events",
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/events",
|
||||||
"GET /repos/{owner}/{repo}/issues/{issue_number}/labels",
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/labels",
|
||||||
"GET /repos/{owner}/{repo}/issues/{issue_number}/reactions",
|
"GET /repos/{owner}/{repo}/issues/{issue_number}/reactions",
|
||||||
@@ -69609,6 +69615,8 @@ var paginatingEndpoints = [
|
|||||||
"GET /user/subscriptions",
|
"GET /user/subscriptions",
|
||||||
"GET /user/teams",
|
"GET /user/teams",
|
||||||
"GET /users",
|
"GET /users",
|
||||||
|
"GET /users/{user_id}/projectsV2/{project_number}/fields",
|
||||||
|
"GET /users/{user_id}/projectsV2/{project_number}/items",
|
||||||
"GET /users/{username}/attestations/{subject_digest}",
|
"GET /users/{username}/attestations/{subject_digest}",
|
||||||
"GET /users/{username}/events",
|
"GET /users/{username}/events",
|
||||||
"GET /users/{username}/events/orgs/{org}",
|
"GET /users/{username}/events/orgs/{org}",
|
||||||
@@ -69621,6 +69629,7 @@ var paginatingEndpoints = [
|
|||||||
"GET /users/{username}/orgs",
|
"GET /users/{username}/orgs",
|
||||||
"GET /users/{username}/packages",
|
"GET /users/{username}/packages",
|
||||||
"GET /users/{username}/projects",
|
"GET /users/{username}/projects",
|
||||||
|
"GET /users/{username}/projectsV2",
|
||||||
"GET /users/{username}/received_events",
|
"GET /users/{username}/received_events",
|
||||||
"GET /users/{username}/received_events/public",
|
"GET /users/{username}/received_events/public",
|
||||||
"GET /users/{username}/repos",
|
"GET /users/{username}/repos",
|
||||||
|
|||||||
82
docs/advanced-version-configuration.md
Normal file
82
docs/advanced-version-configuration.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# Advanced Version Configuration
|
||||||
|
|
||||||
|
This document covers advanced options for configuring which version of uv to install.
|
||||||
|
|
||||||
|
## Install the latest version
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install the latest version of uv
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
version: "latest"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install a specific version
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install a specific version of uv
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
version: "0.4.4"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install a version by supplying a semver range or pep440 specifier
|
||||||
|
|
||||||
|
You can specify a [semver range](https://github.com/npm/node-semver?tab=readme-ov-file#ranges)
|
||||||
|
or [pep440 specifier](https://peps.python.org/pep-0440/#version-specifiers)
|
||||||
|
to install the latest version that satisfies the range.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install a semver range of uv
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
version: ">=0.4.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Pinning a minor version of uv
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
version: "0.4.x"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install a pep440-specifier-satisfying version of uv
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
version: ">=0.4.25,<0.5"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Resolution strategy
|
||||||
|
|
||||||
|
By default, when resolving version ranges, setup-uv will install the highest compatible version.
|
||||||
|
You can change this behavior using the `resolution-strategy` input:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install the lowest compatible version of uv
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
version: ">=0.4.0"
|
||||||
|
resolution-strategy: "lowest"
|
||||||
|
```
|
||||||
|
|
||||||
|
The supported resolution strategies are:
|
||||||
|
- `highest` (default): Install the latest version that satisfies the constraints
|
||||||
|
- `lowest`: Install the oldest version that satisfies the constraints
|
||||||
|
|
||||||
|
This can be useful for testing compatibility with older versions of uv, similar to uv's own `--resolution-strategy` option.
|
||||||
|
|
||||||
|
## Install a version defined in a requirements or config file
|
||||||
|
|
||||||
|
You can use the `version-file` input to specify a file that contains the version of uv to install.
|
||||||
|
This can either be a `pyproject.toml` or `uv.toml` file which defines a `required-version` or
|
||||||
|
uv defined as a dependency in `pyproject.toml` or `requirements.txt`.
|
||||||
|
|
||||||
|
[asdf](https://asdf-vm.com/) `.tool-versions` is also supported, but without the `ref` syntax.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install uv based on the version defined in pyproject.toml
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
version-file: "pyproject.toml"
|
||||||
|
```
|
||||||
189
docs/caching.md
Normal file
189
docs/caching.md
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
# Caching
|
||||||
|
|
||||||
|
This document covers all caching-related configuration options for setup-uv.
|
||||||
|
|
||||||
|
## Enable caching
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The cache is pruned before it is uploaded to the GitHub Actions cache. This can lead to
|
||||||
|
> a small or empty cache. See [Disable cache pruning](#disable-cache-pruning) for more details.
|
||||||
|
|
||||||
|
If you enable caching, the [uv cache](https://docs.astral.sh/uv/concepts/cache/) will be uploaded to
|
||||||
|
the GitHub Actions cache. This can speed up runs that reuse the cache by several minutes.
|
||||||
|
Caching is enabled by default on GitHub-hosted runners.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
>
|
||||||
|
> On self-hosted runners this is usually not needed since the cache generated by uv on the runner's
|
||||||
|
> filesystem is not removed after a run. For more details see [Local cache path](#local-cache-path).
|
||||||
|
|
||||||
|
You can optionally define a custom cache key suffix.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Enable caching and define a custom cache key suffix
|
||||||
|
id: setup-uv
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
cache-suffix: "optional-suffix"
|
||||||
|
```
|
||||||
|
|
||||||
|
When the cache was successfully restored, the output `cache-hit` will be set to `true` and you can
|
||||||
|
use it in subsequent steps. For example, to use the cache in the above case:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Do something if the cache was restored
|
||||||
|
if: steps.setup-uv.outputs.cache-hit == 'true'
|
||||||
|
run: echo "Cache was restored"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cache dependency glob
|
||||||
|
|
||||||
|
If you want to control when the GitHub Actions cache is invalidated, specify a glob pattern with the
|
||||||
|
`cache-dependency-glob` input. The GitHub Actions cache will be invalidated if any file matching the glob pattern
|
||||||
|
changes. If you use relative paths, they are relative to the repository root.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
>
|
||||||
|
> You can look up supported patterns [here](https://github.com/actions/toolkit/tree/main/packages/glob#patterns)
|
||||||
|
>
|
||||||
|
> The default is
|
||||||
|
> ```yaml
|
||||||
|
> cache-dependency-glob: |
|
||||||
|
> **/*requirements*.txt
|
||||||
|
> **/*requirements*.in
|
||||||
|
> **/*constraints*.txt
|
||||||
|
> **/*constraints*.in
|
||||||
|
> **/pyproject.toml
|
||||||
|
> **/uv.lock
|
||||||
|
> **/*.py.lock
|
||||||
|
> ```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Define a cache dependency glob
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
cache-dependency-glob: "**/pyproject.toml"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Define a list of cache dependency globs
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
cache-dependency-glob: |
|
||||||
|
**/requirements*.txt
|
||||||
|
**/pyproject.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Define an absolute cache dependency glob
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
cache-dependency-glob: "/tmp/my-folder/requirements*.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Never invalidate the cache
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
cache-dependency-glob: ""
|
||||||
|
```
|
||||||
|
|
||||||
|
## Restore cache
|
||||||
|
|
||||||
|
Restoring an existing cache can be enabled or disabled with the `restore-cache` input.
|
||||||
|
By default, the cache will be restored.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Don't restore an existing cache
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
restore-cache: false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Save cache
|
||||||
|
|
||||||
|
You can also disable saving the cache after the run with the `save-cache` input.
|
||||||
|
This can be useful to save cache storage when you know you will not use the cache of the run again.
|
||||||
|
By default, the cache will be saved.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Don't save the cache after the run
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
save-cache: false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Local cache path
|
||||||
|
|
||||||
|
If caching is enabled, this action controls where uv stores its cache on the runner's filesystem
|
||||||
|
by setting `UV_CACHE_DIR`.
|
||||||
|
|
||||||
|
It defaults to `setup-uv-cache` in the `TMP` dir, `D:\a\_temp\setup-uv-cache` on Windows and
|
||||||
|
`/tmp/setup-uv-cache` on Linux/macOS. You can change the default by specifying the path with the
|
||||||
|
`cache-local-path` input.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> If the environment variable `UV_CACHE_DIR` is already set this action will not override it.
|
||||||
|
> If you configured [cache-dir](https://docs.astral.sh/uv/reference/settings/#cache-dir) in your
|
||||||
|
> config file then it is also respected and this action will not set `UV_CACHE_DIR`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Define a custom uv cache path
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
cache-local-path: "/path/to/cache"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Disable cache pruning
|
||||||
|
|
||||||
|
By default, the uv cache is pruned after every run, removing pre-built wheels, but retaining any
|
||||||
|
wheels that were built from source. On GitHub-hosted runners, it's typically faster to omit those
|
||||||
|
pre-built wheels from the cache (and instead re-download them from the registry on each run).
|
||||||
|
However, on self-hosted or local runners, preserving the cache may be more efficient. See
|
||||||
|
the [documentation](https://docs.astral.sh/uv/concepts/cache/#caching-in-continuous-integration) for
|
||||||
|
more information.
|
||||||
|
|
||||||
|
If you want to persist the entire cache across runs, disable cache pruning with the `prune-cache`
|
||||||
|
input.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Don't prune the cache before saving it
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
prune-cache: false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cache Python installs
|
||||||
|
|
||||||
|
By default, the Python install dir (`uv python dir` / `UV_PYTHON_INSTALL_DIR`) is not cached,
|
||||||
|
for the same reason that the dependency cache is pruned.
|
||||||
|
If you want to cache Python installs along with your dependencies, set the `cache-python` input to `true`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Cache Python installs
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
cache-python: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ignore nothing to cache
|
||||||
|
|
||||||
|
By default, the action will fail if caching is enabled but there is nothing to upload (the uv cache directory does not exist).
|
||||||
|
If you want to ignore this, set the `ignore-nothing-to-cache` input to `true`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Ignore nothing to cache
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
enable-cache: true
|
||||||
|
ignore-nothing-to-cache: true
|
||||||
|
```
|
||||||
70
docs/customization.md
Normal file
70
docs/customization.md
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# Customization
|
||||||
|
|
||||||
|
This document covers advanced customization options including checksum validation, custom manifests, and problem matchers.
|
||||||
|
|
||||||
|
## Validate checksum
|
||||||
|
|
||||||
|
You can specify a checksum to validate the downloaded executable. Checksums up to the default version
|
||||||
|
are automatically verified by this action. The sha256 hashes can be found on the
|
||||||
|
[releases page](https://github.com/astral-sh/uv/releases) of the uv repo.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install a specific version and validate the checksum
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
version: "0.3.1"
|
||||||
|
checksum: "e11b01402ab645392c7ad6044db63d37e4fd1e745e015306993b07695ea5f9f8"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Manifest file
|
||||||
|
|
||||||
|
The `manifest-file` input allows you to specify a JSON manifest that lists available uv versions,
|
||||||
|
architectures, and their download URLs. By default, this action uses the manifest file contained
|
||||||
|
in this repository, which is automatically updated with each release of uv.
|
||||||
|
|
||||||
|
The manifest file contains an array of objects, each describing a version,
|
||||||
|
architecture, platform, and the corresponding download URL. For example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"version": "0.7.13",
|
||||||
|
"artifactName": "uv-aarch64-apple-darwin.tar.gz",
|
||||||
|
"arch": "aarch64",
|
||||||
|
"platform": "apple-darwin",
|
||||||
|
"downloadUrl": "https://github.com/astral-sh/uv/releases/download/0.7.13/uv-aarch64-apple-darwin.tar.gz"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
You can supply a custom manifest file URL to define additional versions,
|
||||||
|
architectures, or different download URLs.
|
||||||
|
This is useful if you maintain your own uv builds or want to override the default sources.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Use a custom manifest file
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
manifest-file: "https://example.com/my-custom-manifest.json"
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> When you use a custom manifest file and do not set the `version` input, its default value is `latest`.
|
||||||
|
> This means the action will install the latest version available in the custom manifest file.
|
||||||
|
> This is different from the default behavior of installing the latest version from the official uv releases.
|
||||||
|
|
||||||
|
## Add problem matchers
|
||||||
|
|
||||||
|
This action automatically adds
|
||||||
|
[problem matchers](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md)
|
||||||
|
for python errors.
|
||||||
|
|
||||||
|
You can disable this by setting the `add-problem-matchers` input to `false`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install the latest version of uv without problem matchers
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
add-problem-matchers: false
|
||||||
|
```
|
||||||
146
docs/environment-and-tools.md
Normal file
146
docs/environment-and-tools.md
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
# Environment and Tools
|
||||||
|
|
||||||
|
This document covers environment activation, tool directory configuration, and authentication options.
|
||||||
|
|
||||||
|
## Activate environment
|
||||||
|
|
||||||
|
You can set `activate-environment` to `true` to automatically activate a venv.
|
||||||
|
This allows directly using it in later steps:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install the latest version of uv and activate the environment
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
activate-environment: true
|
||||||
|
- run: uv pip install pip
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
>
|
||||||
|
> Activating the environment adds your dependencies to the `PATH`, which could break some workflows.
|
||||||
|
> For example, if you have a dependency which requires uv, e.g., `hatch`, activating the
|
||||||
|
> environment will shadow the `uv` binary installed by this action and may result in a different uv
|
||||||
|
> version being used.
|
||||||
|
>
|
||||||
|
> We do not recommend using this setting for most use-cases. Instead, use `uv run` to execute
|
||||||
|
> commands in the environment.
|
||||||
|
|
||||||
|
## GitHub authentication token
|
||||||
|
|
||||||
|
This action uses the GitHub API to fetch the uv release artifacts. To avoid hitting the GitHub API
|
||||||
|
rate limit too quickly, an authentication token can be provided via the `github-token` input. By
|
||||||
|
default, the `GITHUB_TOKEN` secret is used, which is automatically provided by GitHub Actions.
|
||||||
|
|
||||||
|
If the default
|
||||||
|
[permissions for the GitHub token](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
|
||||||
|
are not sufficient, you can provide a custom GitHub token with the necessary permissions.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install the latest version of uv with a custom GitHub token
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
|
||||||
|
```
|
||||||
|
|
||||||
|
## UV_TOOL_DIR
|
||||||
|
|
||||||
|
On Windows `UV_TOOL_DIR` is set to `uv-tool-dir` in the `TMP` dir (e.g. `D:\a\_temp\uv-tool-dir`).
|
||||||
|
On GitHub hosted runners this is on the much faster `D:` drive.
|
||||||
|
|
||||||
|
On all other platforms the tool environments are placed in the
|
||||||
|
[default location](https://docs.astral.sh/uv/concepts/tools/#tools-directory).
|
||||||
|
|
||||||
|
If you want to change this behaviour (especially on self-hosted runners) you can use the `tool-dir`
|
||||||
|
input:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install the latest version of uv with a custom tool dir
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
tool-dir: "/path/to/tool/dir"
|
||||||
|
```
|
||||||
|
|
||||||
|
## UV_TOOL_BIN_DIR
|
||||||
|
|
||||||
|
On Windows `UV_TOOL_BIN_DIR` is set to `uv-tool-bin-dir` in the `TMP` dir (e.g.
|
||||||
|
`D:\a\_temp\uv-tool-bin-dir`). On GitHub hosted runners this is on the much faster `D:` drive. This
|
||||||
|
path is also automatically added to the PATH.
|
||||||
|
|
||||||
|
On all other platforms the tool binaries get installed to the
|
||||||
|
[default location](https://docs.astral.sh/uv/concepts/tools/#the-bin-directory).
|
||||||
|
|
||||||
|
If you want to change this behaviour (especially on self-hosted runners) you can use the
|
||||||
|
`tool-bin-dir` input:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Install the latest version of uv with a custom tool bin dir
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
tool-bin-dir: "/path/to/tool-bin/dir"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tilde Expansion
|
||||||
|
|
||||||
|
This action supports expanding the `~` character to the user's home directory for the following inputs:
|
||||||
|
|
||||||
|
- `version-file`
|
||||||
|
- `cache-local-path`
|
||||||
|
- `tool-dir`
|
||||||
|
- `tool-bin-dir`
|
||||||
|
- `cache-dependency-glob`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Expand the tilde character
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
cache-local-path: "~/path/to/cache"
|
||||||
|
tool-dir: "~/path/to/tool/dir"
|
||||||
|
tool-bin-dir: "~/path/to/tool-bin/dir"
|
||||||
|
cache-dependency-glob: "~/my-cache-buster"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ignore empty workdir
|
||||||
|
|
||||||
|
By default, the action will warn if the workdir is empty, because this is usually the case when
|
||||||
|
`actions/checkout` is configured to run after `setup-uv`, which is not supported.
|
||||||
|
|
||||||
|
If you want to ignore this, set the `ignore-empty-workdir` input to `true`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Ignore empty workdir
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
ignore-empty-workdir: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
This action sets several environment variables that influence uv's behavior and can be used by subsequent steps:
|
||||||
|
|
||||||
|
- `UV_PYTHON`: Set when `python-version` input is specified. Controls which Python version uv uses.
|
||||||
|
- `UV_CACHE_DIR`: Set when caching is enabled (unless already configured in uv config files). Controls where uv stores its cache.
|
||||||
|
- `UV_TOOL_DIR`: Set when `tool-dir` input is specified. Controls where uv installs tool environments.
|
||||||
|
- `UV_TOOL_BIN_DIR`: Set when `tool-bin-dir` input is specified. Controls where uv installs tool binaries.
|
||||||
|
- `UV_PYTHON_INSTALL_DIR`: Always set. Controls where uv installs Python versions.
|
||||||
|
- `VIRTUAL_ENV`: Set when `activate-environment` is true. Points to the activated virtual environment.
|
||||||
|
|
||||||
|
**Environment variables that affect the action behavior:**
|
||||||
|
|
||||||
|
- `UV_NO_MODIFY_PATH`: If set, prevents the action from modifying PATH. Cannot be used with `activate-environment`.
|
||||||
|
- `UV_CACHE_DIR`: If already set, the action will respect it instead of setting its own cache directory.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Example using environment variables
|
||||||
|
uses: astral-sh/setup-uv@v6
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
tool-dir: "/custom/tool/dir"
|
||||||
|
enable-cache: true
|
||||||
|
|
||||||
|
- name: Check environment variables
|
||||||
|
run: |
|
||||||
|
echo "UV_PYTHON: $UV_PYTHON"
|
||||||
|
echo "UV_CACHE_DIR: $UV_CACHE_DIR"
|
||||||
|
echo "UV_TOOL_DIR: $UV_TOOL_DIR"
|
||||||
|
echo "UV_PYTHON_INSTALL_DIR: $UV_PYTHON_INSTALL_DIR"
|
||||||
|
```
|
||||||
1601
package-lock.json
generated
1601
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -21,28 +21,28 @@
|
|||||||
"author": "@eifinger",
|
"author": "@eifinger",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": "^4.0.5",
|
"@actions/cache": "^4.1.0",
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^1.11.1",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/glob": "^0.5.0",
|
"@actions/glob": "^0.5.0",
|
||||||
"@actions/io": "^1.1.3",
|
"@actions/io": "^1.1.3",
|
||||||
"@actions/tool-cache": "^2.0.2",
|
"@actions/tool-cache": "^2.0.2",
|
||||||
"@octokit/core": "^7.0.5",
|
"@octokit/core": "^7.0.5",
|
||||||
"@octokit/plugin-paginate-rest": "^13.1.1",
|
"@octokit/plugin-paginate-rest": "^13.2.0",
|
||||||
"@octokit/plugin-rest-endpoint-methods": "^16.1.0",
|
"@octokit/plugin-rest-endpoint-methods": "^16.1.0",
|
||||||
"@renovatebot/pep440": "^4.2.1",
|
"@renovatebot/pep440": "^4.2.1",
|
||||||
"smol-toml": "^1.4.2",
|
"smol-toml": "^1.4.2",
|
||||||
"undici": "^7.16.0"
|
"undici": "^7.16.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "2.2.4",
|
"@biomejs/biome": "2.2.5",
|
||||||
"@types/js-yaml": "^4.0.9",
|
"@types/js-yaml": "^4.0.9",
|
||||||
"@types/node": "^24.7.0",
|
"@types/node": "^24.7.0",
|
||||||
"@types/semver": "^7.7.1",
|
"@types/semver": "^7.7.1",
|
||||||
"@vercel/ncc": "^0.38.4",
|
"@vercel/ncc": "^0.38.4",
|
||||||
"jest": "^30.1.3",
|
"jest": "^30.2.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"ts-jest": "^29.4.4",
|
"ts-jest": "^29.4.4",
|
||||||
"typescript": "^5.9.2"
|
"typescript": "^5.9.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ 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 type { Endpoints } from "@octokit/types";
|
||||||
import * as pep440 from "@renovatebot/pep440";
|
import * as pep440 from "@renovatebot/pep440";
|
||||||
|
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 { Octokit } from "../utils/octokit";
|
||||||
import type { Architecture, Platform } from "../utils/platforms";
|
import type { Architecture, Platform } from "../utils/platforms";
|
||||||
@@ -134,6 +135,7 @@ export async function resolveVersion(
|
|||||||
versionInput: string,
|
versionInput: string,
|
||||||
manifestFile: string | undefined,
|
manifestFile: string | undefined,
|
||||||
githubToken: string,
|
githubToken: string,
|
||||||
|
resolutionStrategy: "highest" | "lowest" = "highest",
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
core.debug(`Resolving version: ${versionInput}`);
|
core.debug(`Resolving version: ${versionInput}`);
|
||||||
let version: string;
|
let version: string;
|
||||||
@@ -164,7 +166,10 @@ export async function resolveVersion(
|
|||||||
}
|
}
|
||||||
const availableVersions = await getAvailableVersions(githubToken);
|
const availableVersions = await getAvailableVersions(githubToken);
|
||||||
core.debug(`Available versions: ${availableVersions}`);
|
core.debug(`Available versions: ${availableVersions}`);
|
||||||
const resolvedVersion = maxSatisfying(availableVersions, version);
|
const resolvedVersion =
|
||||||
|
resolutionStrategy === "lowest"
|
||||||
|
? minSatisfying(availableVersions, version)
|
||||||
|
: maxSatisfying(availableVersions, version);
|
||||||
if (resolvedVersion === undefined) {
|
if (resolvedVersion === undefined) {
|
||||||
throw new Error(`No version found for ${version}`);
|
throw new Error(`No version found for ${version}`);
|
||||||
}
|
}
|
||||||
@@ -264,3 +269,24 @@ function maxSatisfying(
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function minSatisfying(
|
||||||
|
versions: string[],
|
||||||
|
version: string,
|
||||||
|
): string | undefined {
|
||||||
|
// For semver, we need to use a different approach since tc.evaluateVersions only returns max
|
||||||
|
// Let's use semver directly for min satisfying
|
||||||
|
const minSemver = semver.minSatisfying(versions, version);
|
||||||
|
if (minSemver !== null) {
|
||||||
|
core.debug(`Found a version that satisfies the semver range: ${minSemver}`);
|
||||||
|
return minSemver;
|
||||||
|
}
|
||||||
|
const minPep440 = pep440.minSatisfying(versions, version);
|
||||||
|
if (minPep440 !== null) {
|
||||||
|
core.debug(
|
||||||
|
`Found a version that satisfies the pep440 specifier: ${minPep440}`,
|
||||||
|
);
|
||||||
|
return minPep440;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
manifestFile,
|
manifestFile,
|
||||||
pythonDir,
|
pythonDir,
|
||||||
pythonVersion,
|
pythonVersion,
|
||||||
|
resolutionStrategy,
|
||||||
toolBinDir,
|
toolBinDir,
|
||||||
toolDir,
|
toolDir,
|
||||||
versionFile as versionFileInput,
|
versionFile as versionFileInput,
|
||||||
@@ -72,7 +73,8 @@ async function run(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function detectEmptyWorkdir(): void {
|
function detectEmptyWorkdir(): void {
|
||||||
if (fs.readdirSync(".").length === 0) {
|
const dirToCheck = workingDirectory || ".";
|
||||||
|
if (fs.readdirSync(dirToCheck).length === 0) {
|
||||||
if (ignoreEmptyWorkdir) {
|
if (ignoreEmptyWorkdir) {
|
||||||
core.info(
|
core.info(
|
||||||
"Empty workdir detected. Ignoring because ignore-empty-workdir is enabled",
|
"Empty workdir detected. Ignoring because ignore-empty-workdir is enabled",
|
||||||
@@ -120,7 +122,12 @@ async function determineVersion(
|
|||||||
manifestFile: string | undefined,
|
manifestFile: string | undefined,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
if (versionInput !== "") {
|
if (versionInput !== "") {
|
||||||
return await resolveVersion(versionInput, manifestFile, githubToken);
|
return await resolveVersion(
|
||||||
|
versionInput,
|
||||||
|
manifestFile,
|
||||||
|
githubToken,
|
||||||
|
resolutionStrategy,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (versionFileInput !== "") {
|
if (versionFileInput !== "") {
|
||||||
const versionFromFile = getUvVersionFromFile(versionFileInput);
|
const versionFromFile = getUvVersionFromFile(versionFileInput);
|
||||||
@@ -129,7 +136,12 @@ async function determineVersion(
|
|||||||
`Could not determine uv version from file: ${versionFileInput}`,
|
`Could not determine uv version from file: ${versionFileInput}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return await resolveVersion(versionFromFile, manifestFile, githubToken);
|
return await resolveVersion(
|
||||||
|
versionFromFile,
|
||||||
|
manifestFile,
|
||||||
|
githubToken,
|
||||||
|
resolutionStrategy,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const versionFromUvToml = getUvVersionFromFile(
|
const versionFromUvToml = getUvVersionFromFile(
|
||||||
`${workingDirectory}${path.sep}uv.toml`,
|
`${workingDirectory}${path.sep}uv.toml`,
|
||||||
@@ -146,6 +158,7 @@ async function determineVersion(
|
|||||||
versionFromUvToml || versionFromPyproject || "latest",
|
versionFromUvToml || versionFromPyproject || "latest",
|
||||||
manifestFile,
|
manifestFile,
|
||||||
githubToken,
|
githubToken,
|
||||||
|
resolutionStrategy,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export const githubToken = core.getInput("github-token");
|
|||||||
export const manifestFile = getManifestFile();
|
export const manifestFile = getManifestFile();
|
||||||
export const addProblemMatchers =
|
export const addProblemMatchers =
|
||||||
core.getInput("add-problem-matchers") === "true";
|
core.getInput("add-problem-matchers") === "true";
|
||||||
|
export const resolutionStrategy = getResolutionStrategy();
|
||||||
|
|
||||||
function getVersionFile(): string {
|
function getVersionFile(): string {
|
||||||
const versionFileInput = core.getInput("version-file");
|
const versionFileInput = core.getInput("version-file");
|
||||||
@@ -186,3 +187,16 @@ function getManifestFile(): string | undefined {
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getResolutionStrategy(): "highest" | "lowest" {
|
||||||
|
const resolutionStrategyInput = core.getInput("resolution-strategy");
|
||||||
|
if (resolutionStrategyInput === "lowest") {
|
||||||
|
return "lowest";
|
||||||
|
}
|
||||||
|
if (resolutionStrategyInput === "highest" || resolutionStrategyInput === "") {
|
||||||
|
return "highest";
|
||||||
|
}
|
||||||
|
throw new Error(
|
||||||
|
`Invalid resolution-strategy: ${resolutionStrategyInput}. Must be 'highest' or 'lowest'.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user