2023-03-09 10:44:56 +00:00
/* eslint no-unsafe-finally: "off" */
2022-03-31 19:11:27 +00:00
import * as cache from '@actions/cache' ;
import * as core from '@actions/core' ;
2020-12-17 15:03:54 +00:00
import fs from 'fs' ;
import * as path from 'path' ;
import * as semver from 'semver' ;
2022-07-19 12:20:19 +00:00
import * as exec from '@actions/exec' ;
2020-12-17 15:03:54 +00:00
export const IS_WINDOWS = process . platform === 'win32' ;
export const IS_LINUX = process . platform === 'linux' ;
2022-07-22 08:02:07 +00:00
export const IS_MAC = process . platform === 'darwin' ;
2021-04-12 17:59:38 +00:00
export const WINDOWS_ARCHS = [ 'x86' , 'x64' ] ;
export const WINDOWS_PLATFORMS = [ 'win32' , 'win64' ] ;
2020-12-17 15:03:54 +00:00
const PYPY_VERSION_FILE = 'PYPY_VERSION' ;
export interface IPyPyManifestAsset {
filename : string ;
arch : string ;
platform : string ;
download_url : string ;
}
export interface IPyPyManifestRelease {
pypy_version : string ;
python_version : string ;
stable : boolean ;
latest_pypy : boolean ;
files : IPyPyManifestAsset [ ] ;
}
/ * * c r e a t e S y m l i n k s f o r d o w n l o a d e d P y P y
* It should be executed only for downloaded versions in runtime , because
* toolcache versions have this setup .
* /
export function createSymlinkInFolder (
folderPath : string ,
sourceName : string ,
targetName : string ,
setExecutable = false
) {
const sourcePath = path . join ( folderPath , sourceName ) ;
const targetPath = path . join ( folderPath , targetName ) ;
if ( fs . existsSync ( targetPath ) ) {
return ;
}
fs . symlinkSync ( sourcePath , targetPath ) ;
if ( ! IS_WINDOWS && setExecutable ) {
fs . chmodSync ( targetPath , '755' ) ;
}
}
export function validateVersion ( version : string ) {
return isNightlyKeyword ( version ) || Boolean ( semver . validRange ( version ) ) ;
}
export function isNightlyKeyword ( pypyVersion : string ) {
return pypyVersion === 'nightly' ;
}
export function getPyPyVersionFromPath ( installDir : string ) {
return path . basename ( path . dirname ( installDir ) ) ;
}
/ * *
* In tool - cache , we put PyPy to '<toolcache_root>/PyPy/<python_version>/x64'
* There is no easy way to determine what PyPy version is located in specific folder
* 'pypy --version' is not reliable enough since it is not set properly for preview versions
* "7.3.3rc1" is marked as '7.3.3' in 'pypy --version'
* so we put PYPY_VERSION file to PyPy directory when install it to VM and read it when we need to know version
* PYPY_VERSION contains exact version from 'versions.json'
* /
export function readExactPyPyVersionFile ( installDir : string ) {
let pypyVersion = '' ;
2023-03-09 10:44:56 +00:00
const fileVersion = path . join ( installDir , PYPY_VERSION_FILE ) ;
2020-12-17 15:03:54 +00:00
if ( fs . existsSync ( fileVersion ) ) {
2023-02-20 10:28:16 +00:00
pypyVersion = fs . readFileSync ( fileVersion ) . toString ( ) . trim ( ) ;
2020-12-17 15:03:54 +00:00
}
return pypyVersion ;
}
export function writeExactPyPyVersionFile (
installDir : string ,
resolvedPyPyVersion : string
) {
const pypyFilePath = path . join ( installDir , PYPY_VERSION_FILE ) ;
fs . writeFileSync ( pypyFilePath , resolvedPyPyVersion ) ;
}
/ * *
* Python version should be specified explicitly like "x.y" ( 2.7 , 3.6 , 3.7 )
* "3.x" or "3" are not supported
* because it could cause ambiguity when both PyPy version and Python version are not precise
* /
export function validatePythonVersionFormatForPyPy ( version : string ) {
const re = /^\d+\.\d+$/ ;
return re . test ( version ) ;
}
2021-11-17 10:31:22 +00:00
export function isGhes ( ) : boolean {
const ghUrl = new URL (
process . env [ 'GITHUB_SERVER_URL' ] || 'https://github.com'
) ;
return ghUrl . hostname . toUpperCase ( ) !== 'GITHUB.COM' ;
}
2022-03-31 19:11:27 +00:00
export function isCacheFeatureAvailable ( ) : boolean {
2022-12-19 13:00:46 +00:00
if ( cache . isFeatureAvailable ( ) ) {
return true ;
}
2022-03-31 19:11:27 +00:00
2022-12-19 13:00:46 +00:00
if ( isGhes ( ) ) {
core . warning (
'Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.'
) ;
2022-03-31 19:11:27 +00:00
return false ;
}
2022-12-19 13:00:46 +00:00
core . warning (
'The runner was not able to contact the cache service. Caching will be skipped'
) ;
return false ;
2022-03-31 19:11:27 +00:00
}
2022-07-19 12:20:19 +00:00
2022-12-07 17:12:42 +00:00
export function logWarning ( message : string ) : void {
const warningPrefix = '[warning]' ;
core . info ( ` ${ warningPrefix } ${ message } ` ) ;
}
async function getWindowsInfo() {
const { stdout } = await exec . getExecOutput (
'powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Caption"' ,
undefined ,
2022-07-19 12:20:19 +00:00
{
silent : true
}
) ;
2022-12-07 17:12:42 +00:00
const windowsVersion = stdout . trim ( ) . split ( ' ' ) [ 3 ] ;
2022-07-19 12:20:19 +00:00
2022-12-07 17:12:42 +00:00
return { osName : 'Windows' , osVersion : windowsVersion } ;
}
async function getMacOSInfo() {
const { stdout } = await exec . getExecOutput ( 'sw_vers' , [ '-productVersion' ] , {
silent : true
} ) ;
2022-07-19 12:20:19 +00:00
2022-12-07 17:12:42 +00:00
const macOSVersion = stdout . trim ( ) ;
return { osName : 'macOS' , osVersion : macOSVersion } ;
2022-07-19 12:20:19 +00:00
}
2022-07-25 13:02:06 +00:00
2022-12-07 17:12:42 +00:00
export async function getLinuxInfo() {
const { stdout } = await exec . getExecOutput ( 'lsb_release' , [ '-i' , '-r' , '-s' ] , {
silent : true
} ) ;
const [ osName , osVersion ] = stdout . trim ( ) . split ( '\n' ) ;
core . debug ( ` OS Name: ${ osName } , Version: ${ osVersion } ` ) ;
return { osName : osName , osVersion : osVersion } ;
}
export async function getOSInfo() {
let osInfo ;
try {
if ( IS_WINDOWS ) {
osInfo = await getWindowsInfo ( ) ;
} else if ( IS_LINUX ) {
osInfo = await getLinuxInfo ( ) ;
} else if ( IS_MAC ) {
osInfo = await getMacOSInfo ( ) ;
}
} catch ( err ) {
const error = err as Error ;
core . debug ( error . message ) ;
} finally {
return osInfo ;
}
2022-07-25 13:02:06 +00:00
}