mirror of
https://github.com/actions/runner.git
synced 2026-03-22 02:54:01 +08:00
Compare commits
18 Commits
rentziass/
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4259ffb6dc | ||
|
|
4e8e1ff020 | ||
|
|
b6cca8fb99 | ||
|
|
18d0789c74 | ||
|
|
c985a9ff03 | ||
|
|
45ed15ddf3 | ||
|
|
c5dcf59d26 | ||
|
|
c7f6c49ba0 | ||
|
|
40dd583def | ||
|
|
68f2e9adb7 | ||
|
|
2b98d42113 | ||
|
|
ce8ce410b0 | ||
|
|
5310e90af2 | ||
|
|
98323280e8 | ||
|
|
5ef3270368 | ||
|
|
1138dd80f7 | ||
|
|
99910ca83e | ||
|
|
bcd04cfbf0 |
@@ -4,7 +4,7 @@
|
|||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
|
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
|
||||||
"ghcr.io/devcontainers/features/dotnet": {
|
"ghcr.io/devcontainers/features/dotnet": {
|
||||||
"version": "8.0.418"
|
"version": "8.0.419"
|
||||||
},
|
},
|
||||||
"ghcr.io/devcontainers/features/node:1": {
|
"ghcr.io/devcontainers/features/node:1": {
|
||||||
"version": "20"
|
"version": "20"
|
||||||
|
|||||||
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -78,7 +78,7 @@ jobs:
|
|||||||
# Upload runner package tar.gz/zip as artifact
|
# Upload runner package tar.gz/zip as artifact
|
||||||
- name: Publish Artifact
|
- name: Publish Artifact
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: runner-package-${{ matrix.runtime }}
|
name: runner-package-${{ matrix.runtime }}
|
||||||
path: |
|
path: |
|
||||||
@@ -111,10 +111,10 @@ jobs:
|
|||||||
core.setOutput('version', version);
|
core.setOutput('version', version);
|
||||||
|
|
||||||
- name: Setup Docker buildx
|
- name: Setup Docker buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v4
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v7
|
||||||
with:
|
with:
|
||||||
context: ./images
|
context: ./images
|
||||||
load: true
|
load: true
|
||||||
|
|||||||
8
.github/workflows/docker-publish.yml
vendored
8
.github/workflows/docker-publish.yml
vendored
@@ -38,10 +38,10 @@ jobs:
|
|||||||
core.setOutput('version', runnerVersion);
|
core.setOutput('version', runnerVersion);
|
||||||
|
|
||||||
- name: Setup Docker buildx
|
- name: Setup Docker buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v4
|
||||||
|
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
- name: Log into registry ${{ env.REGISTRY }}
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
id: build-and-push
|
id: build-and-push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v7
|
||||||
with:
|
with:
|
||||||
context: ./images
|
context: ./images
|
||||||
platforms: |
|
platforms: |
|
||||||
@@ -68,7 +68,7 @@ jobs:
|
|||||||
org.opencontainers.image.description=https://github.com/actions/runner/releases/tag/v${{ steps.image.outputs.version }}
|
org.opencontainers.image.description=https://github.com/actions/runner/releases/tag/v${{ steps.image.outputs.version }}
|
||||||
|
|
||||||
- name: Generate attestation
|
- name: Generate attestation
|
||||||
uses: actions/attest-build-provenance@v3
|
uses: actions/attest-build-provenance@v4
|
||||||
with:
|
with:
|
||||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
||||||
|
|||||||
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@@ -118,7 +118,7 @@ jobs:
|
|||||||
# Upload runner package tar.gz/zip as artifact.
|
# Upload runner package tar.gz/zip as artifact.
|
||||||
- name: Publish Artifact
|
- name: Publish Artifact
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: runner-packages-${{ matrix.runtime }}
|
name: runner-packages-${{ matrix.runtime }}
|
||||||
path: |
|
path: |
|
||||||
@@ -309,10 +309,10 @@ jobs:
|
|||||||
core.setOutput('version', runnerVersion);
|
core.setOutput('version', runnerVersion);
|
||||||
|
|
||||||
- name: Setup Docker buildx
|
- name: Setup Docker buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v4
|
||||||
|
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
- name: Log into registry ${{ env.REGISTRY }}
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@@ -320,7 +320,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
id: build-and-push
|
id: build-and-push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v7
|
||||||
with:
|
with:
|
||||||
context: ./images
|
context: ./images
|
||||||
platforms: |
|
platforms: |
|
||||||
@@ -339,7 +339,7 @@ jobs:
|
|||||||
org.opencontainers.image.description=https://github.com/actions/runner/releases/tag/v${{ steps.image.outputs.version }}
|
org.opencontainers.image.description=https://github.com/actions/runner/releases/tag/v${{ steps.image.outputs.version }}
|
||||||
|
|
||||||
- name: Generate attestation
|
- name: Generate attestation
|
||||||
uses: actions/attest-build-provenance@v3
|
uses: actions/attest-build-provenance@v4
|
||||||
with:
|
with:
|
||||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ ARG TARGETOS
|
|||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
ARG RUNNER_VERSION
|
ARG RUNNER_VERSION
|
||||||
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.7.0
|
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.7.0
|
||||||
ARG DOCKER_VERSION=29.2.0
|
ARG DOCKER_VERSION=29.3.0
|
||||||
ARG BUILDX_VERSION=0.31.1
|
ARG BUILDX_VERSION=0.32.1
|
||||||
|
|
||||||
RUN apt update -y && apt install curl unzip -y
|
RUN apt update -y && apt install curl unzip -y
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,33 @@
|
|||||||
## What's Changed
|
## What's Changed
|
||||||
* chore: update Node versions by @github-actions[bot] in https://github.com/actions/runner/pull/4200
|
* Log inner exception message. by @TingluoHuang in https://github.com/actions/runner/pull/4265
|
||||||
* Update dotnet sdk to latest version @8.0.417 by @github-actions[bot] in https://github.com/actions/runner/pull/4201
|
* Fix composite post-step marker display names by @ericsciple in https://github.com/actions/runner/pull/4267
|
||||||
* Bump System.Formats.Asn1 and System.Security.Cryptography.Pkcs by @dependabot[bot] in https://github.com/actions/runner/pull/4202
|
* Bump actions/download-artifact from 7 to 8 by @dependabot[bot] in https://github.com/actions/runner/pull/4269
|
||||||
* Allow empty container options by @ericsciple in https://github.com/actions/runner/pull/4208
|
* chore: update Node versions by @github-actions[bot] in https://github.com/actions/runner/pull/4272
|
||||||
* Update Docker to v29.1.5 and Buildx to v0.31.0 by @github-actions[bot] in https://github.com/actions/runner/pull/4212
|
* Avoid throw in SelfUpdaters. by @TingluoHuang in https://github.com/actions/runner/pull/4274
|
||||||
* Report job level annotations by @TingluoHuang in https://github.com/actions/runner/pull/4216
|
* Fix parser comparison mismatches by @ericsciple in https://github.com/actions/runner/pull/4273
|
||||||
* Fix local action display name showing `Run /./` instead of `Run ./` by @ericsciple in https://github.com/actions/runner/pull/4218
|
* Devcontainer: bump base image Ubuntu version by @MaxHorstmann in https://github.com/actions/runner/pull/4277
|
||||||
* Update Docker to v29.2.0 and Buildx to v0.31.1 by @github-actions[bot] in https://github.com/actions/runner/pull/4219
|
* Support `entrypoint` and `command` for service containers by @ericsciple in https://github.com/actions/runner/pull/4276
|
||||||
* Add support for libssl3 and libssl3t64 for newer Debian/Ubuntu versions by @nekketsuuu in https://github.com/actions/runner/pull/4213
|
* Bump actions/upload-artifact from 6 to 7 by @dependabot[bot] in https://github.com/actions/runner/pull/4270
|
||||||
* Validate work dir during runner start up. by @TingluoHuang in https://github.com/actions/runner/pull/4227
|
* Bump docker/login-action from 3 to 4 by @dependabot[bot] in https://github.com/actions/runner/pull/4278
|
||||||
* Bump hook to 0.8.1 by @nikola-jokic in https://github.com/actions/runner/pull/4222
|
* Fix positional arg bug in ExpressionParser.CreateTree by @ericsciple in https://github.com/actions/runner/pull/4279
|
||||||
* Support return job result as exitcode in hosted runner. by @TingluoHuang in https://github.com/actions/runner/pull/4233
|
* Bump docker/build-push-action from 6 to 7 by @dependabot[bot] in https://github.com/actions/runner/pull/4283
|
||||||
* Add telemetry tracking for deprecated set-output and save-state commands by @ericsciple in https://github.com/actions/runner/pull/4221
|
* Bump docker/setup-buildx-action from 3 to 4 by @dependabot[bot] in https://github.com/actions/runner/pull/4282
|
||||||
* Fix parser comparison mismatches by @ericsciple in https://github.com/actions/runner/pull/4220
|
* Bump actions/attest-build-provenance from 3 to 4 by @dependabot[bot] in https://github.com/actions/runner/pull/4266
|
||||||
* Remove unnecessary connection test during some registration flows by @zarenner in https://github.com/actions/runner/pull/4244
|
* Bump @stylistic/eslint-plugin from 5.9.0 to 5.10.0 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/4281
|
||||||
* chore: update Node versions by @github-actions[bot] in https://github.com/actions/runner/pull/4249
|
* Update Docker to v29.3.0 and Buildx to v0.32.1 by @github-actions[bot] in https://github.com/actions/runner/pull/4286
|
||||||
* Update dotnet sdk to latest version @8.0.418 by @github-actions[bot] in https://github.com/actions/runner/pull/4250
|
* chore: update Node versions by @github-actions[bot] in https://github.com/actions/runner/pull/4287
|
||||||
* Fix link to SECURITY.md in README by @TingluoHuang in https://github.com/actions/runner/pull/4253
|
* Fix cancellation token race during parser comparison by @ericsciple in https://github.com/actions/runner/pull/4280
|
||||||
* Try to infer runner is on hosted/ghes when githuburl is empty. by @TingluoHuang in https://github.com/actions/runner/pull/4254
|
* Bump @typescript-eslint/eslint-plugin from 8.47.0 to 8.54.0 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/4230
|
||||||
* Add Node.js 20 deprecation warning annotation (Phase 1) by @salmanmkc in https://github.com/actions/runner/pull/4242
|
* Exit with specified exit code when runner is outdated by @nikola-jokic in https://github.com/actions/runner/pull/4285
|
||||||
* Update Node.js 20 deprecation date to June 2nd, 2026 by @salmanmkc in https://github.com/actions/runner/pull/4258
|
* Report infra_error for action download failures. by @TingluoHuang in https://github.com/actions/runner/pull/4294
|
||||||
* Composite Action Step Markers by @ericsciple in https://github.com/actions/runner/pull/4243
|
* Update dotnet sdk to latest version @8.0.419 by @github-actions[bot] in https://github.com/actions/runner/pull/4301
|
||||||
* Symlink actions cache by @paveliak in https://github.com/actions/runner/pull/4260
|
* Node 24 enforcement + Linux ARM32 deprecation support by @salmanmkc in https://github.com/actions/runner/pull/4303
|
||||||
* Bump minimatch in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/4261
|
* Bump @typescript-eslint/eslint-plugin from 8.54.0 to 8.57.1 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/4304
|
||||||
* Bump @stylistic/eslint-plugin from 3.1.0 to 5.9.0 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/4257
|
|
||||||
|
|
||||||
## New Contributors
|
## New Contributors
|
||||||
* @nekketsuuu made their first contribution in https://github.com/actions/runner/pull/4213
|
* @MaxHorstmann made their first contribution in https://github.com/actions/runner/pull/4277
|
||||||
* @zarenner made their first contribution in https://github.com/actions/runner/pull/4244
|
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/actions/runner/compare/v2.331.0...v2.332.0
|
**Full Changelog**: https://github.com/actions/runner/compare/v2.332.0...v2.333.0
|
||||||
|
|
||||||
_Note: Actions Runner follows a progressive release policy, so the latest release might not be available to your enterprise, organization, or repository yet.
|
_Note: Actions Runner follows a progressive release policy, so the latest release might not be available to your enterprise, organization, or repository yet.
|
||||||
To confirm which version of the Actions Runner you should expect, please view the download instructions for your enterprise, organization, or repository.
|
To confirm which version of the Actions Runner you should expect, please view the download instructions for your enterprise, organization, or repository.
|
||||||
|
|||||||
526
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
526
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
@@ -12,9 +12,9 @@
|
|||||||
"@actions/glob": "^0.4.0"
|
"@actions/glob": "^0.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@stylistic/eslint-plugin": "^5.9.0",
|
"@stylistic/eslint-plugin": "^5.10.0",
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
"@typescript-eslint/eslint-plugin": "^8.57.1",
|
||||||
"@typescript-eslint/parser": "^8.0.0",
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
"@vercel/ncc": "^0.38.3",
|
"@vercel/ncc": "^0.38.3",
|
||||||
"eslint": "^8.47.0",
|
"eslint": "^8.47.0",
|
||||||
@@ -93,9 +93,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-community/regexpp": {
|
"node_modules/@eslint-community/regexpp": {
|
||||||
"version": "4.10.0",
|
"version": "4.12.2",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
|
||||||
"integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
|
"integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||||
@@ -228,9 +228,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@stylistic/eslint-plugin": {
|
"node_modules/@stylistic/eslint-plugin": {
|
||||||
"version": "5.9.0",
|
"version": "5.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz",
|
||||||
"integrity": "sha512-FqqSkvDMYJReydrMhlugc71M76yLLQWNfmGq+SIlLa7N3kHp8Qq8i2PyWrVNAfjOyOIY+xv9XaaYwvVW7vroMA==",
|
"integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.9.1",
|
"@eslint-community/eslint-utils": "^4.9.1",
|
||||||
@@ -247,19 +247,6 @@
|
|||||||
"eslint": "^9.0.0 || ^10.0.0"
|
"eslint": "^9.0.0 || ^10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/types": {
|
|
||||||
"version": "8.56.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz",
|
|
||||||
"integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": {
|
"node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
||||||
@@ -321,21 +308,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz",
|
||||||
"integrity": "sha512-fe0rz9WJQ5t2iaLfdbDc9T80GJy0AeO453q8C3YCilnGozvOyCG5t+EZtg7j7D88+c3FipfP/x+wzGnh1xp8ZA==",
|
"integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.12.2",
|
||||||
"@typescript-eslint/scope-manager": "8.47.0",
|
"@typescript-eslint/scope-manager": "8.57.1",
|
||||||
"@typescript-eslint/type-utils": "8.47.0",
|
"@typescript-eslint/type-utils": "8.57.1",
|
||||||
"@typescript-eslint/utils": "8.47.0",
|
"@typescript-eslint/utils": "8.57.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.47.0",
|
"@typescript-eslint/visitor-keys": "8.57.1",
|
||||||
"graphemer": "^1.4.0",
|
"ignore": "^7.0.5",
|
||||||
"ignore": "^7.0.0",
|
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"ts-api-utils": "^2.1.0"
|
"ts-api-utils": "^2.4.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -345,8 +330,8 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/parser": "^8.47.0",
|
"@typescript-eslint/parser": "^8.57.1",
|
||||||
"eslint": "^8.57.0 || ^9.0.0",
|
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||||
"typescript": ">=4.8.4 <6.0.0"
|
"typescript": ">=4.8.4 <6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -361,11 +346,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/ts-api-utils": {
|
"node_modules/@typescript-eslint/eslint-plugin/node_modules/ts-api-utils": {
|
||||||
"version": "2.1.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
|
||||||
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
|
"integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.12"
|
"node": ">=18.12"
|
||||||
},
|
},
|
||||||
@@ -374,17 +358,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz",
|
||||||
"integrity": "sha512-lJi3PfxVmo0AkEY93ecfN+r8SofEqZNGByvHAI3GBLrvt1Cw6H5k1IM02nSzu0RfUafr2EvFSw0wAsZgubNplQ==",
|
"integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.47.0",
|
"@typescript-eslint/scope-manager": "8.57.1",
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.47.0",
|
"@typescript-eslint/typescript-estree": "8.57.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.47.0",
|
"@typescript-eslint/visitor-keys": "8.57.1",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.4.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -394,20 +377,19 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^8.57.0 || ^9.0.0",
|
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||||
"typescript": ">=4.8.4 <6.0.0"
|
"typescript": ">=4.8.4 <6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/project-service": {
|
"node_modules/@typescript-eslint/project-service": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz",
|
||||||
"integrity": "sha512-2X4BX8hUeB5JcA1TQJ7GjcgulXQ+5UkNb0DL8gHsHUHdFoiCTJoYLTpib3LtSDPZsRET5ygN4qqIWrHyYIKERA==",
|
"integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/tsconfig-utils": "^8.47.0",
|
"@typescript-eslint/tsconfig-utils": "^8.57.1",
|
||||||
"@typescript-eslint/types": "^8.47.0",
|
"@typescript-eslint/types": "^8.57.1",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.4.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -421,14 +403,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz",
|
||||||
"integrity": "sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg==",
|
"integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.47.0"
|
"@typescript-eslint/visitor-keys": "8.57.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -439,11 +420,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/tsconfig-utils": {
|
"node_modules/@typescript-eslint/tsconfig-utils": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz",
|
||||||
"integrity": "sha512-ybUAvjy4ZCL11uryalkKxuT3w3sXJAuWhOoGS3T/Wu+iUu1tGJmk5ytSY8gbdACNARmcYEB0COksD2j6hfGK2g==",
|
"integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
@@ -456,17 +436,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz",
|
||||||
"integrity": "sha512-QC9RiCmZ2HmIdCEvhd1aJELBlD93ErziOXXlHEZyuBo3tBiAZieya0HLIxp+DoDWlsQqDawyKuNEhORyku+P8A==",
|
"integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.47.0",
|
"@typescript-eslint/typescript-estree": "8.57.1",
|
||||||
"@typescript-eslint/utils": "8.47.0",
|
"@typescript-eslint/utils": "8.57.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.4.3",
|
||||||
"ts-api-utils": "^2.1.0"
|
"ts-api-utils": "^2.4.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -476,16 +455,15 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^8.57.0 || ^9.0.0",
|
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||||
"typescript": ">=4.8.4 <6.0.0"
|
"typescript": ">=4.8.4 <6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils/node_modules/ts-api-utils": {
|
"node_modules/@typescript-eslint/type-utils/node_modules/ts-api-utils": {
|
||||||
"version": "2.1.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
|
||||||
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
|
"integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.12"
|
"node": ">=18.12"
|
||||||
},
|
},
|
||||||
@@ -494,11 +472,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz",
|
||||||
"integrity": "sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A==",
|
"integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
@@ -508,22 +485,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz",
|
||||||
"integrity": "sha512-k6ti9UepJf5NpzCjH31hQNLHQWupTRPhZ+KFF8WtTuTpy7uHPfeg2NM7cP27aCGajoEplxJDFVCEm9TGPYyiVg==",
|
"integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/project-service": "8.47.0",
|
"@typescript-eslint/project-service": "8.57.1",
|
||||||
"@typescript-eslint/tsconfig-utils": "8.47.0",
|
"@typescript-eslint/tsconfig-utils": "8.57.1",
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.47.0",
|
"@typescript-eslint/visitor-keys": "8.57.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.4.3",
|
||||||
"fast-glob": "^3.3.2",
|
"minimatch": "^10.2.2",
|
||||||
"is-glob": "^4.0.3",
|
"semver": "^7.7.3",
|
||||||
"minimatch": "^9.0.4",
|
"tinyglobby": "^0.2.15",
|
||||||
"semver": "^7.6.0",
|
"ts-api-utils": "^2.4.0"
|
||||||
"ts-api-utils": "^2.1.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -546,9 +521,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
||||||
"version": "5.0.3",
|
"version": "5.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
|
||||||
"integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==",
|
"integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^4.0.2"
|
"balanced-match": "^4.0.2"
|
||||||
@@ -558,26 +533,25 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||||
"version": "9.0.7",
|
"version": "10.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
|
||||||
"integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==",
|
"integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^5.0.2"
|
"brace-expansion": "^5.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16 || 14 >=14.17"
|
"node": "18 || 20 || >=22"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/ts-api-utils": {
|
"node_modules/@typescript-eslint/typescript-estree/node_modules/ts-api-utils": {
|
||||||
"version": "2.1.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
|
||||||
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
|
"integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.12"
|
"node": ">=18.12"
|
||||||
},
|
},
|
||||||
@@ -586,16 +560,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz",
|
||||||
"integrity": "sha512-g7XrNf25iL4TJOiPqatNuaChyqt49a/onq5YsJ9+hXeugK+41LVg7AxikMfM02PC6jbNtZLCJj6AUcQXJS/jGQ==",
|
"integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.7.0",
|
"@eslint-community/eslint-utils": "^4.9.1",
|
||||||
"@typescript-eslint/scope-manager": "8.47.0",
|
"@typescript-eslint/scope-manager": "8.57.1",
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.47.0"
|
"@typescript-eslint/typescript-estree": "8.57.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -605,19 +578,18 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^8.57.0 || ^9.0.0",
|
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||||
"typescript": ">=4.8.4 <6.0.0"
|
"typescript": ">=4.8.4 <6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz",
|
||||||
"integrity": "sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==",
|
"integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"eslint-visitor-keys": "^4.2.1"
|
"eslint-visitor-keys": "^5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -628,13 +600,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
|
||||||
"version": "4.2.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
|
||||||
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
|
"integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
@@ -1150,11 +1121,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "^2.1.3"
|
"ms": "^2.1.3"
|
||||||
},
|
},
|
||||||
@@ -2217,9 +2187,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flatted": {
|
"node_modules/flatted": {
|
||||||
"version": "3.2.7",
|
"version": "3.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||||
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/for-each": {
|
"node_modules/for-each": {
|
||||||
@@ -4019,9 +3989,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.6.2",
|
"version": "7.7.4",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -4319,6 +4289,51 @@
|
|||||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/tinyglobby": {
|
||||||
|
"version": "0.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||||
|
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"fdir": "^6.5.0",
|
||||||
|
"picomatch": "^4.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tinyglobby/node_modules/fdir": {
|
||||||
|
"version": "6.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||||
|
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"picomatch": "^3 || ^4"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"picomatch": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tinyglobby/node_modules/picomatch": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/titleize": {
|
"node_modules/titleize": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
|
||||||
@@ -4756,9 +4771,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@eslint-community/regexpp": {
|
"@eslint-community/regexpp": {
|
||||||
"version": "4.10.0",
|
"version": "4.12.2",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
|
||||||
"integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
|
"integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@eslint/eslintrc": {
|
"@eslint/eslintrc": {
|
||||||
@@ -4854,9 +4869,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@stylistic/eslint-plugin": {
|
"@stylistic/eslint-plugin": {
|
||||||
"version": "5.9.0",
|
"version": "5.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz",
|
||||||
"integrity": "sha512-FqqSkvDMYJReydrMhlugc71M76yLLQWNfmGq+SIlLa7N3kHp8Qq8i2PyWrVNAfjOyOIY+xv9XaaYwvVW7vroMA==",
|
"integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@eslint-community/eslint-utils": "^4.9.1",
|
"@eslint-community/eslint-utils": "^4.9.1",
|
||||||
@@ -4867,12 +4882,6 @@
|
|||||||
"picomatch": "^4.0.3"
|
"picomatch": "^4.0.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": {
|
|
||||||
"version": "8.56.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz",
|
|
||||||
"integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"eslint-visitor-keys": {
|
"eslint-visitor-keys": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
||||||
@@ -4914,20 +4923,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/eslint-plugin": {
|
"@typescript-eslint/eslint-plugin": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz",
|
||||||
"integrity": "sha512-fe0rz9WJQ5t2iaLfdbDc9T80GJy0AeO453q8C3YCilnGozvOyCG5t+EZtg7j7D88+c3FipfP/x+wzGnh1xp8ZA==",
|
"integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.12.2",
|
||||||
"@typescript-eslint/scope-manager": "8.47.0",
|
"@typescript-eslint/scope-manager": "8.57.1",
|
||||||
"@typescript-eslint/type-utils": "8.47.0",
|
"@typescript-eslint/type-utils": "8.57.1",
|
||||||
"@typescript-eslint/utils": "8.47.0",
|
"@typescript-eslint/utils": "8.57.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.47.0",
|
"@typescript-eslint/visitor-keys": "8.57.1",
|
||||||
"graphemer": "^1.4.0",
|
"ignore": "^7.0.5",
|
||||||
"ignore": "^7.0.0",
|
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"ts-api-utils": "^2.1.0"
|
"ts-api-utils": "^2.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ignore": {
|
"ignore": {
|
||||||
@@ -4937,99 +4945,98 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ts-api-utils": {
|
"ts-api-utils": {
|
||||||
"version": "2.1.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
|
||||||
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
|
"integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/parser": {
|
"@typescript-eslint/parser": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz",
|
||||||
"integrity": "sha512-lJi3PfxVmo0AkEY93ecfN+r8SofEqZNGByvHAI3GBLrvt1Cw6H5k1IM02nSzu0RfUafr2EvFSw0wAsZgubNplQ==",
|
"integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/scope-manager": "8.47.0",
|
"@typescript-eslint/scope-manager": "8.57.1",
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.47.0",
|
"@typescript-eslint/typescript-estree": "8.57.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.47.0",
|
"@typescript-eslint/visitor-keys": "8.57.1",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.4.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/project-service": {
|
"@typescript-eslint/project-service": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz",
|
||||||
"integrity": "sha512-2X4BX8hUeB5JcA1TQJ7GjcgulXQ+5UkNb0DL8gHsHUHdFoiCTJoYLTpib3LtSDPZsRET5ygN4qqIWrHyYIKERA==",
|
"integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/tsconfig-utils": "^8.47.0",
|
"@typescript-eslint/tsconfig-utils": "^8.57.1",
|
||||||
"@typescript-eslint/types": "^8.47.0",
|
"@typescript-eslint/types": "^8.57.1",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.4.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/scope-manager": {
|
"@typescript-eslint/scope-manager": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz",
|
||||||
"integrity": "sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg==",
|
"integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.47.0"
|
"@typescript-eslint/visitor-keys": "8.57.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/tsconfig-utils": {
|
"@typescript-eslint/tsconfig-utils": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz",
|
||||||
"integrity": "sha512-ybUAvjy4ZCL11uryalkKxuT3w3sXJAuWhOoGS3T/Wu+iUu1tGJmk5ytSY8gbdACNARmcYEB0COksD2j6hfGK2g==",
|
"integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/type-utils": {
|
"@typescript-eslint/type-utils": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz",
|
||||||
"integrity": "sha512-QC9RiCmZ2HmIdCEvhd1aJELBlD93ErziOXXlHEZyuBo3tBiAZieya0HLIxp+DoDWlsQqDawyKuNEhORyku+P8A==",
|
"integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.47.0",
|
"@typescript-eslint/typescript-estree": "8.57.1",
|
||||||
"@typescript-eslint/utils": "8.47.0",
|
"@typescript-eslint/utils": "8.57.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.4.3",
|
||||||
"ts-api-utils": "^2.1.0"
|
"ts-api-utils": "^2.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ts-api-utils": {
|
"ts-api-utils": {
|
||||||
"version": "2.1.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
|
||||||
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
|
"integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/types": {
|
"@typescript-eslint/types": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz",
|
||||||
"integrity": "sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A==",
|
"integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@typescript-eslint/typescript-estree": {
|
"@typescript-eslint/typescript-estree": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz",
|
||||||
"integrity": "sha512-k6ti9UepJf5NpzCjH31hQNLHQWupTRPhZ+KFF8WtTuTpy7uHPfeg2NM7cP27aCGajoEplxJDFVCEm9TGPYyiVg==",
|
"integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/project-service": "8.47.0",
|
"@typescript-eslint/project-service": "8.57.1",
|
||||||
"@typescript-eslint/tsconfig-utils": "8.47.0",
|
"@typescript-eslint/tsconfig-utils": "8.57.1",
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.47.0",
|
"@typescript-eslint/visitor-keys": "8.57.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.4.3",
|
||||||
"fast-glob": "^3.3.2",
|
"minimatch": "^10.2.2",
|
||||||
"is-glob": "^4.0.3",
|
"semver": "^7.7.3",
|
||||||
"minimatch": "^9.0.4",
|
"tinyglobby": "^0.2.15",
|
||||||
"semver": "^7.6.0",
|
"ts-api-utils": "^2.4.0"
|
||||||
"ts-api-utils": "^2.1.0"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
@@ -5039,58 +5046,58 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "5.0.3",
|
"version": "5.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
|
||||||
"integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==",
|
"integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^4.0.2"
|
"balanced-match": "^4.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimatch": {
|
"minimatch": {
|
||||||
"version": "9.0.7",
|
"version": "10.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
|
||||||
"integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==",
|
"integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^5.0.2"
|
"brace-expansion": "^5.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ts-api-utils": {
|
"ts-api-utils": {
|
||||||
"version": "2.1.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
|
||||||
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
|
"integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/utils": {
|
"@typescript-eslint/utils": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz",
|
||||||
"integrity": "sha512-g7XrNf25iL4TJOiPqatNuaChyqt49a/onq5YsJ9+hXeugK+41LVg7AxikMfM02PC6jbNtZLCJj6AUcQXJS/jGQ==",
|
"integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@eslint-community/eslint-utils": "^4.7.0",
|
"@eslint-community/eslint-utils": "^4.9.1",
|
||||||
"@typescript-eslint/scope-manager": "8.47.0",
|
"@typescript-eslint/scope-manager": "8.57.1",
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.47.0"
|
"@typescript-eslint/typescript-estree": "8.57.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/visitor-keys": {
|
"@typescript-eslint/visitor-keys": {
|
||||||
"version": "8.47.0",
|
"version": "8.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz",
|
||||||
"integrity": "sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==",
|
"integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "8.47.0",
|
"@typescript-eslint/types": "8.57.1",
|
||||||
"eslint-visitor-keys": "^4.2.1"
|
"eslint-visitor-keys": "^5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"eslint-visitor-keys": {
|
"eslint-visitor-keys": {
|
||||||
"version": "4.2.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
|
||||||
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
|
"integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5438,9 +5445,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ms": "^2.1.3"
|
"ms": "^2.1.3"
|
||||||
@@ -6191,9 +6198,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flatted": {
|
"flatted": {
|
||||||
"version": "3.2.7",
|
"version": "3.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||||
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"for-each": {
|
"for-each": {
|
||||||
@@ -7389,9 +7396,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "7.6.2",
|
"version": "7.7.4",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"shebang-command": {
|
"shebang-command": {
|
||||||
@@ -7587,6 +7594,31 @@
|
|||||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"tinyglobby": {
|
||||||
|
"version": "0.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||||
|
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fdir": "^6.5.0",
|
||||||
|
"picomatch": "^4.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"fdir": {
|
||||||
|
"version": "6.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||||
|
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
|
"picomatch": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"titleize": {
|
"titleize": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
|
||||||
|
|||||||
@@ -35,9 +35,9 @@
|
|||||||
"@actions/glob": "^0.4.0"
|
"@actions/glob": "^0.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@stylistic/eslint-plugin": "^5.9.0",
|
"@stylistic/eslint-plugin": "^5.10.0",
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
"@typescript-eslint/eslint-plugin": "^8.57.1",
|
||||||
"@typescript-eslint/parser": "^8.0.0",
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
"@vercel/ncc": "^0.38.3",
|
"@vercel/ncc": "^0.38.3",
|
||||||
"eslint": "^8.47.0",
|
"eslint": "^8.47.0",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ NODE_URL=https://nodejs.org/dist
|
|||||||
NODE_ALPINE_URL=https://github.com/actions/alpine_nodejs/releases/download
|
NODE_ALPINE_URL=https://github.com/actions/alpine_nodejs/releases/download
|
||||||
# When you update Node versions you must also create a new release of alpine_nodejs at that updated version.
|
# When you update Node versions you must also create a new release of alpine_nodejs at that updated version.
|
||||||
# Follow the instructions here: https://github.com/actions/alpine_nodejs?tab=readme-ov-file#getting-started
|
# Follow the instructions here: https://github.com/actions/alpine_nodejs?tab=readme-ov-file#getting-started
|
||||||
NODE20_VERSION="20.20.0"
|
NODE20_VERSION="20.20.1"
|
||||||
NODE24_VERSION="24.14.0"
|
NODE24_VERSION="24.14.0"
|
||||||
|
|
||||||
get_abs_path() {
|
get_abs_path() {
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ if %ERRORLEVEL% EQU 0 (
|
|||||||
exit /b 0
|
exit /b 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if "%ACTIONS_RUNNER_RETURN_VERSION_DEPRECATED_EXIT_CODE%"=="1" (
|
||||||
|
if %ERRORLEVEL% EQU 7 (
|
||||||
|
echo "Runner listener exit with deprecated version error code: %ERRORLEVEL%."
|
||||||
|
exit /b %ERRORLEVEL%
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if %ERRORLEVEL% EQU 1 (
|
if %ERRORLEVEL% EQU 1 (
|
||||||
echo "Runner listener exit with terminated error, stop the service, no retry needed."
|
echo "Runner listener exit with terminated error, stop the service, no retry needed."
|
||||||
exit /b 0
|
exit /b 0
|
||||||
|
|||||||
@@ -34,11 +34,13 @@ fi
|
|||||||
|
|
||||||
updateFile="update.finished"
|
updateFile="update.finished"
|
||||||
"$DIR"/bin/Runner.Listener run $*
|
"$DIR"/bin/Runner.Listener run $*
|
||||||
|
|
||||||
returnCode=$?
|
returnCode=$?
|
||||||
if [[ $returnCode == 0 ]]; then
|
if [[ $returnCode == 0 ]]; then
|
||||||
echo "Runner listener exit with 0 return code, stop the service, no retry needed."
|
echo "Runner listener exit with 0 return code, stop the service, no retry needed."
|
||||||
exit 0
|
exit 0
|
||||||
|
elif [[ "$ACTIONS_RUNNER_RETURN_VERSION_DEPRECATED_EXIT_CODE" == "1" && $returnCode -eq 7 ]]; then
|
||||||
|
echo "Runner listener exit with deprecated version exit code: ${returnCode}."
|
||||||
|
exit "$returnCode"
|
||||||
elif [[ $returnCode == 1 ]]; then
|
elif [[ $returnCode == 1 ]]; then
|
||||||
echo "Runner listener exit with terminated error, stop the service, no retry needed."
|
echo "Runner listener exit with terminated error, stop the service, no retry needed."
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -25,7 +25,14 @@ call "%~dp0run-helper.cmd" %*
|
|||||||
if %ERRORLEVEL% EQU 1 (
|
if %ERRORLEVEL% EQU 1 (
|
||||||
echo "Restarting runner..."
|
echo "Restarting runner..."
|
||||||
goto :launch_helper
|
goto :launch_helper
|
||||||
) else (
|
|
||||||
echo "Exiting runner..."
|
|
||||||
exit /b 0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if "%ACTIONS_RUNNER_RETURN_VERSION_DEPRECATED_EXIT_CODE%"=="1" (
|
||||||
|
if %ERRORLEVEL% EQU 7 (
|
||||||
|
echo "Exiting runner with deprecated version error code: %ERRORLEVEL%"
|
||||||
|
exit /b %ERRORLEVEL%
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "Exiting runner..."
|
||||||
|
exit /b 0
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ run() {
|
|||||||
returnCode=$?
|
returnCode=$?
|
||||||
if [[ $returnCode -eq 2 ]]; then
|
if [[ $returnCode -eq 2 ]]; then
|
||||||
echo "Restarting runner..."
|
echo "Restarting runner..."
|
||||||
|
elif [[ "$ACTIONS_RUNNER_RETURN_VERSION_DEPRECATED_EXIT_CODE" == "1" && $returnCode -eq 7 ]]; then
|
||||||
|
echo "Exiting runner..."
|
||||||
|
exit "$returnCode"
|
||||||
else
|
else
|
||||||
echo "Exiting runner..."
|
echo "Exiting runner..."
|
||||||
exit 0
|
exit 0
|
||||||
@@ -42,6 +45,9 @@ runWithManualTrap() {
|
|||||||
returnCode=$?
|
returnCode=$?
|
||||||
if [[ $returnCode -eq 2 ]]; then
|
if [[ $returnCode -eq 2 ]]; then
|
||||||
echo "Restarting runner..."
|
echo "Restarting runner..."
|
||||||
|
elif [[ "$ACTIONS_RUNNER_RETURN_VERSION_DEPRECATED_EXIT_CODE" == "1" && $returnCode -eq 7 ]]; then
|
||||||
|
echo "Exiting runner..."
|
||||||
|
exit "$returnCode"
|
||||||
else
|
else
|
||||||
echo "Exiting runner..."
|
echo "Exiting runner..."
|
||||||
# Unregister signal handling before exit
|
# Unregister signal handling before exit
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ namespace GitHub.Runner.Common
|
|||||||
// and the runner should be restarted. This is a temporary code and will be removed in the future after
|
// and the runner should be restarted. This is a temporary code and will be removed in the future after
|
||||||
// the runner is migrated to runner admin.
|
// the runner is migrated to runner admin.
|
||||||
public const int RunnerConfigurationRefreshed = 6;
|
public const int RunnerConfigurationRefreshed = 6;
|
||||||
|
public const int RunnerVersionDeprecated = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Features
|
public static class Features
|
||||||
@@ -194,8 +195,22 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly string RequireNode24Flag = "actions.runner.requirenode24";
|
public static readonly string RequireNode24Flag = "actions.runner.requirenode24";
|
||||||
public static readonly string WarnOnNode20Flag = "actions.runner.warnonnode20";
|
public static readonly string WarnOnNode20Flag = "actions.runner.warnonnode20";
|
||||||
|
|
||||||
|
// Feature flags for Linux ARM32 deprecation
|
||||||
|
public static readonly string DeprecateLinuxArm32Flag = "actions_runner_deprecate_linux_arm32";
|
||||||
|
public static readonly string KillLinuxArm32Flag = "actions_runner_kill_linux_arm32";
|
||||||
|
|
||||||
// Blog post URL for Node 20 deprecation
|
// Blog post URL for Node 20 deprecation
|
||||||
public static readonly string Node20DeprecationUrl = "https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/";
|
public static readonly string Node20DeprecationUrl = "https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/";
|
||||||
|
|
||||||
|
// Node 20 migration dates (hardcoded fallbacks, can be overridden via job variables)
|
||||||
|
public static readonly string Node24DefaultDate = "June 2nd, 2026";
|
||||||
|
public static readonly string Node20RemovalDate = "September 16th, 2026";
|
||||||
|
|
||||||
|
// Variable keys for server-overridable dates
|
||||||
|
public static readonly string Node24DefaultDateVariable = "actions_runner_node24_default_date";
|
||||||
|
public static readonly string Node20RemovalDateVariable = "actions_runner_node20_removal_date";
|
||||||
|
|
||||||
|
public static readonly string LinuxArm32DeprecationMessage = "Linux ARM32 runners are deprecated and will no longer be supported after {0}. Please migrate to a supported platform.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly string InternalTelemetryIssueDataKey = "_internal_telemetry";
|
public static readonly string InternalTelemetryIssueDataKey = "_internal_telemetry";
|
||||||
@@ -277,6 +292,7 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly string AllowUnsupportedCommands = "ACTIONS_ALLOW_UNSECURE_COMMANDS";
|
public static readonly string AllowUnsupportedCommands = "ACTIONS_ALLOW_UNSECURE_COMMANDS";
|
||||||
public static readonly string AllowUnsupportedStopCommandTokens = "ACTIONS_ALLOW_UNSECURE_STOPCOMMAND_TOKENS";
|
public static readonly string AllowUnsupportedStopCommandTokens = "ACTIONS_ALLOW_UNSECURE_STOPCOMMAND_TOKENS";
|
||||||
public static readonly string RequireJobContainer = "ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER";
|
public static readonly string RequireJobContainer = "ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER";
|
||||||
|
public static readonly string ReturnVersionDeprecatedExitCode = "ACTIONS_RUNNER_RETURN_VERSION_DEPRECATED_EXIT_CODE";
|
||||||
public static readonly string RunnerDebug = "ACTIONS_RUNNER_DEBUG";
|
public static readonly string RunnerDebug = "ACTIONS_RUNNER_DEBUG";
|
||||||
public static readonly string StepDebug = "ACTIONS_STEP_DEBUG";
|
public static readonly string StepDebug = "ACTIONS_STEP_DEBUG";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace GitHub.Runner.Common.Util
|
|||||||
{
|
{
|
||||||
return (Constants.Runner.NodeMigration.Node24, null);
|
return (Constants.Runner.NodeMigration.Node24, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get environment variable details with source information
|
// Get environment variable details with source information
|
||||||
var forceNode24Details = GetEnvironmentVariableDetails(
|
var forceNode24Details = GetEnvironmentVariableDetails(
|
||||||
Constants.Runner.NodeMigration.ForceNode24Variable, workflowEnvironment);
|
Constants.Runner.NodeMigration.ForceNode24Variable, workflowEnvironment);
|
||||||
@@ -108,14 +108,50 @@ namespace GitHub.Runner.Common.Util
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if Node24 is requested but running on ARM32 Linux, and determines if fallback is needed.
|
/// Checks if Node24 is requested but running on ARM32 Linux, and determines if fallback is needed.
|
||||||
|
/// Also handles ARM32 deprecation and kill switch phases.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="preferredVersion">The preferred Node version</param>
|
/// <param name="preferredVersion">The preferred Node version</param>
|
||||||
|
/// <param name="deprecateArm32">Feature flag indicating ARM32 Linux is deprecated</param>
|
||||||
|
/// <param name="killArm32">Feature flag indicating ARM32 Linux should no longer work</param>
|
||||||
/// <returns>A tuple containing the adjusted node version and an optional warning message</returns>
|
/// <returns>A tuple containing the adjusted node version and an optional warning message</returns>
|
||||||
public static (string nodeVersion, string warningMessage) CheckNodeVersionForLinuxArm32(string preferredVersion)
|
public static (string nodeVersion, string warningMessage) CheckNodeVersionForLinuxArm32(
|
||||||
|
string preferredVersion,
|
||||||
|
bool deprecateArm32 = false,
|
||||||
|
bool killArm32 = false,
|
||||||
|
string node20RemovalDate = null)
|
||||||
{
|
{
|
||||||
if (string.Equals(preferredVersion, Constants.Runner.NodeMigration.Node24, StringComparison.OrdinalIgnoreCase) &&
|
bool isArm32Linux = Constants.Runner.PlatformArchitecture.Equals(Constants.Architecture.Arm) &&
|
||||||
Constants.Runner.PlatformArchitecture.Equals(Constants.Architecture.Arm) &&
|
Constants.Runner.Platform.Equals(Constants.OSPlatform.Linux);
|
||||||
Constants.Runner.Platform.Equals(Constants.OSPlatform.Linux))
|
|
||||||
|
if (!isArm32Linux)
|
||||||
|
{
|
||||||
|
return (preferredVersion, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ARM32 kill switch: runner should no longer work on this platform
|
||||||
|
if (killArm32)
|
||||||
|
{
|
||||||
|
return (null, "Linux ARM32 runners are no longer supported. Please migrate to a supported platform.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ARM32 deprecation warning: continue using node20 but warn about upcoming end of support
|
||||||
|
if (deprecateArm32)
|
||||||
|
{
|
||||||
|
string effectiveDate = string.IsNullOrEmpty(node20RemovalDate) ? Constants.Runner.NodeMigration.Node20RemovalDate : node20RemovalDate;
|
||||||
|
string deprecationWarning = string.Format(
|
||||||
|
Constants.Runner.NodeMigration.LinuxArm32DeprecationMessage,
|
||||||
|
effectiveDate);
|
||||||
|
|
||||||
|
if (string.Equals(preferredVersion, Constants.Runner.NodeMigration.Node24, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return (Constants.Runner.NodeMigration.Node20, deprecationWarning);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (preferredVersion, deprecationWarning);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy behavior: fall back to node20 if node24 was requested on ARM32
|
||||||
|
if (string.Equals(preferredVersion, Constants.Runner.NodeMigration.Node24, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return (Constants.Runner.NodeMigration.Node20, "Node 24 is not supported on Linux ARM32 platforms. Falling back to Node 20.");
|
return (Constants.Runner.NodeMigration.Node20, "Node 24 is not supported on Linux ARM32 platforms. Falling back to Node 20.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,9 +141,9 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
catch (AccessDeniedException e) when (e.ErrorCode == 1)
|
catch (AccessDeniedException e) when (e.ErrorCode == 1)
|
||||||
{
|
{
|
||||||
terminal.WriteError($"An error occured: {e.Message}");
|
terminal.WriteError($"An error occurred: {e.Message}");
|
||||||
trace.Error(e);
|
trace.Error(e);
|
||||||
return Constants.Runner.ReturnCode.TerminatedError;
|
return GetRunnerVersionDeprecatedExitCode();
|
||||||
}
|
}
|
||||||
catch (RunnerNotFoundException e)
|
catch (RunnerNotFoundException e)
|
||||||
{
|
{
|
||||||
@@ -159,6 +159,16 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int GetRunnerVersionDeprecatedExitCode()
|
||||||
|
{
|
||||||
|
if (StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable(Constants.Variables.Actions.ReturnVersionDeprecatedExitCode)))
|
||||||
|
{
|
||||||
|
return Constants.Runner.ReturnCode.RunnerVersionDeprecated;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Constants.Runner.ReturnCode.TerminatedError;
|
||||||
|
}
|
||||||
|
|
||||||
private static void LoadAndSetEnv()
|
private static void LoadAndSetEnv()
|
||||||
{
|
{
|
||||||
var binDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
var binDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
|
|||||||
@@ -115,6 +115,14 @@ namespace GitHub.Runner.Worker
|
|||||||
executionContext.Result = TaskResult.Failed;
|
executionContext.Result = TaskResult.Failed;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
catch (FailedToDownloadActionException ex)
|
||||||
|
{
|
||||||
|
// Log the error and fail the PrepareActionsAsync Initialization.
|
||||||
|
Trace.Error($"Caught exception from PrepareActionsAsync Initialization: {ex}");
|
||||||
|
executionContext.InfrastructureError(ex.InnerException?.Message ?? ex.Message, category: "error_download_action");
|
||||||
|
executionContext.Result = TaskResult.Failed;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
catch (InvalidActionArchiveException ex)
|
catch (InvalidActionArchiveException ex)
|
||||||
{
|
{
|
||||||
// Log the error and fail the PrepareActionsAsync Initialization.
|
// Log the error and fail the PrepareActionsAsync Initialization.
|
||||||
@@ -1157,93 +1165,102 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
// Allow up to 20 * 60s for any action to be downloaded from github graph.
|
// Allow up to 20 * 60s for any action to be downloaded from github graph.
|
||||||
int timeoutSeconds = 20 * 60;
|
int timeoutSeconds = 20 * 60;
|
||||||
while (retryCount < 3)
|
try
|
||||||
{
|
{
|
||||||
string requestId = string.Empty;
|
while (retryCount < 3)
|
||||||
using (var actionDownloadTimeout = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds)))
|
|
||||||
using (var actionDownloadCancellation = CancellationTokenSource.CreateLinkedTokenSource(actionDownloadTimeout.Token, executionContext.CancellationToken))
|
|
||||||
{
|
{
|
||||||
try
|
string requestId = string.Empty;
|
||||||
|
using (var actionDownloadTimeout = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds)))
|
||||||
|
using (var actionDownloadCancellation = CancellationTokenSource.CreateLinkedTokenSource(actionDownloadTimeout.Token, executionContext.CancellationToken))
|
||||||
{
|
{
|
||||||
//open zip stream in async mode
|
try
|
||||||
using (FileStream fs = new(archiveFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: _defaultFileStreamBufferSize, useAsync: true))
|
|
||||||
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
|
||||||
using (var httpClient = new HttpClient(httpClientHandler))
|
|
||||||
{
|
{
|
||||||
httpClient.DefaultRequestHeaders.Authorization = CreateAuthHeader(downloadAuthToken);
|
//open zip stream in async mode
|
||||||
|
using (FileStream fs = new(archiveFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: _defaultFileStreamBufferSize, useAsync: true))
|
||||||
httpClient.DefaultRequestHeaders.UserAgent.AddRange(HostContext.UserAgents);
|
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
||||||
using (var response = await httpClient.GetAsync(downloadUrl))
|
using (var httpClient = new HttpClient(httpClientHandler))
|
||||||
{
|
{
|
||||||
requestId = UrlUtil.GetGitHubRequestId(response.Headers);
|
httpClient.DefaultRequestHeaders.Authorization = CreateAuthHeader(downloadAuthToken);
|
||||||
if (!string.IsNullOrEmpty(requestId))
|
|
||||||
{
|
|
||||||
Trace.Info($"Request URL: {downloadUrl} X-GitHub-Request-Id: {requestId} Http Status: {response.StatusCode}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
httpClient.DefaultRequestHeaders.UserAgent.AddRange(HostContext.UserAgents);
|
||||||
|
using (var response = await httpClient.GetAsync(downloadUrl))
|
||||||
{
|
{
|
||||||
using (var result = await response.Content.ReadAsStreamAsync())
|
requestId = UrlUtil.GetGitHubRequestId(response.Headers);
|
||||||
|
if (!string.IsNullOrEmpty(requestId))
|
||||||
{
|
{
|
||||||
await result.CopyToAsync(fs, _defaultCopyBufferSize, actionDownloadCancellation.Token);
|
Trace.Info($"Request URL: {downloadUrl} X-GitHub-Request-Id: {requestId} Http Status: {response.StatusCode}");
|
||||||
await fs.FlushAsync(actionDownloadCancellation.Token);
|
}
|
||||||
|
|
||||||
// download succeed, break out the retry loop.
|
if (response.IsSuccessStatusCode)
|
||||||
break;
|
{
|
||||||
|
using (var result = await response.Content.ReadAsStreamAsync())
|
||||||
|
{
|
||||||
|
await result.CopyToAsync(fs, _defaultCopyBufferSize, actionDownloadCancellation.Token);
|
||||||
|
await fs.FlushAsync(actionDownloadCancellation.Token);
|
||||||
|
|
||||||
|
// download succeed, break out the retry loop.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (response.StatusCode == HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
// It doesn't make sense to retry in this case, so just stop
|
||||||
|
throw new ActionNotFoundException(new Uri(downloadUrl), requestId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Something else bad happened, let's go to our retry logic
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (response.StatusCode == HttpStatusCode.NotFound)
|
|
||||||
{
|
|
||||||
// It doesn't make sense to retry in this case, so just stop
|
|
||||||
throw new ActionNotFoundException(new Uri(downloadUrl), requestId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Something else bad happened, let's go to our retry logic
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
catch (OperationCanceledException) when (executionContext.CancellationToken.IsCancellationRequested)
|
||||||
catch (OperationCanceledException) when (executionContext.CancellationToken.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
Trace.Info("Action download has been cancelled.");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException ex) when (!executionContext.CancellationToken.IsCancellationRequested && retryCount >= 2)
|
|
||||||
{
|
|
||||||
Trace.Info($"Action download final retry timeout after {timeoutSeconds} seconds.");
|
|
||||||
throw new TimeoutException($"Action '{downloadUrl}' download has timed out. Error: {ex.Message} {requestId}");
|
|
||||||
}
|
|
||||||
catch (ActionNotFoundException)
|
|
||||||
{
|
|
||||||
Trace.Info($"The action at '{downloadUrl}' does not exist");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (Exception ex) when (retryCount < 2)
|
|
||||||
{
|
|
||||||
retryCount++;
|
|
||||||
Trace.Error($"Fail to download archive '{downloadUrl}' -- Attempt: {retryCount}");
|
|
||||||
Trace.Error(ex);
|
|
||||||
if (actionDownloadTimeout.Token.IsCancellationRequested)
|
|
||||||
{
|
{
|
||||||
// action download didn't finish within timeout
|
Trace.Info("Action download has been cancelled.");
|
||||||
executionContext.Warning($"Action '{downloadUrl}' didn't finish download within {timeoutSeconds} seconds. {requestId}");
|
throw;
|
||||||
}
|
}
|
||||||
else
|
catch (OperationCanceledException ex) when (!executionContext.CancellationToken.IsCancellationRequested && retryCount >= 2)
|
||||||
{
|
{
|
||||||
executionContext.Warning($"Failed to download action '{downloadUrl}'. Error: {ex.Message} {requestId}");
|
Trace.Info($"Action download final retry timeout after {timeoutSeconds} seconds.");
|
||||||
|
throw new TimeoutException($"Action '{downloadUrl}' download has timed out. Error: {ex.Message} {requestId}");
|
||||||
|
}
|
||||||
|
catch (ActionNotFoundException)
|
||||||
|
{
|
||||||
|
Trace.Info($"The action at '{downloadUrl}' does not exist");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (retryCount < 2)
|
||||||
|
{
|
||||||
|
retryCount++;
|
||||||
|
Trace.Error($"Fail to download archive '{downloadUrl}' -- Attempt: {retryCount}");
|
||||||
|
Trace.Error(ex);
|
||||||
|
if (actionDownloadTimeout.Token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
// action download didn't finish within timeout
|
||||||
|
executionContext.Warning($"Action '{downloadUrl}' didn't finish download within {timeoutSeconds} seconds. {requestId}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
executionContext.Warning($"Failed to download action '{downloadUrl}'. Error: {ex.Message} {requestId}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GITHUB_ACTION_DOWNLOAD_NO_BACKOFF")))
|
if (String.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GITHUB_ACTION_DOWNLOAD_NO_BACKOFF")))
|
||||||
{
|
{
|
||||||
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30));
|
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30));
|
||||||
executionContext.Warning($"Back off {backOff.TotalSeconds} seconds before retry.");
|
executionContext.Warning($"Back off {backOff.TotalSeconds} seconds before retry.");
|
||||||
await Task.Delay(backOff);
|
await Task.Delay(backOff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex) when (!(ex is OperationCanceledException) && !executionContext.CancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
Trace.Error($"Failed to download archive '{downloadUrl}' after {retryCount + 1} attempts.");
|
||||||
|
Trace.Error(ex);
|
||||||
|
throw new FailedToDownloadActionException($"Failed to download archive '{downloadUrl}' after {retryCount + 1} attempts.", ex);
|
||||||
|
}
|
||||||
|
|
||||||
ArgUtil.NotNullOrEmpty(archiveFile, nameof(archiveFile));
|
ArgUtil.NotNullOrEmpty(archiveFile, nameof(archiveFile));
|
||||||
executionContext.Debug($"Download '{downloadUrl}' to '{archiveFile}'");
|
executionContext.Debug($"Download '{downloadUrl}' to '{archiveFile}'");
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
List<string> StepEnvironmentOverrides { get; }
|
List<string> StepEnvironmentOverrides { get; }
|
||||||
|
|
||||||
ExecutionContext Root { get; }
|
IExecutionContext Root { get; }
|
||||||
ExecutionContext Parent { get; }
|
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
void InitializeJob(Pipelines.AgentJobRequestMessage message, CancellationToken token);
|
void InitializeJob(Pipelines.AgentJobRequestMessage message, CancellationToken token);
|
||||||
@@ -251,7 +250,9 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExecutionContext Root
|
IExecutionContext IExecutionContext.Root => Root;
|
||||||
|
|
||||||
|
private ExecutionContext Root
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -266,13 +267,7 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExecutionContext Parent
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _parentExecutionContext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public JobContext JobContext
|
public JobContext JobContext
|
||||||
{
|
{
|
||||||
@@ -859,6 +854,12 @@ namespace GitHub.Runner.Worker
|
|||||||
// Track Node.js 20 actions for deprecation warning
|
// Track Node.js 20 actions for deprecation warning
|
||||||
Global.DeprecatedNode20Actions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
Global.DeprecatedNode20Actions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
// Track actions upgraded from Node.js 20 to Node.js 24
|
||||||
|
Global.UpgradedToNode24Actions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
// Track actions stuck on Node.js 20 due to ARM32 (separate from general deprecation)
|
||||||
|
Global.Arm32Node20Actions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
// Job Outputs
|
// Job Outputs
|
||||||
JobOutputs = new Dictionary<string, VariableValue>(StringComparer.OrdinalIgnoreCase);
|
JobOutputs = new Dictionary<string, VariableValue>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
|||||||
@@ -34,5 +34,7 @@ namespace GitHub.Runner.Worker
|
|||||||
public bool HasDeprecatedSetOutput { get; set; }
|
public bool HasDeprecatedSetOutput { get; set; }
|
||||||
public bool HasDeprecatedSaveState { get; set; }
|
public bool HasDeprecatedSaveState { get; set; }
|
||||||
public HashSet<string> DeprecatedNode20Actions { get; set; }
|
public HashSet<string> DeprecatedNode20Actions { get; set; }
|
||||||
|
public HashSet<string> UpgradedToNode24Actions { get; set; }
|
||||||
|
public HashSet<string> Arm32Node20Actions { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,14 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
|
|
||||||
public sealed class HandlerFactory : RunnerService, IHandlerFactory
|
public sealed class HandlerFactory : RunnerService, IHandlerFactory
|
||||||
{
|
{
|
||||||
|
internal static bool ShouldTrackAsArm32Node20(bool deprecateArm32, string preferredNodeVersion, string finalNodeVersion, string platformWarningMessage)
|
||||||
|
{
|
||||||
|
return deprecateArm32 &&
|
||||||
|
!string.IsNullOrEmpty(platformWarningMessage) &&
|
||||||
|
string.Equals(preferredNodeVersion, Constants.Runner.NodeMigration.Node24, StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
string.Equals(finalNodeVersion, Constants.Runner.NodeMigration.Node20, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
public IHandler Create(
|
public IHandler Create(
|
||||||
IExecutionContext executionContext,
|
IExecutionContext executionContext,
|
||||||
Pipelines.ActionStepDefinitionReference action,
|
Pipelines.ActionStepDefinitionReference action,
|
||||||
@@ -65,19 +73,12 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
nodeData.NodeVersion = Common.Constants.Runner.NodeMigration.Node20;
|
nodeData.NodeVersion = Common.Constants.Runner.NodeMigration.Node20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track Node.js 20 actions for deprecation annotation
|
// Read flags early; actionName is also resolved up front for tracking after version is determined
|
||||||
if (string.Equals(nodeData.NodeVersion, Constants.Runner.NodeMigration.Node20, StringComparison.InvariantCultureIgnoreCase))
|
bool warnOnNode20 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.WarnOnNode20Flag) ?? false;
|
||||||
{
|
bool deprecateArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.DeprecateLinuxArm32Flag) ?? false;
|
||||||
bool warnOnNode20 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.WarnOnNode20Flag) ?? false;
|
bool killArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.KillLinuxArm32Flag) ?? false;
|
||||||
if (warnOnNode20)
|
string node20RemovalDate = executionContext.Global.Variables?.Get(Constants.Runner.NodeMigration.Node20RemovalDateVariable);
|
||||||
{
|
string actionName = GetActionName(action);
|
||||||
string actionName = GetActionName(action);
|
|
||||||
if (!string.IsNullOrEmpty(actionName))
|
|
||||||
{
|
|
||||||
executionContext.Global.DeprecatedNode20Actions?.Add(actionName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if node20 was explicitly specified in the action
|
// Check if node20 was explicitly specified in the action
|
||||||
// We don't modify if node24 was explicitly specified
|
// We don't modify if node24 was explicitly specified
|
||||||
@@ -87,7 +88,15 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
bool requireNode24 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.RequireNode24Flag) ?? false;
|
bool requireNode24 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.RequireNode24Flag) ?? false;
|
||||||
|
|
||||||
var (nodeVersion, configWarningMessage) = NodeUtil.DetermineActionsNodeVersion(environment, useNode24ByDefault, requireNode24);
|
var (nodeVersion, configWarningMessage) = NodeUtil.DetermineActionsNodeVersion(environment, useNode24ByDefault, requireNode24);
|
||||||
var (finalNodeVersion, platformWarningMessage) = NodeUtil.CheckNodeVersionForLinuxArm32(nodeVersion);
|
var (finalNodeVersion, platformWarningMessage) = NodeUtil.CheckNodeVersionForLinuxArm32(nodeVersion, deprecateArm32, killArm32, node20RemovalDate);
|
||||||
|
|
||||||
|
// ARM32 kill switch: fail the step
|
||||||
|
if (finalNodeVersion == null)
|
||||||
|
{
|
||||||
|
executionContext.Error(platformWarningMessage);
|
||||||
|
throw new InvalidOperationException(platformWarningMessage);
|
||||||
|
}
|
||||||
|
|
||||||
nodeData.NodeVersion = finalNodeVersion;
|
nodeData.NodeVersion = finalNodeVersion;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(configWarningMessage))
|
if (!string.IsNullOrEmpty(configWarningMessage))
|
||||||
@@ -100,6 +109,26 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
executionContext.Warning(platformWarningMessage);
|
executionContext.Warning(platformWarningMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track actions based on their final node version
|
||||||
|
if (!string.IsNullOrEmpty(actionName))
|
||||||
|
{
|
||||||
|
if (string.Equals(finalNodeVersion, Constants.Runner.NodeMigration.Node24, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Action was upgraded from node20 to node24
|
||||||
|
executionContext.Global.UpgradedToNode24Actions?.Add(actionName);
|
||||||
|
}
|
||||||
|
else if (ShouldTrackAsArm32Node20(deprecateArm32, nodeVersion, finalNodeVersion, platformWarningMessage))
|
||||||
|
{
|
||||||
|
// Action is on node20 because ARM32 can't run node24
|
||||||
|
executionContext.Global.Arm32Node20Actions?.Add(actionName);
|
||||||
|
}
|
||||||
|
else if (warnOnNode20)
|
||||||
|
{
|
||||||
|
// Action is still running on node20 (general case)
|
||||||
|
executionContext.Global.DeprecatedNode20Actions?.Add(actionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Show information about Node 24 migration in Phase 2
|
// Show information about Node 24 migration in Phase 2
|
||||||
if (useNode24ByDefault && !requireNode24 && string.Equals(finalNodeVersion, Constants.Runner.NodeMigration.Node24, StringComparison.OrdinalIgnoreCase))
|
if (useNode24ByDefault && !requireNode24 && string.Equals(finalNodeVersion, Constants.Runner.NodeMigration.Node24, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
@@ -109,6 +138,30 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
executionContext.Output(infoMessage);
|
executionContext.Output(infoMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (string.Equals(nodeData.NodeVersion, Constants.Runner.NodeMigration.Node24, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
var (finalNodeVersion, platformWarningMessage) = NodeUtil.CheckNodeVersionForLinuxArm32(nodeData.NodeVersion, deprecateArm32, killArm32, node20RemovalDate);
|
||||||
|
|
||||||
|
// ARM32 kill switch: fail the step
|
||||||
|
if (finalNodeVersion == null)
|
||||||
|
{
|
||||||
|
executionContext.Error(platformWarningMessage);
|
||||||
|
throw new InvalidOperationException(platformWarningMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
var preferredVersion = nodeData.NodeVersion;
|
||||||
|
nodeData.NodeVersion = finalNodeVersion;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(platformWarningMessage))
|
||||||
|
{
|
||||||
|
executionContext.Warning(platformWarningMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(actionName) && ShouldTrackAsArm32Node20(deprecateArm32, preferredVersion, finalNodeVersion, platformWarningMessage))
|
||||||
|
{
|
||||||
|
executionContext.Global.Arm32Node20Actions?.Add(actionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(handler as INodeScriptActionHandler).Data = nodeData;
|
(handler as INodeScriptActionHandler).Data = nodeData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,13 +58,23 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
|
|
||||||
public Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
|
public Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
|
||||||
{
|
{
|
||||||
// Use NodeUtil to check if Node24 is requested but we're on ARM32 Linux
|
bool deprecateArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.DeprecateLinuxArm32Flag) ?? false;
|
||||||
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion);
|
bool killArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.KillLinuxArm32Flag) ?? false;
|
||||||
|
string node20RemovalDate = executionContext.Global.Variables?.Get(Constants.Runner.NodeMigration.Node20RemovalDateVariable);
|
||||||
|
|
||||||
|
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32, killArm32, node20RemovalDate);
|
||||||
|
|
||||||
|
if (nodeVersion == null)
|
||||||
|
{
|
||||||
|
executionContext.Error(warningMessage);
|
||||||
|
throw new InvalidOperationException(warningMessage);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(warningMessage))
|
if (!string.IsNullOrEmpty(warningMessage))
|
||||||
{
|
{
|
||||||
executionContext.Warning(warningMessage);
|
executionContext.Warning(warningMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(nodeVersion);
|
return Task.FromResult(nodeVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,8 +152,18 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
|
|
||||||
public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
|
public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
|
||||||
{
|
{
|
||||||
// Use NodeUtil to check if Node24 is requested but we're on ARM32 Linux
|
bool deprecateArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.DeprecateLinuxArm32Flag) ?? false;
|
||||||
var (nodeExternal, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion);
|
bool killArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.KillLinuxArm32Flag) ?? false;
|
||||||
|
string node20RemovalDate = executionContext.Global.Variables?.Get(Constants.Runner.NodeMigration.Node20RemovalDateVariable);
|
||||||
|
|
||||||
|
var (nodeExternal, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32, killArm32, node20RemovalDate);
|
||||||
|
|
||||||
|
if (nodeExternal == null)
|
||||||
|
{
|
||||||
|
executionContext.Error(warningMessage);
|
||||||
|
throw new InvalidOperationException(warningMessage);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(warningMessage))
|
if (!string.IsNullOrEmpty(warningMessage))
|
||||||
{
|
{
|
||||||
executionContext.Warning(warningMessage);
|
executionContext.Warning(warningMessage);
|
||||||
@@ -273,8 +293,18 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
|
|
||||||
private string CheckPlatformForAlpineContainer(IExecutionContext executionContext, string preferredVersion)
|
private string CheckPlatformForAlpineContainer(IExecutionContext executionContext, string preferredVersion)
|
||||||
{
|
{
|
||||||
// Use NodeUtil to check if Node24 is requested but we're on ARM32 Linux
|
bool deprecateArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.DeprecateLinuxArm32Flag) ?? false;
|
||||||
var (nodeExternal, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion);
|
bool killArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.KillLinuxArm32Flag) ?? false;
|
||||||
|
string node20RemovalDate = executionContext.Global.Variables?.Get(Constants.Runner.NodeMigration.Node20RemovalDateVariable);
|
||||||
|
|
||||||
|
var (nodeExternal, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32, killArm32, node20RemovalDate);
|
||||||
|
|
||||||
|
if (nodeExternal == null)
|
||||||
|
{
|
||||||
|
executionContext.Error(warningMessage);
|
||||||
|
throw new InvalidOperationException(warningMessage);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(warningMessage))
|
if (!string.IsNullOrEmpty(warningMessage))
|
||||||
{
|
{
|
||||||
executionContext.Warning(warningMessage);
|
executionContext.Warning(warningMessage);
|
||||||
|
|||||||
@@ -736,14 +736,38 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add deprecation warning annotation for Node.js 20 actions
|
// Read dates from server variables with hardcoded fallbacks
|
||||||
|
var node24DefaultDateRaw = context.Global.Variables?.Get(Constants.Runner.NodeMigration.Node24DefaultDateVariable);
|
||||||
|
var node24DefaultDate = string.IsNullOrEmpty(node24DefaultDateRaw) ? Constants.Runner.NodeMigration.Node24DefaultDate : node24DefaultDateRaw;
|
||||||
|
var node20RemovalDateRaw = context.Global.Variables?.Get(Constants.Runner.NodeMigration.Node20RemovalDateVariable);
|
||||||
|
var node20RemovalDate = string.IsNullOrEmpty(node20RemovalDateRaw) ? Constants.Runner.NodeMigration.Node20RemovalDate : node20RemovalDateRaw;
|
||||||
|
|
||||||
|
// Add deprecation warning annotation for Node.js 20 actions (Phase 1 - actions still running on node20)
|
||||||
if (context.Global.DeprecatedNode20Actions?.Count > 0)
|
if (context.Global.DeprecatedNode20Actions?.Count > 0)
|
||||||
{
|
{
|
||||||
var sortedActions = context.Global.DeprecatedNode20Actions.OrderBy(a => a, StringComparer.OrdinalIgnoreCase);
|
var sortedActions = context.Global.DeprecatedNode20Actions.OrderBy(a => a, StringComparer.OrdinalIgnoreCase);
|
||||||
var actionsList = string.Join(", ", sortedActions);
|
var actionsList = string.Join(", ", sortedActions);
|
||||||
var deprecationMessage = $"Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected: {actionsList}. Actions will be forced to run with Node.js 24 by default starting June 2nd, 2026. Please check if updated versions of these actions are available that support Node.js 24. To opt into Node.js 24 now, set the FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true environment variable on the runner or in your workflow file. Once Node.js 24 becomes the default, you can temporarily opt out by setting ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. For more information see: {Constants.Runner.NodeMigration.Node20DeprecationUrl}";
|
var deprecationMessage = $"Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected: {actionsList}. Actions will be forced to run with Node.js 24 by default starting {node24DefaultDate}. Node.js 20 will be removed from the runner on {node20RemovalDate}. Please check if updated versions of these actions are available that support Node.js 24. To opt into Node.js 24 now, set the FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true environment variable on the runner or in your workflow file. Once Node.js 24 becomes the default, you can temporarily opt out by setting ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. For more information see: {Constants.Runner.NodeMigration.Node20DeprecationUrl}";
|
||||||
context.Warning(deprecationMessage);
|
context.Warning(deprecationMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add annotation for actions upgraded from Node.js 20 to Node.js 24 (Phase 2/3)
|
||||||
|
if (context.Global.UpgradedToNode24Actions?.Count > 0)
|
||||||
|
{
|
||||||
|
var sortedActions = context.Global.UpgradedToNode24Actions.OrderBy(a => a, StringComparer.OrdinalIgnoreCase);
|
||||||
|
var actionsList = string.Join(", ", sortedActions);
|
||||||
|
var upgradeMessage = $"Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: {actionsList}. For more information see: {Constants.Runner.NodeMigration.Node20DeprecationUrl}";
|
||||||
|
context.Warning(upgradeMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add annotation for ARM32 actions stuck on Node.js 20 (ARM32 can't run node24)
|
||||||
|
if (context.Global.Arm32Node20Actions?.Count > 0)
|
||||||
|
{
|
||||||
|
var sortedActions = context.Global.Arm32Node20Actions.OrderBy(a => a, StringComparer.OrdinalIgnoreCase);
|
||||||
|
var actionsList = string.Join(", ", sortedActions);
|
||||||
|
var arm32Message = $"The following actions are running on Node.js 20 because Node.js 24 is not available on Linux ARM32: {actionsList}. Linux ARM32 runners are deprecated and will no longer be supported after {node20RemovalDate}. Please migrate to a supported platform. For more information see: {Constants.Runner.NodeMigration.Node20DeprecationUrl}";
|
||||||
|
context.Warning(arm32Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using GitHub.Actions.WorkflowParser;
|
using GitHub.Actions.WorkflowParser;
|
||||||
using GitHub.DistributedTask.Expressions2;
|
using GitHub.DistributedTask.Expressions2;
|
||||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||||
@@ -226,8 +227,12 @@ namespace GitHub.Runner.Worker
|
|||||||
Func<TNew> newEvaluator,
|
Func<TNew> newEvaluator,
|
||||||
Func<TLegacy, TNew, bool> resultComparer)
|
Func<TLegacy, TNew, bool> resultComparer)
|
||||||
{
|
{
|
||||||
// Capture cancellation state before evaluation
|
// Use the root (job-level) cancellation token to detect cancellation race conditions.
|
||||||
var cancellationRequestedBefore = _context.CancellationToken.IsCancellationRequested;
|
// The step-level token only fires on step timeout, not on job cancellation.
|
||||||
|
// Job cancellation mutates JobContext.Status which expression functions read,
|
||||||
|
// so we need the root token to properly detect cancellation between evaluator runs.
|
||||||
|
var rootCancellationToken = _context.Root?.CancellationToken ?? CancellationToken.None;
|
||||||
|
var cancellationRequestedBefore = rootCancellationToken.IsCancellationRequested;
|
||||||
|
|
||||||
// Legacy evaluator
|
// Legacy evaluator
|
||||||
var legacyException = default(Exception);
|
var legacyException = default(Exception);
|
||||||
@@ -261,7 +266,7 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Capture cancellation state after evaluation
|
// Capture cancellation state after evaluation
|
||||||
var cancellationRequestedAfter = _context.CancellationToken.IsCancellationRequested;
|
var cancellationRequestedAfter = rootCancellationToken.IsCancellationRequested;
|
||||||
|
|
||||||
// Compare results or exceptions
|
// Compare results or exceptions
|
||||||
bool hasMismatch = false;
|
bool hasMismatch = false;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace GitHub.DistributedTask.Expressions2
|
|||||||
IEnumerable<IFunctionInfo> functions,
|
IEnumerable<IFunctionInfo> functions,
|
||||||
Boolean allowCaseFunction = true)
|
Boolean allowCaseFunction = true)
|
||||||
{
|
{
|
||||||
var context = new ParseContext(expression, trace, namedValues, functions, allowCaseFunction);
|
var context = new ParseContext(expression, trace, namedValues, functions, allowCaseFunction: allowCaseFunction);
|
||||||
context.Trace.Info($"Parsing expression: <{expression}>");
|
context.Trace.Info($"Parsing expression: <{expression}>");
|
||||||
return CreateTree(context);
|
return CreateTree(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2556,6 +2556,25 @@ namespace GitHub.DistributedTask.WebApi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public sealed class FailedToDownloadActionException : DistributedTaskException
|
||||||
|
{
|
||||||
|
public FailedToDownloadActionException(String message)
|
||||||
|
: base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public FailedToDownloadActionException(String message, Exception innerException)
|
||||||
|
: base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private FailedToDownloadActionException(SerializationInfo info, StreamingContext context)
|
||||||
|
: base(info, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public sealed class InvalidActionArchiveException : DistributedTaskException
|
public sealed class InvalidActionArchiveException : DistributedTaskException
|
||||||
{
|
{
|
||||||
|
|||||||
104
src/Test/L0/Sdk/ExpressionParserL0.cs
Normal file
104
src/Test/L0/Sdk/ExpressionParserL0.cs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
using GitHub.DistributedTask.Expressions2;
|
||||||
|
using GitHub.DistributedTask.Expressions2.Sdk;
|
||||||
|
using GitHub.DistributedTask.ObjectTemplating;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace GitHub.Runner.Common.Tests.Sdk
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Regression tests for ExpressionParser.CreateTree to verify that
|
||||||
|
/// allowCaseFunction does not accidentally set allowUnknownKeywords.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ExpressionParserL0
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Sdk")]
|
||||||
|
public void CreateTree_RejectsUnrecognizedNamedValue()
|
||||||
|
{
|
||||||
|
// Regression: allowCaseFunction was passed positionally into
|
||||||
|
// the allowUnknownKeywords parameter, causing all named values
|
||||||
|
// to be silently accepted.
|
||||||
|
var parser = new ExpressionParser();
|
||||||
|
var namedValues = new List<INamedValueInfo>
|
||||||
|
{
|
||||||
|
new NamedValueInfo<ContextValueNode>("inputs"),
|
||||||
|
};
|
||||||
|
|
||||||
|
var ex = Assert.Throws<ParseException>(() =>
|
||||||
|
parser.CreateTree("github.event.repository.private", null, namedValues, null));
|
||||||
|
|
||||||
|
Assert.Contains("Unrecognized named-value", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Sdk")]
|
||||||
|
public void CreateTree_AcceptsRecognizedNamedValue()
|
||||||
|
{
|
||||||
|
var parser = new ExpressionParser();
|
||||||
|
var namedValues = new List<INamedValueInfo>
|
||||||
|
{
|
||||||
|
new NamedValueInfo<ContextValueNode>("inputs"),
|
||||||
|
};
|
||||||
|
|
||||||
|
var node = parser.CreateTree("inputs.foo", null, namedValues, null);
|
||||||
|
|
||||||
|
Assert.NotNull(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Sdk")]
|
||||||
|
public void CreateTree_CaseFunctionWorks_WhenAllowed()
|
||||||
|
{
|
||||||
|
var parser = new ExpressionParser();
|
||||||
|
var namedValues = new List<INamedValueInfo>
|
||||||
|
{
|
||||||
|
new NamedValueInfo<ContextValueNode>("github"),
|
||||||
|
};
|
||||||
|
|
||||||
|
var node = parser.CreateTree("case(github.event_name, 'push', 'Push Event')", null, namedValues, null, allowCaseFunction: true);
|
||||||
|
|
||||||
|
Assert.NotNull(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Sdk")]
|
||||||
|
public void CreateTree_CaseFunctionRejected_WhenDisallowed()
|
||||||
|
{
|
||||||
|
var parser = new ExpressionParser();
|
||||||
|
var namedValues = new List<INamedValueInfo>
|
||||||
|
{
|
||||||
|
new NamedValueInfo<ContextValueNode>("github"),
|
||||||
|
};
|
||||||
|
|
||||||
|
var ex = Assert.Throws<ParseException>(() =>
|
||||||
|
parser.CreateTree("case(github.event_name, 'push', 'Push Event')", null, namedValues, null, allowCaseFunction: false));
|
||||||
|
|
||||||
|
Assert.Contains("Unrecognized function", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Sdk")]
|
||||||
|
public void CreateTree_CaseFunctionDoesNotAffectUnknownKeywords()
|
||||||
|
{
|
||||||
|
// The key regression test: with allowCaseFunction=true (default),
|
||||||
|
// unrecognized named values must still be rejected.
|
||||||
|
var parser = new ExpressionParser();
|
||||||
|
var namedValues = new List<INamedValueInfo>
|
||||||
|
{
|
||||||
|
new NamedValueInfo<ContextValueNode>("inputs"),
|
||||||
|
};
|
||||||
|
|
||||||
|
var ex = Assert.Throws<ParseException>(() =>
|
||||||
|
parser.CreateTree("github.ref", null, namedValues, null, allowCaseFunction: true));
|
||||||
|
|
||||||
|
Assert.Contains("Unrecognized named-value", ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -198,7 +198,8 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
Func<Task> action = async () => await _actionManager.PrepareActionsAsync(_ec.Object, actions);
|
Func<Task> action = async () => await _actionManager.PrepareActionsAsync(_ec.Object, actions);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
await Assert.ThrowsAsync<ActionNotFoundException>(action);
|
var ex = await Assert.ThrowsAsync<FailedToDownloadActionException>(action);
|
||||||
|
Assert.IsType<ActionNotFoundException>(ex.InnerException);
|
||||||
|
|
||||||
var watermarkFile = Path.Combine(_hc.GetDirectory(WellKnownDirectory.Actions), ActionName, "main.completed");
|
var watermarkFile = Path.Combine(_hc.GetDirectory(WellKnownDirectory.Actions), ActionName, "main.completed");
|
||||||
Assert.False(File.Exists(watermarkFile));
|
Assert.False(File.Exists(watermarkFile));
|
||||||
|
|||||||
@@ -928,6 +928,58 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void Load_ContainerAction_RejectsInvalidExpressionContext()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
Setup();
|
||||||
|
|
||||||
|
var actionManifest = new ActionManifestManager();
|
||||||
|
actionManifest.Initialize(_hc);
|
||||||
|
|
||||||
|
// Act & Assert — github is not a valid context for container-runs-env (only inputs is allowed)
|
||||||
|
var ex = Assert.Throws<ArgumentException>(() =>
|
||||||
|
actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "dockerfileaction_env_invalid_context.yml")));
|
||||||
|
|
||||||
|
Assert.Contains("Failed to load", ex.Message);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Teardown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void Load_ContainerAction_AcceptsValidExpressionContext()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
Setup();
|
||||||
|
|
||||||
|
var actionManifest = new ActionManifestManager();
|
||||||
|
actionManifest.Initialize(_hc);
|
||||||
|
|
||||||
|
// Act — inputs is a valid context for container-runs-env
|
||||||
|
var result = actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "dockerfileaction_arg_env_expression.yml"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var containerAction = result.Execution as ContainerActionExecutionDataNew;
|
||||||
|
Assert.NotNull(containerAction);
|
||||||
|
Assert.Equal("${{ inputs.entryPoint }}", containerAction.Environment[1].Value.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Teardown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Setup([CallerMemberName] string name = "")
|
private void Setup([CallerMemberName] string name = "")
|
||||||
{
|
{
|
||||||
_ecTokenSource?.Dispose();
|
_ecTokenSource?.Dispose();
|
||||||
|
|||||||
@@ -926,6 +926,58 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void Load_ContainerAction_RejectsInvalidExpressionContext()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
Setup();
|
||||||
|
|
||||||
|
var actionManifest = new ActionManifestManagerLegacy();
|
||||||
|
actionManifest.Initialize(_hc);
|
||||||
|
|
||||||
|
// Act & Assert — github is not a valid context for container-runs-env (only inputs is allowed)
|
||||||
|
var ex = Assert.Throws<ArgumentException>(() =>
|
||||||
|
actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "dockerfileaction_env_invalid_context.yml")));
|
||||||
|
|
||||||
|
Assert.Contains("Failed to load", ex.Message);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Teardown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void Load_ContainerAction_AcceptsValidExpressionContext()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
Setup();
|
||||||
|
|
||||||
|
var actionManifest = new ActionManifestManagerLegacy();
|
||||||
|
actionManifest.Initialize(_hc);
|
||||||
|
|
||||||
|
// Act — inputs is a valid context for container-runs-env
|
||||||
|
var result = actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "dockerfileaction_arg_env_expression.yml"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var containerAction = result.Execution as ContainerActionExecutionData;
|
||||||
|
Assert.NotNull(containerAction);
|
||||||
|
Assert.Equal("${{ inputs.entryPoint }}", containerAction.Environment[1].Value.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Teardown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Setup([CallerMemberName] string name = "")
|
private void Setup([CallerMemberName] string name = "")
|
||||||
{
|
{
|
||||||
_ecTokenSource?.Dispose();
|
_ecTokenSource?.Dispose();
|
||||||
|
|||||||
@@ -379,6 +379,40 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void Load_BothParsersRejectInvalidExpressionContext()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Arrange — regression test: both parsers must reject github context
|
||||||
|
// in container-runs-env (only inputs is allowed per schema)
|
||||||
|
Setup();
|
||||||
|
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||||
|
|
||||||
|
var legacyManager = new ActionManifestManagerLegacy();
|
||||||
|
legacyManager.Initialize(_hc);
|
||||||
|
_hc.SetSingleton<IActionManifestManagerLegacy>(legacyManager);
|
||||||
|
|
||||||
|
var newManager = new ActionManifestManager();
|
||||||
|
newManager.Initialize(_hc);
|
||||||
|
_hc.SetSingleton<IActionManifestManager>(newManager);
|
||||||
|
|
||||||
|
var wrapper = new ActionManifestManagerWrapper();
|
||||||
|
wrapper.Initialize(_hc);
|
||||||
|
|
||||||
|
var manifestPath = Path.Combine(TestUtil.GetTestDataPath(), "dockerfileaction_env_invalid_context.yml");
|
||||||
|
|
||||||
|
// Act & Assert — both parsers should reject, wrapper should throw
|
||||||
|
Assert.Throws<ArgumentException>(() => wrapper.Load(_ec.Object, manifestPath));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Teardown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string GetFullExceptionMessage(Exception ex)
|
private string GetFullExceptionMessage(Exception ex)
|
||||||
{
|
{
|
||||||
var messages = new List<string>();
|
var messages = new List<string>();
|
||||||
|
|||||||
@@ -370,5 +370,504 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
Assert.Contains("./.github/actions/my-action", deprecatedActions);
|
Assert.Contains("./.github/actions/my-action", deprecatedActions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void Node20Action_TrackedAsUpgradedWhenUseNode24ByDefaultEnabled()
|
||||||
|
{
|
||||||
|
using (TestHostContext hc = CreateTestContext())
|
||||||
|
{
|
||||||
|
// Arrange.
|
||||||
|
var hf = new HandlerFactory();
|
||||||
|
hf.Initialize(hc);
|
||||||
|
|
||||||
|
var variables = new Dictionary<string, VariableValue>
|
||||||
|
{
|
||||||
|
{ Constants.Runner.NodeMigration.WarnOnNode20Flag, new VariableValue("true") },
|
||||||
|
{ Constants.Runner.NodeMigration.UseNode24ByDefaultFlag, new VariableValue("true") }
|
||||||
|
};
|
||||||
|
Variables serverVariables = new(hc, variables);
|
||||||
|
var deprecatedActions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
var upgradedActions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
_ec.Setup(x => x.Global).Returns(new GlobalContext()
|
||||||
|
{
|
||||||
|
Variables = serverVariables,
|
||||||
|
EnvironmentVariables = new Dictionary<string, string>(),
|
||||||
|
DeprecatedNode20Actions = deprecatedActions,
|
||||||
|
UpgradedToNode24Actions = upgradedActions
|
||||||
|
});
|
||||||
|
|
||||||
|
var actionRef = new RepositoryPathReference
|
||||||
|
{
|
||||||
|
Name = "actions/checkout",
|
||||||
|
Ref = "v4"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act.
|
||||||
|
var data = new NodeJSActionExecutionData();
|
||||||
|
data.NodeVersion = "node20";
|
||||||
|
var handler = hf.Create(
|
||||||
|
_ec.Object,
|
||||||
|
actionRef,
|
||||||
|
new Mock<IStepHost>().Object,
|
||||||
|
data,
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Variables(hc, new Dictionary<string, VariableValue>()),
|
||||||
|
"",
|
||||||
|
new List<JobExtensionRunner>()
|
||||||
|
) as INodeScriptActionHandler;
|
||||||
|
|
||||||
|
// On non-ARM32 platforms, action should be upgraded to node24
|
||||||
|
// and tracked in UpgradedToNode24Actions, NOT in DeprecatedNode20Actions
|
||||||
|
bool isArm32Linux = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture == System.Runtime.InteropServices.Architecture.Arm &&
|
||||||
|
System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (!isArm32Linux)
|
||||||
|
{
|
||||||
|
Assert.Equal("node24", handler.Data.NodeVersion);
|
||||||
|
Assert.Contains("actions/checkout@v4", upgradedActions);
|
||||||
|
Assert.DoesNotContain("actions/checkout@v4", deprecatedActions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void Node20Action_NotUpgradedWhenPhase1Only()
|
||||||
|
{
|
||||||
|
using (TestHostContext hc = CreateTestContext())
|
||||||
|
{
|
||||||
|
// Arrange.
|
||||||
|
var hf = new HandlerFactory();
|
||||||
|
hf.Initialize(hc);
|
||||||
|
|
||||||
|
var variables = new Dictionary<string, VariableValue>
|
||||||
|
{
|
||||||
|
{ Constants.Runner.NodeMigration.WarnOnNode20Flag, new VariableValue("true") }
|
||||||
|
};
|
||||||
|
Variables serverVariables = new(hc, variables);
|
||||||
|
var deprecatedActions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
var upgradedActions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
_ec.Setup(x => x.Global).Returns(new GlobalContext()
|
||||||
|
{
|
||||||
|
Variables = serverVariables,
|
||||||
|
EnvironmentVariables = new Dictionary<string, string>(),
|
||||||
|
DeprecatedNode20Actions = deprecatedActions,
|
||||||
|
UpgradedToNode24Actions = upgradedActions
|
||||||
|
});
|
||||||
|
|
||||||
|
var actionRef = new RepositoryPathReference
|
||||||
|
{
|
||||||
|
Name = "actions/checkout",
|
||||||
|
Ref = "v4"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act.
|
||||||
|
var data = new NodeJSActionExecutionData();
|
||||||
|
data.NodeVersion = "node20";
|
||||||
|
var handler = hf.Create(
|
||||||
|
_ec.Object,
|
||||||
|
actionRef,
|
||||||
|
new Mock<IStepHost>().Object,
|
||||||
|
data,
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Variables(hc, new Dictionary<string, VariableValue>()),
|
||||||
|
"",
|
||||||
|
new List<JobExtensionRunner>()
|
||||||
|
) as INodeScriptActionHandler;
|
||||||
|
|
||||||
|
// In Phase 1 (no UseNode24ByDefault), action stays on node20
|
||||||
|
// and should be in DeprecatedNode20Actions
|
||||||
|
Assert.Equal("node20", handler.Data.NodeVersion);
|
||||||
|
Assert.Contains("actions/checkout@v4", deprecatedActions);
|
||||||
|
Assert.Empty(upgradedActions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void ExplicitNode24Action_KillArm32Flag_ThrowsOnArm32()
|
||||||
|
{
|
||||||
|
using (TestHostContext hc = CreateTestContext())
|
||||||
|
{
|
||||||
|
// Arrange.
|
||||||
|
var hf = new HandlerFactory();
|
||||||
|
hf.Initialize(hc);
|
||||||
|
|
||||||
|
var variables = new Dictionary<string, VariableValue>
|
||||||
|
{
|
||||||
|
{ Constants.Runner.NodeMigration.KillLinuxArm32Flag, new VariableValue("true") }
|
||||||
|
};
|
||||||
|
Variables serverVariables = new(hc, variables);
|
||||||
|
|
||||||
|
_ec.Setup(x => x.Global).Returns(new GlobalContext()
|
||||||
|
{
|
||||||
|
Variables = serverVariables,
|
||||||
|
EnvironmentVariables = new Dictionary<string, string>()
|
||||||
|
});
|
||||||
|
|
||||||
|
var actionRef = new RepositoryPathReference
|
||||||
|
{
|
||||||
|
Name = "actions/checkout",
|
||||||
|
Ref = "v5"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act - action explicitly declares node24
|
||||||
|
var data = new NodeJSActionExecutionData();
|
||||||
|
data.NodeVersion = "node24";
|
||||||
|
|
||||||
|
bool isArm32Linux = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture == System.Runtime.InteropServices.Architecture.Arm &&
|
||||||
|
System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (isArm32Linux)
|
||||||
|
{
|
||||||
|
// On ARM32 Linux, kill flag should cause the handler to throw
|
||||||
|
Assert.Throws<InvalidOperationException>(() => hf.Create(
|
||||||
|
_ec.Object,
|
||||||
|
actionRef,
|
||||||
|
new Mock<IStepHost>().Object,
|
||||||
|
data,
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Variables(hc, new Dictionary<string, VariableValue>()),
|
||||||
|
"",
|
||||||
|
new List<JobExtensionRunner>()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// On other platforms, should proceed normally
|
||||||
|
var handler = hf.Create(
|
||||||
|
_ec.Object,
|
||||||
|
actionRef,
|
||||||
|
new Mock<IStepHost>().Object,
|
||||||
|
data,
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Variables(hc, new Dictionary<string, VariableValue>()),
|
||||||
|
"",
|
||||||
|
new List<JobExtensionRunner>()
|
||||||
|
) as INodeScriptActionHandler;
|
||||||
|
|
||||||
|
Assert.Equal("node24", handler.Data.NodeVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void ExplicitNode24Action_DeprecateArm32Flag_DowngradesToNode20OnArm32()
|
||||||
|
{
|
||||||
|
using (TestHostContext hc = CreateTestContext())
|
||||||
|
{
|
||||||
|
// Arrange.
|
||||||
|
var hf = new HandlerFactory();
|
||||||
|
hf.Initialize(hc);
|
||||||
|
|
||||||
|
var variables = new Dictionary<string, VariableValue>
|
||||||
|
{
|
||||||
|
{ Constants.Runner.NodeMigration.DeprecateLinuxArm32Flag, new VariableValue("true") }
|
||||||
|
};
|
||||||
|
Variables serverVariables = new(hc, variables);
|
||||||
|
var arm32Actions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
_ec.Setup(x => x.Global).Returns(new GlobalContext()
|
||||||
|
{
|
||||||
|
Variables = serverVariables,
|
||||||
|
EnvironmentVariables = new Dictionary<string, string>(),
|
||||||
|
Arm32Node20Actions = arm32Actions
|
||||||
|
});
|
||||||
|
|
||||||
|
var actionRef = new RepositoryPathReference
|
||||||
|
{
|
||||||
|
Name = "actions/checkout",
|
||||||
|
Ref = "v5"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act - action explicitly declares node24
|
||||||
|
var data = new NodeJSActionExecutionData();
|
||||||
|
data.NodeVersion = "node24";
|
||||||
|
var handler = hf.Create(
|
||||||
|
_ec.Object,
|
||||||
|
actionRef,
|
||||||
|
new Mock<IStepHost>().Object,
|
||||||
|
data,
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Variables(hc, new Dictionary<string, VariableValue>()),
|
||||||
|
"",
|
||||||
|
new List<JobExtensionRunner>()
|
||||||
|
) as INodeScriptActionHandler;
|
||||||
|
|
||||||
|
bool isArm32Linux = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture == System.Runtime.InteropServices.Architecture.Arm &&
|
||||||
|
System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (isArm32Linux)
|
||||||
|
{
|
||||||
|
// On ARM32 Linux, should downgrade to node20 and track
|
||||||
|
Assert.Equal("node20", handler.Data.NodeVersion);
|
||||||
|
Assert.Contains("actions/checkout@v5", arm32Actions);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// On other platforms, should remain node24
|
||||||
|
Assert.Equal("node24", handler.Data.NodeVersion);
|
||||||
|
Assert.Empty(arm32Actions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void ExplicitNode24Action_NoArm32Flags_StaysNode24()
|
||||||
|
{
|
||||||
|
using (TestHostContext hc = CreateTestContext())
|
||||||
|
{
|
||||||
|
// Arrange.
|
||||||
|
var hf = new HandlerFactory();
|
||||||
|
hf.Initialize(hc);
|
||||||
|
|
||||||
|
var variables = new Dictionary<string, VariableValue>();
|
||||||
|
Variables serverVariables = new(hc, variables);
|
||||||
|
var arm32Actions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
var deprecatedActions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
_ec.Setup(x => x.Global).Returns(new GlobalContext()
|
||||||
|
{
|
||||||
|
Variables = serverVariables,
|
||||||
|
EnvironmentVariables = new Dictionary<string, string>(),
|
||||||
|
Arm32Node20Actions = arm32Actions,
|
||||||
|
DeprecatedNode20Actions = deprecatedActions
|
||||||
|
});
|
||||||
|
|
||||||
|
var actionRef = new RepositoryPathReference
|
||||||
|
{
|
||||||
|
Name = "actions/checkout",
|
||||||
|
Ref = "v5"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act - action explicitly declares node24, no ARM32 flags
|
||||||
|
var data = new NodeJSActionExecutionData();
|
||||||
|
data.NodeVersion = "node24";
|
||||||
|
var handler = hf.Create(
|
||||||
|
_ec.Object,
|
||||||
|
actionRef,
|
||||||
|
new Mock<IStepHost>().Object,
|
||||||
|
data,
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Variables(hc, new Dictionary<string, VariableValue>()),
|
||||||
|
"",
|
||||||
|
new List<JobExtensionRunner>()
|
||||||
|
) as INodeScriptActionHandler;
|
||||||
|
|
||||||
|
// On non-ARM32 platforms, should stay node24 and not be tracked in any list
|
||||||
|
bool isArm32Linux = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture == System.Runtime.InteropServices.Architecture.Arm &&
|
||||||
|
System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (!isArm32Linux)
|
||||||
|
{
|
||||||
|
Assert.Equal("node24", handler.Data.NodeVersion);
|
||||||
|
Assert.Empty(arm32Actions);
|
||||||
|
Assert.Empty(deprecatedActions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void Node20Action_RequireNode24_ForcesNode24()
|
||||||
|
{
|
||||||
|
using (TestHostContext hc = CreateTestContext())
|
||||||
|
{
|
||||||
|
// Arrange.
|
||||||
|
var hf = new HandlerFactory();
|
||||||
|
hf.Initialize(hc);
|
||||||
|
|
||||||
|
var variables = new Dictionary<string, VariableValue>
|
||||||
|
{
|
||||||
|
{ Constants.Runner.NodeMigration.RequireNode24Flag, new VariableValue("true") },
|
||||||
|
{ Constants.Runner.NodeMigration.WarnOnNode20Flag, new VariableValue("true") }
|
||||||
|
};
|
||||||
|
Variables serverVariables = new(hc, variables);
|
||||||
|
var upgradedActions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
var deprecatedActions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
_ec.Setup(x => x.Global).Returns(new GlobalContext()
|
||||||
|
{
|
||||||
|
Variables = serverVariables,
|
||||||
|
EnvironmentVariables = new Dictionary<string, string>(),
|
||||||
|
UpgradedToNode24Actions = upgradedActions,
|
||||||
|
DeprecatedNode20Actions = deprecatedActions
|
||||||
|
});
|
||||||
|
|
||||||
|
var actionRef = new RepositoryPathReference
|
||||||
|
{
|
||||||
|
Name = "actions/checkout",
|
||||||
|
Ref = "v4"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act.
|
||||||
|
var data = new NodeJSActionExecutionData();
|
||||||
|
data.NodeVersion = "node20";
|
||||||
|
|
||||||
|
bool isArm32Linux = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture == System.Runtime.InteropServices.Architecture.Arm &&
|
||||||
|
System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (!isArm32Linux)
|
||||||
|
{
|
||||||
|
var handler = hf.Create(
|
||||||
|
_ec.Object,
|
||||||
|
actionRef,
|
||||||
|
new Mock<IStepHost>().Object,
|
||||||
|
data,
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Variables(hc, new Dictionary<string, VariableValue>()),
|
||||||
|
"",
|
||||||
|
new List<JobExtensionRunner>()
|
||||||
|
) as INodeScriptActionHandler;
|
||||||
|
|
||||||
|
// Phase 3: RequireNode24 forces node24, ignoring env vars
|
||||||
|
Assert.Equal("node24", handler.Data.NodeVersion);
|
||||||
|
Assert.Contains("actions/checkout@v4", upgradedActions);
|
||||||
|
Assert.Empty(deprecatedActions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void Node20Action_KillArm32Flag_ThrowsOnArm32()
|
||||||
|
{
|
||||||
|
using (TestHostContext hc = CreateTestContext())
|
||||||
|
{
|
||||||
|
// Arrange.
|
||||||
|
var hf = new HandlerFactory();
|
||||||
|
hf.Initialize(hc);
|
||||||
|
|
||||||
|
var variables = new Dictionary<string, VariableValue>
|
||||||
|
{
|
||||||
|
{ Constants.Runner.NodeMigration.KillLinuxArm32Flag, new VariableValue("true") }
|
||||||
|
};
|
||||||
|
Variables serverVariables = new(hc, variables);
|
||||||
|
|
||||||
|
_ec.Setup(x => x.Global).Returns(new GlobalContext()
|
||||||
|
{
|
||||||
|
Variables = serverVariables,
|
||||||
|
EnvironmentVariables = new Dictionary<string, string>()
|
||||||
|
});
|
||||||
|
|
||||||
|
var actionRef = new RepositoryPathReference
|
||||||
|
{
|
||||||
|
Name = "actions/checkout",
|
||||||
|
Ref = "v4"
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = new NodeJSActionExecutionData();
|
||||||
|
data.NodeVersion = "node20";
|
||||||
|
|
||||||
|
bool isArm32Linux = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture == System.Runtime.InteropServices.Architecture.Arm &&
|
||||||
|
System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (isArm32Linux)
|
||||||
|
{
|
||||||
|
Assert.Throws<InvalidOperationException>(() => hf.Create(
|
||||||
|
_ec.Object,
|
||||||
|
actionRef,
|
||||||
|
new Mock<IStepHost>().Object,
|
||||||
|
data,
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Variables(hc, new Dictionary<string, VariableValue>()),
|
||||||
|
"",
|
||||||
|
new List<JobExtensionRunner>()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// On non-ARM32, should proceed normally (node20 stays)
|
||||||
|
var handler = hf.Create(
|
||||||
|
_ec.Object,
|
||||||
|
actionRef,
|
||||||
|
new Mock<IStepHost>().Object,
|
||||||
|
data,
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Dictionary<string, string>(),
|
||||||
|
new Variables(hc, new Dictionary<string, VariableValue>()),
|
||||||
|
"",
|
||||||
|
new List<JobExtensionRunner>()
|
||||||
|
) as INodeScriptActionHandler;
|
||||||
|
|
||||||
|
Assert.Equal("node20", handler.Data.NodeVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void ExplicitNode24Action_DeprecateArm32_UsesOriginalVersionForTracking()
|
||||||
|
{
|
||||||
|
// Regression test: verifies that when an action explicitly declares node24
|
||||||
|
// and ARM32 deprecation downgrades it to node20, the tracking call uses
|
||||||
|
// the original preferred version ("node24"), not the already-overwritten
|
||||||
|
// nodeData.NodeVersion ("node20"). Without this fix, ShouldTrackAsArm32Node20
|
||||||
|
// would receive (preferred="node20", final="node20") and never return true.
|
||||||
|
string originalPreferred = "node24";
|
||||||
|
string finalAfterArm32Downgrade = "node20";
|
||||||
|
string deprecationWarning = "Linux ARM32 runners are deprecated and will no longer be supported after September 16th, 2026. Please migrate to a supported platform.";
|
||||||
|
|
||||||
|
// Correct: use the original preferred version before assignment
|
||||||
|
bool correctTracking = HandlerFactory.ShouldTrackAsArm32Node20(
|
||||||
|
deprecateArm32: true,
|
||||||
|
preferredNodeVersion: originalPreferred,
|
||||||
|
finalNodeVersion: finalAfterArm32Downgrade,
|
||||||
|
platformWarningMessage: deprecationWarning);
|
||||||
|
Assert.True(correctTracking);
|
||||||
|
|
||||||
|
// Bug scenario: if nodeData.NodeVersion was already overwritten to finalNodeVersion
|
||||||
|
bool buggyTracking = HandlerFactory.ShouldTrackAsArm32Node20(
|
||||||
|
deprecateArm32: true,
|
||||||
|
preferredNodeVersion: finalAfterArm32Downgrade,
|
||||||
|
finalNodeVersion: finalAfterArm32Downgrade,
|
||||||
|
platformWarningMessage: deprecationWarning);
|
||||||
|
Assert.False(buggyTracking);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
[InlineData(true, "node24", "node20", "Linux ARM32 runners are deprecated", true)]
|
||||||
|
[InlineData(true, "node20", "node20", "Linux ARM32 runners are deprecated", false)]
|
||||||
|
[InlineData(true, "node24", "node24", "Linux ARM32 runners are deprecated", false)]
|
||||||
|
[InlineData(true, "node24", "node20", null, false)]
|
||||||
|
[InlineData(false, "node24", "node20", "Linux ARM32 runners are deprecated", false)]
|
||||||
|
public void ShouldTrackAsArm32Node20_ClassifiesOnlyPlatformDowngrades(
|
||||||
|
bool deprecateArm32,
|
||||||
|
string preferredNodeVersion,
|
||||||
|
string finalNodeVersion,
|
||||||
|
string platformWarningMessage,
|
||||||
|
bool expected)
|
||||||
|
{
|
||||||
|
bool actual = HandlerFactory.ShouldTrackAsArm32Node20(
|
||||||
|
deprecateArm32,
|
||||||
|
preferredNodeVersion,
|
||||||
|
finalNodeVersion,
|
||||||
|
platformWarningMessage);
|
||||||
|
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
public sealed class PipelineTemplateEvaluatorWrapperL0
|
public sealed class PipelineTemplateEvaluatorWrapperL0
|
||||||
{
|
{
|
||||||
private CancellationTokenSource _ecTokenSource;
|
private CancellationTokenSource _ecTokenSource;
|
||||||
|
private CancellationTokenSource _rootTokenSource;
|
||||||
private Mock<IExecutionContext> _ec;
|
private Mock<IExecutionContext> _ec;
|
||||||
private TestHostContext _hc;
|
private TestHostContext _hc;
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
|
|
||||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||||
|
|
||||||
// Call EvaluateAndCompare directly: the new evaluator cancels the token
|
// Call EvaluateAndCompare directly: the new evaluator cancels the root token
|
||||||
// and returns a different value, forcing hasMismatch = true.
|
// and returns a different value, forcing hasMismatch = true.
|
||||||
// Because cancellation flipped during the evaluation window, the
|
// Because cancellation flipped during the evaluation window, the
|
||||||
// mismatch should be skipped.
|
// mismatch should be skipped.
|
||||||
@@ -74,7 +75,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
() => "legacy-value",
|
() => "legacy-value",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
_ecTokenSource.Cancel();
|
_rootTokenSource.Cancel();
|
||||||
return "different-value";
|
return "different-value";
|
||||||
},
|
},
|
||||||
(legacy, @new) => string.Equals(legacy, @new, StringComparison.Ordinal));
|
(legacy, @new) => string.Equals(legacy, @new, StringComparison.Ordinal));
|
||||||
@@ -88,6 +89,43 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void EvaluateAndCompare_SkipsMismatchRecording_WhenRootCancellationOccursBetweenEvaluators()
|
||||||
|
{
|
||||||
|
// Simulates job-level cancellation firing between legacy and new evaluator runs.
|
||||||
|
// Root is mocked with a separate CancellationTokenSource to exercise the
|
||||||
|
// _context.Root?.CancellationToken path (the job-level token).
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Setup();
|
||||||
|
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||||
|
|
||||||
|
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||||
|
|
||||||
|
// Legacy evaluator cancels the root token (simulating job cancel) and returns a value.
|
||||||
|
// The new evaluator returns a different value. The mismatch should be skipped.
|
||||||
|
var result = wrapper.EvaluateAndCompare<string, string>(
|
||||||
|
"TestRootCancellationSkip",
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
var legacyValue = "legacy-value";
|
||||||
|
_rootTokenSource.Cancel();
|
||||||
|
return legacyValue;
|
||||||
|
},
|
||||||
|
() => "different-value",
|
||||||
|
(legacy, @new) => string.Equals(legacy, @new, StringComparison.Ordinal));
|
||||||
|
|
||||||
|
Assert.Equal("legacy-value", result);
|
||||||
|
Assert.False(_ec.Object.Global.HasTemplateEvaluatorMismatch);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Teardown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
@@ -862,6 +900,8 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
{
|
{
|
||||||
_ecTokenSource?.Dispose();
|
_ecTokenSource?.Dispose();
|
||||||
_ecTokenSource = new CancellationTokenSource();
|
_ecTokenSource = new CancellationTokenSource();
|
||||||
|
_rootTokenSource?.Dispose();
|
||||||
|
_rootTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
_hc = new TestHostContext(this, name);
|
_hc = new TestHostContext(this, name);
|
||||||
|
|
||||||
@@ -877,6 +917,9 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
WriteDebug = true,
|
WriteDebug = true,
|
||||||
});
|
});
|
||||||
_ec.Setup(x => x.CancellationToken).Returns(_ecTokenSource.Token);
|
_ec.Setup(x => x.CancellationToken).Returns(_ecTokenSource.Token);
|
||||||
|
var rootEc = new Mock<IExecutionContext>();
|
||||||
|
rootEc.Setup(x => x.CancellationToken).Returns(_rootTokenSource.Token);
|
||||||
|
_ec.Setup(x => x.Root).Returns(rootEc.Object);
|
||||||
_ec.Setup(x => x.ExpressionValues).Returns(expressionValues);
|
_ec.Setup(x => x.ExpressionValues).Returns(expressionValues);
|
||||||
_ec.Setup(x => x.ExpressionFunctions).Returns(expressionFunctions);
|
_ec.Setup(x => x.ExpressionFunctions).Returns(expressionFunctions);
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>())).Callback((string tag, string message) => { _hc.GetTrace().Info($"{tag}{message}"); });
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>())).Callback((string tag, string message) => { _hc.GetTrace().Info($"{tag}{message}"); });
|
||||||
@@ -885,6 +928,8 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
|
|
||||||
private void Teardown()
|
private void Teardown()
|
||||||
{
|
{
|
||||||
|
_ecTokenSource?.Dispose();
|
||||||
|
_rootTokenSource?.Dispose();
|
||||||
_hc?.Dispose();
|
_hc?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,5 +59,161 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
Assert.Equal("node20", nodeVersion);
|
Assert.Equal("node20", nodeVersion);
|
||||||
Assert.Null(warningMessage);
|
Assert.Null(warningMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void CheckNodeVersionForArm32_DeprecationFlagShowsWarning()
|
||||||
|
{
|
||||||
|
string preferredVersion = "node24";
|
||||||
|
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32: true);
|
||||||
|
|
||||||
|
bool isArm32 = RuntimeInformation.ProcessArchitecture == Architecture.Arm ||
|
||||||
|
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")?.Contains("ARM") == true;
|
||||||
|
bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (isArm32 && isLinux)
|
||||||
|
{
|
||||||
|
Assert.Equal("node20", nodeVersion);
|
||||||
|
Assert.NotNull(warningMessage);
|
||||||
|
Assert.Contains("deprecated", warningMessage);
|
||||||
|
Assert.Contains("no longer be supported", warningMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal("node24", nodeVersion);
|
||||||
|
Assert.Null(warningMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void CheckNodeVersionForArm32_DeprecationFlagWithNode20PassesThrough()
|
||||||
|
{
|
||||||
|
// Even with deprecation flag, node20 should pass through (not downgraded further)
|
||||||
|
string preferredVersion = "node20";
|
||||||
|
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32: true);
|
||||||
|
|
||||||
|
bool isArm32 = RuntimeInformation.ProcessArchitecture == Architecture.Arm ||
|
||||||
|
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")?.Contains("ARM") == true;
|
||||||
|
bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (isArm32 && isLinux)
|
||||||
|
{
|
||||||
|
Assert.Equal("node20", nodeVersion);
|
||||||
|
Assert.NotNull(warningMessage);
|
||||||
|
Assert.Contains("deprecated", warningMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal("node20", nodeVersion);
|
||||||
|
Assert.Null(warningMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void CheckNodeVersionForArm32_KillFlagReturnsNull()
|
||||||
|
{
|
||||||
|
string preferredVersion = "node24";
|
||||||
|
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, killArm32: true);
|
||||||
|
|
||||||
|
bool isArm32 = RuntimeInformation.ProcessArchitecture == Architecture.Arm ||
|
||||||
|
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")?.Contains("ARM") == true;
|
||||||
|
bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (isArm32 && isLinux)
|
||||||
|
{
|
||||||
|
Assert.Null(nodeVersion);
|
||||||
|
Assert.NotNull(warningMessage);
|
||||||
|
Assert.Contains("no longer supported", warningMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal("node24", nodeVersion);
|
||||||
|
Assert.Null(warningMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void CheckNodeVersionForArm32_KillTakesPrecedenceOverDeprecation()
|
||||||
|
{
|
||||||
|
string preferredVersion = "node20";
|
||||||
|
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32: true, killArm32: true);
|
||||||
|
|
||||||
|
bool isArm32 = RuntimeInformation.ProcessArchitecture == Architecture.Arm ||
|
||||||
|
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")?.Contains("ARM") == true;
|
||||||
|
bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (isArm32 && isLinux)
|
||||||
|
{
|
||||||
|
Assert.Null(nodeVersion);
|
||||||
|
Assert.NotNull(warningMessage);
|
||||||
|
Assert.Contains("no longer supported", warningMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal("node20", nodeVersion);
|
||||||
|
Assert.Null(warningMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void CheckNodeVersionForArm32_ServerOverridableDateUsedInDeprecationWarning()
|
||||||
|
{
|
||||||
|
string preferredVersion = "node24";
|
||||||
|
string customDate = "December 1st, 2027";
|
||||||
|
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(
|
||||||
|
preferredVersion, deprecateArm32: true, node20RemovalDate: customDate);
|
||||||
|
|
||||||
|
bool isArm32 = RuntimeInformation.ProcessArchitecture == Architecture.Arm ||
|
||||||
|
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")?.Contains("ARM") == true;
|
||||||
|
bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (isArm32 && isLinux)
|
||||||
|
{
|
||||||
|
Assert.Equal("node20", nodeVersion);
|
||||||
|
Assert.NotNull(warningMessage);
|
||||||
|
Assert.Contains(customDate, warningMessage);
|
||||||
|
Assert.DoesNotContain(Constants.Runner.NodeMigration.Node20RemovalDate, warningMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal("node24", nodeVersion);
|
||||||
|
Assert.Null(warningMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void CheckNodeVersionForArm32_FallbackDateUsedWhenNoOverride()
|
||||||
|
{
|
||||||
|
string preferredVersion = "node24";
|
||||||
|
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(
|
||||||
|
preferredVersion, deprecateArm32: true);
|
||||||
|
|
||||||
|
bool isArm32 = RuntimeInformation.ProcessArchitecture == Architecture.Arm ||
|
||||||
|
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")?.Contains("ARM") == true;
|
||||||
|
bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||||
|
|
||||||
|
if (isArm32 && isLinux)
|
||||||
|
{
|
||||||
|
Assert.Equal("node20", nodeVersion);
|
||||||
|
Assert.NotNull(warningMessage);
|
||||||
|
Assert.Contains(Constants.Runner.NodeMigration.Node20RemovalDate, warningMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal("node24", nodeVersion);
|
||||||
|
Assert.Null(warningMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/Test/TestData/dockerfileaction_env_invalid_context.yml
Normal file
13
src/Test/TestData/dockerfileaction_env_invalid_context.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
name: 'Action With Invalid Context'
|
||||||
|
description: 'Docker action that uses github context in env (only inputs is allowed)'
|
||||||
|
inputs:
|
||||||
|
my-input:
|
||||||
|
description: 'A test input'
|
||||||
|
required: false
|
||||||
|
default: 'hello'
|
||||||
|
runs:
|
||||||
|
using: 'docker'
|
||||||
|
image: 'Dockerfile'
|
||||||
|
env:
|
||||||
|
VALID: '${{ inputs.my-input }}'
|
||||||
|
INVALID: '${{ github.event.repository.private }}'
|
||||||
@@ -17,7 +17,7 @@ LAYOUT_DIR="$SCRIPT_DIR/../_layout"
|
|||||||
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
|
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
|
||||||
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
||||||
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
||||||
DOTNETSDK_VERSION="8.0.418"
|
DOTNETSDK_VERSION="8.0.419"
|
||||||
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
|
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
|
||||||
RUNNER_VERSION=$(cat runnerversion)
|
RUNNER_VERSION=$(cat runnerversion)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "8.0.418"
|
"version": "8.0.419"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.332.0
|
2.333.0
|
||||||
|
|||||||
Reference in New Issue
Block a user