• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

open-turo / action-setup-tools / 13360358966

17 Feb 2025 12:31AM UTC coverage: 74.865%. Remained the same
13360358966

push

github

open-turo-bot
chore(deps): update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.21.0

199 of 285 branches covered (69.82%)

Branch coverage included in aggregate %.

495 of 642 relevant lines covered (77.1%)

173.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.86
/python.js
1
import os from "os"
2
import path from "path"
3
import assert from "assert"
4

5
import core from "@actions/core"
6

7
import Tool from "./tool.js"
8

9
export default class Python extends Tool {
10
    static tool = "python"
3✔
11
    static envVar = "PYENV_ROOT"
3✔
12
    static envPaths = ["bin", "shims", "plugins/pyenv-virtualenv/shims"]
3✔
13
    static installer = "pyenv"
3✔
14

15
    constructor() {
16
        super(Python.tool)
12✔
17
    }
18

19
    async setup(desiredVersion) {
20
        const [checkVersion, isVersionOverridden] = this.getVersion(
11✔
21
            desiredVersion,
22
            ".python-version",
23
        )
24
        if (!(await this.haveVersion(checkVersion))) {
11!
25
            if (checkVersion) {
11✔
26
                // Ensure pip exists as well, but don't error if it breaks
27
                await this.installPip().catch(() => {})
1✔
28
            }
29
            return checkVersion
11✔
30
        }
31

32
        // Check if pyenv exists and can be run, and capture the version info while
33
        // we're at it
34
        await this.findInstaller()
×
35

36
        // Ensure we have the latest pyenv and python versions available
37
        await this.updatePyenv()
×
38

39
        // Set downstream environment variable for future steps in this Job
40
        if (isVersionOverridden) {
×
41
            core.exportVariable("PYENV_VERSION", checkVersion)
×
42
        }
43

44
        // using -s option to skip the install and become a no-op if the
45
        // version requested to be installed is already installed according to pyenv.
46
        let installCommand = `pyenv install -s`
×
47
        // pyenv install does not pick up the environment variable PYENV_VERSION
48
        // unlike tfenv, so we specify it here as an argument explicitly, if it's set
49
        if (isVersionOverridden) installCommand += ` ${checkVersion}`
×
50

51
        await this.subprocessShell(installCommand).catch(
×
52
            this.logAndExit(`failed to install python version ${checkVersion}`),
53
        )
54

55
        // Sanity check the python command works, and output its version
56
        await this.validateVersion(checkVersion)
×
57

58
        // Sanity check the pip command works, and output its version
59
        await this.version("pip --version")
×
60

61
        // If we got this far, we have successfully configured python.
62
        core.setOutput(Python.tool, checkVersion)
×
63
        this.info("python success!")
×
64
        return checkVersion
×
65
    }
66

67
    /**
68
     * Update pyenv via the 'pyenv update' plugin command, if it's available.
69
     */
70
    async updatePyenv() {
71
        // Extract PYENV_VERSION to stop it complaining
72
        // eslint-disable-next-line no-unused-vars
73
        const { PYENV_VERSION, ...env } = process.env
×
74
        const cmd = `${this.installer} update`
×
75
        await this.subprocessShell(cmd, {
×
76
            // Run outside the repo root so we don't pick up defined version files
77
            cwd: process.env.RUNNER_TEMP,
78
            env: { ...env, ...this.getEnv() },
79
        }).catch((err) => {
80
            this.warning(
×
81
                `Failed to update pyenv, latest versions may not be supported`,
82
            )
83
            if (err.stderr) {
×
84
                this.debug(err.stderr)
×
85
            }
86
        })
87
    }
88

89
    async setEnv() {
90
        core.exportVariable("PYENV_VIRTUALENV_INIT", 1)
×
91
        return super.setEnv()
×
92
    }
93

94
    /**
95
     * Download and configures pyenv.
96
     *
97
     * @param  {string} root - Directory to install pyenv into (PYENV_ROOT).
98
     * @return {string} The value of PYENV_ROOT.
99
     */
100
    async install(root) {
101
        assert(root, "root is required")
1✔
102
        const gh = `https://${process.env.GITHUB_SERVER || "github.com"}/pyenv`
1✔
103
        const url = `${gh}/pyenv/archive/refs/heads/master.tar.gz`
1✔
104

105
        root = await this.downloadTool(url, { dest: root, strip: 1 })
1✔
106
        this.info(`Downloaded pyenv to ${root}`)
1✔
107

108
        return root
1✔
109
    }
110

111
    /**
112
     * Ensures pip is installed.
113
     */
114
    async installPip() {
115
        // Check for an existing version using whatever environment has been set
116
        const pipVersion = await this.version("pip --version", {
1✔
117
            soft: true,
118
            env: { ...process.env },
119
        }).catch(() => {})
120
        if (pipVersion) {
1!
121
            this.debug(`pip is already installed (${pipVersion})`)
1✔
122
            return
1✔
123
        }
124

125
        this.info("Installing pip")
×
126
        const url = "https://bootstrap.pypa.io/get-pip.py"
×
127
        const download = await this.downloadTool(url)
×
128
        await this.subprocessShell(`python ${download}`, {
×
129
            env: { ...process.env },
130
        })
131

132
        // get-pip.py will install to $HOME/.local/bin for a system install, so
133
        // we add it to the PATH or things break
134
        core.addPath(path.join(os.homedir(), ".local/bin"))
×
135

136
        // Just run `pyenv rehash` always and ignore errors because we might be
137
        // in a setup-python environment that doesn't have it
138
        this.info("Rehashing pyenv shims")
×
139
        await this.subprocessShell("pyenv rehash", {
×
140
            env: { ...process.env },
141
        }).catch(() => {})
142

143
        // Sanity check the pip command works, and output its version
144
        await this.version("pip --version", { env: { ...process.env } })
×
145
    }
146
}
147

148
// Register the subclass in our tool list
149
Python.register()
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc