mirror of
https://github.com/actions/setup-python.git
synced 2024-11-21 22:19:24 +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 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 `pipenv`, the action will cache virtualenv directory
|
||||
|
|
|
@ -5,7 +5,7 @@ import * as exec from '@actions/exec';
|
|||
import * as io from '@actions/io';
|
||||
import {getCacheDistributor} from '../src/cache-distributions/cache-factory';
|
||||
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', () => {
|
||||
const pipFileLockHash =
|
||||
|
@ -196,11 +196,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
|||
30000
|
||||
);
|
||||
|
||||
it.each([
|
||||
['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']
|
||||
])(
|
||||
it.each([['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']])(
|
||||
'Should throw an error because dependency file is not found',
|
||||
async (
|
||||
packageManager,
|
||||
|
@ -213,6 +209,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
|||
pythonVersion,
|
||||
dependencyFile
|
||||
);
|
||||
|
||||
await expect(cacheDistributor.restoreCache()).rejects.toThrowError(
|
||||
`No file in ${process.cwd()} matched to [${cacheDependencyPath
|
||||
.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', () => {
|
||||
|
|
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;
|
||||
const cache = __importStar(__nccwpck_require__(7799));
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const constants_1 = __nccwpck_require__(8248);
|
||||
var State;
|
||||
(function (State) {
|
||||
State["STATE_CACHE_PRIMARY_KEY"] = "cache-primary-key";
|
||||
|
@ -59718,9 +59719,12 @@ class CacheDistributor {
|
|||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { primaryKey, restoreKey } = yield this.computeKeys();
|
||||
if (primaryKey.endsWith('-')) {
|
||||
throw new Error(`No file in ${process.cwd()} matched to [${this.cacheDependencyPath
|
||||
.split('\n')
|
||||
.join(',')}], make sure you have checked out the target repository`);
|
||||
const file = this.packageManager === 'pip'
|
||||
? `${this.cacheDependencyPath
|
||||
.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();
|
||||
core.saveState(State.CACHE_PATHS, cachePath);
|
||||
|
@ -59744,6 +59748,19 @@ class 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:
|
||||
|
|
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;
|
||||
const cache = __importStar(__nccwpck_require__(7799));
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const constants_1 = __nccwpck_require__(8248);
|
||||
var State;
|
||||
(function (State) {
|
||||
State["STATE_CACHE_PRIMARY_KEY"] = "cache-primary-key";
|
||||
|
@ -65794,9 +65795,12 @@ class CacheDistributor {
|
|||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { primaryKey, restoreKey } = yield this.computeKeys();
|
||||
if (primaryKey.endsWith('-')) {
|
||||
throw new Error(`No file in ${process.cwd()} matched to [${this.cacheDependencyPath
|
||||
.split('\n')
|
||||
.join(',')}], make sure you have checked out the target repository`);
|
||||
const file = this.packageManager === 'pip'
|
||||
? `${this.cacheDependencyPath
|
||||
.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();
|
||||
core.saveState(State.CACHE_PATHS, cachePath);
|
||||
|
@ -65856,6 +65860,19 @@ function getCacheDistributor(packageManager, pythonVersion, cacheDependencyPath)
|
|||
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:
|
||||
|
@ -65904,10 +65921,12 @@ const path = __importStar(__nccwpck_require__(1017));
|
|||
const os_1 = __importDefault(__nccwpck_require__(2037));
|
||||
const cache_distributor_1 = __importDefault(__nccwpck_require__(8953));
|
||||
const utils_1 = __nccwpck_require__(1314);
|
||||
const constants_1 = __nccwpck_require__(8248);
|
||||
class PipCache extends cache_distributor_1.default {
|
||||
constructor(pythonVersion, cacheDependencyPath = '**/requirements.txt') {
|
||||
super('pip', cacheDependencyPath);
|
||||
this.pythonVersion = pythonVersion;
|
||||
this.cacheDependencyBackupPath = constants_1.CACHE_DEPENDENCY_BACKUP_PATH;
|
||||
}
|
||||
getCacheGlobalDirectories() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
|
@ -65943,7 +65962,8 @@ class PipCache extends cache_distributor_1.default {
|
|||
}
|
||||
computeKeys() {
|
||||
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 restoreKey = '';
|
||||
if (utils_1.IS_LINUX) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import {CACHE_DEPENDENCY_BACKUP_PATH} from './constants';
|
||||
|
||||
export enum State {
|
||||
STATE_CACHE_PRIMARY_KEY = 'cache-primary-key',
|
||||
|
@ -24,10 +25,14 @@ abstract class CacheDistributor {
|
|||
public async restoreCache() {
|
||||
const {primaryKey, restoreKey} = await this.computeKeys();
|
||||
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(
|
||||
`No file in ${process.cwd()} matched to [${this.cacheDependencyPath
|
||||
.split('\n')
|
||||
.join(',')}], make sure you have checked out the target repository`
|
||||
`No file in ${process.cwd()} matched to [${file}], 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 {getLinuxInfo, IS_LINUX, IS_WINDOWS} from '../utils';
|
||||
import {CACHE_DEPENDENCY_BACKUP_PATH} from './constants';
|
||||
|
||||
class PipCache extends CacheDistributor {
|
||||
private cacheDependencyBackupPath: string = CACHE_DEPENDENCY_BACKUP_PATH;
|
||||
|
||||
constructor(
|
||||
private pythonVersion: string,
|
||||
cacheDependencyPath: string = '**/requirements.txt'
|
||||
|
@ -56,7 +59,9 @@ class PipCache extends CacheDistributor {
|
|||
}
|
||||
|
||||
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 restoreKey = '';
|
||||
|
||||
|
|
Loading…
Reference in a new issue