mirror of
https://github.com/actions/setup-python.git
synced 2024-11-22 06:26:25 +00:00
Add another pip default dependency file for cache hash (#604)
This commit is contained in:
parent
869e769ec8
commit
7b9ef6fc5a
7 changed files with 98 additions and 18 deletions
|
@ -52,7 +52,7 @@ Using `architecture` input it is possible to specify the required Python or PyPy
|
||||||
|
|
||||||
The action has built-in functionality for caching and restoring dependencies. It uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `pip`, `pipenv` and `poetry`. The `cache` input is optional, and caching is turned off by default.
|
The action has built-in functionality for caching and restoring dependencies. It uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `pip`, `pipenv` and `poetry`. The `cache` input is optional, and caching is turned off by default.
|
||||||
|
|
||||||
The action defaults to searching for a dependency file (`requirements.txt` for pip, `Pipfile.lock` for pipenv or `poetry.lock` for poetry) in the repository, and uses its hash as a part of the cache key. Input `cache-dependency-path` is used for cases when multiple dependency files are used, they are located in different subdirectories or different files for the hash that want to be used.
|
The action defaults to searching for a dependency file (`requirements.txt` or `pyproject.toml` for pip, `Pipfile.lock` for pipenv or `poetry.lock` for poetry) in the repository, and uses its hash as a part of the cache key. Input `cache-dependency-path` is used for cases when multiple dependency files are used, they are located in different subdirectories or different files for the hash that want to be used.
|
||||||
|
|
||||||
- For `pip`, the action will cache the global cache directory
|
- For `pip`, the action will cache the global cache directory
|
||||||
- For `pipenv`, the action will cache virtualenv directory
|
- For `pipenv`, the action will cache virtualenv directory
|
||||||
|
|
|
@ -5,7 +5,7 @@ import * as exec from '@actions/exec';
|
||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
import {getCacheDistributor} from '../src/cache-distributions/cache-factory';
|
import {getCacheDistributor} from '../src/cache-distributions/cache-factory';
|
||||||
import {State} from '../src/cache-distributions/cache-distributor';
|
import {State} from '../src/cache-distributions/cache-distributor';
|
||||||
import * as utils from './../src/utils';
|
import * as constants from '../src/cache-distributions/constants';
|
||||||
|
|
||||||
describe('restore-cache', () => {
|
describe('restore-cache', () => {
|
||||||
const pipFileLockHash =
|
const pipFileLockHash =
|
||||||
|
@ -196,11 +196,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||||
30000
|
30000
|
||||||
);
|
);
|
||||||
|
|
||||||
it.each([
|
it.each([['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']])(
|
||||||
['pip', '3.8.12', 'requirements-linux.txt', 'requirements-linux.txt'],
|
|
||||||
['pip', '3.8.12', 'requirements.txt', 'requirements.txt'],
|
|
||||||
['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']
|
|
||||||
])(
|
|
||||||
'Should throw an error because dependency file is not found',
|
'Should throw an error because dependency file is not found',
|
||||||
async (
|
async (
|
||||||
packageManager,
|
packageManager,
|
||||||
|
@ -213,6 +209,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||||
pythonVersion,
|
pythonVersion,
|
||||||
dependencyFile
|
dependencyFile
|
||||||
);
|
);
|
||||||
|
|
||||||
await expect(cacheDistributor.restoreCache()).rejects.toThrowError(
|
await expect(cacheDistributor.restoreCache()).rejects.toThrowError(
|
||||||
`No file in ${process.cwd()} matched to [${cacheDependencyPath
|
`No file in ${process.cwd()} matched to [${cacheDependencyPath
|
||||||
.split('\n')
|
.split('\n')
|
||||||
|
@ -220,6 +217,40 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['pip', '3.8.12', 'requirements-linux.txt'],
|
||||||
|
['pip', '3.8.12', 'requirements.txt']
|
||||||
|
])(
|
||||||
|
'Shouldn`t throw an error as there is a default file `pyproject.toml` to use when requirements.txt is not specified',
|
||||||
|
async (packageManager, pythonVersion, dependencyFile) => {
|
||||||
|
const cacheDistributor = getCacheDistributor(
|
||||||
|
packageManager,
|
||||||
|
pythonVersion,
|
||||||
|
dependencyFile
|
||||||
|
);
|
||||||
|
await expect(cacheDistributor.restoreCache()).resolves;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['pip', '3.8.12', 'requirements-linux.txt'],
|
||||||
|
['pip', '3.8.12', 'requirements.txt']
|
||||||
|
])(
|
||||||
|
'Should throw an error as there is no default file `pyproject.toml` to use when requirements.txt is not specified',
|
||||||
|
async (packageManager, pythonVersion, dependencyFile) => {
|
||||||
|
jest.mock('../src/cache-distributions/constants', () => ({
|
||||||
|
CACHE_DEPENDENCY_BACKUP_PATH: '**/pyprojecttest.toml'
|
||||||
|
}));
|
||||||
|
|
||||||
|
const cacheDistributor = getCacheDistributor(
|
||||||
|
packageManager,
|
||||||
|
pythonVersion,
|
||||||
|
dependencyFile
|
||||||
|
);
|
||||||
|
await expect(cacheDistributor.restoreCache()).resolves;
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Dependencies changed', () => {
|
describe('Dependencies changed', () => {
|
||||||
|
|
23
dist/cache-save/index.js
vendored
23
dist/cache-save/index.js
vendored
|
@ -59699,6 +59699,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.State = void 0;
|
exports.State = void 0;
|
||||||
const cache = __importStar(__nccwpck_require__(7799));
|
const cache = __importStar(__nccwpck_require__(7799));
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
|
const constants_1 = __nccwpck_require__(8248);
|
||||||
var State;
|
var State;
|
||||||
(function (State) {
|
(function (State) {
|
||||||
State["STATE_CACHE_PRIMARY_KEY"] = "cache-primary-key";
|
State["STATE_CACHE_PRIMARY_KEY"] = "cache-primary-key";
|
||||||
|
@ -59718,9 +59719,12 @@ class CacheDistributor {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const { primaryKey, restoreKey } = yield this.computeKeys();
|
const { primaryKey, restoreKey } = yield this.computeKeys();
|
||||||
if (primaryKey.endsWith('-')) {
|
if (primaryKey.endsWith('-')) {
|
||||||
throw new Error(`No file in ${process.cwd()} matched to [${this.cacheDependencyPath
|
const file = this.packageManager === 'pip'
|
||||||
.split('\n')
|
? `${this.cacheDependencyPath
|
||||||
.join(',')}], make sure you have checked out the target repository`);
|
.split('\n')
|
||||||
|
.join(',')} or ${constants_1.CACHE_DEPENDENCY_BACKUP_PATH}`
|
||||||
|
: this.cacheDependencyPath.split('\n').join(',');
|
||||||
|
throw new Error(`No file in ${process.cwd()} matched to [${file}], make sure you have checked out the target repository`);
|
||||||
}
|
}
|
||||||
const cachePath = yield this.getCacheGlobalDirectories();
|
const cachePath = yield this.getCacheGlobalDirectories();
|
||||||
core.saveState(State.CACHE_PATHS, cachePath);
|
core.saveState(State.CACHE_PATHS, cachePath);
|
||||||
|
@ -59744,6 +59748,19 @@ class CacheDistributor {
|
||||||
exports["default"] = CacheDistributor;
|
exports["default"] = CacheDistributor;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 8248:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.CACHE_DEPENDENCY_BACKUP_PATH = void 0;
|
||||||
|
const CACHE_DEPENDENCY_BACKUP_PATH = '**/pyproject.toml';
|
||||||
|
exports.CACHE_DEPENDENCY_BACKUP_PATH = CACHE_DEPENDENCY_BACKUP_PATH;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 4553:
|
/***/ 4553:
|
||||||
|
|
28
dist/setup/index.js
vendored
28
dist/setup/index.js
vendored
|
@ -65775,6 +65775,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.State = void 0;
|
exports.State = void 0;
|
||||||
const cache = __importStar(__nccwpck_require__(7799));
|
const cache = __importStar(__nccwpck_require__(7799));
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
|
const constants_1 = __nccwpck_require__(8248);
|
||||||
var State;
|
var State;
|
||||||
(function (State) {
|
(function (State) {
|
||||||
State["STATE_CACHE_PRIMARY_KEY"] = "cache-primary-key";
|
State["STATE_CACHE_PRIMARY_KEY"] = "cache-primary-key";
|
||||||
|
@ -65794,9 +65795,12 @@ class CacheDistributor {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const { primaryKey, restoreKey } = yield this.computeKeys();
|
const { primaryKey, restoreKey } = yield this.computeKeys();
|
||||||
if (primaryKey.endsWith('-')) {
|
if (primaryKey.endsWith('-')) {
|
||||||
throw new Error(`No file in ${process.cwd()} matched to [${this.cacheDependencyPath
|
const file = this.packageManager === 'pip'
|
||||||
.split('\n')
|
? `${this.cacheDependencyPath
|
||||||
.join(',')}], make sure you have checked out the target repository`);
|
.split('\n')
|
||||||
|
.join(',')} or ${constants_1.CACHE_DEPENDENCY_BACKUP_PATH}`
|
||||||
|
: this.cacheDependencyPath.split('\n').join(',');
|
||||||
|
throw new Error(`No file in ${process.cwd()} matched to [${file}], make sure you have checked out the target repository`);
|
||||||
}
|
}
|
||||||
const cachePath = yield this.getCacheGlobalDirectories();
|
const cachePath = yield this.getCacheGlobalDirectories();
|
||||||
core.saveState(State.CACHE_PATHS, cachePath);
|
core.saveState(State.CACHE_PATHS, cachePath);
|
||||||
|
@ -65856,6 +65860,19 @@ function getCacheDistributor(packageManager, pythonVersion, cacheDependencyPath)
|
||||||
exports.getCacheDistributor = getCacheDistributor;
|
exports.getCacheDistributor = getCacheDistributor;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 8248:
|
||||||
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports.CACHE_DEPENDENCY_BACKUP_PATH = void 0;
|
||||||
|
const CACHE_DEPENDENCY_BACKUP_PATH = '**/pyproject.toml';
|
||||||
|
exports.CACHE_DEPENDENCY_BACKUP_PATH = CACHE_DEPENDENCY_BACKUP_PATH;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 5546:
|
/***/ 5546:
|
||||||
|
@ -65904,10 +65921,12 @@ const path = __importStar(__nccwpck_require__(1017));
|
||||||
const os_1 = __importDefault(__nccwpck_require__(2037));
|
const os_1 = __importDefault(__nccwpck_require__(2037));
|
||||||
const cache_distributor_1 = __importDefault(__nccwpck_require__(8953));
|
const cache_distributor_1 = __importDefault(__nccwpck_require__(8953));
|
||||||
const utils_1 = __nccwpck_require__(1314);
|
const utils_1 = __nccwpck_require__(1314);
|
||||||
|
const constants_1 = __nccwpck_require__(8248);
|
||||||
class PipCache extends cache_distributor_1.default {
|
class PipCache extends cache_distributor_1.default {
|
||||||
constructor(pythonVersion, cacheDependencyPath = '**/requirements.txt') {
|
constructor(pythonVersion, cacheDependencyPath = '**/requirements.txt') {
|
||||||
super('pip', cacheDependencyPath);
|
super('pip', cacheDependencyPath);
|
||||||
this.pythonVersion = pythonVersion;
|
this.pythonVersion = pythonVersion;
|
||||||
|
this.cacheDependencyBackupPath = constants_1.CACHE_DEPENDENCY_BACKUP_PATH;
|
||||||
}
|
}
|
||||||
getCacheGlobalDirectories() {
|
getCacheGlobalDirectories() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
@ -65943,7 +65962,8 @@ class PipCache extends cache_distributor_1.default {
|
||||||
}
|
}
|
||||||
computeKeys() {
|
computeKeys() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const hash = yield glob.hashFiles(this.cacheDependencyPath);
|
const hash = (yield glob.hashFiles(this.cacheDependencyPath)) ||
|
||||||
|
(yield glob.hashFiles(this.cacheDependencyBackupPath));
|
||||||
let primaryKey = '';
|
let primaryKey = '';
|
||||||
let restoreKey = '';
|
let restoreKey = '';
|
||||||
if (utils_1.IS_LINUX) {
|
if (utils_1.IS_LINUX) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as cache from '@actions/cache';
|
import * as cache from '@actions/cache';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
import {CACHE_DEPENDENCY_BACKUP_PATH} from './constants';
|
||||||
|
|
||||||
export enum State {
|
export enum State {
|
||||||
STATE_CACHE_PRIMARY_KEY = 'cache-primary-key',
|
STATE_CACHE_PRIMARY_KEY = 'cache-primary-key',
|
||||||
|
@ -24,10 +25,14 @@ abstract class CacheDistributor {
|
||||||
public async restoreCache() {
|
public async restoreCache() {
|
||||||
const {primaryKey, restoreKey} = await this.computeKeys();
|
const {primaryKey, restoreKey} = await this.computeKeys();
|
||||||
if (primaryKey.endsWith('-')) {
|
if (primaryKey.endsWith('-')) {
|
||||||
|
const file =
|
||||||
|
this.packageManager === 'pip'
|
||||||
|
? `${this.cacheDependencyPath
|
||||||
|
.split('\n')
|
||||||
|
.join(',')} or ${CACHE_DEPENDENCY_BACKUP_PATH}`
|
||||||
|
: this.cacheDependencyPath.split('\n').join(',');
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`No file in ${process.cwd()} matched to [${this.cacheDependencyPath
|
`No file in ${process.cwd()} matched to [${file}], make sure you have checked out the target repository`
|
||||||
.split('\n')
|
|
||||||
.join(',')}], make sure you have checked out the target repository`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
src/cache-distributions/constants.ts
Normal file
2
src/cache-distributions/constants.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
const CACHE_DEPENDENCY_BACKUP_PATH: string = '**/pyproject.toml';
|
||||||
|
export {CACHE_DEPENDENCY_BACKUP_PATH};
|
|
@ -8,8 +8,11 @@ import os from 'os';
|
||||||
|
|
||||||
import CacheDistributor from './cache-distributor';
|
import CacheDistributor from './cache-distributor';
|
||||||
import {getLinuxInfo, IS_LINUX, IS_WINDOWS} from '../utils';
|
import {getLinuxInfo, IS_LINUX, IS_WINDOWS} from '../utils';
|
||||||
|
import {CACHE_DEPENDENCY_BACKUP_PATH} from './constants';
|
||||||
|
|
||||||
class PipCache extends CacheDistributor {
|
class PipCache extends CacheDistributor {
|
||||||
|
private cacheDependencyBackupPath: string = CACHE_DEPENDENCY_BACKUP_PATH;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private pythonVersion: string,
|
private pythonVersion: string,
|
||||||
cacheDependencyPath: string = '**/requirements.txt'
|
cacheDependencyPath: string = '**/requirements.txt'
|
||||||
|
@ -56,7 +59,9 @@ class PipCache extends CacheDistributor {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async computeKeys() {
|
protected async computeKeys() {
|
||||||
const hash = await glob.hashFiles(this.cacheDependencyPath);
|
const hash =
|
||||||
|
(await glob.hashFiles(this.cacheDependencyPath)) ||
|
||||||
|
(await glob.hashFiles(this.cacheDependencyBackupPath));
|
||||||
let primaryKey = '';
|
let primaryKey = '';
|
||||||
let restoreKey = '';
|
let restoreKey = '';
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue