Add support of unstable Python versions

This commit is contained in:
MaksimZhukov 2020-07-15 17:57:44 +03:00
parent 654aa00a6e
commit 8fbc418d76
9 changed files with 4179 additions and 4088 deletions

View file

@ -92,6 +92,30 @@ jobs:
``` ```
Download and set up a specific unstable version of Python:
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.9.0-beta.4'
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
stable: false # optional true or false. Defaults to true if not specified
- run: python my_script.py
```
Download and set up a latest available unstable version of Python (including a stable version):
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.9.0-alpha - 3.9.0' # SemVer's version range syntax
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
stable: false # optional true or false. Defaults to true if not specified
- run: python my_script.py
```
# Getting started with Python + Actions # Getting started with Python + Actions
Check out our detailed guide on using [Python with GitHub Actions](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-python-with-github-actions). Check out our detailed guide on using [Python with GitHub Actions](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-python-with-github-actions).

View file

@ -1,13 +0,0 @@
{
"version": "1.2.3",
"stable": true,
"release_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6",
"files": [
{
"filename": "sometool-1.2.3-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6/sometool-1.2.3-linux-x64.tar.gz"
}
]
}

View file

@ -0,0 +1,52 @@
[
{
"version": "1.2.3",
"stable": true,
"release_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6",
"files": [
{
"filename": "sometool-1.2.3-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6/sometool-1.2.3-linux-x64.tar.gz"
},
{
"filename": "sometool-1.2.3-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6/sometool-1.2.3-darwin-x64.tar.gz"
},
{
"filename": "sometool-1.2.3-win32-x64.tar.gz",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.6/sometool-1.2.3-win32-x64.tar.gz"
}
]
},
{
"version": "1.2.3-beta.2",
"stable": false,
"release_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5",
"files": [
{
"filename": "sometool-1.2.3-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5/sometool-1.2.3-linux-x64.tar.gz"
},
{
"filename": "sometool-1.2.3-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-darwin-x64.tar.gz"
},
{
"filename": "sometool-1.2.3-win32-x64.tar.gz",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-win32-x64.tar.gz"
}
]
}
]

View file

