Compare commits

..
20 Commits
Author SHA1 Message Date
Pavel Zwerschke 84fcc9f320 ? 2025-12-16 14:52:35 +01:00
Pavel Zwerschke 292519c071 test ubuntu-24.04-arm 2025-12-16 14:49:27 +01:00
Pavel Zwerschke a4caa61122 WIP 2025-12-16 14:00:00 +01:00
Pavel Zwerschke f18b03747b feat: Adjust debug log message for activate-environment 2025-12-16 13:58:50 +01:00
Pavel Zwerschke ea732fd64a ci: Remove macos-13 tests (#240) 2025-12-09 22:25:24 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> fc696d768f chore(deps): bump the nodejs group with 9 updates (#239)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 10:55:48 +01:00
dependabot[bot] 71b46b9941 chore(deps): bump the gh-actions group with 3 updates (#238) 2025-12-01 07:55:46 +01:00
Pavel Zwerschke 82d477f15f feat: Switch order of pixi info and pixi install (#234) 2025-11-03 11:25:42 +01:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Pavel Zwerschke
a976380763 chore(deps): bump the nodejs group across 1 directory with 9 updates (#233)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2025-11-03 10:33:38 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> de110d6265 chore(deps): bump the gh-actions group with 4 updates (#232)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-01 06:47:05 +01:00
Ruben Arts 59d669bca0 Update documentation links to new pixi URLs (#230) 2025-10-20 06:26:01 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 046c0f75f2 chore(deps): bump the gh-actions group with 3 updates (#228)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-19 17:30:41 +02:00
github-actions[bot] 34ef3cc298 docs: Reference latest Pixi version in README (#227) 2025-10-19 17:30:07 +02:00
Olivier Lacroix 28eb668aaf feat: Allow caching global environment(s) (#226) 2025-10-19 15:37:21 +02:00
Olivier LacroixandPavel Zwerschke 194d461b21 Add possibility to install global environments (#221)
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2025-09-22 11:51:37 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 40ab2611f4 chore(deps): bump the nodejs group with 7 updates (#223)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-01 11:47:19 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 83ecca31f5 chore(deps): bump actions/checkout from 4.2.2 to 5.0.0 in the gh-actions group (#222)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-01 13:41:15 +02:00
Olivier Lacroix ba511d5090 Add pypi-keyring-provider option (#220) 2025-08-13 14:23:50 +02:00
Pavel Zwerschke fef5c9568c chore: Bump to node 24 (#219) 2025-08-11 23:29:05 +02:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Pavel Zwerschke
62618497c3 chore(deps): bump the nodejs group with 7 updates (#218)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2025-08-11 21:09:58 +00:00
21 changed files with 30947 additions and 26562 deletions
+11 -11
View File
@@ -15,15 +15,15 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Install pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.4.0
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.4.0
with:
version: 9
- name: Install Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: 20
cache: pnpm
@@ -41,13 +41,13 @@ jobs:
name: Reference latest version in README
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Assert latest setup-pixi version is mentioned in README
run: |
set -euo pipefail
latest_version="$(jq -r '.version' package.json)"
count_expected=19
count_expected=21
count_actual="$(grep -c "setup-pixi@v$latest_version" README.md || true)"
if [ "$count_actual" -ne "$count_expected" ]; then
echo "::error file=README.md::Expected $count_expected mentions of \`setup-pixi@v$latest_version\` in README.md, but found $count_actual."
@@ -62,7 +62,7 @@ jobs:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Assert latest pixi version is mentioned in README
run: |
@@ -79,7 +79,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create pull request
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9
if: failure() && github.ref_name == 'main'
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -90,15 +90,15 @@ jobs:
check-dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Install pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.4.0
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.4.0
with:
version: 9
- name: Install Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: 20
cache: pnpm
@@ -119,7 +119,7 @@ jobs:
id: diff
# If index.js or post.js are different than expected, upload the expected version as an artifact
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with:
name: dist
+2 -2
View File
@@ -12,7 +12,7 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: Quantco/ui-actions/version-metadata@cd71d2a0e30b25569f6d723e57acca83347e58fc # v1.0.18
id: version-metadata
with:
@@ -24,7 +24,7 @@ jobs:
TAG_NAME: v${{ steps.version-metadata.outputs.newVersion }}
- name: Create release
if: steps.version-metadata.outputs.changed == 'true'
uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 # v2.3.2
uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2
with:
generate_release_notes: true
tag_name: v${{ steps.version-metadata.outputs.newVersion }}
+1155 -1106
View File
File diff suppressed because it is too large Load Diff
+62 -27
View File
@@ -23,9 +23,9 @@ GitHub Action to set up the [pixi](https://github.com/prefix-dev/pixi) package m
## Usage
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
pixi-version: v0.49.0
pixi-version: v0.59.0
cache: true
auth-host: prefix.dev
@@ -35,7 +35,7 @@ GitHub Action to set up the [pixi](https://github.com/prefix-dev/pixi) package m
> [!WARNING]
> Since pixi is not yet stable, the API of this action may change between minor versions.
> Please pin the versions of this action to a specific version (i.e., `prefix-dev/setup-pixi@v0.8.14`) to avoid breaking changes.
> Please pin the versions of this action to a specific version (i.e., `prefix-dev/setup-pixi@v0.9.3`) to avoid breaking changes.
> You can automatically update the version of this action by using [Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot).
>
> Put the following in your `.github/dependabot.yml` file to enable Dependabot for your GitHub Actions:
@@ -59,14 +59,17 @@ To see all available input arguments, see the [`action.yml`](action.yml) file.
### Caching
The action supports caching of the pixi environment.
By default, caching is enabled if a `pixi.lock` file is present.
The action supports caching of the project and global pixi environments.
By default, project environment caching is enabled if a `pixi.lock` file is present.
It will then use the `pixi.lock` file to generate a hash of the environment and cache it.
If the cache is hit, the action will skip the installation and use the cached environment.
You can specify the behavior by setting the `cache` input argument.
If you need to customize your cache-key, you can use the `cache-key` input argument.
This will be the prefix of the cache key. The full cache key will be `<cache-key><conda-arch>-<hash>`.
Global environment caching is disabled by default and can be enabled by setting the `global-cache` input to `true`.
As there is no lockfile for global environments, the cache will expire at the end of every month to ensure it does not go stale.
If you need to customize your cache-key, you can use the `cache-key` and `global-cache-key` input arguments.
These will be the prefixes of the cache keys. The full cache keys will be `<cache-key><conda-arch>-<hash>` and `<global-cache-key><conda-arch>-<YYYY-MM>-<hash>` respectively.
#### Only save caches on `main`
@@ -74,7 +77,7 @@ In order to not exceed the [10 GB cache size limit](https://docs.github.com/en/a
This can be done by setting the `cache-write` argument.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
cache: true
cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
@@ -119,7 +122,7 @@ test:
environment: [py311, py312]
steps:
- uses: actions/checkout@v4
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
environments: ${{ matrix.environment }}
```
@@ -129,7 +132,7 @@ test:
The following example will install both the `py311` and the `py312` environment on the runner.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
# separated by spaces
environments: >-
@@ -143,16 +146,36 @@ The following example will install both the `py311` and the `py312` environment
> [!WARNING]
> If you don't specify any environment, the `default` environment will be installed and cached, even if you use other environments.
### Global Environments
You can specify `pixi global install` commands by setting the `global-environments` input argument.
This will create one environment per line, and install them.
This is useful in particular to install executables that are needed for `pixi install` to work properly.
For instance, the `keyring`, or `gcloud` executables. The following example shows how to install both in separate global environments.
By default, global environments are not cached. You can enable caching by setting the `global-cache` input to `true`.
```yml
- uses: prefix-dev/setup-pixi@v0.9.3
with:
global-environments: |
google-cloud-sdk
keyring --with keyrings.google-artifactregistry-auth
- run: |
gcloud --version
keyring --list-backends
```
### Authentication
There are currently three ways to authenticate with pixi:
There are currently five ways to authenticate with pixi:
- using a token
- using a username and password
- using a conda-token
- using an S3 key pair
- using keyring for PyPI registries
For more information, see the [pixi documentation](https://prefix.dev/docs/pixi/authentication).
For more information, see the [pixi documentation](https://pixi.sh/latest/deployment/authentication/).
> [!WARNING]
> Please only store sensitive information using [GitHub secrets](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions). Do not store them in your repository.
@@ -165,7 +188,7 @@ Specify the token using the `auth-token` input argument.
This form of authentication (bearer token in the request headers) is mainly used at [prefix.dev](https://prefix.dev).
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
auth-host: prefix.dev
auth-token: ${{ secrets.PREFIX_DEV_TOKEN }}
@@ -177,7 +200,7 @@ Specify the username and password using the `auth-username` and `auth-password`
This form of authentication (HTTP Basic Auth) is used in some enterprise environments with [artifactory](https://jfrog.com/artifactory) for example.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
auth-host: custom-artifactory.com
auth-username: ${{ secrets.PIXI_USERNAME }}
@@ -190,7 +213,7 @@ Specify the conda-token using the `auth-conda-token` input argument.
This form of authentication (token is encoded in URL: `https://my-quetz-instance.com/t/<token>/get/custom-channel`) is used at [anaconda.org](https://anaconda.org) or with [quetz instances](https://github.com/mamba-org/quetz).
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
auth-host: anaconda.org # or my-quetz-instance.com
auth-conda-token: ${{ secrets.CONDA_TOKEN }}
@@ -202,7 +225,7 @@ Specify the S3 key pair using the `auth-access-key-id` and `auth-secret-access-k
You can also specify the session token using the `auth-session-token` input argument.
```yaml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
auth-host: s3://my-s3-bucket
auth-s3-access-key-id: ${{ secrets.ACCESS_KEY_ID }}
@@ -213,6 +236,18 @@ You can also specify the session token using the `auth-session-token` input argu
See the [pixi documentation](https://pixi.sh/latest/advanced/s3) for more information about S3 authentication.
#### PyPI keyring provider
You can specify whether to use keyring to look up credentials for PyPI.
```yml
- uses: prefix-dev/setup-pixi@v0.9.3
with:
pypi-keyring-provider: subprocess # one of 'subprocess', 'disabled'
```
You can use the [`global-environments`](#global-environments) input to install `keyring` and its backends.
### Custom shell wrapper
`setup-pixi` allows you to run command inside of the pixi environment by specifying a custom shell wrapper with `shell: pixi run bash -e {0}`.
@@ -274,7 +309,7 @@ To this end, `setup-pixi` adds all environment variables set when executing `pix
As a result, all installed binaries can be accessed without having to call `pixi run`.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
activate-environment: true
```
@@ -282,7 +317,7 @@ As a result, all installed binaries can be accessed without having to call `pixi
If you are installing multiple environments, you will need to specify the name of the environment that you want to be activated.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
environments: >-
py311
@@ -296,10 +331,10 @@ However, be aware that this option augments the environment of your job.
### `--frozen` and `--locked`
You can specify whether `setup-pixi` should run `pixi install --frozen` or `pixi install --locked` depending on the `frozen` or the `locked` input argument.
See the [official documentation](https://prefix.dev/docs/pixi/cli#install) for more information about the `--frozen` and `--locked` flags.
See the [official documentation](https://pixi.sh/latest/reference/cli/pixi/install/#update-options) for more information about the `--frozen` and `--locked` flags.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
locked: true
# or
@@ -318,7 +353,7 @@ The first one is the debug logging of the action itself.
This can be enabled by running the action with the `RUNNER_DEBUG` environment variable set to `true`.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
env:
RUNNER_DEBUG: true
```
@@ -336,7 +371,7 @@ The second type is the debug logging of the pixi executable.
This can be specified by setting the `log-level` input.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
# one of `q`, `default`, `v`, `vv`, or `vvv`.
log-level: vvv
@@ -362,7 +397,7 @@ If nothing is specified, `post-cleanup` will default to `true`.
On self-hosted runners, you also might want to alter the default pixi install location to a temporary location. You can use `pixi-bin-path: ${{ runner.temp }}/bin/pixi` to do this.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
post-cleanup: true
# ${{ runner.temp }}\Scripts\pixi.exe on Windows
@@ -378,7 +413,7 @@ You can also use a preinstalled local version of pixi on the runner by not setti
This can be overwritten by setting the `manifest-path` input argument.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
manifest-path: pyproject.toml
```
@@ -388,7 +423,7 @@ This can be overwritten by setting the `manifest-path` input argument.
If you only want to install pixi and not install the current project, you can use the `run-install` option.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
run-install: false
```
@@ -399,7 +434,7 @@ You can also download pixi from a custom URL by setting the `pixi-url` input arg
Optionally, you can combine this with the `pixi-url-headers` input argument to supply additional headers for the download request, such as a bearer token.
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
pixi-url: https://pixi-mirror.example.com/releases/download/v0.48.0/pixi-x86_64-unknown-linux-musl
pixi-url-headers: '{"Authorization": "Bearer ${{ secrets.PIXI_MIRROR_BEARER_TOKEN }}"}'
@@ -415,7 +450,7 @@ It will be rendered with the following variables:
By default, `pixi-url` is equivalent to the following template:
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
- uses: prefix-dev/setup-pixi@v0.9.3
with:
pixi-url: |
{{#if latest~}}
+17 -2
View File
@@ -23,6 +23,9 @@ inputs:
environments:
description: |
A space-separated list of environments to install. If not specified, only the default environment is installed.
global-environments:
description: |
A newline-separated list of packages to install globally with `pixi global install`.
activate-environment:
description: |
If the installed environment should be "activated" for the current job, modifying `$GITHUB_ENV` and
@@ -34,13 +37,21 @@ inputs:
description: Whether to use `pixi install --frozen`. Defaults to `false`.
cache:
description: Whether to cache the pixi environment. Defaults to `true`. Only works if `pixi.lock` is present.
global-cache:
description: |
Whether to cache the global environment(s). Defaults to `false`. As there is no lockfile for global environment,
the global cache will expire at the end of every month, to ensure it does not go stale.
cache-key:
description: |
Cache key prefix to use for caching the pixi environment.
Defaults to `pixi-`. The full cache key is `<cache-key><conda-arch>-<sha-256-of-pixi-lock>`.
global-cache-key:
description: |
Cache key prefix to use for caching the global environments.
Defaults to `pixi-global-`. The full cache key is `<global-cache-key><conda-arch>-<sha-256-of-global-environments>`.
cache-write:
description: |
Whether to write to the cache or only read from it. Defaults to `true`.
Whether to write to the cache or only read from it. Defaults to `true`. Applies to both project and global caches as the case may be.
pixi-bin-path:
description: |
Path to the pixi binary to use. Defaults to `~/.pixi/bin/pixi`.
@@ -63,12 +74,16 @@ inputs:
description: Secret access key to use for S3 authentication.
auth-s3-session-token:
description: Session token to use for S3 authentication.
pypi-keyring-provider:
description: |
Specifies whether to use keyring to look up credentials for PyPI.
options: disabled, subprocess
post-cleanup:
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.
runs:
using: node20
using: node24
main: dist/index.js
post: dist/post.js
Generated Vendored
+24908 -19585
View File
File diff suppressed because one or more lines are too long
Generated Vendored
+3787 -4678
View File
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -1,6 +1,6 @@
{
"name": "setup-pixi",
"version": "0.8.14",
"version": "0.9.3",
"private": true,
"description": "Action to set up the pixi package manager.",
"scripts": {
@@ -22,25 +22,25 @@
"author": "Pavel Zwerschke <pavelzw@gmail.com>",
"license": "BSD-3-Clause",
"dependencies": {
"@actions/cache": "^4.0.3",
"@actions/cache": "^4.1.0",
"@actions/core": "^1.11.1",
"@actions/exec": "^1.1.1",
"@actions/io": "^1.1.3",
"@actions/io": "^2.0.0",
"@actions/tool-cache": "^2.0.2",
"handlebars": "^4.7.8",
"smol-toml": "^1.4.0",
"untildify": "^5.0.0",
"which": "^5.0.0",
"zod": "^3.25.67"
"smol-toml": "^1.5.2",
"untildify": "^6.0.0",
"which": "^6.0.0",
"zod": "^4.1.13"
},
"devDependencies": {
"@eslint/js": "^9.30.0",
"@types/node": "^24.0.8",
"@eslint/js": "^9.39.1",
"@types/node": "^24.10.1",
"@types/which": "^3.0.4",
"eslint": "^9.30.0",
"prettier": "^3.6.2",
"tsup": "^8.4.0",
"typescript": "^5.8.2",
"typescript-eslint": "^8.35.1"
"eslint": "^9.39.1",
"prettier": "^3.7.3",
"tsup": "^8.5.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.48.0"
}
}
+688 -999
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -35,11 +35,11 @@ const getNewPathComponents = (path: string): string[] => {
if (!currentPath) {
throw new Error('Unable to obtain current PATH from environment')
}
core.debug(`Found current path '${currentPath}'`)
core.debug(`Got new path '${path}'`)
if (!path.endsWith(currentPath)) {
throw new Error('Unable to handle environment activation which does not only append to PATH')
}
core.debug(`Found current path '${currentPath}'`)
core.debug(`Got new path '${path}'`)
const newPath = path.slice(0, path.length - currentPath.length)
return newPath.split(osPath.delimiter).filter((p) => p.length > 0)
}
@@ -48,6 +48,7 @@ export const activateEnvironment = async (environment: string): Promise<void> =>
// First, obtain the environment variables that would be set by environment activation
const envOption = environment === 'default' ? '' : `-e ${environment}`
const shellHookOutput = await executeGetOutput(pixiCmd(`shell-hook ${envOption} --json`), { silent: true })
core.debug(`Got shell hook output '${shellHookOutput.stdout}'`)
const shellHook = JSON.parse(shellHookOutput.stdout) as ShellHook
// Then, we split the environment variables into the special 'PATH' and all others
+148 -66
View File
@@ -5,79 +5,161 @@ import * as cache from '@actions/cache'
import { options } from './options'
import { getCondaArch, sha256 } from './util'
export const generateCacheKey = async (cacheKeyPrefix: string) =>
Promise.all([fs.readFile(options.pixiLockFile), fs.readFile(options.pixiBinPath)])
.then(([lockfileContent, pixiBinary]) => {
const lockfileSha = sha256(lockfileContent)
core.debug(`lockfileSha: ${lockfileSha}`)
const pixiSha = sha256(pixiBinary)
core.debug(`pixiSha: ${pixiSha}`)
// the path to the lock file decides where the pixi env is created (../.pixi/env)
// since conda envs are not relocatable, we need to include the path in the cache key
const lockfilePathSha = sha256(options.pixiLockFile)
core.debug(`lockfilePathSha: ${lockfilePathSha}`)
const environments = sha256(options.environments?.join(' ') ?? '')
core.debug(`environments: ${environments}`)
// since the lockfile path is not necessarily absolute, we need to include the cwd in the cache key
const cwdSha = sha256(process.cwd())
core.debug(`cwdSha: ${cwdSha}`)
const sha = sha256(lockfileSha + environments + pixiSha + lockfilePathSha + cwdSha)
core.debug(`sha: ${sha}`)
return `${cacheKeyPrefix}${getCondaArch()}-${sha}`
})
.catch((err: unknown) => {
const getYearMonth = () => {
// this gets us the current month formatted as YYYY-MM
return new Date().toLocaleDateString('en-CA', { year: 'numeric', month: '2-digit' })
}
let pixiSha: string | undefined
const getPixiSha = async () => {
if (pixiSha) {
return pixiSha
}
const pixiBinary = await fs.readFile(options.pixiBinPath)
pixiSha = sha256(pixiBinary)
return pixiSha
}
export const generateProjectCacheKey = async (cacheKeyPrefix: string) => {
try {
const [lockfileContent, pixiSha] = await Promise.all([fs.readFile(options.pixiLockFile), getPixiSha()])
const lockfileSha = sha256(lockfileContent)
core.debug(`lockfileSha: ${lockfileSha}`)
core.debug(`pixiSha: ${pixiSha}`)
// the path to the lock file decides where the pixi env is created (../.pixi/env)
// since conda envs are not relocatable, we need to include the path in the cache key
const lockfilePathSha = sha256(options.pixiLockFile)
core.debug(`lockfilePathSha: ${lockfilePathSha}`)
const environments = sha256(options.environments?.join(' ') ?? '')
core.debug(`environments: ${environments}`)
// since the lockfile path is not necessarily absolute, we need to include the cwd in the cache key
const cwdSha = sha256(process.cwd())
core.debug(`cwdSha: ${cwdSha}`)
const sha = sha256(lockfileSha + environments + pixiSha + lockfilePathSha + cwdSha)
core.debug(`sha: ${sha}`)
return `${cacheKeyPrefix}${getCondaArch()}-${sha}`
} catch (err: unknown) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Failed to generate cache key: ${err}`)
}
}
export const generateGlobalCacheKey = async (cacheKeyPrefix: string) => {
try {
const pixiSha = await getPixiSha()
core.debug(`pixiSha: ${pixiSha}`)
const globalEnvironments = sha256(options.globalEnvironments?.join(' ') ?? '')
core.debug(`globalEnvironments: ${globalEnvironments}`)
const sha = sha256(globalEnvironments + pixiSha + getGlobalCachePath())
core.debug(`sha: ${sha}`)
return `${cacheKeyPrefix}${getCondaArch()}-${getYearMonth()}-${sha}`
} catch (err: unknown) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Failed to generate cache key: ${err}`)
}
}
const projectCachePath = path.join(path.dirname(options.pixiLockFile), '.pixi')
const getGlobalCachePath = () => {
const pixiHome = process.env.PIXI_HOME
if (pixiHome) {
return path.join(pixiHome, 'envs')
}
const home = process.env.HOME
if (home) {
return path.join(home, '.pixi', 'envs')
}
throw new Error('Neither PIXI_HOME nor HOME environment variables are set.')
}
let projectCacheHit = false
let globalCacheHit = false
async function _tryRestoreCache(
type: 'project' | 'global',
keyPrefix: string,
generateKey: (prefix: string) => Promise<string>,
cachePath: string,
onHit: () => void
): Promise<string | undefined> {
return core.group(`Restoring ${type} cache`, async () => {
const cacheKey = await generateKey(keyPrefix)
core.debug(`Cache key: ${cacheKey}`)
core.debug(`Cache path: ${cachePath}`)
const key = await cache.restoreCache([cachePath], cacheKey, undefined, undefined, false)
if (key) {
core.info(`Restored cache with key \`${key}\``)
onHit()
} else {
core.info(`Cache miss`)
}
return key
})
}
async function _saveCache(
type: 'project' | 'global',
wasHit: boolean,
keyPrefix: string,
generateKey: (prefix: string) => Promise<string>,
cachePath: string
) {
if (wasHit) {
core.debug(`Skipping ${type} cache save because cache was restored.`)
return
}
await core.group(`Saving ${type.toLowerCase()} cache`, async () => {
const cacheKey = await generateKey(keyPrefix)
try {
const cacheId = await cache.saveCache([cachePath], cacheKey, undefined, false)
core.info(`Saved cache with ID "${cacheId.toString()}"`)
} catch (err: unknown) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Failed to generate cache key: ${err}`)
})
core.error(`Error saving ${type} cache: ${err}`)
}
})
}
const cachePath = path.join(path.dirname(options.pixiLockFile), '.pixi')
let cacheHit = false
export const tryRestoreCache = (): Promise<string | undefined> => {
export const tryRestoreProjectCache = async (): Promise<string | undefined> => {
const cache_ = options.cache
if (!cache_) {
core.debug('Skipping pixi cache restore.')
return Promise.resolve(undefined)
core.debug('Skipping project cache restore.')
return undefined
}
return core.group('Restoring pixi cache', () =>
generateCacheKey(cache_.cacheKeyPrefix).then((cacheKey) => {
core.debug(`Cache key: ${cacheKey}`)
core.debug(`Cache path: ${cachePath}`)
return cache.restoreCache([cachePath], cacheKey, undefined, undefined, false).then((key) => {
if (key) {
core.info(`Restored cache with key \`${key}\``)
cacheHit = true
} else {
core.info(`Cache miss`)
}
return key
})
})
)
return _tryRestoreCache('project', cache_.cacheKeyPrefix, generateProjectCacheKey, projectCachePath, () => {
projectCacheHit = true
})
}
export const saveCache = () => {
const cache_ = options.cache
if (!cache_?.cacheWrite) {
core.debug('Skipping pixi cache save.')
return Promise.resolve(undefined)
export const tryRestoreGlobalCache = async (): Promise<string | undefined> => {
const cache_ = options.globalCache
if (!cache_ || !options.globalEnvironments || options.globalEnvironments.length === 0) {
core.debug('Skipping global cache restore.')
return undefined
}
if (cacheHit) {
core.debug('Skipping pixi cache save because cache was restored.')
return Promise.resolve(undefined)
return _tryRestoreCache('global', cache_.cacheKeyPrefix, generateGlobalCacheKey, getGlobalCachePath(), () => {
globalCacheHit = true
})
}
export const saveProjectCache = async () => {
const cache_ = options.cache
if (!cache_?.cacheWrite || !options.runInstall) {
core.debug('Skipping project cache save.')
return
}
return core.group('Saving pixi cache', () =>
generateCacheKey(cache_.cacheKeyPrefix).then((cacheKey) =>
cache
.saveCache([cachePath], cacheKey, undefined, false)
.then((cacheId) => {
core.info(`Saved cache with ID "${cacheId.toString()}"`)
})
.catch((err: unknown) => {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
core.error(`Error saving cache: ${err}`)
})
)
)
await _saveCache('project', projectCacheHit, cache_.cacheKeyPrefix, generateProjectCacheKey, projectCachePath)
}
export const saveGlobalCache = async () => {
const cache_ = options.globalCache
if (!cache_?.cacheWrite || !options.globalEnvironments || options.globalEnvironments.length === 0) {
core.debug('Skipping global cache save.')
return
}
await _saveCache('global', globalCacheHit, cache_.cacheKeyPrefix, generateGlobalCacheKey, getGlobalCachePath())
}
+85 -52
View File
@@ -7,51 +7,47 @@ import { downloadTool } from '@actions/tool-cache'
import type { PixiSource } from './options'
import { options } from './options'
import { execute, pixiCmd, renderPixiUrl } from './util'
import { saveCache, tryRestoreCache } from './cache'
import { tryRestoreGlobalCache, tryRestoreProjectCache, saveGlobalCache, saveProjectCache } from './cache'
import { activateEnvironment } from './activate'
const downloadPixi = (source: PixiSource) => {
const downloadPixi = async (source: PixiSource) => {
const url = renderPixiUrl(source.urlTemplate, source.version)
return core.group('Downloading Pixi', () => {
await core.group('Downloading Pixi', async () => {
core.debug('Installing pixi')
core.debug(`Downloading pixi from ${url}`)
core.debug(`Using headers: ${JSON.stringify(source.headers)}`)
return fs
.mkdir(path.dirname(options.pixiBinPath), { recursive: true })
.then(() => downloadTool(url, options.pixiBinPath, undefined, source.headers))
.then((_downloadPath) => fs.chmod(options.pixiBinPath, 0o755))
.then(() => {
core.info(`Pixi installed to ${options.pixiBinPath}`)
})
await fs.mkdir(path.dirname(options.pixiBinPath), { recursive: true })
await downloadTool(url, options.pixiBinPath, undefined, source.headers)
await fs.chmod(options.pixiBinPath, 0o755)
core.info(`Pixi installed to ${options.pixiBinPath}`)
})
}
const pixiLogin = () => {
const pixiLogin = async () => {
const auth = options.auth
if (!auth) {
core.debug('Skipping pixi login.')
return Promise.resolve(0)
return
}
core.debug(`auth keys: ${Object.keys(auth).toString()}`)
return core.group('Logging in to private channel', () => {
await core.group('Logging in to private channel', async () => {
// tokens get censored in the logs as long as they are a github secret
if ('token' in auth) {
core.debug(`Logging in to ${auth.host} with token`)
return execute(pixiCmd(`auth login --token ${auth.token} ${auth.host}`, false))
}
if ('username' in auth) {
await execute(pixiCmd(`auth login --token ${auth.token} ${auth.host}`, false))
} else if ('username' in auth) {
core.debug(`Logging in to ${auth.host} with username and password`)
return execute(pixiCmd(`auth login --username ${auth.username} --password ${auth.password} ${auth.host}`, false))
}
if ('s3AccessKeyId' in auth) {
await execute(pixiCmd(`auth login --username ${auth.username} --password ${auth.password} ${auth.host}`, false))
} else if ('s3AccessKeyId' in auth) {
core.debug(`Logging in to ${auth.host} with s3 credentials`)
const command = auth.s3SessionToken
? `auth login --s3-access-key-id ${auth.s3AccessKeyId} --s3-secret-access-key ${auth.s3SecretAccessKey} --s3-session-token ${auth.s3SessionToken} ${auth.host}`
: `auth login --s3-access-key-id ${auth.s3AccessKeyId} --s3-secret-access-key ${auth.s3SecretAccessKey} ${auth.host}`
return execute(pixiCmd(command, false))
await execute(pixiCmd(command, false))
} else if ('condaToken' in auth) {
core.debug(`Logging in to ${auth.host} with conda token`)
await execute(pixiCmd(`auth login --conda-token ${auth.condaToken} ${auth.host}`, false))
}
core.debug(`Logging in to ${auth.host} with conda token`)
return execute(pixiCmd(`auth login --conda-token ${auth.condaToken} ${auth.host}`, false))
})
}
@@ -59,33 +55,58 @@ const addPixiToPath = () => {
core.addPath(path.dirname(options.pixiBinPath))
}
const pixiGlobalInstall = async () => {
const { globalEnvironments } = options
if (!globalEnvironments) {
core.debug('Skipping pixi global install.')
return
}
await tryRestoreGlobalCache()
core.debug('Installing global environments')
for (const env of globalEnvironments) {
const command = `global install ${env}`
await core.group(`pixi ${command}`, () => execute(pixiCmd(command, false)))
}
await saveGlobalCache()
}
const pixiInstall = async () => {
if (!options.runInstall) {
core.debug('Skipping pixi install.')
return Promise.resolve()
return
}
return tryRestoreCache()
.then(async (_cacheKey) => {
if (options.environments) {
for (const environment of options.environments) {
core.debug(`Installing environment ${environment}`)
const command = `install -e ${environment}${options.frozen ? ' --frozen' : ''}${
options.locked ? ' --locked' : ''
}`
await core.group(`pixi ${command}`, () => execute(pixiCmd(command)))
}
} else {
const command = `install${options.frozen ? ' --frozen' : ''}${options.locked ? ' --locked' : ''}`
return core.group(`pixi ${command}`, () => execute(pixiCmd(command)))
}
})
.then(saveCache)
await tryRestoreProjectCache()
const environments = options.environments ?? [undefined]
for (const environment of environments) {
core.debug(`Installing environment ${environment ?? 'default'}`)
let command = `install`
if (environment) {
command += ` -e ${environment}`
}
if (options.frozen) {
command += ' --frozen'
}
if (options.locked) {
command += ' --locked'
}
if (options.pypiKeyringProvider) {
command += ` --pypi-keyring-provider ${options.pypiKeyringProvider}`
}
await core.group(`pixi ${command}`, () => execute(pixiCmd(command)))
}
await saveProjectCache()
}
const generateList = async () => {
if (!options.runInstall) {
core.debug('Skipping pixi list.')
return Promise.resolve()
return
}
if (
'version' in options.pixiSource &&
@@ -95,7 +116,7 @@ const generateList = async () => {
core.warning(
'pixi list is not supported for pixi versions < `v0.13.0`. Please set `pixi-version` to `v0.13.0` or later.'
)
return Promise.resolve()
return
}
let command = 'list'
if (
@@ -111,17 +132,21 @@ const generateList = async () => {
if (options.environments) {
for (const environment of options.environments) {
core.debug(`Listing environment ${environment}`)
await core.group(`pixi ${command} -e ${environment}`, () => execute(pixiCmd(`${command} -e ${environment}`)))
const cmd = `${command} -e ${environment}`
await core.group(`pixi ${cmd}`, () => execute(pixiCmd(cmd)))
}
return Promise.resolve()
} else {
return core.group(`pixi ${command}`, () => execute(pixiCmd(command)))
await core.group(`pixi ${command}`, () => execute(pixiCmd(command)))
}
}
const generateInfo = () => core.group('pixi info', () => execute(pixiCmd('info')))
const generateInfo = async () => {
await core.group('pixi info', () => execute(pixiCmd('info')))
}
const activateEnv = (environment: string) => core.group('Activate environment', () => activateEnvironment(environment))
const activateEnv = async (environment: string) => {
await core.group('Activate environment', () => activateEnvironment(environment))
}
const run = async () => {
core.debug(`process.env.HOME: ${process.env.HOME ?? '-'}`)
@@ -131,17 +156,21 @@ const run = async () => {
}
addPixiToPath()
await pixiLogin()
await pixiInstall()
await pixiGlobalInstall()
await generateInfo()
await pixiInstall()
await generateList()
if (options.activatedEnvironment) {
await activateEnv(options.activatedEnvironment)
}
}
run()
.then(() => exit(0)) // workaround for https://github.com/actions/toolkit/issues/1578
.catch((error: unknown) => {
const main = async () => {
try {
await run()
// workaround for https://github.com/actions/toolkit/issues/1578
exit(0)
} catch (error: unknown) {
if (core.isDebug()) {
throw error
}
@@ -151,6 +180,10 @@ run()
} else if (typeof error === 'string') {
core.setFailed(error)
exit(1)
} else {
throw error
}
throw error
})
}
}
void main()
+57 -8
View File
@@ -21,7 +21,9 @@ type Inputs = Readonly<{
frozen?: boolean
locked?: boolean
cache?: boolean
globalCache?: boolean
cacheKey?: string
globalCacheKey?: string
cacheWrite?: boolean
pixiBinPath?: string
authHost?: string
@@ -32,7 +34,9 @@ type Inputs = Readonly<{
authS3AccessKeyId?: string
authS3SecretAccessKey?: string
authS3SessionToken?: string
pypiKeyringProvider?: 'disabled' | 'subprocess'
postCleanup?: boolean
globalEnvironments?: string[]
}>
export interface PixiSource {
@@ -66,6 +70,11 @@ interface Cache {
cacheWrite: boolean
}
interface GlobalCache {
cacheKeyPrefix: string
cacheWrite: boolean
}
export type Options = Readonly<{
pixiSource: PixiSource
downloadPixi: boolean
@@ -77,10 +86,13 @@ export type Options = Readonly<{
frozen: boolean
locked: boolean
cache?: Cache
globalCache?: GlobalCache
pixiBinPath: string
auth?: Auth
pypiKeyringProvider?: 'disabled' | 'subprocess'
postCleanup: boolean
activatedEnvironment?: string
globalEnvironments?: string[]
}>
const pixiPath = 'pixi.toml'
const pyprojectPath = 'pyproject.toml'
@@ -88,6 +100,9 @@ const pyprojectPath = 'pyproject.toml'
const logLevelSchema = z.enum(['q', 'default', 'v', 'vv', 'vvv'])
export type LogLevel = z.infer<typeof logLevelSchema>
const pypiKeyringProviderSchema = z.enum(['disabled', 'subprocess'])
export type PypiKeyringProvider = z.infer<typeof pypiKeyringProviderSchema>
export const PATHS = {
pixiBin: path.join(os.homedir(), '.pixi', 'bin', `pixi${os.platform() === 'win32' ? '.exe' : ''}`)
}
@@ -113,7 +128,7 @@ const inputOrEnvironmentVariable = (key: string): string | undefined => {
return undefined
}
const parseOrUndefined = <T>(key: string, schema: z.ZodSchema<T>, errorMessage?: string): T | undefined => {
const parseOrUndefined = <T>(key: string, schema: z.ZodType<T>, errorMessage?: string): T | undefined => {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
@@ -128,7 +143,7 @@ const parseOrUndefined = <T>(key: string, schema: z.ZodSchema<T>, errorMessage?:
return maybeResult.data
}
const parseOrUndefinedJSON = <T>(key: string, schema: z.ZodSchema<T>): T | undefined => {
const parseOrUndefinedJSON = <T>(key: string, schema: z.ZodType<T>): T | undefined => {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
@@ -136,7 +151,7 @@ const parseOrUndefinedJSON = <T>(key: string, schema: z.ZodSchema<T>): T | undef
return schema.parse(JSON.parse(input))
}
const parseOrUndefinedList = <T>(key: string, schema: z.ZodSchema<T>): T[] | undefined => {
const parseOrUndefinedList = <T>(key: string, schema: z.ZodType<T>): T[] | undefined => {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
@@ -147,16 +162,33 @@ const parseOrUndefinedList = <T>(key: string, schema: z.ZodSchema<T>): T[] | und
.filter((s) => s !== '')
}
const parseOrUndefinedMultilineList = <T>(key: string, schema: z.ZodType<T>): T[] | undefined => {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
}
return input
.split('\n')
.map((s) => schema.parse(s.trim()))
.filter((s) => s !== '')
}
const validateInputs = (inputs: Inputs): void => {
if (inputs.pixiUrlHeaders && !inputs.pixiUrl) {
throw new Error('You need to specify pixi-url when using pixi-url-headers')
}
if (inputs.cacheKey !== undefined && inputs.cache === false) {
throw new Error('Cannot specify cache key without caching')
throw new Error('Cannot specify project cache key without project caching')
}
if (inputs.globalCacheKey !== undefined && inputs.globalCache === false) {
throw new Error('Cannot specify global cache key without global caching')
}
if (inputs.runInstall === false && inputs.cache === true) {
throw new Error('Cannot cache without running install')
}
if (inputs.globalCache === true && (!inputs.globalEnvironments || inputs.globalEnvironments.length === 0)) {
throw new Error('Cannot use global-cache without specifying global-environments')
}
if (inputs.runInstall === false && inputs.frozen === true) {
throw new Error('Cannot use `frozen: true` when not running install')
}
@@ -291,10 +323,19 @@ const inferOptions = (inputs: Inputs): Options => {
} else if (inputs.activateEnvironment && inputs.activateEnvironment !== 'false') {
activatedEnvironment = inputs.activateEnvironment
}
const cache = inputs.cacheKey
? { cacheKeyPrefix: inputs.cacheKey, cacheWrite: inputs.cacheWrite ?? true }
: inputs.cache === true || (lockFileAvailable && inputs.cache !== false)
? { cacheKeyPrefix: 'pixi-', cacheWrite: inputs.cacheWrite ?? true }
const cache =
inputs.cache === true || (lockFileAvailable && inputs.cache !== false)
? {
cacheKeyPrefix: inputs.cacheKey ?? 'pixi-',
cacheWrite: inputs.cacheWrite ?? true
}
: undefined
const globalCache =
inputs.globalCache === true && inputs.globalEnvironments && inputs.globalEnvironments.length > 0
? {
cacheKeyPrefix: inputs.globalCacheKey ?? 'pixi-global-',
cacheWrite: inputs.cacheWrite ?? true
}
: undefined
const frozen = inputs.frozen ?? false
const locked = inputs.locked ?? (lockFileAvailable && !frozen)
@@ -323,8 +364,11 @@ const inferOptions = (inputs: Inputs): Options => {
s3SessionToken: inputs.authS3SessionToken
}) as Auth)
const postCleanup = inputs.postCleanup ?? true
const pypiKeyringProvider = inputs.pypiKeyringProvider
return {
globalEnvironments: inputs.globalEnvironments,
pixiSource,
pypiKeyringProvider,
downloadPixi,
logLevel,
manifestPath,
@@ -335,6 +379,7 @@ const inferOptions = (inputs: Inputs): Options => {
frozen,
locked,
cache,
globalCache,
pixiBinPath,
auth,
postCleanup
@@ -371,7 +416,9 @@ const getOptions = () => {
locked: parseOrUndefinedJSON('locked', z.boolean()),
frozen: parseOrUndefinedJSON('frozen', z.boolean()),
cache: parseOrUndefinedJSON('cache', z.boolean()),
globalCache: parseOrUndefinedJSON('global-cache', z.boolean()),
cacheKey: parseOrUndefined('cache-key', z.string()),
globalCacheKey: parseOrUndefined('global-cache-key', z.string()),
cacheWrite: parseOrUndefinedJSON('cache-write', z.boolean()),
pixiBinPath: parseOrUndefined('pixi-bin-path', z.string()),
authHost: parseOrUndefined('auth-host', z.string()),
@@ -382,6 +429,8 @@ const getOptions = () => {
authS3AccessKeyId: parseOrUndefined('auth-s3-access-key-id', z.string()),
authS3SecretAccessKey: parseOrUndefined('auth-s3-secret-access-key', z.string()),
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())
}
core.debug(`Inputs: ${JSON.stringify(inputs)}`)
+2 -2
View File
@@ -1,9 +1,9 @@
[project]
[workspace]
name = "test-auth-s3"
channels = ["s3://rattler-s3-testing/channel", "conda-forge"]
platforms = ["osx-arm64", "osx-64", "linux-64", "linux-aarch64", "win-64"]
[project.s3-options.rattler-s3-testing]
[workspace.s3-options.rattler-s3-testing]
endpoint-url = "https://e1a7cde76f1780ec06bac859036dbaf7.eu.r2.cloudflarestorage.com"
force-path-style = true
region = "auto"
+1 -1
View File
@@ -1,4 +1,4 @@
[project]
[workspace]
name = "test-auth"
channels = ["conda-forge", "https://repo.prefix.dev/setup-pixi-test"]
platforms = ["osx-arm64", "osx-64", "linux-64", "linux-aarch64", "win-64"]
+1 -1
View File
@@ -1,4 +1,4 @@
[project]
[workspace]
name = "test-win-arm64"
channels = ["conda-forge"]
platforms = [
+1 -1
View File
@@ -1,4 +1,4 @@
[project]
[workspace]
name = "test-default"
channels = ["conda-forge"]
platforms = ["linux-64", "linux-aarch64", "osx-64", "osx-arm64", "win-64"]
+1 -1
View File
@@ -1,4 +1,4 @@
[project]
[workspace]
name = "test-default"
version = "0.1.0"
description = "Add a short description here"
+1 -1
View File
@@ -1,4 +1,4 @@
[project]
[workspace]
name = "test-package"
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
+1 -1
View File
@@ -1,4 +1,4 @@
[project]
[workspace]
name = "test-no-lockfile"
channels = ["conda-forge"]
platforms = ["linux-64", "linux-aarch64", "osx-64", "osx-arm64", "win-64"]
+2 -2
View File
@@ -19,7 +19,7 @@ lint = ["ruff>=0.1.14"]
[tool.ruff]
target-version = "py310"
line-length = 100
exclude = [ ".pixi", "__pycache__" ]
exclude = [".pixi", "__pycache__"]
# the TOML parser should also support comments in lists
lint.select = [
# flake8-bugbear
@@ -34,7 +34,7 @@ lint.select = [
"F",
]
[tool.pixi.project]
[tool.pixi.workspace]
name = "pyproject-manifest"
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]