Compare commits

..
130 Commits
Author SHA1 Message Date
a0af7a2287 Implement working directory setup (#236)
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 22:35:04 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 51b98037a9 chore(deps): bump the nodejs group with 10 updates (#244)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-10 19:23:16 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 54b8d30703 chore(deps): bump the gh-actions group with 5 updates (#243)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-10 11:46:39 +01:00
github-actions[bot] dce9fafa77 Reference latest Pixi version in README (#242) 2026-01-01 03:43:33 +00: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
Yannik Tausch 8ca4608ef7 feat: Replace pixi-url-bearer-token by pixi-url-headers (#217) 2025-07-25 15:46:30 +02:00
Yannik Tausch b1ab8f237b feat: Add Support for Handlebars Templates in pixi-url (#213) 2025-07-23 11:58:57 +02:00
Yannik Tausch d7951c27cd test: Skip tests with secrets on fork PRs (#216) 2025-07-22 17:39:23 +02:00
Yannik Tausch 4522f6409d feat: Allow specifying inputs as environment variables (#214) 2025-07-22 12:53:59 +02:00
Yannik Tausch a8c5cac0eb test: Enable failure tests (#215) 2025-07-22 11:14:53 +02:00
Pavel Zwerschke 307e5e5842 fix: Multiple invokations of setup-pixi (#211) 2025-07-18 09:43:49 +02:00
Yannik TauschandPavel Zwerschke 273e4808c8 feat: Add pixi-url-bearer-token to authenticate when downloading from pixi-url (#210)
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2025-07-11 18:38:08 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> c690703e5f Bump softprops/action-gh-release from 2.2.2 to 2.3.2 in the gh-actions group (#209)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-08 13:28:17 +02:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Pavel Zwerschke
29045c2e67 Bump the nodejs group with 7 updates (#208)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2025-07-01 07:41:26 +00:00
github-actions[bot] 2fd23d90b5 Reference latest Pixi version in README (#207) 2025-07-01 07:03:47 +00:00
Daniel Elsner 14c8aabd75 fix: Forcefully remove empty parents directory on post-cleanup (#205) 2025-06-12 17:01:57 +02:00
Daniel Elsner 97359467ea fix: Ignore errors in post-cleanup if files do not exist (#204) 2025-06-12 13:02:18 +02:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Pavel Zwerschke
1d2add66b9 Bump the nodejs group across 1 directory with 8 updates (#203)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2025-06-12 12:01:02 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 64e585d510 Bump the gh-actions group with 2 updates (#199)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 11:54:41 +02:00
Pavel Zwerschke 22ee2b0fa0 docs: Add security policy (#202) 2025-05-23 12:12:45 +00:00
Pavel Zwerschke 19eac09b39 feat: Add support for windows arm runners (#197) 2025-04-16 00:39:41 +02:00
Pavel Zwerschke 5044b25024 refactor: Use smol-toml instead of js-toml (#195) 2025-04-14 14:14:22 +02:00
Pavel Zwerschke 72cc21dab3 fix: TOML parsing failing on windows (#194) 2025-04-14 14:01:01 +02:00
Pavel Zwerschke dbaed5efa0 fix: Support TOML 1.0 for pyproject.toml parsing (#191) 2025-04-08 12:47:53 +02:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Pavel Zwerschke
30d4899438 Bump the nodejs group with 6 updates (#187)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2025-04-08 11:56:29 +02:00
dependabot[bot] 00ff9955aa Bump the gh-actions group with 3 updates (#188) 2025-04-01 07:11:56 +02:00
Pavel Zwerschke 8eaba7c61d fix: Behavior if pixi is on path with spaces (#185) 2025-03-31 13:02:35 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 0aa0cc06bf Bump the nodejs group with 10 updates (#181)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 10:08:44 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 0eb8fc3d66 Bump the gh-actions group with 3 updates (#180)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 09:56:29 +00:00
Pavel Zwerschke 9c0726f354 Adjust pull request template (#182) 2025-03-07 10:56:27 +01:00
Pavel Zwerschke 2970de4ad9 Mention run-install in documentation (#179) 2025-02-24 09:50:24 +01:00
Pavel Zwerschke 92815284c5 Add S3 authentication (#176) 2025-02-20 09:18:19 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 0f64e482e3 Bump nodejs dependencies (#172)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-11 16:52:49 +01:00
github-actions[bot] a0eec1ad27 Reference latest Pixi version in README (#169) 2025-02-11 16:20:42 +01:00
Pavel Zwerschke 87426edf79 bump pixi version in readme every three months 2025-02-11 16:14:12 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> ce8f9d00d4 Bump the gh-actions group with 4 updates (#171)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-01 11:39:46 +00:00
github-actions[bot] fb4fb2a4bc Reference latest Pixi version in README (#167) 2025-01-20 09:09:06 +00:00
github-actions[bot] ab924e6d23 Reference latest Pixi version in README (#162) 2025-01-06 12:37:21 +00:00
dependabot[bot] 6bfb8b7dfb Bump the gh-actions group with 4 updates (#164) 2025-01-06 13:21:31 +01:00
github-actions[bot] 2b0dd8ca2a Reference latest Pixi version in README (#161) 2024-12-16 09:42:38 +00:00
github-actions[bot] 22fa653352 Reference latest Pixi version in README (#160) 2024-12-09 07:48:01 +00:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Pavel Zwerschke
6a44a227db Bump the dependencies group across 1 directory with 10 updates (#157)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2024-12-02 11:48:30 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 7ae9fd8364 Bump the dependencies group across 1 directory with 4 updates (#158)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:39:37 +01:00
github-actions[bot] 688f47c746 Reference latest Pixi version in README (#156) 2024-11-25 07:55:29 +01:00
github-actions[bot] 18f2bb3495 Reference latest Pixi version in README (#155) 2024-11-18 07:43:02 +00:00
github-actions[bot] 1c636cc10e Reference latest Pixi version in README (#151) 2024-11-11 08:22:26 +01:00
github-actions[bot] 05fd7ec7d7 Reference latest Pixi version in README (#149) 2024-10-21 09:19:37 +02:00
github-actions[bot] 5f57a9658a Reference latest Pixi version in README (#147) 2024-10-14 07:19:34 +00:00
Pavel Zwerschke 68baa735c7 pin actions by sha (#146) 2024-10-01 09:02:10 +00:00
github-actions[bot] 41f1f69e78 Reference latest Pixi version in README (#140) 2024-09-24 14:47:19 +02:00
github-actions[bot] 6efead024a Reference latest Pixi version in README (#138) 2024-09-09 18:20:10 +02:00
Jens Ochsenmeier 45f572edb8 Update dependencies, fix config linting (#135) 2024-08-30 14:29:08 +02:00
github-actions[bot] 540c964f19 Reference latest Pixi version in README (#134) 2024-08-26 14:01:20 +02:00
github-actions[bot] 116a6623f4 Reference latest Pixi version in README (#132) 2024-08-12 09:05:53 +02:00
Pavel Zwerschke 1f8c1bbd15 Mention pixi exec in docs (#131) 2024-08-02 09:44:51 +00:00
dependabot[bot] 3d7bf9c29e Bump softprops/action-gh-release from 2.0.6 to 2.0.8 in the dependencies group (#130) 2024-08-01 07:57:12 +02:00
github-actions[bot] 58e91c2a92 Reference latest Pixi version in README (#128) 2024-07-29 06:10:24 +00:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Pavel Zwerschke
0723139b37 Bump the dependencies group across 1 directory with 6 updates (#127)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2024-07-15 13:16:38 +00:00
github-actions[bot] 5c2501535f Reference latest Pixi version in README (#125) 2024-07-08 12:09:19 +02:00
dependabot[bot] 992a3081e2 Bump the dependencies group with 2 updates (#123) 2024-07-01 08:02:16 +02:00
github-actions[bot] 67207fdc51 Reference latest Pixi version in README (#121) 2024-06-17 11:34:42 +00:00
Jens Ochsenmeier a9af4756ad ESLint: Migrate to flat config, isolate Prettier, fix errors (#120) 2024-06-14 14:54:49 +02:00
Ruben Arts ba3bb36eb2 fix: use iarna/toml instead of toml (#118) 2024-06-01 01:31:15 +02:00
Jonas Haag b68487257f Improve run-install wording (#116) 2024-05-23 20:02:37 +02:00
Bela Stoyan 2058dcd92f Fix saving cache taking too long (#113) 2024-05-23 14:33:35 +02:00
github-actions[bot] fd715b50ef Reference latest Pixi version in README (#112) 2024-05-21 12:00:39 +02:00
Oliver Borchert d72307a91c Add activate-environment option (#108) 2024-05-11 15:11:52 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 2fcf8775bc Bump github actions (#110)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-11 08:47:59 +00:00
Pavel Zwerschke dbc36a133b Fix CI (#109) 2024-05-11 10:36:22 +02:00
github-actions[bot] c36e4b321e Reference latest Pixi version in README (#104) 2024-04-29 12:15:13 +02:00
github-actions[bot]andpavelzw 7d0875d54d Reference latest Pixi version in README (#101)
Co-authored-by: pavelzw <29506042+pavelzw@users.noreply.github.com>
2024-04-22 15:26:50 +02:00
Ruben Arts 2d1adc67f7 chore: align docs with pixi (#100) 2024-04-18 11:21:56 +02:00
Ruben ArtsandPavel Zwerschke 632d179351 Add better support for pyproject.toml pixi projects (#87)
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2024-04-16 14:31:30 +02:00
Yannik Tausch 60414de954 support preinstalled local pixi (#98) 2024-04-15 09:37:12 +02:00
nichmor 4fc8d82a01 fix: restoring cache for pyproject.toml (#95) 2024-04-11 15:28:58 +02:00
wpbonelliandPavel Zwerschke 42f9edde75 fix: respect frozen/locked inputs for pixi list (#94)
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2024-04-11 14:32:36 +02:00
github-actions[bot] 92e1dd3a46 Reference latest Pixi version in README (#92) 2024-04-08 08:33:42 +02:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Pavel Zwerschke
07648b19d8 Bump the dependencies group with 2 updates (#90)
* Bump the dependencies group with 2 updates

Bumps the dependencies group with 2 updates: [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) and [softprops/action-gh-release](https://github.com/softprops/action-gh-release).


Updates `peter-evans/create-pull-request` from 6.0.1 to 6.0.2
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/a4f52f8033a6168103c2538976c07b467e8163bc...70a41aba780001da0a30141984ae2a0c95d8704e)

Updates `softprops/action-gh-release` from 1 to 2
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* pin versions

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2024-04-01 13:42:54 +00:00
dependabot[bot] d0cc138dee Bump the dependencies group with 4 updates (#89) 2024-04-01 13:32:25 +00:00
github-actions[bot] 3d635066b4 Reference latest Pixi version in README (#86) 2024-03-25 07:43:13 +01:00
Ruben Arts 2e317cc221 Improve multi environment example (#85)
Align with pixi.sh
2024-03-18 13:21:23 +00:00
Pavel Zwerschke 603fd64350 Create pull request template (#84) 2024-03-11 14:39:41 +00:00
github-actions[bot] f0903b2941 Reference latest Pixi version in README (#83) 2024-03-11 08:17:51 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> d2f0e65db7 Bump the dependencies group with 7 updates (#80)
Bumps the dependencies group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) | `3.2.3` | `3.2.4` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `20.11.14` | `20.11.24` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `6.20.0` | `7.1.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `6.20.0` | `7.1.0` |
| [eslint](https://github.com/eslint/eslint) | `8.56.0` | `8.57.0` |
| [prettier](https://github.com/prettier/prettier) | `3.2.4` | `3.2.5` |
| [tsup](https://github.com/egoist/tsup) | `8.0.1` | `8.0.2` |


Updates `@actions/cache` from 3.2.3 to 3.2.4
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/cache)

Updates `@types/node` from 20.11.14 to 20.11.24
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@typescript-eslint/eslint-plugin` from 6.20.0 to 7.1.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.1.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 6.20.0 to 7.1.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.1.0/packages/parser)

Updates `eslint` from 8.56.0 to 8.57.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.56.0...v8.57.0)

Updates `prettier` from 3.2.4 to 3.2.5
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.2.4...3.2.5)

Updates `tsup` from 8.0.1 to 8.0.2
- [Release notes](https://github.com/egoist/tsup/releases)
- [Changelog](https://github.com/egoist/tsup/blob/dev/.releaserc.json)
- [Commits](https://github.com/egoist/tsup/compare/v8.0.1...v8.0.2)

---
updated-dependencies:
- dependency-name: "@actions/cache"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependencies
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tsup
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-01 08:31:53 +00:00
dependabot[bot] 0aa5efde00 Bump the dependencies group with 2 updates (#81)
* Bump the dependencies group with 2 updates

Bumps the dependencies group with 2 updates: [pnpm/action-setup](https://github.com/pnpm/action-setup) and [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request).


Updates `pnpm/action-setup` from 2 to 3
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v2...v3)

Updates `peter-evans/create-pull-request` from 6.0.0 to 6.0.1
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/b1ddad2c994a25fbc81a28b3ec0e368bb2021c50...a4f52f8033a6168103c2538976c07b467e8163bc)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: dependencies
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 07:28:31 +00:00
Ruben ArtsandPavel Zwerschke 20681dbcbf Add pwsh as pixi shells to the tests and documentation (#79)
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2024-02-17 10:38:13 +01:00
Pavel Zwerschke 26e623ccb6 Add no-pixi-toml test (#77) 2024-02-05 14:46:46 +00:00
Pavel Zwerschke 19b5e6071f Fix cache-write behavior (#76) 2024-02-04 11:01:53 +01:00
Pavel Zwerschke afa1d6a5d1 Add warning about caching with multi-envs (#75) 2024-02-02 20:42:38 +00:00
Pavel Zwerschke 52708b32f2 Fix typos (#74) 2024-02-02 20:29:14 +00:00
Pavel Zwerschke c2a7a27098 Add support for multiple envs (#70) 2024-02-01 16:06:26 +01:00
Pavel Zwerschke ad0427dce9 Add pixi list to output (#69) 2024-02-01 14:40:22 +00:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Pavel Zwerschke
77992cdabd Bump the dependencies group with 7 updates (#73)
* Bump the dependencies group with 7 updates

Bumps the dependencies group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) | `3.2.2` | `3.2.3` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `20.10.6` | `20.11.14` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `6.16.0` | `6.20.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `6.16.0` | `6.20.0` |
| [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) | `16.6.0` | `16.6.2` |
| [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) | `5.1.2` | `5.1.3` |
| [prettier](https://github.com/prettier/prettier) | `3.1.1` | `3.2.4` |


Updates `@actions/cache` from 3.2.2 to 3.2.3
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/cache)

Updates `@types/node` from 20.10.6 to 20.11.14
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@typescript-eslint/eslint-plugin` from 6.16.0 to 6.20.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.20.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 6.16.0 to 6.20.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.20.0/packages/parser)

Updates `eslint-plugin-n` from 16.6.0 to 16.6.2
- [Release notes](https://github.com/eslint-community/eslint-plugin-n/releases)
- [Commits](https://github.com/eslint-community/eslint-plugin-n/compare/16.6.0...16.6.2)

Updates `eslint-plugin-prettier` from 5.1.2 to 5.1.3
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.1.2...v5.1.3)

Updates `prettier` from 3.1.1 to 3.2.4
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.1.1...3.2.4)

---
updated-dependencies:
- dependency-name: "@actions/cache"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: eslint-plugin-n
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: eslint-plugin-prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* build

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com>
2024-02-01 09:55:06 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> a07becb301 Bump peter-evans/create-pull-request from 5.0.2 to 6.0.0 (#72)
Bumps the dependencies group with 1 update: [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request).


Updates `peter-evans/create-pull-request` from 5.0.2 to 6.0.0
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/153407881ec5c347639a548ade7d8ad1d6740e38...b1ddad2c994a25fbc81a28b3ec0e368bb2021c50)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 08:28:33 +01:00
Pavel Zwerschke 3f5ab780ba Add more tests (#71) 2024-02-01 00:16:28 +01:00
Pavel Zwerschke ca3b9ac762 Add cwd sha to cache key (#68) 2024-01-19 06:56:38 +01:00
Pavel Zwerschke b0a2ad1b73 Use pixi sha for cache (#67) 2024-01-18 23:42:19 +02:00
Pavel Zwerschke d2ec573e39 Fix failing auth tests (#64) 2024-01-10 12:24:10 +00:00
github-actions[bot] 364fd4a471 Reference latest Pixi version in README (#63) 2024-01-08 08:31:11 +02:00
dependabot[bot] d3921e201b Bump the dependencies group with 5 updates (#62) 2024-01-01 08:23:49 +01:00
dependabot[bot] da13ca0475 Bump the dependencies group with 5 updates (#61) 2023-12-18 07:27:04 +00:00
Pavel Zwerschke aaf4a7974f Update dependabot configuration (#60) 2023-12-18 07:20:29 +00:00
dependabot[bot] 93dbcae723 Bump actions/upload-artifact from 3 to 4 (#59) 2023-12-18 08:14:06 +01:00
dependabot[bot] 710eaf3767 Bump the dev-dependencies group with 5 updates (#56) 2023-12-11 07:39:14 +00:00
dependabot[bot] 4fff2fe0d5 Bump typescript from 5.3.2 to 5.3.3 (#54) 2023-12-11 07:32:41 +00:00
github-actions[bot] 4ffa03f79e Reference latest Pixi version in README (#55) 2023-12-11 08:21:52 +01:00
dependabot[bot] 94888c4be7 Bump the dev-dependencies group with 5 updates (#50) 2023-12-04 07:31:05 +01:00
Pavel Zwerschke 0a92b78ec2 Add example configuration for dependabot.yml (#49) 2023-11-30 15:58:29 +01:00
github-actions[bot] 73721a4a25 Reference latest Pixi version in README (#47) 2023-11-30 14:45:05 +01:00
Pavel Zwerschke daf1d94cb0 Add workflow to update pixi version, move check-dist to build.yml (#46) 2023-11-30 14:44:24 +01:00
dependabot[bot] ed66d56836 Bump tsup from 8.0.0 to 8.0.1 (#45) 2023-11-27 07:09:56 +00:00
dependabot[bot] be4e12d1ed Bump typescript from 5.2.2 to 5.3.2 (#44) 2023-11-27 07:03:01 +00:00
dependabot[bot] 2d35805042 Bump the dev-dependencies group with 3 updates (#43) 2023-11-27 07:56:10 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 1a80a4f562 Bump tsup from 7.2.0 to 8.0.0 (#42)
* Bump tsup from 7.2.0 to 8.0.0

Bumps [tsup](https://github.com/egoist/tsup) from 7.2.0 to 8.0.0.
- [Release notes](https://github.com/egoist/tsup/releases)
- [Changelog](https://github.com/egoist/tsup/blob/dev/.releaserc.json)
- [Commits](https://github.com/egoist/tsup/compare/v7.2.0...v8.0.0)

---
updated-dependencies:
- dependency-name: tsup
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-20 10:07:31 +00:00
dependabot[bot] 265e2c593b Bump the dev-dependencies group with 4 updates (#41) 2023-11-20 08:45:55 +01:00
45 changed files with 104566 additions and 47336 deletions
-28
View File
@@ -1,28 +0,0 @@
module.exports = {
ignorePatterns: ['dist/**/*', 'build/**/*'],
extends: ['standard', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: '2020'
},
plugins: ['@typescript-eslint', 'prettier'],
rules: {
'import/order': 'error',
'no-use-before-define': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'n/no-callback-literal': 'off',
'@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports' }],
'@typescript-eslint/no-use-before-define': 'error',
'prettier/prettier': [
'error',
{
tabWidth: 2,
printWidth: 120,
singleQuote: true,
trailingComma: 'none',
semi: false
}
]
}
}
+1 -1
View File
@@ -1 +1 @@
dist/** -diff linguist-generated=true
dist/** merge=binary -diff linguist-generated=true
+3
View File
@@ -0,0 +1,3 @@
If updating documentation:
- [ ] Updated documentation in https://github.com/prefix-dev/pixi/blob/main/docs/integration/ci/github_actions.md as well
@@ -0,0 +1,7 @@
:8080 {
@unauthorized not header Authorization "Bearer s3cr3tT0k3nABC123"
respond @unauthorized "Unauthorized: Invalid token" 401
root * ./assets
file_server
}
+8 -6
View File
@@ -3,14 +3,16 @@ updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
interval: monthly
groups:
gh-actions:
patterns:
- '*'
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
interval: monthly
groups:
dev-dependencies:
nodejs:
patterns:
- "*eslint*"
- "@types/*"
- "prettier"
- '*'
+1 -1
View File
@@ -23,4 +23,4 @@ changelog:
- dependencies
- title: 🤷🏻 Other changes
labels:
- "*"
- '*'
+84 -8
View File
@@ -6,20 +6,24 @@ on:
pull_request:
branches: [main]
merge_group:
schedule:
# every 3 months
- cron: 0 0 1 */3 *
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.4.0
with:
version: 8
version: 9
- name: Install Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: 20
cache: pnpm
@@ -29,7 +33,7 @@ jobs:
- name: Rebuild the dist/ directory
run: pnpm build
- name: Lint
run: pnpm lint
@@ -37,14 +41,86 @@ jobs:
name: Reference latest version in README
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Assert latest setup-pixi version is mentioned in README
run: |
set -euo pipefail
latest_version="$(jq -r '.version' package.json)"
count_expected=10
count_expected=23
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."
echo "::error file=README.md::Expected $count_expected mentions of \`setup-pixi@v$latest_version\` in README.md, but found $count_actual."
exit 1
fi
reference-latest-pixi-version-in-readme:
name: Reference latest Pixi version in README
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Assert latest pixi version is mentioned in README
run: |
set -euo pipefail
latest_version="$(gh repo view --json latestRelease prefix-dev/pixi | jq -r '.latestRelease.tagName')"
count_expected=1
count_actual="$(grep -c "pixi-version: $latest_version" README.md || true)"
if [ "$count_actual" -ne "$count_expected" ]; then
echo "::error file=README.md::Expected $count_expected mentions of \`pixi-version: $latest_version\` in README.md, but found $count_actual."
sed -i "s/pixi-version: .*/pixi-version: $latest_version/" README.md
exit 1
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create pull request
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
if: failure() && github.ref_name == 'main'
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Reference latest Pixi version in README
title: Reference latest Pixi version in README
labels: ignore for release
check-dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.4.0
with:
version: 9
- name: Install Node.js
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: 20
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Rebuild the dist/ directory
run: pnpm build
- name: Compare the expected and actual dist/ directories
run: |
if [ "$(git diff --ignore-space-at-eol dist/* | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. See status below:"
git diff
exit 1
fi
id: diff
# If index.js or post.js are different than expected, upload the expected version as an artifact
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with:
name: dist
path: dist/
-48
View File
@@ -1,48 +0,0 @@
name: Check dist
on:
push:
branches: [main]
pull_request:
branches: [main]
merge_group:
jobs:
check-dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Rebuild the dist/ directory
run: pnpm build
- name: Compare the expected and actual dist/ directories
run: |
if [ "$(git diff --ignore-space-at-eol dist/* | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. See status below:"
git diff
exit 1
fi
id: diff
# If index.js or post.js are different than expected, upload the expected version as an artifact
- uses: actions/upload-artifact@v3
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with:
name: dist
path: dist/
+3 -3
View File
@@ -12,8 +12,8 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Quantco/ui-actions/version-metadata@v1
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: Quantco/ui-actions/version-metadata@cd71d2a0e30b25569f6d723e57acca83347e58fc # v1.0.18
id: version-metadata
with:
file: ./package.json
@@ -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@v1
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
generate_release_notes: true
tag_name: v${{ steps.version-metadata.outputs.newVersion }}
+932 -179
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -97,3 +97,9 @@ Thumbs.db
# Ignore built ts files
__tests__/runner/*
lib/**/*
# Ignore jetbrains files
.idea
# ESBuild metafile
metafile*.json
+3
View File
@@ -0,0 +1,3 @@
dist
pnpm-lock.yaml
pixi.lock
+3
View File
@@ -0,0 +1,3 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
+314 -31
View File
@@ -23,9 +23,10 @@ GitHub Action to set up the [pixi](https://github.com/prefix-dev/pixi) package m
## Usage
```yml
- uses: prefix-dev/setup-pixi@v0.4.1
- uses: prefix-dev/setup-pixi@v0.9.4
with:
pixi-version: v0.7.0
pixi-version: v0.62.2
cache: true
auth-host: prefix.dev
auth-token: ${{ secrets.PREFIX_DEV_TOKEN }}
@@ -34,8 +35,23 @@ 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.4.1`) to avoid breaking changes.
> Please pin the versions of this action to a specific version (i.e., `prefix-dev/setup-pixi@v0.9.4`) 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:
>
> ```yml
> version: 2
> updates:
> - package-ecosystem: github-actions
> directory: /
> schedule:
> interval: monthly # or daily, weekly
> groups:
> dependencies:
> patterns:
> - '*'
> ```
## Features
@@ -43,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`
@@ -58,21 +77,105 @@ 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.4.1
- uses: prefix-dev/setup-pixi@v0.9.4
with:
cache: true
cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
```
### Multiple environments
With pixi, you can create multiple environments for different requirements.
You can also specify which environment(s) you want to install by setting the `environments` input argument.
This will install all environments that are specified and cache them.
```toml
[project]
name = "my-package"
channels = ["conda-forge"]
platforms = ["linux-64"]
[dependencies]
python = ">=3.11"
pip = "*"
polars = ">=0.14.24,<0.21"
[feature.py311.dependencies]
python = "3.11.*"
[feature.py312.dependencies]
python = "3.12.*"
[environments]
py311 = ["py311"]
py312 = ["py312"]
```
#### Multiple environments using a matrix
The following example will install the `py311` and `py312` environments in different jobs.
```yml
test:
runs-on: ubuntu-latest
strategy:
matrix:
environment: [py311, py312]
steps:
- uses: actions/checkout@v4
- uses: prefix-dev/setup-pixi@v0.9.4
with:
environments: ${{ matrix.environment }}
```
#### Install multiple environments in one job
The following example will install both the `py311` and the `py312` environment on the runner.
```yml
- uses: prefix-dev/setup-pixi@v0.9.4
with:
# separated by spaces
environments: >-
py311
py312
- run: |
pixi run -e py311 test
pixi run -e py312 test
```
> [!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.4
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.
@@ -85,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.4.1
- uses: prefix-dev/setup-pixi@v0.9.4
with:
auth-host: prefix.dev
auth-token: ${{ secrets.PREFIX_DEV_TOKEN }}
@@ -97,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.4.1
- uses: prefix-dev/setup-pixi@v0.9.4
with:
auth-host: custom-artifactory.com
auth-username: ${{ secrets.PIXI_USERNAME }}
@@ -106,29 +209,58 @@ This form of authentication (HTTP Basic Auth) is used in some enterprise environ
#### Conda-token
Specify the conda-token using the `conda-token` input argument.
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.4.1
- uses: prefix-dev/setup-pixi@v0.9.4
with:
auth-host: anaconda.org # or my-quetz-instance.com
conda-token: ${{ secrets.CONDA_TOKEN }}
auth-conda-token: ${{ secrets.CONDA_TOKEN }}
```
#### S3
Specify the S3 key pair using the `auth-access-key-id` and `auth-secret-access-key` input arguments.
You can also specify the session token using the `auth-session-token` input argument.
```yaml
- uses: prefix-dev/setup-pixi@v0.9.4
with:
auth-host: s3://my-s3-bucket
auth-s3-access-key-id: ${{ secrets.ACCESS_KEY_ID }}
auth-s3-secret-access-key: ${{ secrets.SECRET_ACCESS_KEY }}
# only needed if your key uses a session token
auth-s3-session-token: ${{ secrets.SESSION_TOKEN }}
```
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.4
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 {0}`.
`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}`.
This can be useful if you want to run commands inside of the pixi environment, but don't want to use the `pixi run` command for each command.
```yml
- run: | # everything here will be run inside of the pixi environment
python --version
pip install -e --no-deps .
shell: pixi run bash {0}
pip install --no-deps -e .
shell: pixi run bash -e {0}
```
You can even run python scripts like this:
You can even run Python scripts like this:
```yml
- run: | # everything here will be run inside of the pixi environment
@@ -137,18 +269,72 @@ You can even run python scripts like this:
shell: pixi run python {0}
```
If you want to use PowerShell, you need to specify `-Command` as well.
```yml
- run: | # everything here will be run inside of the pixi environment
python --version | Select-String "3.11"
shell: pixi run pwsh -Command {0} # pwsh works on all platforms
```
> [!NOTE]
> Under the hood, the `shell: xyz {0}` option is implemented by creating a temporary script file and calling `xyz` with that script file as an argument.
> This file does not have the executable bit set, so you cannot use `shell: pixi run {0}` directly but instead have to use `shell: pixi run bash {0}`.
> There are some custom shells provided by GitHub that have slightly different behavior, see [`jobs.<job_id>.steps[*].shell`](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell) in the documentation.
> See the [official documentation](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#custom-shell) and [ADR 0277](https://github.com/actions/runner/blob/main/docs/adrs/0277-run-action-shell-options.md) for more information about how the `shell:` input works in GitHub Actions.
#### One-off shell wrapper using `pixi exec`
With `pixi exec`, you can also run a one-off command inside a temporary pixi environment.
```yml
- run: | # everything here will be run inside of the temporary pixi environment
zstd --version
shell: pixi exec --spec zstd -- bash -e {0}
```
```yml
- run: | # everything here will be run inside of the temporary pixi environment
import ruamel.yaml
# ...
shell: pixi exec --spec python=3.11.* --spec ruamel.yaml -- python {0}
```
See [here](https://pixi.sh/latest/reference/cli#exec) for more information about `pixi exec`.
### Environment activation
Instead of using a custom shell wrapper, you can also make all pixi-installed binaries available to subsequent steps by "activating" the installed environment in the currently running job.
To this end, `setup-pixi` adds all environment variables set when executing `pixi run` to `$GITHUB_ENV` and, similarly, adds all path modifications to `$GITHUB_PATH`.
As a result, all installed binaries can be accessed without having to call `pixi run`.
```yml
- uses: prefix-dev/setup-pixi@v0.9.4
with:
activate-environment: true
```
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.9.4
with:
environments: >-
py311
py312
activate-environment: py311
```
Activating an environment may be more useful than using a custom shell wrapper as it allows non-shell based steps to access binaries on the path.
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.4.1
- uses: prefix-dev/setup-pixi@v0.9.4
with:
locked: true
# or
@@ -164,12 +350,12 @@ There are two types of debug logging that you can enable.
#### Debug logging of the action
The first one is the debug logging of the action itself.
This can be enabled by running the action with the `ACTIONS_RUNNER_DEBUG` environment variable set to `true`.
This can be enabled by running the action with the `RUNNER_DEBUG` environment variable set to `true`.
```yml
- uses: prefix-dev/setup-pixi@v0.4.1
- uses: prefix-dev/setup-pixi@v0.9.4
env:
ACTIONS_RUNNER_DEBUG: true
RUNNER_DEBUG: true
```
Alternatively, you can enable debug logging for the action by re-running the action in debug mode:
@@ -185,13 +371,13 @@ 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.4.1
- uses: prefix-dev/setup-pixi@v0.9.4
with:
# one of `q`, `default`, `v`, `vv`, or `vvv`.
log-level: vvv
```
If nothing is specified, `setup-pixi` will default to `default` or `vv` depending on if [debug logging is enabled for the action](#debug-logging-of-the-action).
If nothing is specified, `log-level` will default to `default` or `vv` depending on if [debug logging is enabled for the action](#debug-logging-of-the-action).
### Self-hosted runners
@@ -206,18 +392,115 @@ If you set `post-cleanup` to `true`, the action will delete the following files:
- the rattler cache
- other rattler files in `~/.rattler`
If nothing is specified, `setup-pixi` will default to `true`.
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.4.1
- uses: prefix-dev/setup-pixi@v0.9.4
with:
post-cleanup: true
# ${{ runner.temp }}\Scripts\pixi.exe on Windows
pixi-bin-path: ${{ runner.temp }}/bin/pixi
```
You can also use a preinstalled local version of pixi on the runner by not setting any of the `pixi-version`,
`pixi-url` or `pixi-bin-path` inputs. This action will then try to find a local version of pixi in the runner's PATH.
### Using the `pyproject.toml` as a manifest file for pixi
`setup-pixi` will automatically pick up the `pyproject.toml` if it contains a `[tool.pixi.project]` section and no `pixi.toml`.
This can be overwritten by setting the `manifest-path` input argument.
```yml
- uses: prefix-dev/setup-pixi@v0.9.4
with:
manifest-path: pyproject.toml
```
### Working directory for monorepos
If you're working with a monorepo where your pixi project is in a subdirectory, you can use the `working-directory` input to specify where pixi should look for manifest files (`pixi.toml` or `pyproject.toml`).
```yml
- uses: prefix-dev/setup-pixi@v0.9.4
with:
working-directory: ./packages/my-project
```
This will make pixi look for `pixi.toml` or `pyproject.toml` in the `./packages/my-project` directory instead of the repository root. All pixi commands will be executed from this working directory.
> [!NOTE]
> The `working-directory` input only affects commands run by `setup-pixi` itself.
> For subsequent `run:` steps, you need to set the working directory separately:
>
> ```yml
> - run: pixi run test
> working-directory: ./packages/my-project
> ```
You can combine `working-directory` with `manifest-path` if needed:
```yml
- uses: prefix-dev/setup-pixi@v0.9.4
with:
working-directory: ./packages/my-project
manifest-path: custom-pixi.toml
```
### Only install pixi
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.9.4
with:
run-install: false
```
### 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-headers` input argument to supply additional headers for the download request, such as a bearer token.
```yml
- uses: prefix-dev/setup-pixi@v0.9.4
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 }}"}'
```
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.9.4
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).
@@ -225,6 +508,6 @@ If you want to see more examples, you can take a look at the [GitHub Workflows o
## Local Development
1. Clone this repository.
1. Run `pnpm install` inside the repository (if you don't have [`pnpm`](https://github.com/pnpm/pnpm) installed, you can install it with `npm install -g pnpm` or `brew install pnpm`).
1. Run `pnpm dev` for live transpilation of the TypeScript source code.
1. To test the action, you can run [`act`](https://github.com/nektos/act) (inside docker) or use :sparkles: CI driven development :sparkles:.
2. Run `pnpm install` inside the repository (if you don't have [`pnpm`](https://github.com/pnpm/pnpm) installed, you can install it with `pixi global install pnpm`).
3. Run `pnpm dev` for live transpilation of the TypeScript source code.
4. To test the action, you can run [`act`](https://github.com/nektos/act) (inside docker) or use :sparkles: CI driven development :sparkles:.
+7
View File
@@ -0,0 +1,7 @@
# Reporting Security Issues
We take security bugs in our projects seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/prefix-dev/setup-pixi/security/advisories/new) tab.
We will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
+39 -4
View File
@@ -9,28 +9,53 @@ inputs:
pixi-version:
description: Version of pixi to install
pixi-url:
description: URL of pixi to install
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.
One of `q`, `default`, `v`, `vv`, or `vvv`.
manifest-path:
description: Path to the manifest file (i.e., `pixi.toml`) to use for the pixi CLI. Defaults to `pixi.toml`.
working-directory:
description: |
Working directory to use for pixi commands. If specified, pixi will look for manifest files (pixi.toml or pyproject.toml)
in this directory instead of the repository root. Useful for monorepos where pixi projects are in subdirectories.
run-install:
description: Whether to run `pixi install` after setting up the environment. Defaults to `true`.
description: Whether to run `pixi install` after installing pixi. Defaults to `true`.
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
`$GITHUB_PATH`. If more than one environment is specified in `environments`, this must be the name of the
environment. Defaults to `false`. Requires at least pixi v0.21.0.
locked:
description: Whether to use `pixi install --locked`. Defaults to `true` when the lockfile is present, otherwise `false`.
frozen:
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`.
@@ -47,12 +72,22 @@ inputs:
description: Password to use for authentication.
auth-conda-token:
description: Conda token to use for authentication.
auth-s3-access-key-id:
description: Access key ID to use for S3 authentication.
auth-s3-secret-access-key:
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
+62618 -39098
View File
File diff suppressed because one or more lines are too long
Generated Vendored
+29378 -4215
View File
File diff suppressed because one or more lines are too long
+42
View File
@@ -0,0 +1,42 @@
// @ts-check
import eslint from '@eslint/js'
import tseslint from 'typescript-eslint'
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
...tseslint.configs.stylisticTypeChecked,
{
ignores: ['dist/*']
},
{
languageOptions: {
parserOptions: {
project: true,
tsconfigRootDir: import.meta.dirname
}
}
},
{
rules: {
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_'
}
],
'@typescript-eslint/prefer-nullish-coalescing': [
'error',
{
ignoreConditionalTests: true
}
]
}
},
// disable type checking for config files as they aren't in the TS root
{
files: ['eslint.config.mjs', 'prettier.config.mjs', 'tsup.config.js'],
...tseslint.configs.disableTypeChecked
}
)
+22 -23
View File
@@ -1,13 +1,14 @@
{
"name": "setup-pixi",
"version": "0.4.1",
"version": "0.9.4",
"private": true,
"description": "Action to set up the pixi package manager.",
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"lint": "eslint ./src --ext ts",
"lint:fix": "eslint ./src --ext ts --fix"
"eslint": "eslint .",
"lint": "pnpm eslint && prettier -c .",
"lint:fix": "eslint . --fix && prettier -w ."
},
"repository": {
"type": "git",
@@ -21,27 +22,25 @@
"author": "Pavel Zwerschke <pavelzw@gmail.com>",
"license": "BSD-3-Clause",
"dependencies": {
"@actions/cache": "^3.2.2",
"@actions/core": "^1.10.1",
"@actions/exec": "^1.1.1",
"@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.1",
"untildify": "^5.0.0",
"zod": "^3.22.4"
"@actions/cache": "^5.0.1",
"@actions/core": "^2.0.1",
"@actions/exec": "^2.0.0",
"@actions/io": "^2.0.0",
"@actions/tool-cache": "^2.0.2",
"handlebars": "^4.7.8",
"smol-toml": "^1.6.0",
"untildify": "^6.0.0",
"which": "^6.0.0",
"zod": "^4.3.4"
},
"devDependencies": {
"@types/node": "^20.9.0",
"@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser": "^6.10.0",
"eslint": "^8.53.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-n": "^16.3.1",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-promise": "^6.1.1",
"prettier": "^3.1.0",
"tsup": "^7.2.0",
"typescript": "^5.2.2"
"@eslint/js": "^9.39.2",
"@types/node": "^25.0.3",
"@types/which": "^3.0.4",
"eslint": "^9.39.2",
"prettier": "^3.7.4",
"tsup": "^8.5.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.51.0"
}
}
+1789 -2483
View File
File diff suppressed because it is too large Load Diff
+9
View File
@@ -0,0 +1,9 @@
const config = {
tabWidth: 2,
printWidth: 120,
singleQuote: true,
trailingComma: 'none',
semi: false
}
export default config
+70
View File
@@ -0,0 +1,70 @@
import os from 'os'
import * as osPath from 'path'
import * as core from '@actions/core'
import { executeGetOutput, pixiCmd } from './util'
interface ShellHook {
environment_variables: Record<string, string>
}
const splitEnvironment = (shellHook: ShellHook): [Record<string, string>, string?] => {
if (os.platform() === 'win32') {
// On Windows, environment variables are case-insensitive but JSON isn't...
const pathEnvs = Object.keys(shellHook.environment_variables).filter((k) => k.toUpperCase() === 'PATH')
if (pathEnvs.length > 0) {
const caseSensitivePathName = pathEnvs[0]
const path = shellHook.environment_variables[caseSensitivePathName]
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete shellHook.environment_variables[caseSensitivePathName]
return [shellHook.environment_variables, path]
}
} else {
if ('PATH' in shellHook.environment_variables) {
const path = shellHook.environment_variables.PATH
delete shellHook.environment_variables.PATH
return [shellHook.environment_variables, path]
}
}
// If the path cannot be found, return all other environment variables
return [shellHook.environment_variables]
}
const getNewPathComponents = (path: string): string[] => {
const currentPath = process.env.PATH
if (!currentPath) {
throw new Error('Unable to obtain current PATH from environment')
}
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)
}
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 })
const shellHook = JSON.parse(shellHookOutput.stdout) as ShellHook
// Then, we split the environment variables into the special 'PATH' and all others
const [envVars, path] = splitEnvironment(shellHook)
// Finally, new path components are added...
if (path) {
const newComponents = getNewPathComponents(path)
for (const component of newComponents) {
core.info(`Adding path component '${component}'`)
core.addPath(component)
}
}
// ... as well as all remaining environment variables
for (const key of Object.keys(envVars)) {
core.info(`Exporting environment variable '${key}=${envVars[key]}'`)
core.exportVariable(key, envVars[key])
}
}
+147 -54
View File
@@ -5,68 +5,161 @@ import * as cache from '@actions/cache'
import { options } from './options'
import { getCondaArch, sha256 } from './util'
export const generateCacheKey = async (cacheKeyPrefix: string) =>
fs
.readFile(options.pixiLockFile, 'utf-8')
.then((content) => {
const contentsSha = sha256(content)
// 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 lockFileSha = sha256(options.pixiLockFile)
const sha = sha256(contentsSha + lockFileSha)
return `${cacheKeyPrefix}${getCondaArch()}-${sha}`
})
.catch((err) => {
throw new Error(`Failed to generate cache key: ${err}`)
})
const getYearMonth = () => {
// this gets us the current month formatted as YYYY-MM
return new Date().toLocaleDateString('en-CA', { year: 'numeric', month: '2-digit' })
}
const cachePath = path.join(path.dirname(options.pixiLockFile), '.pixi')
let pixiSha: string | undefined
const getPixiSha = async () => {
if (pixiSha) {
return pixiSha
}
const pixiBinary = await fs.readFile(options.pixiBinPath)
pixiSha = sha256(pixiBinary)
return pixiSha
}
let cacheHit = false
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 working directory in the cache key
const cwdSha = sha256(options.workingDirectory)
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 tryRestoreCache = (): Promise<string | undefined> => {
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
core.error(`Error saving ${type} cache: ${err}`)
}
})
}
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_ || !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}\``)
})
.catch((err) => {
core.error(`Error saving cache: ${err.message}`)
})
)
)
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())
}
+144 -42
View File
@@ -6,41 +6,48 @@ 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 { saveCache, tryRestoreCache } from './cache'
import { execute, pixiCmd, renderPixiUrl } from './util'
import { tryRestoreGlobalCache, tryRestoreProjectCache, saveGlobalCache, saveProjectCache } from './cache'
import { activateEnvironment } from './activate'
const downloadPixi = (source: PixiSource) => {
const url = 'version' in source ? getPixiUrlFromVersion(source.version) : source.url
return core.group('Downloading Pixi', () => {
const downloadPixi = async (source: PixiSource) => {
const url = renderPixiUrl(source.urlTemplate, source.version)
await core.group('Downloading Pixi', async () => {
core.debug('Installing pixi')
core.debug(`Downloading pixi from ${url}`)
return fs
.mkdir(path.dirname(options.pixiBinPath), { recursive: true })
.then(() => downloadTool(url, options.pixiBinPath))
.then((_downloadPath) => fs.chmod(options.pixiBinPath, 0o755))
.then(() => core.info(`Pixi installed to ${options.pixiBinPath}`))
core.debug(`Using headers: ${JSON.stringify(source.headers)}`)
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)}`)
return core.group('Logging in to private channel', () => {
core.debug(`auth keys: ${Object.keys(auth).toString()}`)
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))
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}`
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))
})
}
@@ -48,40 +55,135 @@ 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((_cacheKey) =>
execute(pixiCmd(`install${options.frozen ? ' --frozen' : ''}${options.locked ? ' --locked' : ''}`))
)
.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 generateInfo = () => core.group('pixi info', () => execute(pixiCmd('info')))
const generateList = async () => {
if (!options.runInstall) {
core.debug('Skipping pixi list.')
return
}
if (
'version' in options.pixiSource &&
options.pixiSource.version !== 'latest' &&
options.pixiSource.version < 'v0.13.0'
) {
core.warning(
'pixi list is not supported for pixi versions < `v0.13.0`. Please set `pixi-version` to `v0.13.0` or later.'
)
return
}
let command = 'list'
if (
'version' in options.pixiSource &&
options.pixiSource.version !== 'latest' &&
options.pixiSource.version < 'v0.14.0'
) {
if (options.frozen) core.warning('pixi versions < `v0.14.0` do not support the --frozen option for pixi list.')
if (options.locked) core.warning('pixi versions < `v0.14.0` do not support the --locked option for pixi list.')
} else {
command = `${command}${options.frozen ? ' --frozen' : ''}${options.locked ? ' --locked' : ''}`
}
if (options.environments) {
for (const environment of options.environments) {
core.debug(`Listing environment ${environment}`)
const cmd = `${command} -e ${environment}`
await core.group(`pixi ${cmd}`, () => execute(pixiCmd(cmd)))
}
} else {
await core.group(`pixi ${command}`, () => execute(pixiCmd(command)))
}
}
const generateInfo = async () => {
await core.group('pixi info', () => execute(pixiCmd('info')))
}
const activateEnv = async (environment: string) => {
await core.group('Activate environment', () => activateEnvironment(environment))
}
const run = async () => {
core.debug(`process.env.HOME: ${process.env.HOME}`)
core.debug(`process.env.HOME: ${process.env.HOME ?? '-'}`)
core.debug(`os.homedir(): ${os.homedir()}`)
await downloadPixi(options.pixiSource)
if (options.downloadPixi) {
await downloadPixi(options.pixiSource)
}
addPixiToPath()
await pixiLogin()
await pixiInstall()
await pixiGlobalInstall()
await generateInfo()
await pixiInstall()
await generateList()
if (options.activatedEnvironment) {
await activateEnv(options.activatedEnvironment)
}
}
run().catch((error) => {
if (core.isDebug()) {
throw error
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
}
if (error instanceof Error) {
core.setFailed(error.message)
exit(1)
} else if (typeof error === 'string') {
core.setFailed(error)
exit(1)
} else {
throw error
}
}
if (error instanceof Error) {
core.setFailed(error.message)
exit(1)
} else if (typeof error === 'string') {
core.setFailed(error)
exit(1)
}
throw error
})
}
void main()
+267 -50
View File
@@ -1,21 +1,30 @@
import path from 'path'
import os from 'os'
import { exit } from 'process'
import { existsSync } from 'fs'
import { existsSync, readFileSync } from 'fs'
import * as core from '@actions/core'
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 = {
type Inputs = Readonly<{
pixiVersion?: string
pixiUrl?: string
pixiUrlHeaders?: NodeJS.Dict<string>
logLevel?: LogLevel
manifestPath?: string
workingDirectory?: string
runInstall?: boolean
environments?: string[]
activateEnvironment?: string
frozen?: boolean
locked?: boolean
cache?: boolean
globalCache?: boolean
cacheKey?: string
globalCacheKey?: string
cacheWrite?: boolean
pixiBinPath?: string
authHost?: string
@@ -23,16 +32,19 @@ type Inputs = {
authUsername?: string
authPassword?: string
authCondaToken?: string
authS3AccessKeyId?: string
authS3SecretAccessKey?: string
authS3SessionToken?: string
pypiKeyringProvider?: 'disabled' | 'subprocess'
postCleanup?: boolean
}
globalEnvironments?: string[]
}>
export type PixiSource =
| {
version: string
}
| {
url: string
}
export interface PixiSource {
urlTemplate: string
headers?: NodeJS.Dict<string>
version: string
}
type Auth = {
host: string
@@ -47,38 +59,80 @@ type Auth = {
| {
condaToken: string
}
| {
s3AccessKeyId: string
s3SecretAccessKey: string
s3SessionToken?: string
}
)
type Cache = {
interface Cache {
cacheKeyPrefix: string
cacheWrite: boolean
}
interface GlobalCache {
cacheKeyPrefix: string
cacheWrite: boolean
}
export type Options = Readonly<{
pixiSource: PixiSource
downloadPixi: boolean
logLevel: LogLevel
manifestPath: string
workingDirectory: string
pixiLockFile: string
runInstall: boolean
environments?: string[]
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'
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' : ''}`)
}
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 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.ZodType<T>, errorMessage?: string): T | undefined => {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
}
const maybeResult = schema.safeParse(input)
@@ -91,25 +145,52 @@ 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 input = core.getInput(key)
// GitHub actions sets empty inputs to the empty string, but we want undefined
if (input === '') {
const parseOrUndefinedJSON = <T>(key: string, schema: z.ZodType<T>): T | undefined => {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
}
return schema.parse(JSON.parse(input))
}
const parseOrUndefinedList = <T>(key: string, schema: z.ZodType<T>): T[] | undefined => {
const input = inputOrEnvironmentVariable(key)
if (input === undefined) {
return undefined
}
return input
.split(' ')
.map((s) => schema.parse(s))
.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.pixiVersion && inputs.pixiUrl) {
throw new Error('You need to specify either pixi-version or pixi-url')
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')
}
@@ -122,46 +203,156 @@ const validateInputs = (inputs: Inputs): void => {
if ((inputs.authUsername && !inputs.authPassword) || (!inputs.authUsername && inputs.authPassword)) {
throw new Error('You need to specify both auth-username and auth-password')
}
if (
(inputs.authS3AccessKeyId && !inputs.authS3SecretAccessKey) ||
(!inputs.authS3AccessKeyId && inputs.authS3SecretAccessKey)
) {
throw new Error('You need to specify both auth-s3-access-key-id and auth-s3-secret-access-key')
}
if (inputs.authS3SessionToken && (!inputs.authS3AccessKeyId || !inputs.authS3SecretAccessKey)) {
throw new Error(
'You need to specify both auth-s3-access-key-id and auth-s3-secret-access-key when using auth-s3-session-token'
)
}
// now we can assume that authUsername is defined iff authPassword is defined
if (inputs.authHost) {
if (!inputs.authToken && !inputs.authUsername && !inputs.authCondaToken) {
if (!inputs.authToken && !inputs.authUsername && !inputs.authCondaToken && !inputs.authS3AccessKeyId) {
throw new Error('You need to specify either auth-token or auth-username and auth-password or auth-conda-token')
}
if (
(inputs.authToken && (inputs.authUsername || inputs.authCondaToken)) ||
(inputs.authUsername && inputs.authCondaToken)
) {
throw new Error('You cannot specify two auth methods')
let authCount = 0
if (inputs.authToken) {
authCount++
}
if (inputs.authUsername) {
authCount++
}
if (inputs.authCondaToken) {
authCount++
}
if (inputs.authS3AccessKeyId) {
authCount++
}
if (authCount > 1) {
throw new Error('You cannot specify multiple auth methods')
}
}
if (!inputs.authHost) {
if (inputs.authToken || inputs.authUsername || inputs.authCondaToken) {
if (inputs.authToken || inputs.authUsername || inputs.authCondaToken || inputs.authS3AccessKeyId) {
throw new Error('You need to specify auth-host')
}
}
if (inputs.cacheWrite && !inputs.cacheKey && !inputs.cache) {
throw new Error('cache-write is only valid with cache-key or cache specified.')
if (inputs.runInstall === false && inputs.environments) {
throw new Error('Cannot specify environments without running install')
}
if (inputs.activateEnvironment === 'true' && inputs.environments && inputs.environments.length > 1) {
throw new Error('When installing multiple environments, `activate-environment` must specify the environment name')
}
}
const determinePixiInstallation = (pixiUrlOrVersionSet: boolean, pixiBinPath: string | undefined) => {
const preinstalledPixi = which.sync('pixi', { nothrow: true })
if (pixiUrlOrVersionSet || pixiBinPath) {
if (preinstalledPixi) {
core.debug(`Local pixi found at ${preinstalledPixi} is being ignored.`)
}
return {
downloadPixi: true,
pixiBinPath: pixiBinPath ? path.resolve(untildify(pixiBinPath)) : PATHS.pixiBin
}
}
if (preinstalledPixi) {
core.info(`Using pre-installed pixi at ${preinstalledPixi}`)
return { downloadPixi: false, pixiBinPath: preinstalledPixi }
}
return { downloadPixi: true, pixiBinPath: PATHS.pixiBin }
}
const inferOptions = (inputs: Inputs): Options => {
const runInstall = inputs.runInstall ?? true
const pixiSource = inputs.pixiVersion
? { version: inputs.pixiVersion }
: inputs.pixiUrl
? { url: inputs.pixiUrl }
: { 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,
inputs.pixiBinPath
)
const logLevel = inputs.logLevel ?? (core.isDebug() ? 'vv' : 'default')
const manifestPath = inputs.manifestPath ? path.resolve(untildify(inputs.manifestPath)) : 'pixi.toml'
const pixiLockFile = path.join(path.dirname(manifestPath), path.basename(manifestPath).replace(/\.toml$/, '.lock'))
// Determine the working directory - resolve to absolute path if provided
const workingDirectory = inputs.workingDirectory ? path.resolve(untildify(inputs.workingDirectory)) : process.cwd()
core.debug(`Working directory: ${workingDirectory}`)
// infer manifest path from inputs or default to pixi.toml or pyproject.toml depending on what is present in the working directory.
const pixiTomlPathInWorkingDir = path.join(workingDirectory, pixiPath)
const pyprojectTomlPathInWorkingDir = path.join(workingDirectory, pyprojectPath)
let manifestPath = pixiTomlPathInWorkingDir // default
if (inputs.manifestPath) {
// If manifest path is provided, resolve it relative to working directory if it's not absolute
manifestPath = path.isAbsolute(inputs.manifestPath)
? path.resolve(untildify(inputs.manifestPath))
: path.resolve(workingDirectory, inputs.manifestPath)
} else {
if (existsSync(pixiTomlPathInWorkingDir)) {
manifestPath = pixiTomlPathInWorkingDir
core.debug(`Found pixi.toml at: ${manifestPath}`)
} else if (existsSync(pyprojectTomlPathInWorkingDir)) {
try {
const fileContent = readFileSync(pyprojectTomlPathInWorkingDir, 'utf-8')
const parsedContent: Record<string, unknown> = parse(fileContent)
// Test if the tool.pixi table is present in the pyproject.toml file, if so, use it as the manifest file.
if (parsedContent.tool && typeof parsedContent.tool === 'object' && 'pixi' in parsedContent.tool) {
core.debug(`The tool.pixi table found, using ${pyprojectTomlPathInWorkingDir} as manifest file.`)
manifestPath = pyprojectTomlPathInWorkingDir
}
} catch (error) {
core.error(`Error while trying to read ${pyprojectTomlPathInWorkingDir} file.`)
core.error(error as Error)
}
} else if (runInstall) {
core.warning(
`Could not find any manifest file in ${workingDirectory}. Defaulting to ${pixiTomlPathInWorkingDir}.`
)
}
}
const pixiLockFile = path.join(path.dirname(manifestPath), 'pixi.lock')
const lockFileAvailable = existsSync(pixiLockFile)
core.debug(`lockFileAvailable: ${lockFileAvailable}`)
const cache = inputs.cacheKey
? { cacheKeyPrefix: inputs.cacheKey, cacheWrite: inputs.cacheWrite ?? true }
: inputs.cache === true || (lockFileAvailable && inputs.cache !== false)
? { cacheKeyPrefix: 'pixi-', cacheWrite: true }
core.debug(`lockFileAvailable: ${lockFileAvailable ? 'yes' : 'no'}`)
if (!lockFileAvailable && inputs.cacheWrite === true) {
throw new Error('You cannot specify cache-write = true without a lock file present')
}
let activatedEnvironment // default is undefined
if (inputs.activateEnvironment === 'true') {
if (inputs.environments) {
activatedEnvironment = inputs.environments[0]
} else {
activatedEnvironment = 'default'
}
} else if (inputs.activateEnvironment && inputs.activateEnvironment !== 'false') {
activatedEnvironment = inputs.activateEnvironment
}
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 pixiBinPath = inputs.pixiBinPath ? path.resolve(untildify(inputs.pixiBinPath)) : PATHS.pixiBin
const frozen = inputs.frozen ?? false
const locked = inputs.locked ?? (lockFileAvailable && !frozen)
const auth = !inputs.authHost
@@ -176,21 +367,36 @@ const inferOptions = (inputs: Inputs): Options => {
host: inputs.authHost,
condaToken: inputs.authCondaToken
}
: {
host: inputs.authHost,
username: inputs.authUsername!,
password: inputs.authPassword!
}) as Auth)
: inputs.authUsername
? {
host: inputs.authHost,
username: inputs.authUsername,
password: inputs.authPassword
}
: {
host: inputs.authHost,
s3AccessKeyId: inputs.authS3AccessKeyId,
s3SecretAccessKey: inputs.authS3SecretAccessKey,
s3SessionToken: inputs.authS3SessionToken
}) as Auth)
const postCleanup = inputs.postCleanup ?? true
const pypiKeyringProvider = inputs.pypiKeyringProvider
return {
globalEnvironments: inputs.globalEnvironments,
pixiSource,
pypiKeyringProvider,
downloadPixi,
logLevel,
manifestPath,
workingDirectory,
pixiLockFile,
runInstall,
environments: inputs.environments,
activatedEnvironment,
frozen,
locked,
cache,
globalCache,
pixiBinPath,
auth,
postCleanup
@@ -213,18 +419,24 @@ 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()),
pixiUrl: parseOrUndefined('pixi-url', z.string()),
pixiUrlHeaders: parseOrUndefinedJSON('pixi-url-headers', z.record(z.string(), z.string())),
logLevel: parseOrUndefined(
'log-level',
logLevelSchema,
'log-level must be one of `q`, `default`, `v`, `vv`, `vvv`.'
),
manifestPath: parseOrUndefined('manifest-path', z.string()),
workingDirectory: parseOrUndefined('working-directory', z.string()),
runInstall: parseOrUndefinedJSON('run-install', z.boolean()),
environments: parseOrUndefinedList('environments', z.string()),
activateEnvironment: parseOrUndefined('activate-environment', z.string()),
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()),
@@ -232,6 +444,11 @@ const getOptions = () => {
authUsername: parseOrUndefined('auth-username', z.string()),
authPassword: parseOrUndefined('auth-password', z.string()),
authCondaToken: parseOrUndefined('auth-conda-token', z.string()),
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)}`)
+43 -28
View File
@@ -1,30 +1,37 @@
import fs from 'fs/promises'
import { existsSync } from 'fs'
import path from 'path'
import * as os from 'os'
import os from 'os'
import { exit } from 'process'
import * as core from '@actions/core'
import { options } from './options'
const removeEmptyParentDirs = (dirPath: string): Promise<void> => {
return fs.readdir(dirPath).then((files) => {
if (files.length === 0) {
core.debug(`Removing empty directory ${dirPath}.`)
return fs.rm(dirPath, { recursive: true }).then(() => {
const parentDir = path.dirname(dirPath)
if (parentDir !== dirPath) {
return removeEmptyParentDirs(parentDir)
}
})
}
return Promise.resolve()
})
if (existsSync(dirPath)) {
return fs.readdir(dirPath).then((files) => {
if (files.length === 0) {
core.debug(`Removing empty directory ${dirPath}.`)
return fs.rm(dirPath, { recursive: true, force: true }).then(() => {
const parentDir = path.dirname(dirPath)
if (parentDir !== dirPath) {
return removeEmptyParentDirs(parentDir)
}
})
}
})
}
return Promise.resolve()
}
const cleanupPixiBin = () => {
const pixiBinPath = options.pixiBinPath
const pixiBinDir = path.dirname(pixiBinPath)
core.debug(`Cleaning up pixi binary ${pixiBinPath}.`)
return fs.rm(pixiBinPath).then(() => removeEmptyParentDirs(pixiBinDir))
if (existsSync(pixiBinPath)) {
return fs.rm(pixiBinPath).then(() => removeEmptyParentDirs(pixiBinDir))
} else {
return removeEmptyParentDirs(pixiBinDir)
}
}
const cleanupEnv = () => {
@@ -34,12 +41,18 @@ const cleanupEnv = () => {
}
const envDir = path.join(path.dirname(options.manifestPath), '.pixi')
core.debug(`Cleaning up .pixi directory ${envDir}.`)
return fs.rm(envDir, { recursive: true })
return fs.rm(envDir, {
recursive: true,
// Ignore exceptions if environment does not exist anymore,
// to avoid errors if setup-pixi is used multiple times within the same workflow.
force: true
})
}
const determineCacheDir = () => {
const determineCacheDir = (): string => {
// rattler uses dirs::cache_dir https://docs.rs/dirs/latest/dirs/fn.cache_dir.html
if (os.platform() === 'win32') {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return process.env.LOCALAPPDATA!
}
if (os.platform() === 'linux') {
@@ -68,16 +81,18 @@ const run = () => {
return Promise.resolve()
}
run().catch((error) => {
if (core.isDebug()) {
run()
.then(() => exit(0)) // workaround for https://github.com/actions/toolkit/issues/1578
.catch((error: unknown) => {
if (core.isDebug()) {
throw error
}
if (error instanceof Error) {
core.setFailed(error.message)
exit(1)
} else if (typeof error === 'string') {
core.setFailed(error)
exit(1)
}
throw error
}
if (error instanceof Error) {
core.setFailed(error.message)
exit(1)
} else if (typeof error === 'string') {
core.setFailed(error)
exit(1)
}
throw error
})
})
+35 -14
View File
@@ -1,9 +1,18 @@
import type { BinaryLike } from 'crypto'
import { createHash } from 'crypto'
import * as os from 'os'
import os from 'os'
import * as core from '@actions/core'
import { exec } from '@actions/exec'
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> = {
@@ -12,7 +21,8 @@ export const getCondaArch = () => {
'linux-x64': 'linux-64',
'linux-arm64': 'linux-aarch64',
'linux-ppc64': 'linux-ppc64le',
'win32-x64': 'win-64'
'win32-x64': 'win-64',
'win32-arm64': 'win-arm64'
}
const arch = archDict[`${os.platform()}-${os.arch()}`]
if (!arch) {
@@ -47,17 +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 (arch === 'aarch64' && platform === 'pc-windows-msvc') {
throw new Error('Windows on ARM is currently not supported')
}
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) => {
@@ -69,15 +79,26 @@ export const sha256Short = (s: BinaryLike) => {
}
export const execute = (cmd: string[]) => {
core.debug(`Executing: ${cmd.join(' ')}`)
return exec(cmd[0], cmd.slice(1))
core.debug(`Executing: \`${cmd.toString()}\``)
// needs escaping if cmd[0] contains spaces
// https://github.com/prefix-dev/setup-pixi/issues/184#issuecomment-2765724843
return exec(`"${cmd[0]}"`, cmd.slice(1), { cwd: options.workingDirectory })
}
export const executeGetOutput = (cmd: string[], execOptions: ExecOptions) => {
core.debug(`Executing: \`${cmd.toString()}\``)
// needs escaping if cmd[0] contains spaces
// https://github.com/prefix-dev/setup-pixi/issues/184#issuecomment-2765724843
const defaultOptions = { cwd: options.workingDirectory }
return getExecOutput(`"${cmd[0]}"`, cmd.slice(1), { ...defaultOptions, ...execOptions })
}
export const pixiCmd = (command: string, withManifestPath = true) => {
let commandArray = [options.pixiBinPath].concat(command.split(' '))
let commandArray = [options.pixiBinPath].concat(command.split(' ').filter((x) => x !== ''))
if (withManifestPath) {
commandArray = commandArray.concat(['--manifest-path', options.manifestPath])
}
commandArray = commandArray.concat(['--color', 'always'])
switch (options.logLevel) {
case 'vvv':
commandArray = commandArray.concat(['-vvv'])
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
[workspace]
name = "test-auth-s3"
channels = ["s3://rattler-s3-testing/channel", "conda-forge"]
platforms = ["osx-arm64", "osx-64", "linux-64", "linux-aarch64", "win-64"]
[workspace.s3-options.rattler-s3-testing]
endpoint-url = "https://e1a7cde76f1780ec06bac859036dbaf7.eu.r2.cloudflarestorage.com"
force-path-style = true
region = "auto"
[dependencies]
my-webserver = "*"
python = "*"
+1 -4
View File
@@ -1,8 +1,5 @@
[project]
[workspace]
name = "test-auth"
version = "0.1.0"
description = "Add a short description here"
authors = ["Pavel"]
channels = ["conda-forge", "https://repo.prefix.dev/setup-pixi-test"]
platforms = ["osx-arm64", "osx-64", "linux-64", "linux-aarch64", "win-64"]
+229
View File
@@ -0,0 +1,229 @@
version: 6
environments:
default:
channels:
- url: https://conda.anaconda.org/conda-forge/
packages:
linux-64:
- conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2
- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2
- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda
- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda
linux-aarch64:
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-2_gnu.tar.bz2
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h68df207_7.conda
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-14.2.0-he277a41_2.conda
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-14.2.0-he9431aa_2.conda
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-14.2.0-he277a41_2.conda
osx-64:
- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda
osx-arm64:
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda
win-64:
- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda
- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda
- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_26.conda
- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34438-hfd919c2_26.conda
win-arm64:
- conda: https://conda.anaconda.org/conda-forge/win-arm64/bzip2-1.0.8-hfbbf558_7.conda
- conda: https://conda.anaconda.org/conda-forge/win-arm64/vc-14.3-hfe6595e_26.conda
- conda: https://conda.anaconda.org/conda-forge/win-arm64/vc14_runtime-14.42.34438-hfe4e545_26.conda
packages:
- conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2
sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726
md5: d7c89558ba9fa0495403155b64376d81
license: None
size: 2562
timestamp: 1578324546067
- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2
build_number: 16
sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22
md5: 73aaf86a425cc6e73fcf236a5a46396d
depends:
- _libgcc_mutex 0.1 conda_forge
- libgomp >=7.5.0
constrains:
- openmp_impl 9999
license: BSD-3-Clause
license_family: BSD
size: 23621
timestamp: 1650670423406
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-2_gnu.tar.bz2
build_number: 16
sha256: 3702bef2f0a4d38bd8288bbe54aace623602a1343c2cfbefd3fa188e015bebf0
md5: 6168d71addc746e8f2b8d57dfd2edcea
depends:
- libgomp >=7.5.0
constrains:
- openmp_impl 9999
license: BSD-3-Clause
license_family: BSD
size: 23712
timestamp: 1650670790230
- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda
sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d
md5: 62ee74e96c5ebb0af99386de58cf9553
depends:
- __glibc >=2.17,<3.0.a0
- libgcc-ng >=12
license: bzip2-1.0.6
license_family: BSD
size: 252783
timestamp: 1720974456583
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h68df207_7.conda
sha256: 2258b0b33e1cb3a9852d47557984abb6e7ea58e3d7f92706ec1f8e879290c4cb
md5: 56398c28220513b9ea13d7b450acfb20
depends:
- libgcc-ng >=12
license: bzip2-1.0.6
license_family: BSD
size: 189884
timestamp: 1720974504976
- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda
sha256: cad153608b81fb24fc8c509357daa9ae4e49dfc535b2cb49b91e23dbd68fc3c5
md5: 7ed4301d437b59045be7e051a0308211
depends:
- __osx >=10.13
license: bzip2-1.0.6
license_family: BSD
size: 134188
timestamp: 1720974491916
- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda
sha256: adfa71f158cbd872a36394c56c3568e6034aa55c623634b37a4836bd036e6b91
md5: fc6948412dbbbe9a4c9ddbbcfe0a79ab
depends:
- __osx >=11.0
license: bzip2-1.0.6
license_family: BSD
size: 122909
timestamp: 1720974522888
- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda
sha256: 35a5dad92e88fdd7fc405e864ec239486f4f31eec229e31686e61a140a8e573b
md5: 276e7ffe9ffe39688abc665ef0f45596
depends:
- ucrt >=10.0.20348.0
- vc >=14.2,<15
- vc14_runtime >=14.29.30139
license: bzip2-1.0.6
license_family: BSD
size: 54927
timestamp: 1720974860185
- conda: https://conda.anaconda.org/conda-forge/win-arm64/bzip2-1.0.8-hfbbf558_7.conda
sha256: f6b3f14c17f7aebe0ac88e74957644da17288b1b78f8776ed4f04a4e6e4a7d9c
md5: 86d73707c1a3db358fb0b42fb6e33add
depends:
- vc >=14.3,<15
- vc14_runtime >=14.40.33810
license: bzip2-1.0.6
license_family: BSD
size: 54629
timestamp: 1720974690059
- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda
sha256: 3a572d031cb86deb541d15c1875aaa097baefc0c580b54dc61f5edab99215792
md5: ef504d1acbd74b7cc6849ef8af47dd03
depends:
- __glibc >=2.17,<3.0.a0
- _openmp_mutex >=4.5
constrains:
- libgomp 14.2.0 h767d61c_2
- libgcc-ng ==14.2.0=*_2
license: GPL-3.0-only WITH GCC-exception-3.1
license_family: GPL
size: 847885
timestamp: 1740240653082
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-14.2.0-he277a41_2.conda
sha256: a57f7f9ba2a12f56eafdcd25b6d75f7be10b8fc1a802a58b76a77ca8c66f4503
md5: 6b4268a60b10f29257b51b9b67ff8d76
depends:
- _openmp_mutex >=4.5
constrains:
- libgcc-ng ==14.2.0=*_2
- libgomp 14.2.0 he277a41_2
license: GPL-3.0-only WITH GCC-exception-3.1
license_family: GPL
size: 535507
timestamp: 1740241069780
- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda
sha256: fb7558c328b38b2f9d2e412c48da7890e7721ba018d733ebdfea57280df01904
md5: a2222a6ada71fb478682efe483ce0f92
depends:
- libgcc 14.2.0 h767d61c_2
license: GPL-3.0-only WITH GCC-exception-3.1
license_family: GPL
size: 53758
timestamp: 1740240660904
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-14.2.0-he9431aa_2.conda
sha256: 9647f75cddc18b07eebe6e1f21500eed50a6af2c43c84e831b4c7a597e10d226
md5: 692c2bb75f32cfafb6799cf6d1c5d0e0
depends:
- libgcc 14.2.0 he277a41_2
license: GPL-3.0-only WITH GCC-exception-3.1
license_family: GPL
size: 53622
timestamp: 1740241074834
- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda
sha256: 1a3130e0b9267e781b89399580f3163632d59fe5b0142900d63052ab1a53490e
md5: 06d02030237f4d5b3d9a7e7d348fe3c6
depends:
- __glibc >=2.17,<3.0.a0
license: GPL-3.0-only WITH GCC-exception-3.1
license_family: GPL
size: 459862
timestamp: 1740240588123
- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-14.2.0-he277a41_2.conda
sha256: 4e303711fb7413bf98995beac58e731073099d7a669a3b81e49330ca8da05174
md5: b11c09d9463daf4cae492d29806b1889
license: GPL-3.0-only WITH GCC-exception-3.1
license_family: GPL
size: 462783
timestamp: 1740241005079
- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda
sha256: db8dead3dd30fb1a032737554ce91e2819b43496a0db09927edf01c32b577450
md5: 6797b005cd0f439c4c5c9ac565783700
constrains:
- vs2015_runtime >=14.29.30037
license: LicenseRef-MicrosoftWindowsSDK10
size: 559710
timestamp: 1728377334097
- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_26.conda
sha256: 7a685b5c37e9713fa314a0d26b8b1d7a2e6de5ab758698199b5d5b6dba2e3ce1
md5: d3f0381e38093bde620a8d85f266ae55
depends:
- vc14_runtime >=14.42.34433
track_features:
- vc14
license: BSD-3-Clause
license_family: BSD
size: 17893
timestamp: 1743195261486
- conda: https://conda.anaconda.org/conda-forge/win-arm64/vc-14.3-hfe6595e_26.conda
sha256: dc8f1cbbfd91e267a05cdf9bb0a04e983f9df6b02885446dfe0d796c99e67e0a
md5: a57c01b43b14be7d028c84bad0bc1599
depends:
- vc14_runtime >=14.42.34438
track_features:
- vc14
license: BSD-3-Clause
license_family: BSD
size: 17394
timestamp: 1743194837327
- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34438-hfd919c2_26.conda
sha256: 30dcb71bb166e351aadbdc18f1718757c32cdaa0e1e5d9368469ee44f6bf4709
md5: 91651a36d31aa20c7ba36299fb7068f4
depends:
- ucrt >=10.0.20348.0
constrains:
- vs2015_runtime 14.42.34438.* *_26
license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime
license_family: Proprietary
size: 750733
timestamp: 1743195092905
- conda: https://conda.anaconda.org/conda-forge/win-arm64/vc14_runtime-14.42.34438-hfe4e545_26.conda
sha256: 37cf20eb09cf77e261d61ba40b322e010a7043b4247f01420f8241bd68a683ba
md5: 1995ed932d07efb2fe632778484f9fbb
license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime
license_family: Proprietary
size: 15480436
timestamp: 1743194808631
+14
View File
@@ -0,0 +1,14 @@
[workspace]
name = "test-win-arm64"
channels = ["conda-forge"]
platforms = [
"linux-64",
"linux-aarch64",
"osx-64",
"osx-arm64",
"win-64",
"win-arm64",
]
[dependencies]
bzip2 = "*"
+855 -996
View File
File diff suppressed because it is too large Load Diff
+2 -5
View File
@@ -1,10 +1,7 @@
[project]
[workspace]
name = "test-default"
version = "0.1.0"
description = "Add a short description here"
authors = ["Pavel Zwerschke <pavelzw@gmail.com>"]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-64", "win-64"]
platforms = ["linux-64", "linux-aarch64", "osx-64", "osx-arm64", "win-64"]
[tasks]
test = "python -c 'print(\"Hello world!\")'"
+1 -1
View File
@@ -1,4 +1,4 @@
[project]
[workspace]
name = "test-default"
version = "0.1.0"
description = "Add a short description here"
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
[workspace]
name = "test-package"
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
[dependencies]
python = ">=3.11"
pip = "*"
polars = ">=0.14.24,<0.21"
[feature.py311.dependencies]
python = "3.11.*"
[feature.py312.dependencies]
python = "3.12.*"
[environments]
py311 = ["py311"]
py312 = ["py312"]
+2 -5
View File
@@ -1,10 +1,7 @@
[project]
[workspace]
name = "test-no-lockfile"
version = "0.1.0"
description = "Add a short description here"
authors = ["Pavel Zwerschke <pavelzw@gmail.com>"]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-64", "win-64"]
platforms = ["linux-64", "linux-aarch64", "osx-64", "osx-arm64", "win-64"]
[tasks]
test = "python -c 'print(\"Hello world!\")'"
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
[project]
name = "test-default"
version = "0.1.0"
description = "Add a short description here"
authors = ["Pavel Zwerschke <pavelzw@gmail.com>"]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]
[tasks]
test = "python -c 'print(\"Hello world!\")'"
[dependencies]
python = "3.11.*"
File diff suppressed because it is too large Load Diff
+47
View File
@@ -0,0 +1,47 @@
[project]
name = "pyproject-manifest"
version = "0.1.0"
description = "Testing pyproject-manifest."
readme = "README.md"
requires-python = ">=3.11"
dependencies = ["flask==2.*"]
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[dependency-groups]
# inline lists with mixed types are a toml 1.0 feature
dev = [{ include-group = "lint" }, { include-group = "docs" }, "ipython"]
docs = ["mkdocs>=1.4"]
lint = ["ruff>=0.1.14"]
[tool.ruff]
target-version = "py310"
line-length = 100
exclude = [".pixi", "__pycache__"]
# the TOML parser should also support comments in lists
lint.select = [
# flake8-bugbear
"B",
# flake8-comprehensions
"C4",
# pydocstyle
"D",
# Error
"E",
# pyflakes
"F",
]
[tool.pixi.workspace]
name = "pyproject-manifest"
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
[tool.pixi]
# This dotted inline table fails with the `toml` parser, but works with `@iarna/toml`.
pypi-dependencies.boltons = "*"
[tool.pixi.tasks]
test = "echo 'Running tests...'"
+7 -7
View File
@@ -1,12 +1,12 @@
{
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"outDir": "./lib", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
"module": "CommonJS" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
"outDir": "./lib" /* Redirect output structure to the directory. */,
"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
"strict": true /* Enable all strict type-checking options. */,
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
},
"exclude": ["node_modules", "**/*.test.ts"]
}
+11 -2
View File
@@ -8,9 +8,15 @@ export default defineConfig({
dts: false,
clean: true,
target: 'es2020',
format: ['cjs'],
sourcemap: true,
format: 'cjs',
sourcemap: false,
platform: 'node',
minify: false,
outExtension() {
return {
js: '.js'
}
},
// need to bundle dependencies because they aren't available otherwise when run inside the action
noExternal: [
'@actions/core',
@@ -18,7 +24,10 @@ export default defineConfig({
'@actions/cache',
'@actions/io',
'@actions/tool-cache',
'handlebars',
'untildify',
'smol-toml',
'which',
'zod'
]
})