11 Commits

Author SHA1 Message Date
a2bbe0274e Merge pull request #128 from detsys-pr-bot/detsys-ts-update-65dd73c562ac60a068340f8e0c040bdcf2c59afe
Update `detsys-ts`: Merge pull request #63 from DeterminateSystems/retry-streams
2024-09-04 14:14:50 -04:00
802501548e Update detsys-ts for: Merge pull request #63 from DeterminateSystems/retry-streams (65dd73c562ac60a068340f8e0c040bdcf2c59afe) 2024-09-04 18:05:28 +00:00
7d80c329b4 Merge pull request #126 from detsys-pr-bot/detsys-ts-update-817e4d4123b6fb4eae5aa557658f25f8539e7240
Update `detsys-ts`: Merge pull request #62 from DeterminateSystems/dont-pull-microstackshots
2024-08-26 19:46:57 -04:00
7bc6ec59cc Update detsys-ts for: Merge pull request #62 from DeterminateSystems/dont-pull-microstackshots (817e4d4123b6fb4eae5aa557658f25f8539e7240) 2024-08-26 15:26:03 +00:00
4cf6b19203 Merge pull request #125 from detsys-pr-bot/detsys-ts-update-e8f6e8f54d85aa0fd3d0b694dd3279a21497a33b
Update `detsys-ts`: Merge pull request #61 from DeterminateSystems/use-coalesce-for-array
2024-08-26 10:09:12 -04:00
73ba0ca899 Update detsys-ts for: Merge pull request #61 from DeterminateSystems/use-coalesce-for-array (e8f6e8f54d85aa0fd3d0b694dd3279a21497a33b) 2024-08-26 14:05:27 +00:00
24f53daa86 Merge pull request #124 from detsys-pr-bot/detsys-ts-update-cf1897a891edc164a8240f469cd56d14364e6be1
Update `detsys-ts`: Merge pull request #58 from DeterminateSystems/collect-crash-logs
2024-08-26 09:41:53 -04:00
420fb2aaf7 Update detsys-ts for: Merge pull request #58 from DeterminateSystems/collect-crash-logs (cf1897a891edc164a8240f469cd56d14364e6be1) 2024-08-26 13:31:25 +00:00
db4ee38117 Fixup support for Nix 2.23.0 and later 2024-06-28 14:11:30 -07:00
b0723e0fae Add instructions for new fine grained GitHub PAT 2024-06-18 09:23:51 -07:00
af9a980c7d Lock third-party actions
A caller of this action can lock this action to a specific commit. However because the action itself does not lock its dependent actions to a specific commit this opens the end-user up to possible supply-chain attacks if the dependent actions rewrite their tags.

This PR changes all third party actions to be explicitly locked.

Dependabot will still work and update these hashes for you


I also suggest installing https://github.com/ossf/scorecard in this repo. It will report about these kind of issues.

Note that you should in turn have to audit all the third party deps of the actions that your action depends on. In general this is all a bit of a mess and GitHub's security model is very meh

e.g. see https://github.com/ossf/scorecard/issues/2189
2024-06-18 09:17:15 -07:00
11 changed files with 785 additions and 9378 deletions

View File

@ -138,23 +138,6 @@ jobs:
path-to-flake-dir: 'nix/' # in this example our flake doesn't sit at the root of the repository, it sits under 'nix/flake.nix' path-to-flake-dir: 'nix/' # in this example our flake doesn't sit at the root of the repository, it sits under 'nix/flake.nix'
``` ```
You can also run the update operation in multiple directories, provided that each directory is a valid flake:
```yaml
- name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@vX
with:
flake-dirs: |
flake1
flake2
flake3
```
> **Warning**: If you choose multiple directories, `update-flake-lock` can only update all flake inputs,
> meaning that you can't set the `inputs` parameter. This is due to limitations in input handling in
> GitHub Actions, which only allows for strings, numbers, Booleans, and arrays but not objects, which
> would be the much preferred data type for expressing per-directory inputs.
## Example using a different Git user ## Example using a different Git user
If you want to change the author and / or committer of the flake.lock update commit, you can tweak the `git-{author,committer}-{name,email}` options: If you want to change the author and / or committer of the flake.lock update commit, you can tweak the `git-{author,committer}-{name,email}` options:
@ -202,7 +185,7 @@ git push origin update_flake_lock_action --force
### With a Personal Authentication Token ### With a Personal Authentication Token
By providing a Personal Authentication Token, the PR will be submitted in a way that bypasses this limitation (GitHub will essentially think it is the owner of the PAT submitting the PR, and not an Action). By providing a Personal Authentication Token, the PR will be submitted in a way that bypasses this limitation (GitHub will essentially think it is the owner of the PAT submitting the PR, and not an Action).
You can create a token by visiting https://github.com/settings/tokens and select at least the `repo` scope. Then, store this token in your repository secrets (i.e. `https://github.com/<USER>/<REPO>/settings/secrets/actions`) as `GH_TOKEN_FOR_UPDATES` and set up your workflow file like the following: You can create a token by visiting https://github.com/settings/tokens and select at least the `repo` scope. For the new fine-grained tokens, you need to enable read and write access for "Contents" and "Pull Requests" permissions. Then, store this token in your repository secrets (i.e. `https://github.com/<USER>/<REPO>/settings/secrets/actions`) as `GH_TOKEN_FOR_UPDATES` and set up your workflow file like the following:
```yaml ```yaml
name: update-flake-lock name: update-flake-lock

