├── .direnvrc ├── .envrc ├── .eslintignore ├── .gitattributes ├── .github ├── dependabot.yml ├── linters │ ├── .eslintrc.yml │ ├── .markdown-lint.yml │ ├── .yaml-lint.yml │ └── tsconfig.json └── workflows │ └── test.yml ├── .gitignore ├── .node-version ├── .prettierignore ├── .prettierrc.json ├── LICENSE ├── README.md ├── __tests__ └── main.test.ts ├── action.yml ├── devenv.lock ├── devenv.nix ├── devenv.yaml ├── dist ├── index.js ├── index.js.map ├── licenses.txt └── sourcemap-register.js ├── flake.lock ├── flake.nix ├── package-lock.json ├── package.json ├── src ├── index.ts ├── main.ts └── wait.ts ├── test ├── devshell-flake │ ├── flake.lock │ └── flake.nix └── working-directory │ ├── flake.nix │ └── test.sh └── tsconfig.json /.direnvrc: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------- 2 | # From: https://github.com/direnv/direnv/issues/73#issuecomment-392342423 3 | # ---------------------------------------------------------------- 4 | export_function() { 5 | local name=$1 6 | local alias_dir=$PWD/.direnv/aliases 7 | mkdir -p "$alias_dir" 8 | PATH_add "$alias_dir" 9 | local target="$alias_dir/$name" 10 | if declare -f "$name" >/dev/null; then 11 | echo "#!/usr/bin/env bash" > "$target" 12 | declare -f "$name" >> "$target" 2>/dev/null 13 | # Notice that we add shell variables to the function trigger. 14 | echo "$name \$*" >> "$target" 15 | chmod +x "$target" 16 | fi 17 | } 18 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | source_url "https://raw.githubusercontent.com/cachix/devenv/95f329d49a8a5289d31e0982652f7058a189bfca/direnvrc" "sha256-d+8cBpDfDBj41inrADaJt+bDWhOktwslgoP5YiGJ1v0=" 2 | 3 | use devenv -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | dist/ 3 | node_modules/ 4 | coverage/ 5 | .devenv/ 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | dist/** -diff linguist-generated=true -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: weekly 7 | groups: 8 | actions-minor: 9 | update-types: 10 | - minor 11 | - patch 12 | 13 | - package-ecosystem: npm 14 | directory: / 15 | schedule: 16 | interval: weekly 17 | groups: 18 | npm-development: 19 | dependency-type: development 20 | update-types: 21 | - minor 22 | - patch 23 | npm-production: 24 | dependency-type: production 25 | update-types: 26 | - patch 27 | -------------------------------------------------------------------------------- /.github/linters/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | node: true 3 | es6: true 4 | jest: true 5 | 6 | globals: 7 | Atomics: readonly 8 | SharedArrayBuffer: readonly 9 | 10 | ignorePatterns: 11 | - '!.*' 12 | - '**/node_modules/.*' 13 | - '**/dist/.*' 14 | - '**/coverage/.*' 15 | - '*.json' 16 | 17 | parser: '@typescript-eslint/parser' 18 | 19 | parserOptions: 20 | ecmaVersion: 2023 21 | sourceType: module 22 | project: 23 | - './.github/linters/tsconfig.json' 24 | - './tsconfig.json' 25 | 26 | plugins: 27 | - jest 28 | - '@typescript-eslint' 29 | 30 | extends: 31 | - eslint:recommended 32 | - plugin:@typescript-eslint/eslint-recommended 33 | - plugin:@typescript-eslint/recommended 34 | - plugin:jest/recommended 35 | 36 | rules: 37 | { 38 | 'camelcase': 'off', 39 | 'eslint-comments/no-use': 'off', 40 | 'eslint-comments/no-unused-disable': 'off', 41 | 'i18n-text/no-en': 'off', 42 | 'import/no-namespace': 'off', 43 | 'no-console': 'off', 44 | 'no-unused-vars': 'off', 45 | 'semi': 'off', 46 | '@typescript-eslint/array-type': 'error', 47 | '@typescript-eslint/await-thenable': 'error', 48 | '@typescript-eslint/ban-ts-comment': 'error', 49 | '@typescript-eslint/consistent-type-assertions': 'error', 50 | '@typescript-eslint/explicit-member-accessibility': 51 | ['error', { 'accessibility': 'no-public' }], 52 | '@typescript-eslint/explicit-function-return-type': 53 | ['error', { 'allowExpressions': true }], 54 | '@typescript-eslint/no-array-constructor': 'error', 55 | '@typescript-eslint/no-empty-interface': 'error', 56 | '@typescript-eslint/no-explicit-any': 'error', 57 | '@typescript-eslint/no-extraneous-class': 'error', 58 | '@typescript-eslint/no-for-in-array': 'error', 59 | '@typescript-eslint/no-inferrable-types': 'error', 60 | '@typescript-eslint/no-misused-new': 'error', 61 | '@typescript-eslint/no-namespace': 'error', 62 | '@typescript-eslint/no-non-null-assertion': 'warn', 63 | '@typescript-eslint/no-require-imports': 'error', 64 | '@typescript-eslint/no-unnecessary-qualifier': 'error', 65 | '@typescript-eslint/no-unnecessary-type-assertion': 'error', 66 | '@typescript-eslint/no-unused-vars': 'error', 67 | '@typescript-eslint/no-useless-constructor': 'error', 68 | '@typescript-eslint/no-var-requires': 'error', 69 | '@typescript-eslint/prefer-for-of': 'warn', 70 | '@typescript-eslint/prefer-function-type': 'warn', 71 | '@typescript-eslint/prefer-includes': 'error', 72 | '@typescript-eslint/prefer-string-starts-ends-with': 'error', 73 | '@typescript-eslint/promise-function-async': 'error', 74 | '@typescript-eslint/require-array-sort-compare': 'error', 75 | '@typescript-eslint/restrict-plus-operands': 'error', 76 | '@typescript-eslint/space-before-function-paren': 'off', 77 | '@typescript-eslint/unbound-method': 'error' 78 | } 79 | -------------------------------------------------------------------------------- /.github/linters/.markdown-lint.yml: -------------------------------------------------------------------------------- 1 | # Unordered list style 2 | MD004: 3 | style: dash 4 | 5 | # Ordered list item prefix 6 | MD029: 7 | style: one 8 | 9 | # Spaces after list markers 10 | MD030: 11 | ul_single: 1 12 | ol_single: 1 13 | ul_multi: 1 14 | ol_multi: 1 15 | 16 | # Code block style 17 | MD046: 18 | style: fenced 19 | -------------------------------------------------------------------------------- /.github/linters/.yaml-lint.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | document-end: disable 3 | document-start: 4 | level: warning 5 | present: false 6 | line-length: 7 | level: warning 8 | max: 80 9 | allow-non-breakable-words: true 10 | allow-non-breakable-inline-mappings: true 11 | -------------------------------------------------------------------------------- /.github/linters/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "noEmit": true 6 | }, 7 | "include": ["../../__tests__/**/*", "../../src/**/*"], 8 | "exclude": ["../../dist", "../../node_modules", "../../coverage", "*.json"] 9 | } 10 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: 'nix-shell-action-test' 2 | on: # rebuild any PRs and main branch changes 3 | pull_request: 4 | push: 5 | branches: 6 | - main 7 | - support-devshell 8 | - 'releases/*' 9 | 10 | jobs: 11 | build: # make sure build/ci work properly 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Install Nix 16 | uses: cachix/install-nix-action@v30 17 | with: 18 | extra_nix_config: | 19 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 20 | - uses: actions/setup-node@v4 21 | with: 22 | node-version: 20 23 | - run: | 24 | npm install 25 | - run: | 26 | npm run all 27 | test-latest-nix: 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@v4 31 | - name: Install Nix 32 | uses: cachix/install-nix-action@v30 33 | with: 34 | extra_nix_config: | 35 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 36 | - name: Test Basic Bash Shell 37 | uses: ./ 38 | with: 39 | script: | 40 | echo "test!" 41 | - name: Test Bash Shell with Packages 42 | uses: ./ 43 | with: 44 | packages: hello,docker 45 | script: | 46 | hello 47 | command -v docker 48 | - name: Test Bash Shell with Enviroment 49 | uses: ./ 50 | env: 51 | FUTURE: now 52 | ANSWER: 42 53 | with: 54 | script: | 55 | echo The future is $FUTURE 56 | [[ -z "${ANSWER}" ]] && exit 1 || exit 0 57 | test-legacy-nix: 58 | runs-on: ubuntu-latest 59 | steps: 60 | - uses: actions/checkout@v4 61 | - name: Install Nix 62 | uses: cachix/install-nix-action@v30 63 | with: 64 | nix_path: nixpkgs=channel:release-21.05 65 | extra_nix_config: | 66 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 67 | - name: Test Basic Bash Shell 68 | uses: ./ 69 | with: 70 | script: | 71 | echo "test!" 72 | - name: Test Bash Shell with Packages 73 | uses: ./ 74 | with: 75 | packages: hello,docker 76 | script: | 77 | hello 78 | command -v docker 79 | - name: Test Bash Shell with Enviroment 80 | uses: ./ 81 | env: 82 | FUTURE: now 83 | ANSWER: 42 84 | with: 85 | script: | 86 | echo The future is $FUTURE 87 | [[ -z "${ANSWER}" ]] && exit 1 || exit 0 88 | 89 | test-flakes: 90 | runs-on: ubuntu-latest 91 | steps: 92 | - uses: actions/checkout@v4 93 | - name: Install Nix 94 | uses: cachix/install-nix-action@v30 95 | with: 96 | extra_nix_config: | 97 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 98 | - name: Test Basic Bash Shell with Local Flake 99 | uses: ./ 100 | with: 101 | flakes: .#hello 102 | script: | 103 | hello 104 | - name: Test Bash Shell with Local and External Flakes 105 | uses: ./ 106 | with: 107 | flakes: .#hello,nixpkgs#docker 108 | script: | 109 | hello 110 | command -v docker 111 | 112 | test-local-flake-in-working-directory: 113 | runs-on: ubuntu-latest 114 | steps: 115 | - uses: actions/checkout@v4 116 | - name: Install Nix 117 | uses: cachix/install-nix-action@v30 118 | with: 119 | extra_nix_config: | 120 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 121 | - name: Test Bash Shell with Local and External Flakes 122 | uses: ./ 123 | with: 124 | flakes: .#cowsay,nixpkgs#docker 125 | working-directory: test/working-directory 126 | script: | 127 | pwd 128 | cowsay hello 129 | command -v docker 130 | 131 | test-flakes-from-devshell: 132 | runs-on: ubuntu-latest 133 | steps: 134 | - uses: actions/checkout@v4 135 | - name: Install Nix 136 | uses: cachix/install-nix-action@v30 137 | with: 138 | extra_nix_config: | 139 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 140 | - name: Test Bash Shell with Local and External Flakes 141 | uses: ./ 142 | with: 143 | flakes-from-devshell: true 144 | script: | 145 | pwd 146 | figlet "I'm from the devshell, baby." 147 | 148 | test-flakes-from-devshell-with-custom-shell: 149 | runs-on: ubuntu-latest 150 | steps: 151 | - uses: actions/checkout@v4 152 | - name: Install Nix 153 | uses: cachix/install-nix-action@v30 154 | with: 155 | extra_nix_config: | 156 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 157 | - name: Test Bash Shell with Local and External Flakes 158 | uses: ./ 159 | with: 160 | flakes-from-devshell: true 161 | custom-devshell: ci 162 | script: | 163 | pwd 164 | ponysay "I'm from the CI devshell, baby." 165 | 166 | test-flakes-from-devshell-in-working-directory: 167 | runs-on: ubuntu-latest 168 | steps: 169 | - uses: actions/checkout@v4 170 | - name: Install Nix 171 | uses: cachix/install-nix-action@v30 172 | with: 173 | extra_nix_config: | 174 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 175 | - name: Test Bash Shell with Local Flake in a Working Directory 176 | uses: ./ 177 | with: 178 | working-directory: test/devshell-flake 179 | flakes-from-devshell: true 180 | script: | 181 | pwd 182 | cmatrix -h 183 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependency directory 2 | node_modules 3 | 4 | # Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | jspm_packages/ 46 | 47 | # TypeScript v1 declaration files 48 | typings/ 49 | 50 | # TypeScript cache 51 | *.tsbuildinfo 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Yarn Integrity file 66 | .yarn-integrity 67 | 68 | # dotenv environment variables file 69 | .env 70 | .env.test 71 | 72 | # parcel-bundler cache (https://parceljs.org/) 73 | .cache 74 | 75 | # next.js build output 76 | .next 77 | 78 | # nuxt.js build output 79 | .nuxt 80 | 81 | # vuepress build output 82 | .vuepress/dist 83 | 84 | # Serverless directories 85 | .serverless/ 86 | 87 | # FuseBox cache 88 | .fusebox/ 89 | 90 | # DynamoDB Local files 91 | .dynamodb/ 92 | 93 | # OS metadata 94 | .DS_Store 95 | Thumbs.db 96 | 97 | # Ignore built ts files 98 | __tests__/runner/* 99 | 100 | # IDE files 101 | .idea 102 | .vscode 103 | *.code-workspace 104 | # Devenv 105 | .devenv* 106 | devenv.local.nix 107 | 108 | # direnv 109 | .direnv 110 | 111 | # pre-commit 112 | .pre-commit-config.yaml 113 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 21.7.2 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | coverage/ 4 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": false, 6 | "singleQuote": true, 7 | "quoteProps": "as-needed", 8 | "jsxSingleQuote": false, 9 | "trailingComma": "none", 10 | "bracketSpacing": true, 11 | "bracketSameLine": true, 12 | "arrowParens": "avoid", 13 | "proseWrap": "always", 14 | "htmlWhitespaceSensitivity": "css", 15 | "endOfLine": "lf" 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2018 GitHub, Inc. and contributors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nix-shell-action 2 | 3 | nix-shell-action status 4 | 5 | Run any command you like in a deterministic [Nix](https://nixos.org/nix/) shell 6 | on Linux and macOS. 7 | 8 | ## Usage 9 | 10 | Create `.github/workflows/test.yml` in your repo with the following contents: 11 | 12 | ```yaml 13 | name: 'Test' 14 | on: 15 | pull_request: 16 | push: 17 | jobs: 18 | tests: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v3 22 | - uses: cachix/install-nix-action@v18 23 | with: 24 | nix_path: nixpkgs=channel:nixos-unstable 25 | - uses: workflow/nix-shell-action@v3 26 | with: 27 | packages: hello,docker 28 | script: | 29 | hello 30 | docker --help 31 | ``` 32 | 33 | You can also pass in environment variables: 34 | 35 | ```yaml 36 | - uses: workflow/nix-shell-action@v3 37 | env: 38 | TRANSFORMER: bumblecat 39 | with: 40 | packages: hello,docker 41 | script: | 42 | hello $TRANSFORMER 43 | docker --help 44 | ``` 45 | 46 | For now, this action implicitly depends on having [Nix] installed and set up 47 | correctly, such as through the [install-nix-action] demonstrated in the examples 48 | above. 49 | 50 | See also [cachix-action](https://github.com/cachix/cachix-action) for a simple 51 | binary cache setup to speed up your builds and share binaries with developers. 52 | 53 | ## Usage with Flakes 54 | 55 | Instead of specifying packages, you can use `flakes` to specify fully qualified 56 | flakes to be available in your script. This can be used for both local flakes in 57 | a `flake.nix` in your repo, as well as external flakes. 58 | 59 | ```yaml 60 | name: 'Test' 61 | on: 62 | pull_request: 63 | push: 64 | jobs: 65 | tests: 66 | runs-on: ubuntu-latest 67 | steps: 68 | - uses: actions/checkout@v3 69 | - name: Install Nix 70 | uses: cachix/install-nix-action@v18 71 | with: 72 | extra_nix_config: | 73 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 74 | - uses: workflow/nix-shell-action@v3 75 | with: 76 | flakes: .#hello,nixpkgs#docker 77 | script: | 78 | # Runs hello from a local flake.nix 79 | hello 80 | # Uses docker from the nixpkgs registry (see https://raw.githubusercontent.com/NixOS/flake-registry/master/flake-registry.json) 81 | command -v docker 82 | ``` 83 | 84 | ## Flakes from devShell 85 | 86 | Instead of specifying `flakes`, you can also tell this action to re-use the 87 | `buildInputs` from your `devShell` defined in a `flake.nix`, and automatically 88 | make these available to the script: 89 | 90 | ```yaml 91 | name: 'Test with Flakes from DevShell' 92 | on: 93 | pull_request: 94 | push: 95 | jobs: 96 | tests: 97 | runs-on: ubuntu-latest 98 | steps: 99 | - uses: actions/checkout@v3 100 | - name: Install Nix 101 | uses: cachix/install-nix-action@v18 102 | with: 103 | extra_nix_config: | 104 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 105 | - uses: workflow/nix-shell-action@v3 106 | with: 107 | flakes-from-devshell: true 108 | script: | 109 | # Runs hello from a local flake.nix with a `devShell` 110 | hello 111 | ``` 112 | 113 | # Options `with: ...` 114 | 115 | - `interpreter`: Interpreter to use in the nix shell shebang, defaults to 116 | `bash`. (This is passed to `nix run -c`, used to be `-i` in a nix shell 117 | shebang) 118 | 119 | - `packages`: Comma-separated list of packages to pre-install in your shell. 120 | Cannot be used together with the `flakes` option. 121 | 122 | - `flakes`: Comma-separated list of fully qualified flakes to pre-install in 123 | your shell. Use either `packages` or `flakes`. Cannot be used together with 124 | the `packages` option. 125 | 126 | - `flakes-from-devshell`: If true, supply flakes from a `devShell` provided in 127 | your repo's `flake.nix`. You cannot currently combined this with the `flakes` 128 | nor `packages` options. 129 | 130 | - `custom-devshell`: Specify a custom `devShell` to use. This can be useful if 131 | you have a `devShell` that is not named `devShell` in your `flake.nix`. You 132 | cannot currently combined this with the `flakes` nor `packages` options. 133 | 134 | - `script`: The actual script to execute in your shell. Will be passed to the 135 | `interpreter`, which defaults to `bash` 136 | 137 | - `working-directory`: Execute the script inside the specified working directory 138 | instead of the repository root. Example: `path/to/dir` 139 | 140 | --- 141 | 142 | # FAQ: Passing a Github Token against Rate Limits 143 | 144 | ```yaml 145 | name: 'Test' 146 | on: 147 | pull_request: 148 | push: 149 | jobs: 150 | tests: 151 | runs-on: ubuntu-latest 152 | steps: 153 | - uses: actions/checkout@v3 154 | - uses: cachix/install-nix-action@v18 155 | with: 156 | nix_path: nixpkgs=channel:nixos-unstable 157 | extra_nix_config: | 158 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 159 | - uses: workflow/nix-shell-action@v3 160 | with: 161 | packages: hello,docker 162 | script: | 163 | hello 164 | docker --help 165 | ``` 166 | 167 | # FAQ: How do I pin a specific version of a package? 168 | 169 | See 170 | [This Explanation](https://github.com/workflow/nix-shell-action/issues/346#issuecomment-2440067512) 171 | 172 | --- 173 | 174 | # Hacking 175 | 176 | See https://github.com/actions/typescript-action 177 | 178 | [nix]: https://nixos.org/nix/ 179 | [install-nix-action]: https://github.com/marketplace/actions/install-nix 180 | -------------------------------------------------------------------------------- /__tests__/main.test.ts: -------------------------------------------------------------------------------- 1 | import { wait } from '../src/wait' 2 | 3 | test('throws invalid number', async () => { 4 | const input = parseInt('foo', 10) 5 | await expect(wait(input)).rejects.toThrow('milliseconds not a number') 6 | }) 7 | 8 | test('wait 500 ms', async () => { 9 | const start = new Date() 10 | await wait(500) 11 | const end = new Date() 12 | const delta = Math.abs(end.getTime() - start.getTime()) 13 | expect(delta).toBeGreaterThan(450) 14 | }) 15 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Nix Shell' 2 | description: 3 | 'Run any command you like in a deterministic nix shell on Linux and macOS' 4 | author: '@workflow' 5 | inputs: 6 | interpreter: 7 | required: false 8 | description: 'Interpreter to use in the nix shell shebang' 9 | default: 'bash' 10 | packages: 11 | required: false 12 | description: 13 | 'Comma-separated list of packages to pre-install in your shell. Defaults 14 | to simply "bash". Cannot be used together with the flakes option' 15 | default: 'bash' 16 | flakes: 17 | required: false 18 | description: 19 | 'Comma-separated list of fully qualified flakes to pre-install in your 20 | shell. Use either packages or flakes. Cannot be used together with the 21 | packages option' 22 | default: '' 23 | flakes-from-devshell: 24 | required: false 25 | description: 'If set to true, uses devShell instead.' 26 | default: false 27 | custom-devshell: 28 | required: false 29 | description: 'If set, uses a customly named devShell from the current flake' 30 | default: '' 31 | script: 32 | required: true 33 | description: 'The actual script to execute in the shell' 34 | working-directory: 35 | required: false 36 | description: 37 | 'Execute the script inside the specified working directory instead of the 38 | repository root. Example: path/to/dir' 39 | 40 | branding: 41 | color: 'blue' 42 | icon: 'chevron-right' 43 | runs: 44 | using: 'node20' 45 | main: 'dist/index.js' 46 | -------------------------------------------------------------------------------- /devenv.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "devenv": { 4 | "locked": { 5 | "dir": "src/modules", 6 | "lastModified": 1726826452, 7 | "owner": "cachix", 8 | "repo": "devenv", 9 | "rev": "2bdf6461e88c7e93b94d72d8b11d5a61f167cbf5", 10 | "treeHash": "e10f5d7f21ef64fb0a9c269c400af0cd8f43fb35", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "dir": "src/modules", 15 | "owner": "cachix", 16 | "repo": "devenv", 17 | "type": "github" 18 | } 19 | }, 20 | "flake-compat": { 21 | "flake": false, 22 | "locked": { 23 | "lastModified": 1696426674, 24 | "owner": "edolstra", 25 | "repo": "flake-compat", 26 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 27 | "treeHash": "2addb7b71a20a25ea74feeaf5c2f6a6b30898ecb", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "edolstra", 32 | "repo": "flake-compat", 33 | "type": "github" 34 | } 35 | }, 36 | "gitignore": { 37 | "inputs": { 38 | "nixpkgs": [ 39 | "pre-commit-hooks", 40 | "nixpkgs" 41 | ] 42 | }, 43 | "locked": { 44 | "lastModified": 1709087332, 45 | "owner": "hercules-ci", 46 | "repo": "gitignore.nix", 47 | "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", 48 | "treeHash": "ca14199cabdfe1a06a7b1654c76ed49100a689f9", 49 | "type": "github" 50 | }, 51 | "original": { 52 | "owner": "hercules-ci", 53 | "repo": "gitignore.nix", 54 | "type": "github" 55 | } 56 | }, 57 | "nixpkgs": { 58 | "locked": { 59 | "lastModified": 1716977621, 60 | "owner": "cachix", 61 | "repo": "devenv-nixpkgs", 62 | "rev": "4267e705586473d3e5c8d50299e71503f16a6fb6", 63 | "treeHash": "6d9f1f7ca0faf1bc2eeb397c78a49623260d3412", 64 | "type": "github" 65 | }, 66 | "original": { 67 | "owner": "cachix", 68 | "ref": "rolling", 69 | "repo": "devenv-nixpkgs", 70 | "type": "github" 71 | } 72 | }, 73 | "nixpkgs-stable": { 74 | "locked": { 75 | "lastModified": 1726688310, 76 | "owner": "NixOS", 77 | "repo": "nixpkgs", 78 | "rev": "dbebdd67a6006bb145d98c8debf9140ac7e651d0", 79 | "treeHash": "69acf772d63e2ea2951cce44f03210730c3ae264", 80 | "type": "github" 81 | }, 82 | "original": { 83 | "owner": "NixOS", 84 | "ref": "nixos-24.05", 85 | "repo": "nixpkgs", 86 | "type": "github" 87 | } 88 | }, 89 | "pre-commit-hooks": { 90 | "inputs": { 91 | "flake-compat": "flake-compat", 92 | "gitignore": "gitignore", 93 | "nixpkgs": [ 94 | "nixpkgs" 95 | ], 96 | "nixpkgs-stable": "nixpkgs-stable" 97 | }, 98 | "locked": { 99 | "lastModified": 1726745158, 100 | "owner": "cachix", 101 | "repo": "pre-commit-hooks.nix", 102 | "rev": "4e743a6920eab45e8ba0fbe49dc459f1423a4b74", 103 | "treeHash": "56fbe2a9610b3ad9163a74011131e7624f6b3b81", 104 | "type": "github" 105 | }, 106 | "original": { 107 | "owner": "cachix", 108 | "repo": "pre-commit-hooks.nix", 109 | "type": "github" 110 | } 111 | }, 112 | "root": { 113 | "inputs": { 114 | "devenv": "devenv", 115 | "nixpkgs": "nixpkgs", 116 | "pre-commit-hooks": "pre-commit-hooks" 117 | } 118 | } 119 | }, 120 | "root": "root", 121 | "version": 7 122 | } 123 | -------------------------------------------------------------------------------- /devenv.nix: -------------------------------------------------------------------------------- 1 | {pkgs, ...}: { 2 | # https://devenv.sh/basics/ 3 | env.GREET = "nix-shell-action devenv"; 4 | 5 | # https://devenv.sh/packages/ 6 | packages = [pkgs.git]; 7 | 8 | # https://devenv.sh/languages/ 9 | languages.javascript = { 10 | enable = true; 11 | package = pkgs.nodejs_21; 12 | npm = { 13 | enable = true; 14 | install.enable = true; 15 | }; 16 | }; 17 | 18 | # https://devenv.sh/processes/ 19 | # processes.cargo-watch.exec = "cargo-watch"; 20 | 21 | # https://devenv.sh/services/ 22 | # services.postgres.enable = true; 23 | 24 | # https://devenv.sh/scripts/ 25 | scripts.hello.exec = '' 26 | echo hello from $GREET 27 | ''; 28 | 29 | enterShell = '' 30 | hello 31 | git --version 32 | ''; 33 | 34 | # https://devenv.sh/tests/ 35 | enterTest = '' 36 | echo "Running tests" 37 | git --version | grep --color=auto "${pkgs.git.version}" 38 | ''; 39 | 40 | # https://devenv.sh/pre-commit-hooks/ 41 | # pre-commit.hooks.shellcheck.enable = true; 42 | 43 | # See full reference at https://devenv.sh/reference/options/ 44 | } 45 | -------------------------------------------------------------------------------- /devenv.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://devenv.sh/devenv.schema.json 2 | inputs: 3 | nixpkgs: 4 | url: github:cachix/devenv-nixpkgs/rolling 5 | # If you're using non-OSS software, you can set allowUnfree to true. 6 | # allowUnfree: true 7 | 8 | # If you're willing to use a package that's vulnerable 9 | # permittedInsecurePackages: 10 | # - "openssl-1.1.1w" 11 | 12 | # If you have more than one devenv you can merge them 13 | #imports: 14 | # - ./backend 15 | -------------------------------------------------------------------------------- /dist/licenses.txt: -------------------------------------------------------------------------------- 1 | @actions/core 2 | MIT 3 | The MIT License (MIT) 4 | 5 | Copyright 2019 GitHub 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 12 | 13 | @actions/http-client 14 | MIT 15 | Actions Http Client for Node.js 16 | 17 | Copyright (c) GitHub, Inc. 18 | 19 | All rights reserved. 20 | 21 | MIT License 22 | 23 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 24 | associated documentation files (the "Software"), to deal in the Software without restriction, 25 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 26 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 27 | subject to the following conditions: 28 | 29 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 32 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 33 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 34 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 35 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 36 | 37 | 38 | @fastify/busboy 39 | MIT 40 | Copyright Brian White. All rights reserved. 41 | 42 | Permission is hereby granted, free of charge, to any person obtaining a copy 43 | of this software and associated documentation files (the "Software"), to 44 | deal in the Software without restriction, including without limitation the 45 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 46 | sell copies of the Software, and to permit persons to whom the Software is 47 | furnished to do so, subject to the following conditions: 48 | 49 | The above copyright notice and this permission notice shall be included in 50 | all copies or substantial portions of the Software. 51 | 52 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 53 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 54 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 55 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 56 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 57 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 58 | IN THE SOFTWARE. 59 | 60 | tunnel 61 | MIT 62 | The MIT License (MIT) 63 | 64 | Copyright (c) 2012 Koichi Kobayashi 65 | 66 | Permission is hereby granted, free of charge, to any person obtaining a copy 67 | of this software and associated documentation files (the "Software"), to deal 68 | in the Software without restriction, including without limitation the rights 69 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 70 | copies of the Software, and to permit persons to whom the Software is 71 | furnished to do so, subject to the following conditions: 72 | 73 | The above copyright notice and this permission notice shall be included in 74 | all copies or substantial portions of the Software. 75 | 76 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 77 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 78 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 79 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 80 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 81 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 82 | THE SOFTWARE. 83 | 84 | 85 | undici 86 | MIT 87 | MIT License 88 | 89 | Copyright (c) Matteo Collina and Undici contributors 90 | 91 | Permission is hereby granted, free of charge, to any person obtaining a copy 92 | of this software and associated documentation files (the "Software"), to deal 93 | in the Software without restriction, including without limitation the rights 94 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 95 | copies of the Software, and to permit persons to whom the Software is 96 | furnished to do so, subject to the following conditions: 97 | 98 | The above copyright notice and this permission notice shall be included in all 99 | copies or substantial portions of the Software. 100 | 101 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 102 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 103 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 104 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 105 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 106 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 107 | SOFTWARE. 108 | 109 | 110 | uuid 111 | MIT 112 | The MIT License (MIT) 113 | 114 | Copyright (c) 2010-2020 Robert Kieffer and other contributors 115 | 116 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 117 | 118 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 119 | 120 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 121 | -------------------------------------------------------------------------------- /dist/sourcemap-register.js: -------------------------------------------------------------------------------- 1 | (()=>{var e={650:e=>{var r=Object.prototype.toString;var n=typeof Buffer.alloc==="function"&&typeof Buffer.allocUnsafe==="function"&&typeof Buffer.from==="function";function isArrayBuffer(e){return r.call(e).slice(8,-1)==="ArrayBuffer"}function fromArrayBuffer(e,r,t){r>>>=0;var o=e.byteLength-r;if(o<0){throw new RangeError("'offset' is out of bounds")}if(t===undefined){t=o}else{t>>>=0;if(t>o){throw new RangeError("'length' is out of bounds")}}return n?Buffer.from(e.slice(r,r+t)):new Buffer(new Uint8Array(e.slice(r,r+t)))}function fromString(e,r){if(typeof r!=="string"||r===""){r="utf8"}if(!Buffer.isEncoding(r)){throw new TypeError('"encoding" must be a valid string encoding')}return n?Buffer.from(e,r):new Buffer(e,r)}function bufferFrom(e,r,t){if(typeof e==="number"){throw new TypeError('"value" argument must not be a number')}if(isArrayBuffer(e)){return fromArrayBuffer(e,r,t)}if(typeof e==="string"){return fromString(e,r)}return n?Buffer.from(e):new Buffer(e)}e.exports=bufferFrom},274:(e,r,n)=>{var t=n(339);var o=Object.prototype.hasOwnProperty;var i=typeof Map!=="undefined";function ArraySet(){this._array=[];this._set=i?new Map:Object.create(null)}ArraySet.fromArray=function ArraySet_fromArray(e,r){var n=new ArraySet;for(var t=0,o=e.length;t=0){return r}}else{var n=t.toSetString(e);if(o.call(this._set,n)){return this._set[n]}}throw new Error('"'+e+'" is not in the set.')};ArraySet.prototype.at=function ArraySet_at(e){if(e>=0&&e{var t=n(190);var o=5;var i=1<>1;return r?-n:n}r.encode=function base64VLQ_encode(e){var r="";var n;var i=toVLQSigned(e);do{n=i&a;i>>>=o;if(i>0){n|=u}r+=t.encode(n)}while(i>0);return r};r.decode=function base64VLQ_decode(e,r,n){var i=e.length;var s=0;var l=0;var c,p;do{if(r>=i){throw new Error("Expected more digits in base 64 VLQ value.")}p=t.decode(e.charCodeAt(r++));if(p===-1){throw new Error("Invalid base64 digit: "+e.charAt(r-1))}c=!!(p&u);p&=a;s=s+(p<{var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");r.encode=function(e){if(0<=e&&e{r.GREATEST_LOWER_BOUND=1;r.LEAST_UPPER_BOUND=2;function recursiveSearch(e,n,t,o,i,a){var u=Math.floor((n-e)/2)+e;var s=i(t,o[u],true);if(s===0){return u}else if(s>0){if(n-u>1){return recursiveSearch(u,n,t,o,i,a)}if(a==r.LEAST_UPPER_BOUND){return n1){return recursiveSearch(e,u,t,o,i,a)}if(a==r.LEAST_UPPER_BOUND){return u}else{return e<0?-1:e}}}r.search=function search(e,n,t,o){if(n.length===0){return-1}var i=recursiveSearch(-1,n.length,e,n,t,o||r.GREATEST_LOWER_BOUND);if(i<0){return-1}while(i-1>=0){if(t(n[i],n[i-1],true)!==0){break}--i}return i}},680:(e,r,n)=>{var t=n(339);function generatedPositionAfter(e,r){var n=e.generatedLine;var o=r.generatedLine;var i=e.generatedColumn;var a=r.generatedColumn;return o>n||o==n&&a>=i||t.compareByGeneratedPositionsInflated(e,r)<=0}function MappingList(){this._array=[];this._sorted=true;this._last={generatedLine:-1,generatedColumn:0}}MappingList.prototype.unsortedForEach=function MappingList_forEach(e,r){this._array.forEach(e,r)};MappingList.prototype.add=function MappingList_add(e){if(generatedPositionAfter(this._last,e)){this._last=e;this._array.push(e)}else{this._sorted=false;this._array.push(e)}};MappingList.prototype.toArray=function MappingList_toArray(){if(!this._sorted){this._array.sort(t.compareByGeneratedPositionsInflated);this._sorted=true}return this._array};r.H=MappingList},758:(e,r)=>{function swap(e,r,n){var t=e[r];e[r]=e[n];e[n]=t}function randomIntInRange(e,r){return Math.round(e+Math.random()*(r-e))}function doQuickSort(e,r,n,t){if(n{var t;var o=n(339);var i=n(345);var a=n(274).I;var u=n(449);var s=n(758).U;function SourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}return n.sections!=null?new IndexedSourceMapConsumer(n,r):new BasicSourceMapConsumer(n,r)}SourceMapConsumer.fromSourceMap=function(e,r){return BasicSourceMapConsumer.fromSourceMap(e,r)};SourceMapConsumer.prototype._version=3;SourceMapConsumer.prototype.__generatedMappings=null;Object.defineProperty(SourceMapConsumer.prototype,"_generatedMappings",{configurable:true,enumerable:true,get:function(){if(!this.__generatedMappings){this._parseMappings(this._mappings,this.sourceRoot)}return this.__generatedMappings}});SourceMapConsumer.prototype.__originalMappings=null;Object.defineProperty(SourceMapConsumer.prototype,"_originalMappings",{configurable:true,enumerable:true,get:function(){if(!this.__originalMappings){this._parseMappings(this._mappings,this.sourceRoot)}return this.__originalMappings}});SourceMapConsumer.prototype._charIsMappingSeparator=function SourceMapConsumer_charIsMappingSeparator(e,r){var n=e.charAt(r);return n===";"||n===","};SourceMapConsumer.prototype._parseMappings=function SourceMapConsumer_parseMappings(e,r){throw new Error("Subclasses must implement _parseMappings")};SourceMapConsumer.GENERATED_ORDER=1;SourceMapConsumer.ORIGINAL_ORDER=2;SourceMapConsumer.GREATEST_LOWER_BOUND=1;SourceMapConsumer.LEAST_UPPER_BOUND=2;SourceMapConsumer.prototype.eachMapping=function SourceMapConsumer_eachMapping(e,r,n){var t=r||null;var i=n||SourceMapConsumer.GENERATED_ORDER;var a;switch(i){case SourceMapConsumer.GENERATED_ORDER:a=this._generatedMappings;break;case SourceMapConsumer.ORIGINAL_ORDER:a=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}var u=this.sourceRoot;a.map((function(e){var r=e.source===null?null:this._sources.at(e.source);r=o.computeSourceURL(u,r,this._sourceMapURL);return{source:r,generatedLine:e.generatedLine,generatedColumn:e.generatedColumn,originalLine:e.originalLine,originalColumn:e.originalColumn,name:e.name===null?null:this._names.at(e.name)}}),this).forEach(e,t)};SourceMapConsumer.prototype.allGeneratedPositionsFor=function SourceMapConsumer_allGeneratedPositionsFor(e){var r=o.getArg(e,"line");var n={source:o.getArg(e,"source"),originalLine:r,originalColumn:o.getArg(e,"column",0)};n.source=this._findSourceIndex(n.source);if(n.source<0){return[]}var t=[];var a=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",o.compareByOriginalPositions,i.LEAST_UPPER_BOUND);if(a>=0){var u=this._originalMappings[a];if(e.column===undefined){var s=u.originalLine;while(u&&u.originalLine===s){t.push({line:o.getArg(u,"generatedLine",null),column:o.getArg(u,"generatedColumn",null),lastColumn:o.getArg(u,"lastGeneratedColumn",null)});u=this._originalMappings[++a]}}else{var l=u.originalColumn;while(u&&u.originalLine===r&&u.originalColumn==l){t.push({line:o.getArg(u,"generatedLine",null),column:o.getArg(u,"generatedColumn",null),lastColumn:o.getArg(u,"lastGeneratedColumn",null)});u=this._originalMappings[++a]}}}return t};r.SourceMapConsumer=SourceMapConsumer;function BasicSourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}var t=o.getArg(n,"version");var i=o.getArg(n,"sources");var u=o.getArg(n,"names",[]);var s=o.getArg(n,"sourceRoot",null);var l=o.getArg(n,"sourcesContent",null);var c=o.getArg(n,"mappings");var p=o.getArg(n,"file",null);if(t!=this._version){throw new Error("Unsupported version: "+t)}if(s){s=o.normalize(s)}i=i.map(String).map(o.normalize).map((function(e){return s&&o.isAbsolute(s)&&o.isAbsolute(e)?o.relative(s,e):e}));this._names=a.fromArray(u.map(String),true);this._sources=a.fromArray(i,true);this._absoluteSources=this._sources.toArray().map((function(e){return o.computeSourceURL(s,e,r)}));this.sourceRoot=s;this.sourcesContent=l;this._mappings=c;this._sourceMapURL=r;this.file=p}BasicSourceMapConsumer.prototype=Object.create(SourceMapConsumer.prototype);BasicSourceMapConsumer.prototype.consumer=SourceMapConsumer;BasicSourceMapConsumer.prototype._findSourceIndex=function(e){var r=e;if(this.sourceRoot!=null){r=o.relative(this.sourceRoot,r)}if(this._sources.has(r)){return this._sources.indexOf(r)}var n;for(n=0;n1){v.source=l+_[1];l+=_[1];v.originalLine=i+_[2];i=v.originalLine;v.originalLine+=1;v.originalColumn=a+_[3];a=v.originalColumn;if(_.length>4){v.name=c+_[4];c+=_[4]}}m.push(v);if(typeof v.originalLine==="number"){d.push(v)}}}s(m,o.compareByGeneratedPositionsDeflated);this.__generatedMappings=m;s(d,o.compareByOriginalPositions);this.__originalMappings=d};BasicSourceMapConsumer.prototype._findMapping=function SourceMapConsumer_findMapping(e,r,n,t,o,a){if(e[n]<=0){throw new TypeError("Line must be greater than or equal to 1, got "+e[n])}if(e[t]<0){throw new TypeError("Column must be greater than or equal to 0, got "+e[t])}return i.search(e,r,o,a)};BasicSourceMapConsumer.prototype.computeColumnSpans=function SourceMapConsumer_computeColumnSpans(){for(var e=0;e=0){var t=this._generatedMappings[n];if(t.generatedLine===r.generatedLine){var i=o.getArg(t,"source",null);if(i!==null){i=this._sources.at(i);i=o.computeSourceURL(this.sourceRoot,i,this._sourceMapURL)}var a=o.getArg(t,"name",null);if(a!==null){a=this._names.at(a)}return{source:i,line:o.getArg(t,"originalLine",null),column:o.getArg(t,"originalColumn",null),name:a}}}return{source:null,line:null,column:null,name:null}};BasicSourceMapConsumer.prototype.hasContentsOfAllSources=function BasicSourceMapConsumer_hasContentsOfAllSources(){if(!this.sourcesContent){return false}return this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some((function(e){return e==null}))};BasicSourceMapConsumer.prototype.sourceContentFor=function SourceMapConsumer_sourceContentFor(e,r){if(!this.sourcesContent){return null}var n=this._findSourceIndex(e);if(n>=0){return this.sourcesContent[n]}var t=e;if(this.sourceRoot!=null){t=o.relative(this.sourceRoot,t)}var i;if(this.sourceRoot!=null&&(i=o.urlParse(this.sourceRoot))){var a=t.replace(/^file:\/\//,"");if(i.scheme=="file"&&this._sources.has(a)){return this.sourcesContent[this._sources.indexOf(a)]}if((!i.path||i.path=="/")&&this._sources.has("/"+t)){return this.sourcesContent[this._sources.indexOf("/"+t)]}}if(r){return null}else{throw new Error('"'+t+'" is not in the SourceMap.')}};BasicSourceMapConsumer.prototype.generatedPositionFor=function SourceMapConsumer_generatedPositionFor(e){var r=o.getArg(e,"source");r=this._findSourceIndex(r);if(r<0){return{line:null,column:null,lastColumn:null}}var n={source:r,originalLine:o.getArg(e,"line"),originalColumn:o.getArg(e,"column")};var t=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",o.compareByOriginalPositions,o.getArg(e,"bias",SourceMapConsumer.GREATEST_LOWER_BOUND));if(t>=0){var i=this._originalMappings[t];if(i.source===n.source){return{line:o.getArg(i,"generatedLine",null),column:o.getArg(i,"generatedColumn",null),lastColumn:o.getArg(i,"lastGeneratedColumn",null)}}}return{line:null,column:null,lastColumn:null}};t=BasicSourceMapConsumer;function IndexedSourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}var t=o.getArg(n,"version");var i=o.getArg(n,"sections");if(t!=this._version){throw new Error("Unsupported version: "+t)}this._sources=new a;this._names=new a;var u={line:-1,column:0};this._sections=i.map((function(e){if(e.url){throw new Error("Support for url field in sections not implemented.")}var n=o.getArg(e,"offset");var t=o.getArg(n,"line");var i=o.getArg(n,"column");if(t{var t=n(449);var o=n(339);var i=n(274).I;var a=n(680).H;function SourceMapGenerator(e){if(!e){e={}}this._file=o.getArg(e,"file",null);this._sourceRoot=o.getArg(e,"sourceRoot",null);this._skipValidation=o.getArg(e,"skipValidation",false);this._sources=new i;this._names=new i;this._mappings=new a;this._sourcesContents=null}SourceMapGenerator.prototype._version=3;SourceMapGenerator.fromSourceMap=function SourceMapGenerator_fromSourceMap(e){var r=e.sourceRoot;var n=new SourceMapGenerator({file:e.file,sourceRoot:r});e.eachMapping((function(e){var t={generated:{line:e.generatedLine,column:e.generatedColumn}};if(e.source!=null){t.source=e.source;if(r!=null){t.source=o.relative(r,t.source)}t.original={line:e.originalLine,column:e.originalColumn};if(e.name!=null){t.name=e.name}}n.addMapping(t)}));e.sources.forEach((function(t){var i=t;if(r!==null){i=o.relative(r,t)}if(!n._sources.has(i)){n._sources.add(i)}var a=e.sourceContentFor(t);if(a!=null){n.setSourceContent(t,a)}}));return n};SourceMapGenerator.prototype.addMapping=function SourceMapGenerator_addMapping(e){var r=o.getArg(e,"generated");var n=o.getArg(e,"original",null);var t=o.getArg(e,"source",null);var i=o.getArg(e,"name",null);if(!this._skipValidation){this._validateMapping(r,n,t,i)}if(t!=null){t=String(t);if(!this._sources.has(t)){this._sources.add(t)}}if(i!=null){i=String(i);if(!this._names.has(i)){this._names.add(i)}}this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:t,name:i})};SourceMapGenerator.prototype.setSourceContent=function SourceMapGenerator_setSourceContent(e,r){var n=e;if(this._sourceRoot!=null){n=o.relative(this._sourceRoot,n)}if(r!=null){if(!this._sourcesContents){this._sourcesContents=Object.create(null)}this._sourcesContents[o.toSetString(n)]=r}else if(this._sourcesContents){delete this._sourcesContents[o.toSetString(n)];if(Object.keys(this._sourcesContents).length===0){this._sourcesContents=null}}};SourceMapGenerator.prototype.applySourceMap=function SourceMapGenerator_applySourceMap(e,r,n){var t=r;if(r==null){if(e.file==null){throw new Error("SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, "+'or the source map\'s "file" property. Both were omitted.')}t=e.file}var a=this._sourceRoot;if(a!=null){t=o.relative(a,t)}var u=new i;var s=new i;this._mappings.unsortedForEach((function(r){if(r.source===t&&r.originalLine!=null){var i=e.originalPositionFor({line:r.originalLine,column:r.originalColumn});if(i.source!=null){r.source=i.source;if(n!=null){r.source=o.join(n,r.source)}if(a!=null){r.source=o.relative(a,r.source)}r.originalLine=i.line;r.originalColumn=i.column;if(i.name!=null){r.name=i.name}}}var l=r.source;if(l!=null&&!u.has(l)){u.add(l)}var c=r.name;if(c!=null&&!s.has(c)){s.add(c)}}),this);this._sources=u;this._names=s;e.sources.forEach((function(r){var t=e.sourceContentFor(r);if(t!=null){if(n!=null){r=o.join(n,r)}if(a!=null){r=o.relative(a,r)}this.setSourceContent(r,t)}}),this)};SourceMapGenerator.prototype._validateMapping=function SourceMapGenerator_validateMapping(e,r,n,t){if(r&&typeof r.line!=="number"&&typeof r.column!=="number"){throw new Error("original.line and original.column are not numbers -- you probably meant to omit "+"the original mapping entirely and only map the generated position. If so, pass "+"null for the original mapping instead of an object with empty or null values.")}if(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0&&!r&&!n&&!t){return}else if(e&&"line"in e&&"column"in e&&r&&"line"in r&&"column"in r&&e.line>0&&e.column>=0&&r.line>0&&r.column>=0&&n){return}else{throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:n,original:r,name:t}))}};SourceMapGenerator.prototype._serializeMappings=function SourceMapGenerator_serializeMappings(){var e=0;var r=1;var n=0;var i=0;var a=0;var u=0;var s="";var l;var c;var p;var f;var g=this._mappings.toArray();for(var h=0,d=g.length;h0){if(!o.compareByGeneratedPositionsInflated(c,g[h-1])){continue}l+=","}}l+=t.encode(c.generatedColumn-e);e=c.generatedColumn;if(c.source!=null){f=this._sources.indexOf(c.source);l+=t.encode(f-u);u=f;l+=t.encode(c.originalLine-1-i);i=c.originalLine-1;l+=t.encode(c.originalColumn-n);n=c.originalColumn;if(c.name!=null){p=this._names.indexOf(c.name);l+=t.encode(p-a);a=p}}s+=l}return s};SourceMapGenerator.prototype._generateSourcesContent=function SourceMapGenerator_generateSourcesContent(e,r){return e.map((function(e){if(!this._sourcesContents){return null}if(r!=null){e=o.relative(r,e)}var n=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,n)?this._sourcesContents[n]:null}),this)};SourceMapGenerator.prototype.toJSON=function SourceMapGenerator_toJSON(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};if(this._file!=null){e.file=this._file}if(this._sourceRoot!=null){e.sourceRoot=this._sourceRoot}if(this._sourcesContents){e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)}return e};SourceMapGenerator.prototype.toString=function SourceMapGenerator_toString(){return JSON.stringify(this.toJSON())};r.h=SourceMapGenerator},351:(e,r,n)=>{var t;var o=n(591).h;var i=n(339);var a=/(\r?\n)/;var u=10;var s="$$$isSourceNode$$$";function SourceNode(e,r,n,t,o){this.children=[];this.sourceContents={};this.line=e==null?null:e;this.column=r==null?null:r;this.source=n==null?null:n;this.name=o==null?null:o;this[s]=true;if(t!=null)this.add(t)}SourceNode.fromStringWithSourceMap=function SourceNode_fromStringWithSourceMap(e,r,n){var t=new SourceNode;var o=e.split(a);var u=0;var shiftNextLine=function(){var e=getNextLine();var r=getNextLine()||"";return e+r;function getNextLine(){return u=0;r--){this.prepend(e[r])}}else if(e[s]||typeof e==="string"){this.children.unshift(e)}else{throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e)}return this};SourceNode.prototype.walk=function SourceNode_walk(e){var r;for(var n=0,t=this.children.length;n0){r=[];for(n=0;n{function getArg(e,r,n){if(r in e){return e[r]}else if(arguments.length===3){return n}else{throw new Error('"'+r+'" is a required argument.')}}r.getArg=getArg;var n=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;var t=/^data:.+\,.+$/;function urlParse(e){var r=e.match(n);if(!r){return null}return{scheme:r[1],auth:r[2],host:r[3],port:r[4],path:r[5]}}r.urlParse=urlParse;function urlGenerate(e){var r="";if(e.scheme){r+=e.scheme+":"}r+="//";if(e.auth){r+=e.auth+"@"}if(e.host){r+=e.host}if(e.port){r+=":"+e.port}if(e.path){r+=e.path}return r}r.urlGenerate=urlGenerate;function normalize(e){var n=e;var t=urlParse(e);if(t){if(!t.path){return e}n=t.path}var o=r.isAbsolute(n);var i=n.split(/\/+/);for(var a,u=0,s=i.length-1;s>=0;s--){a=i[s];if(a==="."){i.splice(s,1)}else if(a===".."){u++}else if(u>0){if(a===""){i.splice(s+1,u);u=0}else{i.splice(s,2);u--}}}n=i.join("/");if(n===""){n=o?"/":"."}if(t){t.path=n;return urlGenerate(t)}return n}r.normalize=normalize;function join(e,r){if(e===""){e="."}if(r===""){r="."}var n=urlParse(r);var o=urlParse(e);if(o){e=o.path||"/"}if(n&&!n.scheme){if(o){n.scheme=o.scheme}return urlGenerate(n)}if(n||r.match(t)){return r}if(o&&!o.host&&!o.path){o.host=r;return urlGenerate(o)}var i=r.charAt(0)==="/"?r:normalize(e.replace(/\/+$/,"")+"/"+r);if(o){o.path=i;return urlGenerate(o)}return i}r.join=join;r.isAbsolute=function(e){return e.charAt(0)==="/"||n.test(e)};function relative(e,r){if(e===""){e="."}e=e.replace(/\/$/,"");var n=0;while(r.indexOf(e+"/")!==0){var t=e.lastIndexOf("/");if(t<0){return r}e=e.slice(0,t);if(e.match(/^([^\/]+:\/)?\/*$/)){return r}++n}return Array(n+1).join("../")+r.substr(e.length+1)}r.relative=relative;var o=function(){var e=Object.create(null);return!("__proto__"in e)}();function identity(e){return e}function toSetString(e){if(isProtoString(e)){return"$"+e}return e}r.toSetString=o?identity:toSetString;function fromSetString(e){if(isProtoString(e)){return e.slice(1)}return e}r.fromSetString=o?identity:fromSetString;function isProtoString(e){if(!e){return false}var r=e.length;if(r<9){return false}if(e.charCodeAt(r-1)!==95||e.charCodeAt(r-2)!==95||e.charCodeAt(r-3)!==111||e.charCodeAt(r-4)!==116||e.charCodeAt(r-5)!==111||e.charCodeAt(r-6)!==114||e.charCodeAt(r-7)!==112||e.charCodeAt(r-8)!==95||e.charCodeAt(r-9)!==95){return false}for(var n=r-10;n>=0;n--){if(e.charCodeAt(n)!==36){return false}}return true}function compareByOriginalPositions(e,r,n){var t=strcmp(e.source,r.source);if(t!==0){return t}t=e.originalLine-r.originalLine;if(t!==0){return t}t=e.originalColumn-r.originalColumn;if(t!==0||n){return t}t=e.generatedColumn-r.generatedColumn;if(t!==0){return t}t=e.generatedLine-r.generatedLine;if(t!==0){return t}return strcmp(e.name,r.name)}r.compareByOriginalPositions=compareByOriginalPositions;function compareByGeneratedPositionsDeflated(e,r,n){var t=e.generatedLine-r.generatedLine;if(t!==0){return t}t=e.generatedColumn-r.generatedColumn;if(t!==0||n){return t}t=strcmp(e.source,r.source);if(t!==0){return t}t=e.originalLine-r.originalLine;if(t!==0){return t}t=e.originalColumn-r.originalColumn;if(t!==0){return t}return strcmp(e.name,r.name)}r.compareByGeneratedPositionsDeflated=compareByGeneratedPositionsDeflated;function strcmp(e,r){if(e===r){return 0}if(e===null){return 1}if(r===null){return-1}if(e>r){return 1}return-1}function compareByGeneratedPositionsInflated(e,r){var n=e.generatedLine-r.generatedLine;if(n!==0){return n}n=e.generatedColumn-r.generatedColumn;if(n!==0){return n}n=strcmp(e.source,r.source);if(n!==0){return n}n=e.originalLine-r.originalLine;if(n!==0){return n}n=e.originalColumn-r.originalColumn;if(n!==0){return n}return strcmp(e.name,r.name)}r.compareByGeneratedPositionsInflated=compareByGeneratedPositionsInflated;function parseSourceMapInput(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}r.parseSourceMapInput=parseSourceMapInput;function computeSourceURL(e,r,n){r=r||"";if(e){if(e[e.length-1]!=="/"&&r[0]!=="/"){e+="/"}r=e+r}if(n){var t=urlParse(n);if(!t){throw new Error("sourceMapURL could not be parsed")}if(t.path){var o=t.path.lastIndexOf("/");if(o>=0){t.path=t.path.substring(0,o+1)}}r=join(urlGenerate(t),r)}return normalize(r)}r.computeSourceURL=computeSourceURL},997:(e,r,n)=>{n(591).h;r.SourceMapConsumer=n(952).SourceMapConsumer;n(351)},284:(e,r,n)=>{e=n.nmd(e);var t=n(997).SourceMapConsumer;var o=n(17);var i;try{i=n(147);if(!i.existsSync||!i.readFileSync){i=null}}catch(e){}var a=n(650);function dynamicRequire(e,r){return e.require(r)}var u=false;var s=false;var l=false;var c="auto";var p={};var f={};var g=/^data:application\/json[^,]+base64,/;var h=[];var d=[];function isInBrowser(){if(c==="browser")return true;if(c==="node")return false;return typeof window!=="undefined"&&typeof XMLHttpRequest==="function"&&!(window.require&&window.module&&window.process&&window.process.type==="renderer")}function hasGlobalProcessEventEmitter(){return typeof process==="object"&&process!==null&&typeof process.on==="function"}function globalProcessVersion(){if(typeof process==="object"&&process!==null){return process.version}else{return""}}function globalProcessStderr(){if(typeof process==="object"&&process!==null){return process.stderr}}function globalProcessExit(e){if(typeof process==="object"&&process!==null&&typeof process.exit==="function"){return process.exit(e)}}function handlerExec(e){return function(r){for(var n=0;n"}var n=this.getLineNumber();if(n!=null){r+=":"+n;var t=this.getColumnNumber();if(t){r+=":"+t}}}var o="";var i=this.getFunctionName();var a=true;var u=this.isConstructor();var s=!(this.isToplevel()||u);if(s){var l=this.getTypeName();if(l==="[object Object]"){l="null"}var c=this.getMethodName();if(i){if(l&&i.indexOf(l)!=0){o+=l+"."}o+=i;if(c&&i.indexOf("."+c)!=i.length-c.length-1){o+=" [as "+c+"]"}}else{o+=l+"."+(c||"")}}else if(u){o+="new "+(i||"")}else if(i){o+=i}else{o+=r;a=false}if(a){o+=" ("+r+")"}return o}function cloneCallSite(e){var r={};Object.getOwnPropertyNames(Object.getPrototypeOf(e)).forEach((function(n){r[n]=/^(?:is|get)/.test(n)?function(){return e[n].call(e)}:e[n]}));r.toString=CallSiteToString;return r}function wrapCallSite(e,r){if(r===undefined){r={nextPosition:null,curPosition:null}}if(e.isNative()){r.curPosition=null;return e}var n=e.getFileName()||e.getScriptNameOrSourceURL();if(n){var t=e.getLineNumber();var o=e.getColumnNumber()-1;var i=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;var a=i.test(globalProcessVersion())?0:62;if(t===1&&o>a&&!isInBrowser()&&!e.isEval()){o-=a}var u=mapSourcePosition({source:n,line:t,column:o});r.curPosition=u;e=cloneCallSite(e);var s=e.getFunctionName;e.getFunctionName=function(){if(r.nextPosition==null){return s()}return r.nextPosition.name||s()};e.getFileName=function(){return u.source};e.getLineNumber=function(){return u.line};e.getColumnNumber=function(){return u.column+1};e.getScriptNameOrSourceURL=function(){return u.source};return e}var l=e.isEval()&&e.getEvalOrigin();if(l){l=mapEvalOrigin(l);e=cloneCallSite(e);e.getEvalOrigin=function(){return l};return e}return e}function prepareStackTrace(e,r){if(l){p={};f={}}var n=e.name||"Error";var t=e.message||"";var o=n+": "+t;var i={nextPosition:null,curPosition:null};var a=[];for(var u=r.length-1;u>=0;u--){a.push("\n at "+wrapCallSite(r[u],i));i.nextPosition=i.curPosition}i.curPosition=i.nextPosition=null;return o+a.reverse().join("")}function getErrorSource(e){var r=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(e.stack);if(r){var n=r[1];var t=+r[2];var o=+r[3];var a=p[n];if(!a&&i&&i.existsSync(n)){try{a=i.readFileSync(n,"utf8")}catch(e){a=""}}if(a){var u=a.split(/(?:\r\n|\r|\n)/)[t-1];if(u){return n+":"+t+"\n"+u+"\n"+new Array(o).join(" ")+"^"}}}return null}function printErrorAndExit(e){var r=getErrorSource(e);var n=globalProcessStderr();if(n&&n._handle&&n._handle.setBlocking){n._handle.setBlocking(true)}if(r){console.error();console.error(r)}console.error(e.stack);globalProcessExit(1)}function shimEmitUncaughtException(){var e=process.emit;process.emit=function(r){if(r==="uncaughtException"){var n=arguments[1]&&arguments[1].stack;var t=this.listeners(r).length>0;if(n&&!t){return printErrorAndExit(arguments[1])}}return e.apply(this,arguments)}}var S=h.slice(0);var _=d.slice(0);r.wrapCallSite=wrapCallSite;r.getErrorSource=getErrorSource;r.mapSourcePosition=mapSourcePosition;r.retrieveSourceMap=v;r.install=function(r){r=r||{};if(r.environment){c=r.environment;if(["node","browser","auto"].indexOf(c)===-1){throw new Error("environment "+c+" was unknown. Available options are {auto, browser, node}")}}if(r.retrieveFile){if(r.overrideRetrieveFile){h.length=0}h.unshift(r.retrieveFile)}if(r.retrieveSourceMap){if(r.overrideRetrieveSourceMap){d.length=0}d.unshift(r.retrieveSourceMap)}if(r.hookRequire&&!isInBrowser()){var n=dynamicRequire(e,"module");var t=n.prototype._compile;if(!t.__sourceMapSupport){n.prototype._compile=function(e,r){p[r]=e;f[r]=undefined;return t.call(this,e,r)};n.prototype._compile.__sourceMapSupport=true}}if(!l){l="emptyCacheBetweenOperations"in r?r.emptyCacheBetweenOperations:false}if(!u){u=true;Error.prepareStackTrace=prepareStackTrace}if(!s){var o="handleUncaughtExceptions"in r?r.handleUncaughtExceptions:true;try{var i=dynamicRequire(e,"worker_threads");if(i.isMainThread===false){o=false}}catch(e){}if(o&&hasGlobalProcessEventEmitter()){s=true;shimEmitUncaughtException()}}};r.resetRetrieveHandlers=function(){h.length=0;d.length=0;h=S.slice(0);d=_.slice(0);v=handlerExec(d);m=handlerExec(h)}},147:e=>{"use strict";e.exports=require("fs")},17:e=>{"use strict";e.exports=require("path")}};var r={};function __webpack_require__(n){var t=r[n];if(t!==undefined){return t.exports}var o=r[n]={id:n,loaded:false,exports:{}};var i=true;try{e[n](o,o.exports,__webpack_require__);i=false}finally{if(i)delete r[n]}o.loaded=true;return o.exports}(()=>{__webpack_require__.nmd=e=>{e.paths=[];if(!e.children)e.children=[];return e}})();if(typeof __webpack_require__!=="undefined")__webpack_require__.ab=__dirname+"/";var n={};(()=>{__webpack_require__(284).install()})();module.exports=n})(); -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "nixpkgs": { 4 | "locked": { 5 | "lastModified": 1672428209, 6 | "narHash": "sha256-eejhqkDz2cb2vc5VeaWphJz8UXNuoNoM8/Op8eWv2tQ=", 7 | "owner": "NixOS", 8 | "repo": "nixpkgs", 9 | "rev": "293a28df6d7ff3dec1e61e37cc4ee6e6c0fb0847", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "id": "nixpkgs", 14 | "type": "indirect" 15 | } 16 | }, 17 | "root": { 18 | "inputs": { 19 | "nixpkgs": "nixpkgs" 20 | } 21 | } 22 | }, 23 | "root": "root", 24 | "version": 7 25 | } 26 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A very basic flake"; 3 | 4 | outputs = { 5 | self, 6 | nixpkgs, 7 | }: { 8 | packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello; 9 | 10 | packages.x86_64-linux.default = self.packages.x86_64-linux.hello; 11 | 12 | devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell { 13 | buildInputs = [nixpkgs.legacyPackages.x86_64-linux.figlet]; 14 | }; 15 | 16 | ci = nixpkgs.legacyPackages.x86_64-linux.mkShell { 17 | buildInputs = [nixpkgs.legacyPackages.x86_64-linux.ponysay]; 18 | }; 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nix-shell-action", 3 | "description": "Run any command you like in a deterministic Nix shell on Linux and macOS.", 4 | "version": "3.4.0", 5 | "author": "", 6 | "private": true, 7 | "homepage": "https://github.com/actions/typescript-action", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/workflow/nix-shell-action.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/workflow/nix-shell-action/issues" 14 | }, 15 | "keywords": [ 16 | "actions", 17 | "nix", 18 | "ci", 19 | "dependency-management" 20 | ], 21 | "exports": { 22 | ".": "./dist/index.js" 23 | }, 24 | "engines": { 25 | "node": ">=21" 26 | }, 27 | "scripts": { 28 | "bundle": "npm run format:write && npm run package", 29 | "ci-test": "npx jest", 30 | "format:write": "npx prettier --write .", 31 | "format:check": "npx prettier --check .", 32 | "lint": "npx eslint . -c ./.github/linters/.eslintrc.yml", 33 | "package": "npx ncc build src/index.ts -o dist --source-map --license licenses.txt", 34 | "package:watch": "npm run package -- --watch", 35 | "test": "npx jest", 36 | "all": "npm run format:write && npm run lint && npm run test && npm run package" 37 | }, 38 | "license": "MIT", 39 | "jest": { 40 | "preset": "ts-jest", 41 | "verbose": true, 42 | "clearMocks": true, 43 | "testEnvironment": "node", 44 | "moduleFileExtensions": [ 45 | "js", 46 | "ts" 47 | ], 48 | "testMatch": [ 49 | "**/*.test.ts" 50 | ], 51 | "testPathIgnorePatterns": [ 52 | "/node_modules/", 53 | "/dist/" 54 | ], 55 | "transform": { 56 | "^.+\\.ts$": "ts-jest" 57 | }, 58 | "coverageReporters": [ 59 | "json-summary", 60 | "text", 61 | "lcov" 62 | ], 63 | "collectCoverage": true, 64 | "collectCoverageFrom": [ 65 | "./src/**" 66 | ] 67 | }, 68 | "dependencies": { 69 | "@actions/core": "^1.11.1" 70 | }, 71 | "devDependencies": { 72 | "@jest/globals": "^29.7.0", 73 | "@types/jest": "^29.5.14", 74 | "@types/node": "^22.8.1", 75 | "@typescript-eslint/eslint-plugin": "^8.11.0", 76 | "@typescript-eslint/parser": "^8.11.0", 77 | "@vercel/ncc": "^0.38.2", 78 | "eslint": "^8.57.0", 79 | "eslint-plugin-jest": "^28.8.3", 80 | "eslint-plugin-jsonc": "^2.16.0", 81 | "eslint-plugin-prettier": "^5.2.1", 82 | "jest": "^29.7.0", 83 | "make-coverage-badge": "^1.2.0", 84 | "prettier": "^3.3.3", 85 | "prettier-eslint": "^16.3.0", 86 | "ts-jest": "^29.2.5", 87 | "typescript": "^5.6.3" 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The entrypoint for the action. 3 | */ 4 | import { run } from './main' 5 | 6 | // eslint-disable-next-line @typescript-eslint/no-floating-promises 7 | run() 8 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core' 2 | import { execFileSync } from 'child_process' 3 | import { writeFileSync } from 'fs' 4 | 5 | export async function run(): Promise { 6 | try { 7 | const interpreter: string = core.getInput('interpreter') 8 | const packages: string = core.getInput('packages') 9 | const flakes: string = core.getInput('flakes') 10 | const flakesFromDevshell: boolean = core.getBooleanInput( 11 | 'flakes-from-devshell' 12 | ) 13 | const customDevshell: string = core.getInput('custom-devshell') 14 | const script: string = core.getInput('script') 15 | const workingDirectory: string = core.getInput('working-directory') 16 | 17 | const nixWrapperPath = workingDirectory 18 | ? `./wrapper.sh` 19 | : `${__dirname}/wrapper.sh` 20 | const scriptPath = workingDirectory 21 | ? `./script.sh` 22 | : `${__dirname}/script.sh` 23 | 24 | const wrappedPackages = packages 25 | .split(',') 26 | .map(pkg => `nixpkgs.${pkg.trim()}`) 27 | .join(' ') 28 | 29 | const flakeWrappedPackages = flakesFromDevshell 30 | ? flakes 31 | : flakes.split(',').join(' ') || 32 | packages 33 | .split(',') 34 | .map(pkg => `nixpkgs#${pkg.trim()}`) 35 | .join(' ') 36 | 37 | const nixCommand = flakesFromDevshell 38 | ? customDevshell 39 | ? `develop .#${customDevshell}` 40 | : 'develop' 41 | : 'shell' 42 | 43 | const nixWrapper = ` 44 | set -euo pipefail 45 | 46 | verlte() { 47 | [ "$1" = "$(echo -e "$1\n$2" | sort -V | head -n1)" ] 48 | } 49 | 50 | verlt() { 51 | [ "$1" = "$2" ] && return 1 || verlte $1 $2 52 | } 53 | 54 | nix_version=$(nix --version | awk '{ print $3 }') 55 | 56 | if verlt $nix_version 2.4 57 | then 58 | # before nix 2.4: nix run 59 | nix run ${wrappedPackages} -c ${interpreter} ${scriptPath} 60 | else 61 | # nix 2.4 and later: nix shell 62 | nix --experimental-features 'nix-command flakes' ${nixCommand} ${flakeWrappedPackages} -c ${interpreter} ${scriptPath} 63 | fi 64 | ` 65 | 66 | const wrappedScript = ` 67 | set -euo pipefail 68 | 69 | ${script} 70 | ` 71 | 72 | writeFileSync(`${workingDirectory}/${nixWrapperPath}`, nixWrapper, { 73 | mode: 0o755 74 | }) 75 | writeFileSync(`${workingDirectory}/${scriptPath}`, wrappedScript, { 76 | mode: 0o755 77 | }) 78 | 79 | execFileSync(nixWrapperPath, { 80 | cwd: workingDirectory || undefined, 81 | stdio: 'inherit', 82 | shell: 'bash' 83 | }) 84 | } catch (error) { 85 | if (error instanceof Error) core.setFailed(error.message) 86 | } 87 | } 88 | 89 | run() 90 | -------------------------------------------------------------------------------- /src/wait.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Wait for a number of milliseconds. 3 | * @param milliseconds The number of milliseconds to wait. 4 | * @returns {Promise} Resolves with 'done!' after the wait is over. 5 | */ 6 | export async function wait(milliseconds: number): Promise { 7 | return new Promise(resolve => { 8 | if (isNaN(milliseconds)) { 9 | throw new Error('milliseconds not a number') 10 | } 11 | 12 | setTimeout(() => resolve('done!'), milliseconds) 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /test/devshell-flake/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "locked": { 5 | "lastModified": 1667395993, 6 | "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", 7 | "owner": "numtide", 8 | "repo": "flake-utils", 9 | "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "owner": "numtide", 14 | "repo": "flake-utils", 15 | "type": "github" 16 | } 17 | }, 18 | "nixpkgs": { 19 | "locked": { 20 | "lastModified": 1669833724, 21 | "narHash": "sha256-/HEZNyGbnQecrgJnfE8d0WC5c1xuPSD2LUpB6YXlg4c=", 22 | "owner": "NixOS", 23 | "repo": "nixpkgs", 24 | "rev": "4d2b37a84fad1091b9de401eb450aae66f1a741e", 25 | "type": "github" 26 | }, 27 | "original": { 28 | "id": "nixpkgs", 29 | "ref": "22.11", 30 | "type": "indirect" 31 | } 32 | }, 33 | "root": { 34 | "inputs": { 35 | "flake-utils": "flake-utils", 36 | "nixpkgs": "nixpkgs" 37 | } 38 | } 39 | }, 40 | "root": "root", 41 | "version": 7 42 | } 43 | -------------------------------------------------------------------------------- /test/devshell-flake/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A basic flake with a special devShell package"; 3 | 4 | inputs = { 5 | nixpkgs.url = "nixpkgs/22.11"; 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | }; 8 | 9 | outputs = { ... }@inputs: inputs.flake-utils.lib.eachDefaultSystem (system: 10 | let 11 | pkgs = import inputs.nixpkgs { inherit system; }; 12 | in 13 | { 14 | devShell = pkgs.mkShell { 15 | buildInputs = with pkgs; [ 16 | cmatrix 17 | ]; 18 | }; 19 | }); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/working-directory/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A very basic flake"; 3 | 4 | outputs = { self, nixpkgs }: { 5 | 6 | packages.x86_64-linux.cowsay = nixpkgs.legacyPackages.x86_64-linux.cowsay; 7 | 8 | packages.x86_64-linux.default = self.packages.x86_64-linux.cowsay; 9 | 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /test/working-directory/test.sh: -------------------------------------------------------------------------------- 1 | echo hello 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "target": "ES2022", 5 | "module": "NodeNext", 6 | "rootDir": "./src", 7 | "moduleResolution": "NodeNext", 8 | "baseUrl": "./", 9 | "sourceMap": true, 10 | "outDir": "./dist", 11 | "noImplicitAny": true, 12 | "esModuleInterop": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "strict": true, 15 | "skipLibCheck": true, 16 | "newLine": "lf" 17 | }, 18 | "exclude": ["./dist", "./node_modules", "./__tests__", "./coverage"] 19 | } 20 | --------------------------------------------------------------------------------