@ -22,7 +22,7 @@ import * as tc from '@actions/tool-cache';
import * as finder from '../src/find-python'; import * as finder from '../src/find-python';
import * as installer from '../src/install-python'; import * as installer from '../src/install-python';
const pythonRelease = require('./data/python-release.json'); const manifestData = require('./data/versions-manifest.json');
describe('Finder tests', () => { describe('Finder tests', () => {
afterEach(() => { afterEach(() => {
@ -35,15 +35,12 @@ describe('Finder tests', () => {
await io.mkdirP(pythonDir); await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello'); fs.writeFileSync(`${pythonDir}.complete`, 'hello');
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists) // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
await finder.findPythonVersion('3.x', 'x64'); await finder.findPythonVersion('3.x', 'x64', true);
}); });
it('Finds Python if it is not installed, but exists in the manifest', async () => { it('Finds stable Python version if it is not installed, but exists in the manifest', async () => {
const findSpy: jest.SpyInstance = jest.spyOn( const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
installer, findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
'findReleaseFromManifest'
);
findSpy.mockImplementation(() => <tc.IToolRelease>pythonRelease);
const installSpy: jest.SpyInstance = jest.spyOn( const installSpy: jest.SpyInstance = jest.spyOn(
installer, installer,
@ -55,14 +52,36 @@ describe('Finder tests', () => {
fs.writeFileSync(`${pythonDir}.complete`, 'hello'); fs.writeFileSync(`${pythonDir}.complete`, 'hello');
}); });
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists) // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
await finder.findPythonVersion('1.2.3', 'x64'); await finder.findPythonVersion('1.2.3', 'x64', true);
});
it('Finds unstable Python version in the manifest', async () => {
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
const installSpy: jest.SpyInstance = jest.spyOn(
installer,
'installCpythonFromRelease'
);
installSpy.mockImplementation(async () => {
const pythonDir: string = path.join(
toolDir,
'Python',
'1.2.3-beta.2',
'x64'
);
await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
});
// This will throw if it doesn't find it in the manifest (because no such version exists)
await finder.findPythonVersion('1.2.3-beta.2', 'x64', false);
}); });
it('Errors if Python is not installed', async () => { it('Errors if Python is not installed', async () => {
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists) // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
let thrown = false; let thrown = false;
try { try {
await finder.findPythonVersion('3.300000', 'x64'); await finder.findPythonVersion('3.300000', 'x64', true);
} catch { } catch {
thrown = true; thrown = true;
} }
@ -74,6 +93,6 @@ describe('Finder tests', () => {
await io.mkdirP(pythonDir); await io.mkdirP(pythonDir);
fs.writeFileSync(`${pythonDir}.complete`, 'hello'); fs.writeFileSync(`${pythonDir}.complete`, 'hello');
// This will throw if it doesn't find it in the cache (because no such version exists) // This will throw if it doesn't find it in the cache (because no such version exists)
await finder.findPythonVersion('pypy2', 'x64'); await finder.findPythonVersion('pypy2', 'x64', true);
}); });
}); });

View file

@ -8,6 +8,9 @@ inputs:
default: '3.x' default: '3.x'
architecture: architecture:
description: 'The target architecture (x86, x64) of the Python interpreter.' description: 'The target architecture (x86, x64) of the Python interpreter.'
stable:
description: 'Whether to download only stable versions'
default: 'true'
token: token:
description: Used to pull python distributions from actions/python-versions. Since there's a default, this is typically not supplied by the user. description: Used to pull python distributions from actions/python-versions. Since there's a default, this is typically not supplied by the user.
default: ${{ github.token }} default: ${{ github.token }}

8101
dist/index.js vendored

File diff suppressed because it is too large Load diff

View file

@ -71,7 +71,8 @@ function usePyPy(majorVersion: 2 | 3, architecture: string): InstalledVersion {
async function useCpythonVersion( async function useCpythonVersion(
version: string, version: string,
architecture: string architecture: string,
stable: boolean
): Promise<InstalledVersion> { ): Promise<InstalledVersion> {
const desugaredVersionSpec = desugarDevVersion(version); const desugaredVersionSpec = desugarDevVersion(version);
const semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec); const semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec);
@ -88,7 +89,8 @@ async function useCpythonVersion(
); );
const foundRelease = await installer.findReleaseFromManifest( const foundRelease = await installer.findReleaseFromManifest(
semanticVersionSpec, semanticVersionSpec,
architecture architecture,
stable
); );
if (foundRelease && foundRelease.files && foundRelease.files.length > 0) { if (foundRelease && foundRelease.files && foundRelease.files.length > 0) {
@ -171,7 +173,8 @@ export function pythonVersionToSemantic(versionSpec: string) {
export async function findPythonVersion( export async function findPythonVersion(
version: string, version: string,
architecture: string architecture: string,
stable: boolean
): Promise<InstalledVersion> { ): Promise<InstalledVersion> {
switch (version.toUpperCase()) { switch (version.toUpperCase()) {
case 'PYPY2': case 'PYPY2':
@ -179,6 +182,6 @@ export async function findPythonVersion(
case 'PYPY3': case 'PYPY3':
return usePyPy(3, architecture); return usePyPy(3, architecture);
default: default:
return await useCpythonVersion(version, architecture); return await useCpythonVersion(version, architecture, stable);
} }
} }

View file

@ -15,7 +15,8 @@ const IS_WINDOWS = process.platform === 'win32';
export async function findReleaseFromManifest( export async function findReleaseFromManifest(
semanticVersionSpec: string, semanticVersionSpec: string,
architecture: string architecture: string,
stable: boolean
): Promise<tc.IToolRelease | undefined> { ): Promise<tc.IToolRelease | undefined> {
const manifest: tc.IToolRelease[] = await tc.getManifestFromRepo( const manifest: tc.IToolRelease[] = await tc.getManifestFromRepo(
MANIFEST_REPO_OWNER, MANIFEST_REPO_OWNER,
@ -25,7 +26,7 @@ export async function findReleaseFromManifest(
); );
return await tc.findFromManifest( return await tc.findFromManifest(
semanticVersionSpec, semanticVersionSpec,
true, stable,
manifest, manifest,
architecture architecture
); );

View file

@ -8,7 +8,8 @@ async function run() {
let version = core.getInput('python-version'); let version = core.getInput('python-version');
if (version) { if (version) {
const arch: string = core.getInput('architecture') || os.arch(); const arch: string = core.getInput('architecture') || os.arch();
const installed = await finder.findPythonVersion(version, arch); let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
const installed = await finder.findPythonVersion(version, arch, stable);
core.info(`Successfully setup ${installed.impl} (${installed.version})`); core.info(`Successfully setup ${installed.impl} (${installed.version})`);
} }
const matchersPath = path.join(__dirname, '..', '.github'); const matchersPath = path.join(__dirname, '..', '.github');