2021-11-17 13:31:22 +03:00
import * as cache from '@actions/cache' ;
import * as core from '@actions/core' ;
2023-02-20 13:36:57 +01:00
import { CACHE_DEPENDENCY_BACKUP_PATH } from './constants' ;
2021-11-17 13:31:22 +03:00
export enum State {
STATE_CACHE_PRIMARY_KEY = 'cache-primary-key' ,
CACHE_MATCHED_KEY = 'cache-matched-key' ,
CACHE_PATHS = 'cache-paths'
}
abstract class CacheDistributor {
protected CACHE_KEY_PREFIX = 'setup-python' ;
constructor (
protected packageManager : string ,
protected cacheDependencyPath : string
) { }
protected abstract getCacheGlobalDirectories ( ) : Promise < string [ ] > ;
protected abstract computeKeys ( ) : Promise < {
primaryKey : string ;
restoreKey : string [ ] | undefined ;
} > ;
Use correct Poetry config when collecting Poetry projects (#447)
* Use correct Poetry config when collecting Poetry projects
When collecting Poetry projects for caching, a '**/poetry.lock' glob is
used. However, in order to process the Poetry configuration, the
"poetry" command is run from the repo's root directory; this causes
Poetry to return an invalid configuration when there is a Poetry project
inside an inner directory.
Instead of running a single Poetry command, glob for the same pattern,
and run a Poetry command for every discovered project.
* Fix typo: saveSatetSpy -> saveStateSpy
* poetry: Support same virtualenv appearing in multiple projects
* Add nested Poetry projects test
* poetry: Set up environment for each project individually
* tests/cache-restore: Do not look for dependency files outside `data`
When the default dependency path is used for cache distributors, they
are looking for the dependency file in the project's root (including the
source code), which leads to tests taking a significant amount of time,
especially on Windows runners. We thus hit sporadic test failures.
Change the test cases such that dependency files are always searched for
inside of `__tests__/data`, ignoring the rest of the project.
* poetry: Simplify `virtualenvs.in-project` boolean check
* README: Explain that poetry might create multiple caches
* 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.
* poetry: Bump cache primary key
2023-01-03 18:13:00 +02:00
protected async handleLoadedCache() { }
2021-11-17 13:31:22 +03:00
public async restoreCache() {
const { primaryKey , restoreKey } = await this . computeKeys ( ) ;
if ( primaryKey . endsWith ( '-' ) ) {
2023-02-20 13:36:57 +01:00
const file =
this . packageManager === 'pip'
? ` ${ this . cacheDependencyPath
. split ( '\n' )
. join ( ',' ) } or $ { CACHE_DEPENDENCY_BACKUP_PATH } `
: this . cacheDependencyPath . split ( '\n' ) . join ( ',' ) ;
2021-11-17 13:31:22 +03:00
throw new Error (
2024-10-16 15:55:16 +05:30
` The cache folder path(s) for the package manager " ${ this . packageManager } " were retrieved but do not exist on the disk. This likely indicates that there are no dependencies to cache. Consider removing the cache step if it is not needed. `
2021-11-17 13:31:22 +03:00
) ;
}
const cachePath = await this . getCacheGlobalDirectories ( ) ;
core . saveState ( State . CACHE_PATHS , cachePath ) ;
2023-03-10 12:15:18 +01:00
let matchedKey : string | undefined ;
try {
matchedKey = await cache . restoreCache ( cachePath , primaryKey , restoreKey ) ;
} catch ( err ) {
const message = ( err as Error ) . message ;
core . info ( ` [warning] ${ message } ` ) ;
core . setOutput ( 'cache-hit' , false ) ;
return ;
}
core . saveState ( State . STATE_CACHE_PRIMARY_KEY , primaryKey ) ;
2021-11-17 13:31:22 +03:00
Use correct Poetry config when collecting Poetry projects (#447)
* Use correct Poetry config when collecting Poetry projects
When collecting Poetry projects for caching, a '**/poetry.lock' glob is
used. However, in order to process the Poetry configuration, the
"poetry" command is run from the repo's root directory; this causes
Poetry to return an invalid configuration when there is a Poetry project
inside an inner directory.
Instead of running a single Poetry command, glob for the same pattern,
and run a Poetry command for every discovered project.
* Fix typo: saveSatetSpy -> saveStateSpy
* poetry: Support same virtualenv appearing in multiple projects
* Add nested Poetry projects test
* poetry: Set up environment for each project individually
* tests/cache-restore: Do not look for dependency files outside `data`
When the default dependency path is used for cache distributors, they
are looking for the dependency file in the project's root (including the
source code), which leads to tests taking a significant amount of time,
especially on Windows runners. We thus hit sporadic test failures.
Change the test cases such that dependency files are always searched for
inside of `__tests__/data`, ignoring the rest of the project.
* poetry: Simplify `virtualenvs.in-project` boolean check
* README: Explain that poetry might create multiple caches
* 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.
* poetry: Bump cache primary key
2023-01-03 18:13:00 +02:00
await this . handleLoadedCache ( ) ;
2022-04-05 06:57:13 -07:00
this . handleMatchResult ( matchedKey , primaryKey ) ;
}
public handleMatchResult ( matchedKey : string | undefined , primaryKey : string ) {
2021-11-17 13:31:22 +03:00
if ( matchedKey ) {
core . saveState ( State . CACHE_MATCHED_KEY , matchedKey ) ;
core . info ( ` Cache restored from key: ${ matchedKey } ` ) ;
} else {
core . info ( ` ${ this . packageManager } cache is not found ` ) ;
}
2022-04-05 06:57:13 -07:00
core . setOutput ( 'cache-hit' , matchedKey === primaryKey ) ;
2021-11-17 13:31:22 +03:00
}
}
export default CacheDistributor ;