Compare commits

...
5 Commits
12 changed files with 12349 additions and 376 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ jobs:
run: |
set -euo pipefail
latest_version="$(jq -r '.version' package.json)"
count_expected=18
count_expected=19
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."
+243 -112
View File
@@ -190,7 +190,7 @@ jobs:
pixi-url: https://github.com/prefix-dev/pixi/releases/download/v0.14.0/pixi-x86_64-unknown-linux-musl
- run: pixi --version | grep -q "pixi 0.14.0"
pixi-url-bearer-token:
pixi-url-headers-bearer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -216,7 +216,7 @@ jobs:
with:
cache: false
pixi-url: http://localhost:8080/pixi
pixi-url-bearer-token: wrongtoken
pixi-url-headers: '{"Authorization": "Bearer wrongtoken"}'
continue-on-error: true
- name: Fail if wrong token did not fail
run: |
@@ -228,7 +228,54 @@ jobs:
with:
cache: false
pixi-url: http://localhost:8080/pixi
pixi-url-bearer-token: s3cr3tT0k3nABC123
pixi-url-headers: '{"Authorization": "Bearer s3cr3tT0k3nABC123"}'
- run: pixi --version | grep -q "pixi 0.14.0"
pixi-url-custom-template-no-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./
with:
pixi-url: |
{{#if latest ~}}
https://github.com/prefix-dev/pixi/releases/download/v0.14.0/{{pixiFile}}
{{~else~}}
https://github.com/prefix-dev/pixi/releases/download/{{version}}/{{pixiFile}}
{{~/if}}
run-install: false
- run: pixi --version | grep -q "pixi 0.14.0"
pixi-url-custom-template-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./
with:
pixi-url: |
{{#if latest ~}}
https://github.com/prefix-dev/pixi/releases/download/v0.14.0/{{pixiFile}}
{{~else~}}
https://github.com/prefix-dev/pixi/releases/download/{{version}}/{{pixiFile}}
{{~/if}}
run-install: false
pixi-version: v0.15.1
- run: pixi --version | grep -q "pixi 0.15.1"
pixi-url-custom-template-version-latest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./
with:
pixi-url: |
{{#if latest ~}}
https://github.com/prefix-dev/pixi/releases/download/v0.14.0/{{pixiFile}}
{{~else~}}
https://github.com/prefix-dev/pixi/releases/download/{{version}}/{{pixiFile}}
{{~/if}}
run-install: false
pixi-version: latest
- run: pixi --version | grep -q "pixi 0.14.0"
custom-manifest-path:
@@ -467,6 +514,7 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi.toml
@@ -485,6 +533,7 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi.toml
@@ -943,118 +992,200 @@ jobs:
py311 py312
activate-environment: py311
# not properly testable
# https://github.com/actions/runner/issues/2347
# https://github.com/orgs/community/discussions/15452
# test-cache-fail-no-lockfile:
# runs-on: ${{ matrix.os }}
# strategy:
# fail-fast: false
# matrix:
# os: [windows-latest, ubuntu-latest, macos-latest]
# steps:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# - name: Move pixi files
# run: mv test/no-lockfile/* .
# - uses: ./
# with:
# cache: true
# cache-key: test-cache-no-lockfile-${{ github.sha }}-${{ github.run_attempt }}-
# - run: exit 1
# if: success()
env-variable-input-custom-bin-path:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi.toml
run: mv test/default/* .
- uses: ./
env:
SETUP_PIXI_PIXI_BIN_PATH: custom-bin/pixi${{ matrix.os == 'windows-latest' && '.exe' || '' }}
with:
cache: false
- run: |
test -f custom-bin/pixi${{ matrix.os == 'windows-latest' && '.exe' || '' }}
pixi --help
which pixi | grep -q custom-bin/pixi
# which pixi should be absolute
which pixi | grep -q "^/"
# test-incorrect-version:
# runs-on: ${{ matrix.os }}
# strategy:
# fail-fast: false
# matrix:
# os: [windows-latest, ubuntu-latest, macos-latest]
# steps:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# - name: Move pixi files
# run: mv test/default/* .
# - uses: ./
# with:
# pixi-version: 0.1.0
# - run: exit 1
# if: success()
env-variable-input-custom-pixi-url:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi.toml
run: mv test/old-pixi-lockfiles/* .
- uses: ./
env:
SETUP_PIXI_PIXI_URL: https://github.com/prefix-dev/pixi/releases/download/v0.14.0/pixi-x86_64-unknown-linux-musl
with:
cache: false
- run: pixi --version | grep -q "pixi 0.14.0"
# test-frozen-and-locked:
# runs-on: ${{ matrix.os }}
# strategy:
# fail-fast: false
# matrix:
# os: [windows-latest, ubuntu-latest, macos-latest]
# steps:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# - name: Move pixi files
# run: mv test/default/* .
# - uses: ./
# with:
# pixi-version: v0.5.0
# frozen: true
# locked: true
# - run: exit 1
# if: success()
env-variable-input-precendence:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi.toml
run: mv test/old-pixi-lockfiles/* .
- uses: ./
env:
SETUP_PIXI_PIXI_URL: https://github.com/prefix-dev/pixi/releases/download/v0.14.0/pixi-x86_64-unknown-linux-musl
with:
cache: false
pixi-url: https://github.com/prefix-dev/pixi/releases/download/v0.49.0/pixi-x86_64-unknown-linux-musl
- run: pixi --version | grep -q "pixi 0.49.0"
# test-frozen-no-lockfile:
# runs-on: ${{ matrix.os }}
# strategy:
# fail-fast: false
# matrix:
# os: [windows-latest, ubuntu-latest, macos-latest]
# steps:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# - name: Move pixi files
# run: mv test/no-lockfile/* .
# - uses: ./
# with:
# frozen: true
# - run: exit 1
# if: success()
test-cache-fail-no-lockfile:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi files
run: mv test/no-lockfile/* .
- uses: ./
id: test
with:
cache: true
cache-key: test-cache-no-lockfile-${{ github.sha }}-${{ github.run_attempt }}-
continue-on-error: true
- name: Fail on unexpected success
run: |
echo "Unexpected success!"
exit 1
if: ${{ steps.test.outcome != 'failure' }}
# test-locked-no-lockfile:
# runs-on: ${{ matrix.os }}
# strategy:
# fail-fast: false
# matrix:
# os: [windows-latest, ubuntu-latest, macos-latest]
# steps:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# - name: Move pixi files
# run: mv test/no-lockfile/* .
# - uses: ./
# with:
# locked: true
# - run: exit 1
# if: success()
test-incorrect-version:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi files
run: mv test/default/* .
- uses: ./
id: test
with:
pixi-version: 0.1.0
continue-on-error: true
- name: Fail on unexpected success
run: |
echo "Unexpected success!"
exit 1
if: ${{ steps.test.outcome != 'failure' }}
# test-lockfile-not-up-to-date:
# runs-on: ${{ matrix.os }}
# strategy:
# fail-fast: false
# matrix:
# os: [windows-latest, ubuntu-latest, macos-latest]
# steps:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# - name: Move pixi files
# run: mv test/lockfile-not-up-to-date/* .
# - uses: ./
# # locked: true is implicit
# - run: exit 1
# if: success()
test-frozen-and-locked:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi files
run: mv test/default/* .
- uses: ./
id: test
with:
pixi-version: v0.5.0
frozen: true
locked: true
continue-on-error: true
- name: Fail on unexpected success
run: |
echo "Unexpected success!"
exit 1
if: ${{ steps.test.outcome != 'failure' }}
# cache-write-true-no-lockfile:
# timeout-minutes: 10
# runs-on: ${{ matrix.os }}
# strategy:
# fail-fast: false
# matrix:
# os: [windows-latest, ubuntu-latest, macos-latest]
# steps:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# - name: Move pixi files
# run: mv test/no-lockfile/* .
# - uses: ./
# with:
# cache-write: true
test-frozen-no-lockfile:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi files
run: mv test/no-lockfile/* .
- uses: ./
id: test
with:
frozen: true
continue-on-error: true
- name: Fail on unexpected success
run: |
echo "Unexpected success!"
exit 1
if: ${{ steps.test.outcome != 'failure' }}
test-locked-no-lockfile:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi files
run: mv test/no-lockfile/* .
- uses: ./
id: test
with:
locked: true
continue-on-error: true
- name: Fail on unexpected success
run: |
echo "Unexpected success!"
exit 1
if: ${{ steps.test.outcome != 'failure' }}
test-lockfile-not-up-to-date:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi files
run: mv test/lockfile-not-up-to-date/* .
- uses: ./
id: test
# locked: true is implicit
continue-on-error: true
- name: Fail on unexpected success
run: |
echo "Unexpected success!"
exit 1
if: ${{ steps.test.outcome != 'failure' }}
cache-write-true-no-lockfile:
timeout-minutes: 10
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Move pixi files
run: mv test/no-lockfile/* .
- uses: ./
id: test
with:
cache-write: true
continue-on-error: true
- name: Fail on unexpected success
run: |
echo "Unexpected success!"
exit 1
if: ${{ steps.test.outcome != 'failure' }}
+51 -20
View File
@@ -23,7 +23,7 @@ GitHub Action to set up the [pixi](https://github.com/prefix-dev/pixi) package m
## Usage
```yml
- uses: prefix-dev/setup-pixi@v0.8.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
pixi-version: v0.49.0
@@ -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.12`) to avoid breaking changes.
> Please pin the versions of this action to a specific version (i.e., `prefix-dev/setup-pixi@v0.8.14`) 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:
@@ -74,7 +74,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
cache: true
cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
@@ -119,7 +119,7 @@ test:
environment: [py311, py312]
steps:
- uses: actions/checkout@v4
- uses: prefix-dev/setup-pixi@v0.8.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
environments: ${{ matrix.environment }}
```
@@ -129,7 +129,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
# separated by spaces
environments: >-
@@ -165,7 +165,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
auth-host: prefix.dev
auth-token: ${{ secrets.PREFIX_DEV_TOKEN }}
@@ -177,7 +177,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
auth-host: custom-artifactory.com
auth-username: ${{ secrets.PIXI_USERNAME }}
@@ -190,7 +190,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
auth-host: anaconda.org # or my-quetz-instance.com
auth-conda-token: ${{ secrets.CONDA_TOKEN }}
@@ -202,7 +202,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
auth-host: s3://my-s3-bucket
auth-s3-access-key-id: ${{ secrets.ACCESS_KEY_ID }}
@@ -274,7 +274,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
activate-environment: true
```
@@ -282,7 +282,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
environments: >-
py311
@@ -299,7 +299,7 @@ You can specify whether `setup-pixi` should run `pixi install --frozen` or `pixi
See the [official documentation](https://prefix.dev/docs/pixi/cli#install) for more information about the `--frozen` and `--locked` flags.
```yml
- uses: prefix-dev/setup-pixi@v0.8.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
locked: true
# or
@@ -318,7 +318,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
env:
RUNNER_DEBUG: true
```
@@ -336,7 +336,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
# one of `q`, `default`, `v`, `vv`, or `vvv`.
log-level: vvv
@@ -362,7 +362,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
post-cleanup: true
# ${{ runner.temp }}\Scripts\pixi.exe on Windows
@@ -378,7 +378,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
manifest-path: pyproject.toml
```
@@ -388,7 +388,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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
run-install: false
```
@@ -396,15 +396,46 @@ If you only want to install pixi and not install the current project, you can us
### Download pixi from a custom URL
You can also download pixi from a custom URL by setting the `pixi-url` input argument.
Optionally, you can combine this with the `pixi-url-bearer-token` input argument to authenticate the download request.
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.12
- uses: prefix-dev/setup-pixi@v0.8.14
with:
pixi-url: https://pixi-mirror.example.com/releases/download/v0.48.0/pixi-x86_64-unknown-linux-musl
pixi-url-bearer-token: ${{ secrets.PIXI_MIRROR_BEARER_TOKEN }}
pixi-url-headers: '{"Authorization": "Bearer ${{ secrets.PIXI_MIRROR_BEARER_TOKEN }}"}'
```
The `pixi-url` input argument can also be a [Handlebars](https://handlebarsjs.com/) template string.
It will be rendered with the following variables:
- `version`: The version of pixi that is being installed (`latest` or a version like `v0.48.0`).
- `latest`: A boolean indicating if the version is `latest`.
- `pixiFile`: The name of the pixi binary to download, as determined by the system of the runner (e.g., `pixi-x86_64-unknown-linux-musl`).
By default, `pixi-url` is equivalent to the following template:
```yml
- uses: prefix-dev/setup-pixi@v0.8.14
with:
pixi-url: |
{{#if latest~}}
https://github.com/prefix-dev/pixi/releases/latest/download/{{pixiFile}}
{{~else~}}
https://github.com/prefix-dev/pixi/releases/download/{{version}}/{{pixiFile}}
{{~/if}}
```
### Setting inputs from environment variables
Alternatively to setting the inputs in the `with` section, you can also set each of them using environment variables.
The corresponding environment variable names are derived from the input names by converting them to uppercase, replacing hyphens with underscores, and prefixing them with `SETUP_PIXI_`.
For example, the `pixi-bin-path` input can be set using the `SETUP_PIXI_PIXI_BIN_PATH` environment variable.
This is particularly useful if executing the action on a self-hosted runner.
Inputs always take precedence over environment variables.
## More examples
If you want to see more examples, you can take a look at the [GitHub Workflows of this repository](.github/workflows/test.yml).
+3 -3
View File
@@ -9,9 +9,9 @@ inputs:
pixi-version:
description: Version of pixi to install
pixi-url:
description: URL of pixi to install
pixi-url-bearer-token:
description: Bearer token to use for authentication when downloading pixi from a URL.
description: URL of pixi to install. Can be a Handlebars template receiving `version`, `latest`, and `pixiFile` as variables.
pixi-url-headers:
description: Headers to use when fetching the pixi binary from `pixi-url`. Should be a JSON string.
log-level:
description: |
Log level for the pixi CLI.
Generated Vendored
+6003 -128
View File
File diff suppressed because one or more lines are too long
Generated Vendored
+5936 -59
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "setup-pixi",
"version": "0.8.12",
"version": "0.8.14",
"private": true,
"description": "Action to set up the pixi package manager.",
"scripts": {
@@ -27,6 +27,7 @@
"@actions/exec": "^1.1.1",
"@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.2",
"handlebars": "^4.7.8",
"smol-toml": "^1.4.0",
"untildify": "^5.0.0",
"which": "^5.0.0",
@@ -34,7 +35,6 @@
},
"devDependencies": {
"@eslint/js": "^9.30.0",
"@types/eslint__js": "^9.14.0",
"@types/node": "^24.0.8",
"@types/which": "^3.0.4",
"eslint": "^9.30.0",
+46 -11
View File
@@ -23,6 +23,9 @@ importers:
'@actions/tool-cache':
specifier: ^2.0.2
version: 2.0.2
handlebars:
specifier: ^4.7.8
version: 4.7.8
smol-toml:
specifier: ^1.4.0
version: 1.4.0
@@ -39,9 +42,6 @@ importers:
'@eslint/js':
specifier: ^9.30.0
version: 9.30.0
'@types/eslint__js':
specifier: ^9.14.0
version: 9.14.0
'@types/node':
specifier: ^24.0.8
version: 24.0.8
@@ -508,10 +508,6 @@ packages:
cpu: [x64]
os: [win32]
'@types/eslint__js@9.14.0':
resolution: {integrity: sha512-s0jepCjOJWB/GKcuba4jISaVpBudw3ClXJ3fUK4tugChUMQsp6kSwuA8Dcx6wFd/JsJqcY8n4rEpa5RTHs5ypA==}
deprecated: This is a stub types definition. @eslint/js provides its own type definitions, so you do not need this installed.
'@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
@@ -910,6 +906,11 @@ packages:
graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
handlebars@4.7.8:
resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==}
engines: {node: '>=0.4.7'}
hasBin: true
has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
@@ -1054,6 +1055,9 @@ packages:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
minipass@7.1.2:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -1070,6 +1074,9 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
neo-async@2.6.2:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0}
@@ -1224,6 +1231,10 @@ packages:
resolution: {integrity: sha512-IMxaDA/58wBvkvX77ykQ6e9r6fjs8xbxpz8bMCyVQ/fEFWbA5uJrnaVwDuhLrrANGdd7apRyTPDBvI893Bxu9g==}
engines: {node: '>= 18'}
source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
source-map@0.8.0-beta.0:
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
engines: {node: '>= 8'}
@@ -1350,6 +1361,11 @@ packages:
ufo@1.6.1:
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
uglify-js@3.19.3:
resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==}
engines: {node: '>=0.8.0'}
hasBin: true
undici-types@7.8.0:
resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==}
@@ -1394,6 +1410,9 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
wordwrap@1.0.0:
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
@@ -1828,10 +1847,6 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.34.8':
optional: true
'@types/eslint__js@9.14.0':
dependencies:
'@eslint/js': 9.30.0
'@types/estree@1.0.6': {}
'@types/estree@1.0.8': {}
@@ -2284,6 +2299,15 @@ snapshots:
graphemer@1.4.0: {}
handlebars@4.7.8:
dependencies:
minimist: 1.2.8
neo-async: 2.6.2
source-map: 0.6.1
wordwrap: 1.0.0
optionalDependencies:
uglify-js: 3.19.3
has-flag@4.0.0: {}
has-symbols@1.1.0: {}
@@ -2405,6 +2429,8 @@ snapshots:
dependencies:
brace-expansion: 2.0.2
minimist@1.2.8: {}
minipass@7.1.2: {}
mlly@1.7.4:
@@ -2424,6 +2450,8 @@ snapshots:
natural-compare@1.4.0: {}
neo-async@2.6.2: {}
node-fetch@2.7.0:
dependencies:
whatwg-url: 5.0.0
@@ -2545,6 +2573,8 @@ snapshots:
smol-toml@1.4.0: {}
source-map@0.6.1: {}
source-map@0.8.0-beta.0:
dependencies:
whatwg-url: 7.1.0
@@ -2673,6 +2703,9 @@ snapshots:
ufo@1.6.1: {}
uglify-js@3.19.3:
optional: true
undici-types@7.8.0: {}
undici@5.29.0:
@@ -2712,6 +2745,8 @@ snapshots:
word-wrap@1.2.5: {}
wordwrap@1.0.0: {}
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
+4 -5
View File
@@ -6,20 +6,19 @@ import * as core from '@actions/core'
import { downloadTool } from '@actions/tool-cache'
import type { PixiSource } from './options'
import { options } from './options'
import { execute, getPixiUrlFromVersion, pixiCmd } from './util'
import { execute, pixiCmd, renderPixiUrl } from './util'
import { saveCache, tryRestoreCache } from './cache'
import { activateEnvironment } from './activate'
const downloadPixi = (source: PixiSource) => {
const url = 'version' in source ? getPixiUrlFromVersion(source.version) : source.url
const auth = 'bearerToken' in source && source.bearerToken ? `Bearer ${source.bearerToken}` : ''
const url = renderPixiUrl(source.urlTemplate, source.version)
return core.group('Downloading Pixi', () => {
core.debug('Installing pixi')
core.debug(`Downloading pixi from ${url}`)
core.debug(`Using Bearer auth: ${auth ? 'yes' : 'no'}`)
core.debug(`Using headers: ${JSON.stringify(source.headers)}`)
return fs
.mkdir(path.dirname(options.pixiBinPath), { recursive: true })
.then(() => downloadTool(url, options.pixiBinPath, auth))
.then(() => downloadTool(url, options.pixiBinPath, undefined, source.headers))
.then((_downloadPath) => fs.chmod(options.pixiBinPath, 0o755))
.then(() => {
core.info(`Pixi installed to ${options.pixiBinPath}`)
+43 -30
View File
@@ -7,11 +7,12 @@ import * as z from 'zod'
import untildify from 'untildify'
import { parse } from 'smol-toml'
import which from 'which'
import { DEFAULT_PIXI_URL_TEMPLATE } from './util'
type Inputs = Readonly<{
pixiVersion?: string
pixiUrl?: string
pixiUrlBearerToken?: string
pixiUrlHeaders?: NodeJS.Dict<string>
logLevel?: LogLevel
manifestPath?: string
runInstall?: boolean
@@ -34,14 +35,11 @@ type Inputs = Readonly<{
postCleanup?: boolean
}>
export type PixiSource =
| {
version: string
}
| {
url: string
bearerToken?: string
}
export interface PixiSource {
urlTemplate: string
headers?: NodeJS.Dict<string>
version: string
}
type Auth = {
host: string
@@ -94,10 +92,30 @@ export const PATHS = {
pixiBin: path.join(os.homedir(), '.pixi', 'bin', `pixi${os.platform() === 'win32' ? '.exe' : ''}`)
}
const getEnvironmentVariableName = (key: string): string => {
return `SETUP_PIXI_${key.toUpperCase().replace(/-/g, '_')}`
}
const inputOrEnvironmentVariable = (key: string): string | undefined => {
const inputValue = core.getInput(key)
// GitHub actions sets empty inputs to the empty string
if (inputValue !== '') {
return inputValue
}
const envVarName = getEnvironmentVariableName(key)
const envVarValue = process.env[envVarName]
// Empty environment variables are treated as undefined
if (envVarValue !== undefined && envVarValue !== '') {
core.debug(`Using environment variable ${envVarName} with value: ${envVarValue}`)
return envVarValue
}
return undefined
}
const parseOrUndefined = <T>(key: string, schema: z.ZodSchema<T>, errorMessage?: string): T | undefined => {
const input = core.getInput(key)
// GitHub actions sets empty inputs to the empty string, but we want undefined
if (input === '') {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
}
const maybeResult = schema.safeParse(input)
@@ -111,18 +129,16 @@ const parseOrUndefined = <T>(key: string, schema: z.ZodSchema<T>, errorMessage?:
}
const parseOrUndefinedJSON = <T>(key: string, schema: z.ZodSchema<T>): T | undefined => {
const input = core.getInput(key)
// GitHub actions sets empty inputs to the empty string, but we want undefined
if (input === '') {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
}
return schema.parse(JSON.parse(input))
}
const parseOrUndefinedList = <T>(key: string, schema: z.ZodSchema<T>): T[] | undefined => {
const input = core.getInput(key)
// GitHub actions sets empty inputs to the empty string, but we want undefined
if (input === '') {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
}
return input
@@ -132,11 +148,8 @@ const parseOrUndefinedList = <T>(key: string, schema: z.ZodSchema<T>): T[] | und
}
const validateInputs = (inputs: Inputs): void => {
if (inputs.pixiVersion && inputs.pixiUrl) {
throw new Error('You need to specify either pixi-version or pixi-url')
}
if (inputs.pixiUrlBearerToken && !inputs.pixiUrl) {
throw new Error('You need to specify pixi-url when using pixi-url-bearer-token')
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')
@@ -225,11 +238,11 @@ const determinePixiInstallation = (pixiUrlOrVersionSet: boolean, pixiBinPath: st
const inferOptions = (inputs: Inputs): Options => {
const runInstall = inputs.runInstall ?? true
const pixiSource = inputs.pixiVersion
? { version: inputs.pixiVersion }
: inputs.pixiUrl
? { url: inputs.pixiUrl, bearerToken: inputs.pixiUrlBearerToken }
: { version: 'latest' }
const pixiSource: PixiSource = {
urlTemplate: inputs.pixiUrl ?? DEFAULT_PIXI_URL_TEMPLATE,
headers: inputs.pixiUrlHeaders,
version: inputs.pixiVersion ?? 'latest'
}
const { downloadPixi, pixiBinPath } = determinePixiInstallation(
!!inputs.pixiVersion || !!inputs.pixiUrl,
@@ -344,8 +357,8 @@ const getOptions = () => {
z.union([z.literal('latest'), z.string().regex(/^v\d+\.\d+\.\d+$/)]),
'pixi-version must either be `latest` or a version string matching `vX.Y.Z`.'
),
pixiUrl: parseOrUndefined('pixi-url', z.string().url()),
pixiUrlBearerToken: parseOrUndefined('pixi-url-bearer-token', z.string()),
pixiUrl: parseOrUndefined('pixi-url', z.string()),
pixiUrlHeaders: parseOrUndefinedJSON('pixi-url-headers', z.record(z.string(), z.string())),
logLevel: parseOrUndefined(
'log-level',
logLevelSchema,
+16 -5
View File
@@ -5,6 +5,14 @@ import * as core from '@actions/core'
import type { ExecOptions } from '@actions/exec'
import { exec, getExecOutput } from '@actions/exec'
import { options } from './options'
import Handlebars from 'handlebars'
export const DEFAULT_PIXI_URL_TEMPLATE = `\
{{#if latest~}}
https://github.com/prefix-dev/pixi/releases/latest/download/{{pixiFile}}
{{~else~}}
https://github.com/prefix-dev/pixi/releases/download/{{version}}/{{pixiFile}}
{{~/if}}`
export const getCondaArch = () => {
const archDict: Record<string, string> = {
@@ -49,14 +57,17 @@ const getArch = () => {
}
}
export const getPixiUrlFromVersion = (version: string) => {
export const renderPixiUrl = (urlTemplate: string, version: string) => {
const latest = version == 'latest'
const arch = getArch()
const platform = getPlatform()
const pixiFile = `pixi-${arch}-${platform}${platform === 'pc-windows-msvc' ? '.exe' : ''}`
if (version === 'latest') {
return `https://github.com/prefix-dev/pixi/releases/latest/download/${pixiFile}`
}
return `https://github.com/prefix-dev/pixi/releases/download/${version}/${pixiFile}`
const template = Handlebars.compile(urlTemplate)
return template({
version,
latest,
pixiFile
})
}
export const sha256 = (s: BinaryLike) => {
+1
View File
@@ -24,6 +24,7 @@ export default defineConfig({
'@actions/cache',
'@actions/io',
'@actions/tool-cache',
'handlebars',
'untildify',
'smol-toml',
'which',