View File

@ -9,21 +9,10 @@ inputs:
description: "GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT)" description: "GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT)"
required: false required: false
default: ${{ github.token }} default: ${{ github.token }}
commit-msg-template:
description: |
The commit message template to use. You can use these variables in your template:
* `{{ flake_dot_lock }}` is the path to the `flake.lock` file being updated
* `{{ flake_dot_lock_dir }}` is the `flake.lock` file's directory
If you set both this and `commit-msg`, the `commit-msg` setting is used (it does not support templating).
required: false
default: |
flake.lock: Updated in {{ flake_dot_lock_dir }}
commit-msg: commit-msg:
description: | description: "The message provided with the commit"
The message provided with the commit.
required: false required: false
default: "flake.lock: Update"
base: base:
description: "Sets the pull request base branch. Defaults to the branch checked out in the workflow." description: "Sets the pull request base branch. Defaults to the branch checked out in the workflow."
required: false required: false
@ -32,32 +21,12 @@ inputs:
required: false required: false
default: "update_flake_lock_action" default: "update_flake_lock_action"
path-to-flake-dir: path-to-flake-dir:
description: | description: "The path of the directory containing `flake.nix` file within your repository. Useful when `flake.nix` cannot reside at the root of your repository."
The path of the directory containing `flake.nix` file within your repository.
Useful when `flake.nix` cannot reside at the root of your repository.
required: false required: false
flake-dirs:
description: |
A space-separated list of directories containing `flake.nix` files within your repository.
Useful when you have multiple flakes in your repository.
required: false
default: ""
pr-title: pr-title:
description: "The title of the PR to be created" description: "The title of the PR to be created"
required: false required: false
default: "flake.lock: Update" default: "flake.lock: Update"
pr-body-template:
description: |
The pull request body template to use. You can use these variables in your template:
* `{{ comma_separated_dirs }}` is the flake directories that were updated separated by comma
* `{{ space_separated_dirs }}` is the flake directories that were updated separated by space
* `{{ updated_dirs_list }}` is the flake directories that were updated as a Markdown list
If you set both this and `pr-body`, the `pr-body` setting is used (it does not support templating).
required: false
default: |
Just testing.
pr-body: pr-body:
description: "The body of the PR to be created" description: "The body of the PR to be created"
required: false required: false
@ -146,7 +115,7 @@ runs:
- name: Import bot's GPG key for signing commits - name: Import bot's GPG key for signing commits
if: ${{ inputs.sign-commits == 'true' }} if: ${{ inputs.sign-commits == 'true' }}
id: import-gpg id: import-gpg
uses: crazy-max/ghaction-import-gpg@v6 uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0
with: with:
gpg_private_key: ${{ inputs.gpg-private-key }} gpg_private_key: ${{ inputs.gpg-private-key }}
fingerprint: ${{ inputs.gpg-fingerprint }} fingerprint: ${{ inputs.gpg-fingerprint }}
@ -177,7 +146,6 @@ runs:
echo "GIT_COMMITTER_NAME=${{ inputs.git-committer-name }}" >> $GITHUB_ENV echo "GIT_COMMITTER_NAME=${{ inputs.git-committer-name }}" >> $GITHUB_ENV
echo "GIT_COMMITTER_EMAIL=<${{ inputs.git-committer-email }}>" >> $GITHUB_ENV echo "GIT_COMMITTER_EMAIL=<${{ inputs.git-committer-email }}>" >> $GITHUB_ENV
- name: Run update-flake-lock - name: Run update-flake-lock
id: update-flake-lock
shell: bash shell: bash
run: node "$GITHUB_ACTION_PATH/dist/index.js" run: node "$GITHUB_ACTION_PATH/dist/index.js"
env: env:
@ -186,7 +154,6 @@ runs:
INPUT_BASE: ${{ inputs.base }} INPUT_BASE: ${{ inputs.base }}
INPUT_BRANCH: ${{ inputs.branch }} INPUT_BRANCH: ${{ inputs.branch }}
INPUT_COMMIT-MSG: ${{ inputs.commit-msg }} INPUT_COMMIT-MSG: ${{ inputs.commit-msg }}
INPUT_COMMIT-MSG-TEMPLATE: ${{ inputs.commit-msg-template }}
INPUT_GIT-AUTHOR-EMAIL: ${{ inputs.git-author-email }} INPUT_GIT-AUTHOR-EMAIL: ${{ inputs.git-author-email }}
INPUT_GIT-AUTHOR-NAME: ${{ inputs.git-author-name }} INPUT_GIT-AUTHOR-NAME: ${{ inputs.git-author-name }}
INPUT_GIT-COMMITTER-EMAIL: ${{ inputs.git-committer-email }} INPUT_GIT-COMMITTER-EMAIL: ${{ inputs.git-committer-email }}
@ -197,10 +164,8 @@ runs:
INPUT_INPUTS: ${{ inputs.inputs }} INPUT_INPUTS: ${{ inputs.inputs }}
INPUT_NIX-OPTIONS: ${{ inputs.nix-options }} INPUT_NIX-OPTIONS: ${{ inputs.nix-options }}
INPUT_PATH-TO-FLAKE-DIR: ${{ inputs.path-to-flake-dir }} INPUT_PATH-TO-FLAKE-DIR: ${{ inputs.path-to-flake-dir }}
INPUT_FLAKE-DIRS: ${{ inputs.flake-dirs }}
INPUT_PR-ASSIGNEES: ${{ inputs.pr-assignees }} INPUT_PR-ASSIGNEES: ${{ inputs.pr-assignees }}
INPUT_PR-BODY: ${{ inputs.pr-body }} INPUT_PR-BODY: ${{ inputs.pr-body }}
INPUT_PR-BODY-TEMPLATE: ${{ inputs.pr-body-template }}
INPUT_PR-LABELS: ${{ inputs.pr-labels }} INPUT_PR-LABELS: ${{ inputs.pr-labels }}
INPUT_PR-REVIEWERS: ${{ inputs.pr-reviewers }} INPUT_PR-REVIEWERS: ${{ inputs.pr-reviewers }}
INPUT_PR-TITLE: ${{ inputs.pr-title }} INPUT_PR-TITLE: ${{ inputs.pr-title }}
@ -213,7 +178,7 @@ runs:
uses: DamianReeves/write-file-action@v1.3 uses: DamianReeves/write-file-action@v1.3
with: with:
path: pr_body.template path: pr_body.template
contents: ${{ steps.update-flake-lock.outputs.pr-body }} contents: ${{ inputs.pr-body }}
env: {} env: {}
- name: Set additional env variables (GIT_COMMIT_MESSAGE) - name: Set additional env variables (GIT_COMMIT_MESSAGE)
shell: bash shell: bash
@ -225,7 +190,7 @@ runs:
echo "$DELIMITER" >> $GITHUB_ENV echo "$DELIMITER" >> $GITHUB_ENV
echo "GIT_COMMIT_MESSAGE is: ${COMMIT_MESSAGE}" echo "GIT_COMMIT_MESSAGE is: ${COMMIT_MESSAGE}"
- name: Interpolate PR Body - name: Interpolate PR Body
uses: pedrolamas/handlebars-action@v2.4.0 uses: pedrolamas/handlebars-action@2995d7eadacbc8f2f6ab8431a01d84a5fa3b8bb4 # v2.4.0
with: with:
files: "pr_body.template" files: "pr_body.template"
output-filename: "pr_body.txt" output-filename: "pr_body.txt"
@ -242,7 +207,7 @@ runs:
run: rm -f pr_body.txt pr_body.template run: rm -f pr_body.txt pr_body.template
- name: Create PR - name: Create PR
id: create-pr id: create-pr
uses: peter-evans/create-pull-request@v6 uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5
with: with:
base: ${{ inputs.base }} base: ${{ inputs.base }}
branch: ${{ inputs.branch }} branch: ${{ inputs.branch }}

