Compare commits

...
7 changed files with 986 additions and 699 deletions
+37
View File
@@ -1326,3 +1326,40 @@ jobs:
echo "Unexpected success!"
exit 1
if: ${{ steps.test.outcome != 'failure' }}
configuration:
timeout-minutes: 10
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Move pixi.toml
run: mv test/default/* .
- uses: ./
with:
cache: false
configuration: |
change-ps1 = false
- name: Check configuration file was created (Unix)
run: |
test -f ~/.pixi/config.toml
cat ~/.pixi/config.toml
grep -q "change-ps1 = false" ~/.pixi/config.toml
shell: bash
if: matrix.os != 'windows-latest'
- name: Check configuration file was created (Windows)
run: |
if (!(Test-Path "$env:USERPROFILE\.pixi\config.toml")) {
Write-Error "Config file not found"
exit 1
}
Get-Content "$env:USERPROFILE\.pixi\config.toml"
if (!(Select-String -Path "$env:USERPROFILE\.pixi\config.toml" -Pattern "change-ps1 = false" -Quiet)) {
Write-Error "Configuration not found in config file"
exit 1
}
if: matrix.os == 'windows-latest'
- run: pixi run python --version | grep -q 3.11
+16
View File
@@ -458,6 +458,22 @@ If you only want to install pixi and not install the current project, you can us
run-install: false
```
### Global configuration
You can specify global pixi configuration in TOML format using the `configuration` input.
This allows you to customize pixi's behavior by setting various configuration options.
```yml
- uses: prefix-dev/setup-pixi@v0.9.4
with:
configuration: |
run-post-link-scripts = "insecure"
```
The configuration will be written to `~/.pixi/config.toml` before pixi runs any commands.
You can specify any valid pixi configuration option.
For more information about available configuration options, see the [pixi configuration documentation](https://pixi.sh/latest/reference/pixi_configuration/).
### Download pixi from a custom URL
You can also download pixi from a custom URL by setting the `pixi-url` input argument.
+4
View File
@@ -86,6 +86,10 @@ inputs:
description: |
If the action should clean up after itself. Defaults to `true`.
If `true`, the pixi environment, the pixi binary and the rattler files in ~/.rattler and ~/.cache/rattler are removed.
configuration:
description: |
Global pixi configuration in TOML format. Will be written to ~/.pixi/config.toml.
For example, to enable insecure post-link scripts: `run-post-link-scripts = "insecure"`
runs:
using: node24
Generated Vendored
+873 -695
View File
File diff suppressed because it is too large Load Diff
Generated Vendored
+4 -2
View File
@@ -31042,7 +31042,8 @@ var inferOptions = (inputs) => {
globalCache,
pixiBinPath,
auth,
postCleanup
postCleanup,
configuration: inputs.configuration
};
};
var assertOptions = (_options2) => {
@@ -31084,7 +31085,8 @@ var getOptions = () => {
authS3SessionToken: parseOrUndefined("auth-s3-session-token", string2()),
pypiKeyringProvider: parseOrUndefined("pypi-keyring-provider", pypiKeyringProviderSchema),
globalEnvironments: parseOrUndefinedMultilineList("global-environments", string2()),
postCleanup: parseOrUndefinedJSON("post-cleanup", boolean2())
postCleanup: parseOrUndefinedJSON("post-cleanup", boolean2()),
configuration: parseOrUndefined("configuration", string2())
};
core2.debug(`Inputs: ${JSON.stringify(inputs)}`);
validateInputs(inputs);
+46
View File
@@ -4,6 +4,7 @@ import path from 'path'
import { exit } from 'process'
import * as core from '@actions/core'
import { downloadTool } from '@actions/tool-cache'
import { parse, stringify } from 'smol-toml'
import type { PixiSource } from './options'
import { options } from './options'
import { execute, pixiCmd, renderPixiUrl } from './util'
@@ -23,6 +24,50 @@ const downloadPixi = async (source: PixiSource) => {
})
}
const writePixiConfig = async () => {
const { configuration } = options
if (!configuration) {
core.debug('Skipping pixi config setup.')
return
}
await core.group('Writing pixi configuration', async () => {
const configDir = path.join(os.homedir(), '.pixi')
const configPath = path.join(configDir, 'config.toml')
// Validate TOML before writing
let parsedNewConfig: Record<string, unknown>
try {
parsedNewConfig = parse(configuration)
core.debug(`Parsed configuration: ${JSON.stringify(parsedNewConfig)}`)
} catch (error) {
throw new Error(`Invalid TOML configuration: ${error instanceof Error ? error.message : String(error)}`)
}
await fs.mkdir(configDir, { recursive: true })
// Check if config file already exists and throw error if it does
try {
await fs.access(configPath)
throw new Error(
`Configuration file already exists at ${configPath}. ` +
`Please remove the existing file or do not use the configuration input.`
)
} catch (error) {
// If file doesn't exist (ENOENT), continue with writing
if (error instanceof Error && 'code' in error && (error as NodeJS.ErrnoException).code !== 'ENOENT') {
throw error
}
core.debug(`No existing configuration found at ${configPath}, creating new file`)
}
core.debug(`Writing pixi configuration to ${configPath}`)
const tomlContent = stringify(parsedNewConfig)
await fs.writeFile(configPath, tomlContent, 'utf-8')
core.info(`Pixi configuration written to ${configPath}`)
})
}
const pixiLogin = async () => {
const auth = options.auth
if (!auth) {
@@ -155,6 +200,7 @@ const run = async () => {
await downloadPixi(options.pixiSource)
}
addPixiToPath()
await writePixiConfig()
await pixiLogin()
await pixiGlobalInstall()
await generateInfo()
+6 -2
View File
@@ -38,6 +38,7 @@ type Inputs = Readonly<{
pypiKeyringProvider?: 'disabled' | 'subprocess'
postCleanup?: boolean
globalEnvironments?: string[]
configuration?: string
}>
export interface PixiSource {
@@ -95,6 +96,7 @@ export type Options = Readonly<{
postCleanup: boolean
activatedEnvironment?: string
globalEnvironments?: string[]
configuration?: string
}>
const pixiPath = 'pixi.toml'
const pyprojectPath = 'pyproject.toml'
@@ -399,7 +401,8 @@ const inferOptions = (inputs: Inputs): Options => {
globalCache,
pixiBinPath,
auth,
postCleanup
postCleanup,
configuration: inputs.configuration
}
}
@@ -449,7 +452,8 @@ const getOptions = () => {
authS3SessionToken: parseOrUndefined('auth-s3-session-token', z.string()),
pypiKeyringProvider: parseOrUndefined('pypi-keyring-provider', pypiKeyringProviderSchema),
globalEnvironments: parseOrUndefinedMultilineList('global-environments', z.string()),
postCleanup: parseOrUndefinedJSON('post-cleanup', z.boolean())
postCleanup: parseOrUndefinedJSON('post-cleanup', z.boolean()),
configuration: parseOrUndefined('configuration', z.string())
}
core.debug(`Inputs: ${JSON.stringify(inputs)}`)
validateInputs(inputs)