Skip to content

Commit 881ca6e

Browse files
committed
poetry: Run poetry env use only after cache is loaded
The virtualenv cache might contain invalid entries, such as virtualenvs built in previous, buggy versions of this action. The `poetry env use` command will recreate virtualenvs in case they are invalid, but it has to be run only *after* the cache is loaded. Refactor `CacheDistributor` a bit such that the validation (and possible recreation) of virtualenvs happens only after the cache is loaded.
1 parent bc3992e commit 881ca6e

File tree

4 files changed

+68
-34
lines changed

4 files changed

+68
-34
lines changed

dist/cache-save/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59711,6 +59711,9 @@ class CacheDistributor {
5971159711
this.cacheDependencyPath = cacheDependencyPath;
5971259712
this.CACHE_KEY_PREFIX = 'setup-python';
5971359713
}
59714+
handleLoadedCache() {
59715+
return __awaiter(this, void 0, void 0, function* () { });
59716+
}
5971459717
restoreCache() {
5971559718
return __awaiter(this, void 0, void 0, function* () {
5971659719
const { primaryKey, restoreKey } = yield this.computeKeys();
@@ -59723,6 +59726,7 @@ class CacheDistributor {
5972359726
core.saveState(State.CACHE_PATHS, cachePath);
5972459727
core.saveState(State.STATE_CACHE_PRIMARY_KEY, primaryKey);
5972559728
const matchedKey = yield cache.restoreCache(cachePath, primaryKey, restoreKey);
59729+
yield this.handleLoadedCache();
5972659730
this.handleMatchResult(matchedKey, primaryKey);
5972759731
});
5972859732
}

dist/setup/index.js

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65787,6 +65787,9 @@ class CacheDistributor {
6578765787
this.cacheDependencyPath = cacheDependencyPath;
6578865788
this.CACHE_KEY_PREFIX = 'setup-python';
6578965789
}
65790+
handleLoadedCache() {
65791+
return __awaiter(this, void 0, void 0, function* () { });
65792+
}
6579065793
restoreCache() {
6579165794
return __awaiter(this, void 0, void 0, function* () {
6579265795
const { primaryKey, restoreKey } = yield this.computeKeys();
@@ -65799,6 +65802,7 @@ class CacheDistributor {
6579965802
core.saveState(State.CACHE_PATHS, cachePath);
6580065803
core.saveState(State.STATE_CACHE_PRIMARY_KEY, primaryKey);
6580165804
const matchedKey = yield cache.restoreCache(cachePath, primaryKey, restoreKey);
65805+
yield this.handleLoadedCache();
6580265806
this.handleMatchResult(matchedKey, primaryKey);
6580365807
});
6580465808
}
@@ -66097,42 +66101,31 @@ const core = __importStar(__nccwpck_require__(2186));
6609766101
const cache_distributor_1 = __importDefault(__nccwpck_require__(8953));
6609866102
const utils_1 = __nccwpck_require__(1314);
6609966103
class PoetryCache extends cache_distributor_1.default {
66100-
constructor(pythonVersion, patterns = '**/poetry.lock') {
66104+
constructor(pythonVersion, patterns = '**/poetry.lock', poetryProjects = new Set()) {
6610166105
super('poetry', patterns);
6610266106
this.pythonVersion = pythonVersion;
6610366107
this.patterns = patterns;
66108+
this.poetryProjects = poetryProjects;
6610466109
}
6610566110
getCacheGlobalDirectories() {
6610666111
var e_1, _a;
6610766112
return __awaiter(this, void 0, void 0, function* () {
6610866113
// Same virtualenvs path may appear for different projects, hence we use a Set
6610966114
const paths = new Set();
6611066115
const globber = yield glob.create(this.patterns);
66111-
const pythonLocation = yield io.which('python');
66112-
if (pythonLocation) {
66113-
core.debug(`pythonLocation is ${pythonLocation}`);
66114-
}
66115-
else {
66116-
utils_1.logWarning('python binaries were not found in PATH');
66117-
}
6611866116
try {
6611966117
for (var _b = __asyncValues(globber.globGenerator()), _c; _c = yield _b.next(), !_c.done;) {
6612066118
const file = _c.value;
6612166119
const basedir = path.dirname(file);
6612266120
core.debug(`Processing Poetry project at ${basedir}`);
66121+
this.poetryProjects.add(basedir);
6612366122
const poetryConfig = yield this.getPoetryConfiguration(basedir);
6612466123
const cacheDir = poetryConfig['cache-dir'];
6612566124
const virtualenvsPath = poetryConfig['virtualenvs.path'].replace('{cache-dir}', cacheDir);
6612666125
paths.add(virtualenvsPath);
6612766126
if (poetryConfig['virtualenvs.in-project']) {
6612866127
paths.add(path.join(basedir, '.venv'));
6612966128
}
66130-
if (pythonLocation) {
66131-
const { exitCode, stderr } = yield exec.getExecOutput('poetry', ['env', 'use', pythonLocation], { ignoreReturnCode: true, cwd: basedir });
66132-
if (exitCode) {
66133-
utils_1.logWarning(stderr);
66134-
}
66135-
}
6613666129
}
6613766130
}
6613866131
catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -66156,6 +66149,30 @@ class PoetryCache extends cache_distributor_1.default {
6615666149
};
6615766150
});
6615866151
}
66152+
handleLoadedCache() {
66153+
const _super = Object.create(null, {
66154+
handleLoadedCache: { get: () => super.handleLoadedCache }
66155+
});
66156+
return __awaiter(this, void 0, void 0, function* () {
66157+
yield _super.handleLoadedCache.call(this);
66158+
// After the cache is loaded -- make sure virtualenvs use the correct Python version (the one that we have just installed).
66159+
// This will handle invalid caches, recreating virtualenvs if necessary.
66160+
const pythonLocation = yield io.which('python');
66161+
if (pythonLocation) {
66162+
core.debug(`pythonLocation is ${pythonLocation}`);
66163+
}
66164+
else {
66165+
utils_1.logWarning('python binaries were not found in PATH');
66166+
return;
66167+
}
66168+
for (const poetryProject of this.poetryProjects) {
66169+
const { exitCode, stderr } = yield exec.getExecOutput('poetry', ['env', 'use', pythonLocation], { ignoreReturnCode: true, cwd: poetryProject });
66170+
if (exitCode) {
66171+
utils_1.logWarning(stderr);
66172+
}
66173+
}
66174+
});
66175+
}
6615966176
getPoetryConfiguration(basedir) {
6616066177
return __awaiter(this, void 0, void 0, function* () {
6616166178
const { stdout, stderr, exitCode } = yield exec.getExecOutput('poetry', ['config', '--list'], { cwd: basedir });

src/cache-distributions/cache-distributor.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ abstract class CacheDistributor {
1919
primaryKey: string;
2020
restoreKey: string[] | undefined;
2121
}>;
22+
protected async handleLoadedCache() {}
2223

2324
public async restoreCache() {
2425
const {primaryKey, restoreKey} = await this.computeKeys();
@@ -41,6 +42,8 @@ abstract class CacheDistributor {
4142
restoreKey
4243
);
4344

45+
await this.handleLoadedCache();
46+
4447
this.handleMatchResult(matchedKey, primaryKey);
4548
}
4649

src/cache-distributions/poetry-cache.ts

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {logWarning} from '../utils';
1010
class PoetryCache extends CacheDistributor {
1111
constructor(
1212
private pythonVersion: string,
13-
protected patterns: string = '**/poetry.lock'
13+
protected patterns: string = '**/poetry.lock',
14+
protected poetryProjects: Set<string> = new Set<string>()
1415
) {
1516
super('poetry', patterns);
1617
}
@@ -20,16 +21,10 @@ class PoetryCache extends CacheDistributor {
2021
const paths = new Set<string>();
2122
const globber = await glob.create(this.patterns);
2223

23-
const pythonLocation = await io.which('python');
24-
if (pythonLocation) {
25-
core.debug(`pythonLocation is ${pythonLocation}`);
26-
} else {
27-
logWarning('python binaries were not found in PATH');
28-
}
29-
3024
for await (const file of globber.globGenerator()) {
3125
const basedir = path.dirname(file);
3226
core.debug(`Processing Poetry project at ${basedir}`);
27+
this.poetryProjects.add(basedir);
3328

3429
const poetryConfig = await this.getPoetryConfiguration(basedir);
3530

@@ -44,18 +39,6 @@ class PoetryCache extends CacheDistributor {
4439
if (poetryConfig['virtualenvs.in-project']) {
4540
paths.add(path.join(basedir, '.venv'));
4641
}
47-
48-
if (pythonLocation) {
49-
const {exitCode, stderr} = await exec.getExecOutput(
50-
'poetry',
51-
['env', 'use', pythonLocation],
52-
{ignoreReturnCode: true, cwd: basedir}
53-
);
54-
55-
if (exitCode) {
56-
logWarning(stderr);
57-
}
58-
}
5942
}
6043

6144
return [...paths];
@@ -71,6 +54,33 @@ class PoetryCache extends CacheDistributor {
7154
};
7255
}
7356

57+
protected async handleLoadedCache() {
58+
await super.handleLoadedCache();
59+
60+
// After the cache is loaded -- make sure virtualenvs use the correct Python version (the one that we have just installed).
61+
// This will handle invalid caches, recreating virtualenvs if necessary.
62+
63+
const pythonLocation = await io.which('python');
64+
if (pythonLocation) {
65+
core.debug(`pythonLocation is ${pythonLocation}`);
66+
} else {
67+
logWarning('python binaries were not found in PATH');
68+
return;
69+
}
70+
71+
for (const poetryProject of this.poetryProjects) {
72+
const {exitCode, stderr} = await exec.getExecOutput(
73+
'poetry',
74+
['env', 'use', pythonLocation],
75+
{ignoreReturnCode: true, cwd: poetryProject}
76+
);
77+
78+
if (exitCode) {
79+
logWarning(stderr);
80+
}
81+
}
82+
}
83+
7484
private async getPoetryConfiguration(basedir: string) {
7585
const {stdout, stderr, exitCode} = await exec.getExecOutput(
7686
'poetry',

0 commit comments

Comments
 (0)