diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml index c240034..f6fcb10 100644 --- a/.github/workflows/default.yml +++ b/.github/workflows/default.yml @@ -2,16 +2,14 @@ name: default on: pull_request: push: - branches: - - main jobs: # run linters and unit tests lint-and-test-units: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: npm-cache with: path: ~/.npm @@ -43,11 +41,22 @@ jobs: fail-fast: true steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - uses: ./ with: uv-version: ${{ matrix.uv-version }} - - run: uv --version \ No newline at end of file + uv-venv: "my_virt_env" + - run: uv --version + - name: Get python executable on Windows + if: runner.os == 'Windows' + run: | + Get-Command python + - name: Get python executable on non-Windows + if: runner.os != 'Windows' + run: | + which python + - name: Check inside virtual environment + run: python -c "import sys; exit(0 if sys.prefix != sys.base_prefix else 1)" \ No newline at end of file diff --git a/README.md b/README.md index 61b761e..3af33b1 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,20 @@ steps: - run: uv --version ``` +### Create and activate a virtual environment using uv + +```yaml +steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + - uses: yezz123/setup-uv@v1 + with: + uv-venv: "your_venv_name" + - run: uv pip install black # this command will run in the uv environment +``` + ## Contributing ### Create issues diff --git a/__tests__/input.test.ts b/__tests__/input.test.ts index 4e932dc..e063c19 100644 --- a/__tests__/input.test.ts +++ b/__tests__/input.test.ts @@ -1,4 +1,10 @@ -import { getBooleanInput, getInputs, getVersionInput } from '../src/inputs' +import { getInput } from '@actions/core' +import { + getBooleanInput, + getInputs, + getVenvInput, + getVersionInput +} from '../src/inputs' const TEST_ENV_VARS = { INPUT_MISSING: '', @@ -9,7 +15,8 @@ const TEST_ENV_VARS = { INPUT_VERSION_ALPHA: '0.1.3.0a1', 'INPUT_UV-PREVIEW': 'true', - 'INPUT_UV-VERSION': '0.1.2' + 'INPUT_UV-VERSION': '0.1.2', + 'INPUT_UV-VENV': 'my_venv' } describe('options', () => { @@ -42,7 +49,11 @@ describe('options', () => { }) it('getInputs returns inputs', () => { - expect(getInputs()).toStrictEqual({ preview: true, version: '0.1.2' }) + expect(getInputs()).toStrictEqual({ + preview: true, + version: '0.1.2', + venv: 'my_venv' + }) }) it('getVersionInput throws if input is not valid', () => { @@ -58,4 +69,12 @@ describe('options', () => { it('getVersionInput returns version if input is alpha', () => { expect(getVersionInput('version_alpha')).toBe('0.1.3.0a1') }) + + it('getVenvInput returns venv name if input is valid', () => { + expect(getVenvInput('uv-venv')).toBe('my_venv') + }) + + it('getVenvInput returns null if input is not provided', () => { + expect(getVenvInput('SOMETHING')).toBeNull() + }) }) diff --git a/action.yml b/action.yml index 5d31e3a..e6d97c7 100644 --- a/action.yml +++ b/action.yml @@ -9,6 +9,9 @@ inputs: uv-version: description: uv version to use, if version is not provided then latest stable version will be used required: false + uv-venv: + description: virtual environment name to create and activate. + required: false runs: using: node20 main: dist/index.js diff --git a/dist/index.js b/dist/index.js index 00fea83..50dcc60 100644 --- a/dist/index.js +++ b/dist/index.js @@ -31906,13 +31906,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getVersionInput = exports.getBooleanInput = exports.getInputs = void 0; +exports.getVenvInput = exports.getVersionInput = exports.getBooleanInput = exports.getInputs = void 0; const core_1 = __nccwpck_require__(2186); const semver_1 = __importDefault(__nccwpck_require__(1383)); function getInputs() { return { preview: getBooleanInput('uv-preview'), - version: getVersionInput('uv-version') + version: getVersionInput('uv-version'), + venv: getVenvInput('uv-venv') }; } exports.getInputs = getInputs; @@ -31940,6 +31941,47 @@ function getVersionInput(name) { return version.trim(); } exports.getVersionInput = getVersionInput; +function getVenvInput(name) { + const venv = (0, core_1.getInput)(name); + if (!venv) { + return null; + } + return venv.trim(); +} +exports.getVenvInput = getVenvInput; + + +/***/ }), + +/***/ 667: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.activateVenv = exports.createVenv = void 0; +const exec_1 = __nccwpck_require__(1514); +const core_1 = __nccwpck_require__(2186); +const os_1 = __importDefault(__nccwpck_require__(2037)); +async function createVenv(venv) { + await (0, exec_1.exec)('uv', ['venv', venv]); +} +exports.createVenv = createVenv; +async function activateVenv(venv) { + if (os_1.default.platform() === 'win32') { + await (0, exec_1.exec)('powershell', [`${venv}\\Scripts\\activate.ps1`]); + (0, core_1.addPath)(`${venv}/Scripts`); + } + else { + await (0, exec_1.exec)('/bin/bash', ['-c', `source ${venv}/bin/activate`]); + (0, core_1.addPath)(`${venv}/bin`); + } + (0, core_1.exportVariable)('VIRTUAL_ENV', venv); +} +exports.activateVenv = activateVenv; /***/ }), @@ -33851,10 +33893,15 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); const core_1 = __nccwpck_require__(2186); const find_1 = __nccwpck_require__(3288); const inputs_1 = __nccwpck_require__(7063); +const venv_1 = __nccwpck_require__(667); async function run() { try { const inputs = (0, inputs_1.getInputs)(); await (0, find_1.findUv)(inputs); + if (inputs.venv) { + await (0, venv_1.createVenv)(inputs.venv); + await (0, venv_1.activateVenv)(inputs.venv); + } } catch (error) { (0, core_1.setFailed)(errorAsMessage(error)); diff --git a/src/inputs.ts b/src/inputs.ts index b47b42b..0d25c4b 100644 --- a/src/inputs.ts +++ b/src/inputs.ts @@ -1,16 +1,17 @@ import { getInput } from '@actions/core' import semver from 'semver' - export interface Inputs { // Finder related inputs preview: boolean version: string | null + venv: string | null } export function getInputs(): Inputs { return { preview: getBooleanInput('uv-preview'), - version: getVersionInput('uv-version') + version: getVersionInput('uv-version'), + venv: getVenvInput('uv-venv') } } @@ -41,3 +42,11 @@ export function getVersionInput(name: string): string | null { return version.trim() } + +export function getVenvInput(name: string): string | null { + const venv = getInput(name) + if (!venv) { + return null + } + return venv.trim() +} diff --git a/src/main.ts b/src/main.ts index 9e0a1ab..af6b80b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,17 @@ import { setFailed } from '@actions/core' import { findUv } from './find' import { getInputs } from './inputs' - +import { activateVenv, createVenv } from './venv' +import { exec } from '@actions/exec' async function run(): Promise { try { const inputs = getInputs() await findUv(inputs) + if (inputs.venv) { + await createVenv(inputs.venv) + await activateVenv(inputs.venv) + } } catch (error) { setFailed(errorAsMessage(error)) } diff --git a/src/venv.ts b/src/venv.ts new file mode 100644 index 0000000..7e68701 --- /dev/null +++ b/src/venv.ts @@ -0,0 +1,18 @@ +import { exec } from '@actions/exec' +import { exportVariable, addPath } from '@actions/core' +import os from 'os' + +export async function createVenv(venv: string) { + await exec('uv', ['venv', venv]) +} + +export async function activateVenv(venv: string) { + if (os.platform() === 'win32') { + await exec('powershell', [`${venv}\\Scripts\\activate.ps1`]) + addPath(`${venv}/Scripts`) + } else { + await exec('/bin/bash', ['-c', `source ${venv}/bin/activate`]) + addPath(`${venv}/bin`) + } + exportVariable('VIRTUAL_ENV', venv) +}