Skip to content

Commit

Permalink
Add venv creation and activation support (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
Aymane11 committed Feb 19, 2024
1 parent d4f8f2e commit 6fa23a8
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 15 deletions.
23 changes: 16 additions & 7 deletions .github/workflows/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
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)"
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 22 additions & 3 deletions __tests__/input.test.ts
Original file line number Diff line number Diff line change
@@ -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: '',
Expand All @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand All @@ -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()
})
})
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
51 changes: 49 additions & 2 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;


/***/ }),
Expand Down Expand Up @@ -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));
Expand Down
13 changes: 11 additions & 2 deletions src/inputs.ts
Original file line number Diff line number Diff line change
@@ -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')
}
}

Expand Down Expand Up @@ -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()
}
7 changes: 6 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -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<void> {
try {
const inputs = getInputs()

await findUv(inputs)
if (inputs.venv) {
await createVenv(inputs.venv)
await activateVenv(inputs.venv)
}
} catch (error) {
setFailed(errorAsMessage(error))
}
Expand Down
18 changes: 18 additions & 0 deletions src/venv.ts
Original file line number Diff line number Diff line change
@@ -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)
}

0 comments on commit 6fa23a8

Please sign in to comment.