9551
dist/index.js vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,6 @@
"lint": "eslint src/**/*.ts --ignore-pattern *.test.ts", "lint": "eslint src/**/*.ts --ignore-pattern *.test.ts",
"package": "ncc build", "package": "ncc build",
"test": "vitest --watch false", "test": "vitest --watch false",
"test-dev": "vitest",
"all": "pnpm run format && pnpm run lint && pnpm run build && pnpm run package" "all": "pnpm run format && pnpm run lint && pnpm run build && pnpm run package"
}, },
"repository": { "repository": {
@ -29,8 +28,7 @@
"dependencies": { "dependencies": {
"@actions/core": "^1.10.1", "@actions/core": "^1.10.1",
"@actions/exec": "^1.1.1", "@actions/exec": "^1.1.1",
"detsys-ts": "github:DeterminateSystems/detsys-ts", "detsys-ts": "github:DeterminateSystems/detsys-ts"
"handlebars": "^4.7.8"
}, },
"devDependencies": { "devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0",

262
pnpm-lock.yaml generated
View File

@ -13,10 +13,7 @@ dependencies:
version: 1.1.1 version: 1.1.1
detsys-ts: detsys-ts:
specifier: github:DeterminateSystems/detsys-ts specifier: github:DeterminateSystems/detsys-ts
version: github.com/DeterminateSystems/detsys-ts/fe64ba33b4bdeec0991bb65ae00420bf68b9954c version: github.com/DeterminateSystems/detsys-ts/65dd73c562ac60a068340f8e0c040bdcf2c59afe
handlebars:
specifier: ^4.7.8
version: 4.7.8
devDependencies: devDependencies:
'@trivago/prettier-plugin-sort-imports': '@trivago/prettier-plugin-sort-imports':
@ -24,7 +21,7 @@ devDependencies:
version: 4.3.0(prettier@3.2.5) version: 4.3.0(prettier@3.2.5)
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: ^7.11.0 specifier: ^7.11.0
version: 7.11.0(@typescript-eslint/parser@7.11.0)(eslint@8.57.0)(typescript@5.4.5) version: 7.11.0(@typescript-eslint/parser@7.18.0)(eslint@8.57.0)(typescript@5.4.5)
'@vercel/ncc': '@vercel/ncc':
specifier: ^0.38.1 specifier: ^0.38.1
version: 0.38.1 version: 0.38.1
@ -33,13 +30,13 @@ devDependencies:
version: 8.57.0 version: 8.57.0
eslint-import-resolver-typescript: eslint-import-resolver-typescript:
specifier: ^3.6.1 specifier: ^3.6.1
version: 3.6.1(@typescript-eslint/parser@7.11.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) version: 3.6.1(@typescript-eslint/parser@7.18.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
eslint-plugin-github: eslint-plugin-github:
specifier: ^4.10.2 specifier: ^4.10.2
version: 4.10.2(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)(typescript@5.4.5) version: 4.10.2(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)(typescript@5.4.5)
eslint-plugin-import: eslint-plugin-import:
specifier: ^2.29.1 specifier: ^2.29.1
version: 2.29.1(@typescript-eslint/parser@7.11.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) version: 2.29.1(@typescript-eslint/parser@7.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-prettier: eslint-plugin-prettier:
specifier: ^5.1.3 specifier: ^5.1.3
version: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5) version: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5)
@ -1058,9 +1055,9 @@ packages:
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
dev: true dev: true
/@sindresorhus/is@6.3.1: /@sindresorhus/is@7.0.0:
resolution: {integrity: sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ==} resolution: {integrity: sha512-WDTlVTyvFivSOuyvMeedzg2hdoBLZ3f1uNVuEida2Rl9BrfjrIRjWA/VZIrMRLvSwJYCAlCRA3usDt1THytxWQ==}
engines: {node: '>=16'} engines: {node: '>=18'}
dev: false dev: false
/@szmarczak/http-timer@5.0.1: /@szmarczak/http-timer@5.0.1:
@ -1148,6 +1145,33 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/eslint-plugin@7.11.0(@typescript-eslint/parser@7.18.0)(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
'@typescript-eslint/parser': ^7.0.0
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@eslint-community/regexpp': 4.10.0
'@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/scope-manager': 7.11.0
'@typescript-eslint/type-utils': 7.11.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/utils': 7.11.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.11.0
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.3.1
natural-compare: 1.4.0
ts-api-utils: 1.3.0(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5): /@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==} resolution: {integrity: sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || >=20.0.0}
@ -1169,6 +1193,27 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.18.0
debug: 4.3.6
eslint: 8.57.0
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/scope-manager@7.11.0: /@typescript-eslint/scope-manager@7.11.0:
resolution: {integrity: sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==} resolution: {integrity: sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || >=20.0.0}
@ -1177,6 +1222,14 @@ packages:
'@typescript-eslint/visitor-keys': 7.11.0 '@typescript-eslint/visitor-keys': 7.11.0
dev: true dev: true
/@typescript-eslint/scope-manager@7.18.0:
resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==}
engines: {node: ^18.18.0 || >=20.0.0}
dependencies:
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0
dev: true
/@typescript-eslint/type-utils@7.11.0(eslint@8.57.0)(typescript@5.4.5): /@typescript-eslint/type-utils@7.11.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==} resolution: {integrity: sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || >=20.0.0}
@ -1202,6 +1255,11 @@ packages:
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || >=20.0.0}
dev: true dev: true
/@typescript-eslint/types@7.18.0:
resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==}
engines: {node: ^18.18.0 || >=20.0.0}
dev: true
/@typescript-eslint/typescript-estree@7.11.0(typescript@5.4.5): /@typescript-eslint/typescript-estree@7.11.0(typescript@5.4.5):
resolution: {integrity: sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==} resolution: {integrity: sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || >=20.0.0}
@ -1224,6 +1282,28 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/typescript-estree@7.18.0(typescript@5.4.5):
resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0
debug: 4.3.6
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.6.3
ts-api-utils: 1.3.0(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/utils@7.11.0(eslint@8.57.0)(typescript@5.4.5): /@typescript-eslint/utils@7.11.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==} resolution: {integrity: sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || >=20.0.0}
@ -1248,6 +1328,14 @@ packages:
eslint-visitor-keys: 3.4.3 eslint-visitor-keys: 3.4.3
dev: true dev: true
/@typescript-eslint/visitor-keys@7.18.0:
resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==}
engines: {node: ^18.18.0 || >=20.0.0}
dependencies:
'@typescript-eslint/types': 7.18.0
eslint-visitor-keys: 3.4.3
dev: true
/@ungap/structured-clone@1.2.0: /@ungap/structured-clone@1.2.0:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
dev: true dev: true
@ -1733,6 +1821,18 @@ packages:
ms: 2.1.2 ms: 2.1.2
dev: true dev: true
/debug@4.3.6:
resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
dev: true
/decompress-response@6.0.0: /decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -2045,7 +2145,7 @@ packages:
- supports-color - supports-color
dev: true dev: true
/eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.11.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0): /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.18.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0):
resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies: peerDependencies:
@ -2055,8 +2155,8 @@ packages:
debug: 4.3.5 debug: 4.3.5
enhanced-resolve: 5.16.1 enhanced-resolve: 5.16.1
eslint: 8.57.0 eslint: 8.57.0
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.11.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.11.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
fast-glob: 3.3.2 fast-glob: 3.3.2
get-tsconfig: 4.7.5 get-tsconfig: 4.7.5
is-core-module: 2.13.1 is-core-module: 2.13.1
@ -2093,7 +2193,37 @@ packages:
debug: 3.2.7 debug: 3.2.7
eslint: 8.57.0 eslint: 8.57.0
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.11.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.18.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
transitivePeerDependencies:
- supports-color
dev: true
/eslint-module-utils@2.8.1(@typescript-eslint/parser@7.18.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==}
engines: {node: '>=4'}
peerDependencies:
'@typescript-eslint/parser': '*'
eslint: '*'
eslint-import-resolver-node: '*'
eslint-import-resolver-typescript: '*'
eslint-import-resolver-webpack: '*'
peerDependenciesMeta:
'@typescript-eslint/parser':
optional: true
eslint:
optional: true
eslint-import-resolver-node:
optional: true
eslint-import-resolver-typescript:
optional: true
eslint-import-resolver-webpack:
optional: true
dependencies:
'@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.4.5)
debug: 3.2.7
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.18.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -2205,6 +2335,41 @@ packages:
- supports-color - supports-color
dev: true dev: true
/eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==}
engines: {node: '>=4'}
peerDependencies:
'@typescript-eslint/parser': '*'
eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
peerDependenciesMeta:
'@typescript-eslint/parser':
optional: true
dependencies:
'@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.4.5)
array-includes: 3.1.8
array.prototype.findlastindex: 1.2.5
array.prototype.flat: 1.3.2
array.prototype.flatmap: 1.3.2
debug: 3.2.7
doctrine: 2.1.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
hasown: 2.0.2
is-core-module: 2.13.1
is-glob: 4.0.3
minimatch: 3.1.2
object.fromentries: 2.0.8
object.groupby: 1.0.3
object.values: 1.2.0
semver: 6.3.1
tsconfig-paths: 3.15.0
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
dev: true
/eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0): /eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0):
resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==}
engines: {node: '>=4.0'} engines: {node: '>=4.0'}
@ -2558,6 +2723,7 @@ packages:
/get-stream@8.0.1: /get-stream@8.0.1:
resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
engines: {node: '>=16'} engines: {node: '>=16'}
dev: true
/get-stream@9.0.1: /get-stream@9.0.1:
resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==}
@ -2658,21 +2824,21 @@ packages:
get-intrinsic: 1.2.4 get-intrinsic: 1.2.4
dev: true dev: true
/got@14.3.0: /got@14.4.2:
resolution: {integrity: sha512-vZkrXdq5BtPWTXqvjXSpl6zky3zpHaOVfSug/RfFHu3YrtSsvYzopVMDqrh2do77WnGoCSSRCHW25zXOSAQ9zw==} resolution: {integrity: sha512-+Te/qEZ6hr7i+f0FNgXx/6WQteSM/QqueGvxeYQQFm0GDfoxLVJ/oiwUKYMTeioColWUTdewZ06hmrBjw6F7tw==}
engines: {node: '>=20'} engines: {node: '>=20'}
dependencies: dependencies:
'@sindresorhus/is': 6.3.1 '@sindresorhus/is': 7.0.0
'@szmarczak/http-timer': 5.0.1 '@szmarczak/http-timer': 5.0.1
cacheable-lookup: 7.0.0 cacheable-lookup: 7.0.0
cacheable-request: 12.0.1 cacheable-request: 12.0.1
decompress-response: 6.0.0 decompress-response: 6.0.0
form-data-encoder: 4.0.2 form-data-encoder: 4.0.2
get-stream: 8.0.1
http2-wrapper: 2.2.1 http2-wrapper: 2.2.1
lowercase-keys: 3.0.0 lowercase-keys: 3.0.0
p-cancelable: 4.0.1 p-cancelable: 4.0.1
responselike: 3.0.0 responselike: 3.0.0
type-fest: 4.25.0
dev: false dev: false
/graceful-fs@4.2.11: /graceful-fs@4.2.11:
@ -2683,19 +2849,6 @@ packages:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
dev: true dev: true
/handlebars@4.7.8:
resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==}
engines: {node: '>=0.4.7'}
hasBin: true
dependencies:
minimist: 1.2.8
neo-async: 2.6.2
source-map: 0.6.1
wordwrap: 1.0.0
optionalDependencies:
uglify-js: 3.17.4
dev: false
/has-bigints@1.0.2: /has-bigints@1.0.2:
resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
dev: true dev: true
@ -3243,8 +3396,16 @@ packages:
brace-expansion: 2.0.1 brace-expansion: 2.0.1
dev: true dev: true
/minimatch@9.0.5:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
brace-expansion: 2.0.1
dev: true
/minimist@1.2.8: /minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
dev: true
/minipass@7.1.2: /minipass@7.1.2:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
@ -3286,10 +3447,6 @@ packages:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true dev: true
/neo-async@2.6.2:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
dev: false
/node-fetch@2.7.0: /node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0} engines: {node: 4.x || >=6.0.0}
@ -3749,6 +3906,12 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/semver@7.6.3:
resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
engines: {node: '>=10'}
hasBin: true
dev: true
/set-function-length@1.2.2: /set-function-length@1.2.2:
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -3821,11 +3984,6 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
dev: false
/source-map@0.8.0-beta.0: /source-map@0.8.0-beta.0:
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@ -4124,6 +4282,11 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true dev: true
/type-fest@4.25.0:
resolution: {integrity: sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==}
engines: {node: '>=16'}
dev: false
/typed-array-buffer@1.0.2: /typed-array-buffer@1.0.2:
resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -4178,14 +4341,6 @@ packages:
resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
dev: true dev: true
/uglify-js@3.17.4:
resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
engines: {node: '>=0.8.0'}
hasBin: true
requiresBuild: true
dev: false
optional: true
/unbox-primitive@1.0.2: /unbox-primitive@1.0.2:
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
dependencies: dependencies:
@ -4439,10 +4594,6 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/wordwrap@1.0.0:
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
dev: false
/wrap-ansi@7.0.0: /wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -4494,15 +4645,16 @@ packages:
engines: {node: '>=12.20'} engines: {node: '>=12.20'}
dev: true dev: true
github.com/DeterminateSystems/detsys-ts/fe64ba33b4bdeec0991bb65ae00420bf68b9954c: github.com/DeterminateSystems/detsys-ts/65dd73c562ac60a068340f8e0c040bdcf2c59afe:
resolution: {tarball: https://codeload.github.com/DeterminateSystems/detsys-ts/tar.gz/fe64ba33b4bdeec0991bb65ae00420bf68b9954c} resolution: {tarball: https://codeload.github.com/DeterminateSystems/detsys-ts/tar.gz/65dd73c562ac60a068340f8e0c040bdcf2c59afe}
name: detsys-ts name: detsys-ts
version: 1.0.0 version: 1.0.0
dependencies: dependencies:
'@actions/cache': 3.2.4 '@actions/cache': 3.2.4
'@actions/core': 1.10.1 '@actions/core': 1.10.1
'@actions/exec': 1.1.1 '@actions/exec': 1.1.1
got: 14.3.0 got: 14.4.2
type-fest: 4.25.0
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
dev: false dev: false

View File

@ -1,26 +1,15 @@
import { makeNixCommandArgs } from "./nix.js"; import { makeNixCommandArgs } from "./nix.js";
import { renderCommitMessage, renderPullRequestBody } from "./template.js";
import * as actionsCore from "@actions/core"; import * as actionsCore from "@actions/core";
import * as actionsExec from "@actions/exec"; import * as actionsExec from "@actions/exec";
import { DetSysAction, inputs } from "detsys-ts"; import { DetSysAction, inputs } from "detsys-ts";
import * as fs from "fs";
const DEFAULT_FLAKE_DIR = ".";
const PR_BODY_OUTPUT_KEY = "pr-body";
const EVENT_EXECUTION_FAILURE = "execution_failure"; const EVENT_EXECUTION_FAILURE = "execution_failure";
class UpdateFlakeLockAction extends DetSysAction { class UpdateFlakeLockAction extends DetSysAction {
private commitMessage: string; private commitMessage: string;
private commitMessageTemplate: string;
private prBody: string;
private prBodyTemplate: string;
private nixOptions: string[]; private nixOptions: string[];
private flakeInputs: string[]; private flakeInputs: string[];
private pathToFlakeDir: string | null; private pathToFlakeDir: string | null;
private flakeDirsInput: string[] | null;
private flakeDirs: string[];
constructor() { constructor() {
super({ super({
@ -30,55 +19,19 @@ class UpdateFlakeLockAction extends DetSysAction {
}); });
this.commitMessage = inputs.getString("commit-msg"); this.commitMessage = inputs.getString("commit-msg");
this.commitMessageTemplate = inputs.getString("commit-msg-template");
this.prBody = inputs.getString("pr-body");
this.prBodyTemplate = inputs.getString("pr-body-template");
this.flakeInputs = inputs.getArrayOfStrings("inputs", "space"); this.flakeInputs = inputs.getArrayOfStrings("inputs", "space");
this.nixOptions = inputs.getArrayOfStrings("nix-options", "space"); this.nixOptions = inputs.getArrayOfStrings("nix-options", "space");
this.pathToFlakeDir = inputs.getStringOrNull("path-to-flake-dir"); this.pathToFlakeDir = inputs.getStringOrNull("path-to-flake-dir");
this.flakeDirsInput = inputs.getArrayOfStringsOrNull("flake-dirs", "space");
this.validateInputs();
if (this.flakeDirsInput !== null && this.flakeDirsInput.length > 0) {
this.flakeDirs = this.flakeDirsInput;
} else {
this.flakeDirs = [this.pathToFlakeDir ?? DEFAULT_FLAKE_DIR];
}
} }
async main(): Promise<void> { async main(): Promise<void> {
for (const directory of this.flakeDirs) { await this.update();
await this.updateFlakeInDirectory(directory);
}
const prBody =
this.prBody !== ""
? this.prBody
: renderPullRequestBody(this.prBodyTemplate, this.flakeDirs);
actionsCore.setOutput(PR_BODY_OUTPUT_KEY, prBody);
} }
// No post phase // No post phase
async post(): Promise<void> {} async post(): Promise<void> {}
private async updateFlakeInDirectory(flakeDir: string): Promise<void> { async update(): Promise<void> {
this.ensureDirectoryExists(flakeDir);
this.ensureDirectoryIsFlake(flakeDir);
actionsCore.debug(`Running flake lock update in directory \`${flakeDir}\``);
const flakeDotLock = `${flakeDir}/flake.lock`;
const commitMessage =
this.commitMessage !== ""
? this.commitMessage
: renderCommitMessage(
this.commitMessageTemplate,
flakeDir,
flakeDotLock,
);
// Nix command of this form: // Nix command of this form:
// nix ${maybe nix options} flake ${"update" or "lock"} ${maybe --update-input flags} --commit-lock-file --commit-lockfile-summary ${commit message} // nix ${maybe nix options} flake ${"update" or "lock"} ${maybe --update-input flags} --commit-lock-file --commit-lockfile-summary ${commit message}
// Example commands: // Example commands:
@ -87,12 +40,11 @@ class UpdateFlakeLockAction extends DetSysAction {
const nixCommandArgs: string[] = makeNixCommandArgs( const nixCommandArgs: string[] = makeNixCommandArgs(
this.nixOptions, this.nixOptions,
this.flakeInputs, this.flakeInputs,
commitMessage, this.commitMessage,
); );
actionsCore.debug( actionsCore.debug(
JSON.stringify({ JSON.stringify({
directory: flakeDir,
options: this.nixOptions, options: this.nixOptions,
inputs: this.flakeInputs, inputs: this.flakeInputs,
message: this.commitMessage, message: this.commitMessage,
@ -101,7 +53,7 @@ class UpdateFlakeLockAction extends DetSysAction {
); );
const execOptions: actionsExec.ExecOptions = { const execOptions: actionsExec.ExecOptions = {
cwd: flakeDir, cwd: this.pathToFlakeDir !== null ? this.pathToFlakeDir : undefined,
}; };
const exitCode = await actionsExec.exec("nix", nixCommandArgs, execOptions); const exitCode = await actionsExec.exec("nix", nixCommandArgs, execOptions);
@ -110,69 +62,9 @@ class UpdateFlakeLockAction extends DetSysAction {
this.recordEvent(EVENT_EXECUTION_FAILURE, { this.recordEvent(EVENT_EXECUTION_FAILURE, {
exitCode, exitCode,
}); });
actionsCore.setFailed( actionsCore.setFailed(`non-zero exit code of ${exitCode} detected`);
`non-zero exit code of ${exitCode} detected while updating directory \`${flakeDir}\``,
);
} else { } else {
actionsCore.info( actionsCore.info(`flake.lock file was successfully updated`);
`flake.lock file in \`${flakeDir}\` was successfully updated`,
);
}
}
private validateInputs(): void {
// Ensure that either `path-to-flake-dir` or `flake-dirs` is set to a meaningful value but not both
if (
this.flakeDirsInput !== null &&
this.flakeDirsInput.length > 0 &&
this.pathToFlakeDir !== null &&
this.pathToFlakeDir !== ""
) {
throw new Error(
"Both `path-to-flake-dir` and `flake-dirs` are set, whereas only one can be",
);
}
// Ensure that `flake-dirs` isn't an empty array if set
if (this.flakeDirsInput !== null && this.flakeDirsInput.length === 0) {
throw new Error(
"The `flake-dirs` input is set to an empty array; it must contain at least one directory",
);
}
// Ensure that both `flake-dirs` and `inputs` aren't set at the same time
if (
this.flakeDirsInput !== null &&
this.flakeDirsInput.length > 0 &&
this.flakeInputs.length > 0
) {
throw new Error(
`You've set both \`flake-dirs\` and \`inputs\` but you can only set one`,
);
}
}
private ensureDirectoryExists(flakeDir: string): void {
actionsCore.debug(`Checking that flake directory \`${flakeDir}\` exists`);
// Ensure the directory exists
fs.access(flakeDir, fs.constants.F_OK, (err) => {
if (err !== null) {
throw new Error(`Directory \`${flakeDir}\` doesn't exist`);
} else {
actionsCore.debug(`Flake directory \`${flakeDir}\` exists`);
}
});
}
private ensureDirectoryIsFlake(flakeDir: string): void {
const flakeDotNix = `${flakeDir}/flake.nix`;
if (!fs.existsSync(flakeDotNix)) {
throw new Error(
`Directory \`${flakeDir}\` is not a valid flake as it doesn't contain a \`flake.nix\``,
);
} else {
actionsCore.debug(`Directory \`${flakeDir}\` is a valid flake`);
} }
} }
} }

View File

@ -1,16 +1,16 @@
import { makeNixCommandArgs } from "./nix.js"; import { makeNixCommandArgs } from "./nix.js";
import { expect, test } from "vitest"; import { expect, test } from "vitest";
test("Nix command arguments", () => { type TestCase = {
type TestCase = {
inputs: { inputs: {
nixOptions: string[]; nixOptions: string[];
flakeInputs: string[]; flakeInputs: string[];
commitMessage: string; commitMessage: string;
}; };
expected: string[]; expected: string[];
}; };
test("Nix command arguments", () => {
const testCases: TestCase[] = [ const testCases: TestCase[] = [
{ {
inputs: { inputs: {
@ -24,7 +24,8 @@ test("Nix command arguments", () => {
"flake", "flake",
"update", "update",
"--commit-lock-file", "--commit-lock-file",
"--commit-lockfile-summary", "--option",
"commit-lockfile-summary",
"just testing", "just testing",
], ],
}, },
@ -42,7 +43,8 @@ test("Nix command arguments", () => {
"--update-input", "--update-input",
"rust-overlay", "rust-overlay",
"--commit-lock-file", "--commit-lock-file",
"--commit-lockfile-summary", "--option",
"commit-lockfile-summary",
"just testing", "just testing",
], ],
}, },
@ -57,7 +59,8 @@ test("Nix command arguments", () => {
"flake", "flake",
"update", "update",
"--commit-lock-file", "--commit-lock-file",
"--commit-lockfile-summary", "--option",
"commit-lockfile-summary",
"just testing", "just testing",
], ],
}, },

View File

@ -9,10 +9,23 @@ export function makeNixCommandArgs(
input, input,
]); ]);
// NOTE(cole-h): In Nix versions 2.23.0 and later, `commit-lockfile-summary` became an alias to
// the setting `commit-lock-file-summary` (https://github.com/NixOS/nix/pull/10691), and Nix does
// not treat aliases the same as their "real" setting by requiring setting aliases to be
// configured via `--option <alias name> <option value>`
// (https://github.com/NixOS/nix/issues/10989).
// So, we go the long way so that we can support versions both before and after Nix 2.23.0.
const lockfileSummaryFlags = [
"--option",
"commit-lockfile-summary",
commitMessage,
];
const updateLockMechanism = flakeInputFlags.length === 0 ? "update" : "lock"; const updateLockMechanism = flakeInputFlags.length === 0 ? "update" : "lock";
return nixOptions return nixOptions
.concat(["flake", updateLockMechanism]) .concat(["flake", updateLockMechanism])
.concat(flakeInputFlags) .concat(flakeInputFlags)
.concat(["--commit-lock-file", "--commit-lockfile-summary", commitMessage]); .concat(["--commit-lock-file"])
.concat(lockfileSummaryFlags);
} }

View File

@ -1,75 +0,0 @@
import { renderCommitMessage, renderPullRequestBody } from "./template.js";
import { template } from "handlebars";
import { Test, describe, expect, test } from "vitest";
describe("templating", () => {
test("commit message", () => {
type TestCase = {
template: string;
flakeDotLockDir: string;
flakeDotLock: string;
expected: string;
};
const testCases: TestCase[] = [
{
template: "Updating flake.lock in dir {{ flake_dot_lock_dir }}",
flakeDotLockDir: ".",
flakeDotLock: "./flake.lock",
expected: "Updating flake.lock in dir .",
},
{
template:
"Here I go doing some updating of my pristine flake.lock at {{ flake_dot_lock }}",
flakeDotLockDir: "subflake",
flakeDotLock: "subflake/flake.lock",
expected:
"Here I go doing some updating of my pristine flake.lock at subflake/flake.lock",
},
{
template: "This variable doesn't exist: {{ foo }}",
flakeDotLockDir: ".",
flakeDotLock: "./flake.lock",
expected: "This variable doesn't exist: ",
},
];
testCases.forEach(
({ template, flakeDotLockDir, flakeDotLock, expected }) => {
expect(
renderCommitMessage(template, flakeDotLockDir, flakeDotLock),
).toEqual(expected);
},
);
});
test("pull request body", () => {
type TestCase = {
template: string;
dirs: string[];
expected: string;
};
const testCases: TestCase[] = [
{
template: "Updated inputs: {{ comma_separated_dirs }}",
dirs: ["."],
expected: "Updated inputs: .",
},
{
template: "Updated inputs: {{ space_separated_dirs }}",
dirs: ["subflake", "subflake2"],
expected: "Updated inputs: subflake subflake2",
},
{
template: "Updated inputs:\n{{ updated_dirs_list }}",
dirs: ["flake1", "flake2"],
expected: `Updated inputs:\n* flake1\n* flake2`,
},
];
testCases.forEach(({ template, dirs, expected }) => {
expect(renderPullRequestBody(template, dirs)).toEqual(expected);
});
});
});

View File

@ -1,39 +0,0 @@
import Handlebars from "handlebars";
export function renderPullRequestBody(
template: string,
dirs: string[],
): string {
const commaSeparated = dirs.join(", ");
const spaceSeparated = dirs.join(" ");
const dirsList = dirs.map((d: string) => `* ${d}`).join("\n");
const tpl = Handlebars.compile(template);
return tpl({
// eslint-disable-next-line camelcase
comma_separated_dirs: commaSeparated,
// eslint-disable-next-line camelcase
space_separated_dirs: spaceSeparated,
// eslint-disable-next-line camelcase
updated_dirs_list: dirsList,
});
}
export function renderCommitMessage(
template: string,
flakeDotLockDir: string,
flakeDotLock: string,
): string {
return render(template, {
// eslint-disable-next-line camelcase
flake_dot_lock_dir: flakeDotLockDir,
// eslint-disable-next-line camelcase
flake_dot_lock: flakeDotLock,
});
}
function render(template: string, inputs: Record<string, string>): string {
const tpl = Handlebars.compile(template);
return tpl(inputs);
}