Compare commits

..

6 Commits

Author SHA1 Message Date
Philip Gai b7ad1dad31 chore(deps): bump @actions/cache to 6.2.0 (#771)
* chore(deps): bump @actions/cache to 5.2.0

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* chore(deps): update licensed record for @actions/cache 5.2.0

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* chore(deps): bump @actions/cache to 6.2.0

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 290d6c74-496d-441c-bdbe-08fc907e0d44

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-15 21:47:49 -05:00
Priya Gupta 0778a10ce4 Migrate to ESM and upgrade dependencies (#763)
* Migrate to ESM and upgrade dependencies

* Remove unused tsconfig.eslint.json

* bump version to 7.0.0 in package.json and package-lock.json

* Add ESM migration note to README for V7

* Remove unnecessary devDependencies: ts-node, @types/jest

* npm audit fix

* Update README with ESM migration details

Clarified migration details to ESM for action compatibility.

* Downgrade @types/node to ^24, clean up tsconfig and README.
2026-07-15 15:34:36 -05:00
Haritha 924ae3a1cd chore: bump version to 6.5.0 in package.json and package-lock.json (#762)
* chore: bump version to 6.5.0 in package.json and package-lock.json

* chore: update README.md for improved clarity and structure

* License update
2026-06-23 12:03:17 -05:00
Jason Ginchereau e91cc3bfe0 Bump @actions/cache to 5.1.0, log cache write denied (#758)
* Bump @actions/cache to 5.1.0, log cache write denied

* Add cache save tests

* Re-trigger CI
2026-06-22 14:14:01 -05:00
Haritha 4a2405e6ae chore: update @types/node and @typescript-eslint dependencies to latest versions (#755) 2026-06-16 11:46:40 -05:00
Copilot 78961f6f84 chore: update @actions dependencies and refresh license cache (#744)
Agent-Logs-Url: https://github.com/actions/setup-go/sessions/0e15a7f6-9e3f-4b17-98fc-7c6501a56b31

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: priyagupta108 <147705955+priyagupta108@users.noreply.github.com>
2026-04-13 14:45:08 -05:00
66 changed files with 128742 additions and 169111 deletions
-6
View File
@@ -1,6 +0,0 @@
# Ignore list
/*
# Do not ignore these folders:
!__tests__/
!src/
-51
View File
@@ -1,51 +0,0 @@
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:eslint-plugin-jest/recommended',
'eslint-config-prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'eslint-plugin-node', 'eslint-plugin-jest'],
rules: {
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/ban-ts-comment': [
'error',
{
'ts-ignore': 'allow-with-description'
}
],
'no-console': 'error',
'yoda': 'error',
'prefer-const': [
'error',
{
destructuring: 'all'
}
],
'no-control-regex': 'off',
'no-constant-condition': ['error', {checkLoops: false}],
'node/no-extraneous-import': 'error'
},
overrides: [
{
files: ['**/*{test,spec}.ts'],
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'jest/no-standalone-expect': 'off',
'jest/no-conditional-expect': 'off',
'no-console': 'off',
}
}
],
env: {
node: true,
es6: true,
'jest/globals': true
}
};
+3
View File
@@ -10,7 +10,10 @@ allowed:
- cc0-1.0 - cc0-1.0
- unlicense - unlicense
- 0bsd - 0bsd
- blueoak-1.0.0
reviewed: reviewed:
npm: npm:
- "@actions/http-client" - "@actions/http-client"
- "balanced-match"
- "brace-expansion"
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: "@actions/cache" name: "@actions/cache"
version: 5.0.1 version: 6.2.0
type: npm type: npm
summary: Actions cache lib summary: Actions cache lib
homepage: https://github.com/actions/toolkit/tree/main/packages/cache homepage: https://github.com/actions/toolkit/tree/main/packages/cache
-20
View File
@@ -1,20 +0,0 @@
---
name: "@actions/core"
version: 1.11.1
type: npm
summary: Actions core lib
homepage: https://github.com/actions/toolkit/tree/main/packages/core
license: mit
licenses:
- sources: LICENSE.md
text: |-
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []
@@ -1,6 +1,6 @@
--- ---
name: "@actions/core" name: "@actions/core"
version: 2.0.1 version: 3.0.1
type: npm type: npm
summary: Actions core lib summary: Actions core lib
homepage: https://github.com/actions/toolkit/tree/main/packages/core homepage: https://github.com/actions/toolkit/tree/main/packages/core
@@ -1,6 +1,6 @@
--- ---
name: "@actions/exec" name: "@actions/exec"
version: 1.1.1 version: 3.0.0
type: npm type: npm
summary: Actions exec lib summary: Actions exec lib
homepage: https://github.com/actions/toolkit/tree/main/packages/exec homepage: https://github.com/actions/toolkit/tree/main/packages/exec
@@ -1,6 +1,6 @@
--- ---
name: "@actions/glob" name: "@actions/glob"
version: 0.5.0 version: 0.6.1
type: npm type: npm
summary: Actions glob lib summary: Actions glob lib
homepage: https://github.com/actions/toolkit/tree/main/packages/glob homepage: https://github.com/actions/toolkit/tree/main/packages/glob
@@ -1,9 +1,9 @@
--- ---
name: "@actions/exec" name: "@actions/glob"
version: 2.0.0 version: 0.7.0
type: npm type: npm
summary: Actions exec lib summary: Actions glob lib
homepage: https://github.com/actions/toolkit/tree/main/packages/exec homepage: https://github.com/actions/toolkit/tree/main/packages/glob
license: mit license: mit
licenses: licenses:
- sources: LICENSE.md - sources: LICENSE.md
-32
View File
@@ -1,32 +0,0 @@
---
name: "@actions/http-client"
version: 2.2.3
type: npm
summary: Actions Http Client
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
license: mit
licenses:
- sources: LICENSE
text: |
Actions Http Client for Node.js
Copyright (c) GitHub, Inc.
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []
@@ -1,6 +1,6 @@
--- ---
name: "@actions/http-client" name: "@actions/http-client"
version: 3.0.2 version: 4.0.1
type: npm type: npm
summary: Actions Http Client summary: Actions Http Client
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
-20
View File
@@ -1,20 +0,0 @@
---
name: "@actions/io"
version: 2.0.0
type: npm
summary: Actions io lib
homepage: https://github.com/actions/toolkit/tree/main/packages/io
license: mit
licenses:
- sources: LICENSE.md
text: |-
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []
@@ -1,6 +1,6 @@
--- ---
name: "@actions/io" name: "@actions/io"
version: 1.1.3 version: 3.0.2
type: npm type: npm
summary: Actions io lib summary: Actions io lib
homepage: https://github.com/actions/toolkit/tree/main/packages/io homepage: https://github.com/actions/toolkit/tree/main/packages/io
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: "@actions/tool-cache" name: "@actions/tool-cache"
version: 2.0.2 version: 4.0.0
type: npm type: npm
summary: Actions tool-cache lib summary: Actions tool-cache lib
homepage: https://github.com/actions/toolkit/tree/main/packages/tool-cache homepage: https://github.com/actions/toolkit/tree/main/packages/tool-cache
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: "@azure/core-client" name: "@azure/core-client"
version: 1.10.1 version: 1.10.2
type: npm type: npm
summary: Core library for interfacing with AutoRest generated code summary: Core library for interfacing with AutoRest generated code
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-client/ homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-client/
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: "@azure/core-http-compat" name: "@azure/core-http-compat"
version: 2.3.1 version: 2.4.0
type: npm type: npm
summary: Core HTTP Compatibility Library to bridge the gap between Core V1 & V2 packages. summary: Core HTTP Compatibility Library to bridge the gap between Core V1 & V2 packages.
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-compat/ homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-compat/
+2 -2
View File
@@ -1,9 +1,9 @@
--- ---
name: "@azure/core-rest-pipeline" name: "@azure/core-rest-pipeline"
version: 1.22.2 version: 1.24.0
type: npm type: npm
summary: Isomorphic client library for making HTTP requests in node.js and browser. summary: Isomorphic client library for making HTTP requests in node.js and browser.
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-rest-pipeline/ homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-rest-pipeline/README.md
license: mit license: mit
licenses: licenses:
- sources: LICENSE - sources: LICENSE
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: "@azure/core-xml" name: "@azure/core-xml"
version: 1.5.0 version: 1.5.1
type: npm type: npm
summary: Core library for interacting with XML payloads summary: Core library for interacting with XML payloads
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-xml/ homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-xml/
+2 -2
View File
@@ -1,9 +1,9 @@
--- ---
name: "@azure/storage-blob" name: "@azure/storage-blob"
version: 12.29.1 version: 12.32.0
type: npm type: npm
summary: Microsoft Azure Storage SDK for JavaScript - Blob summary: Microsoft Azure Storage SDK for JavaScript - Blob
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/ homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/storage/storage-blob/README.md
license: mit license: mit
licenses: licenses:
- sources: LICENSE - sources: LICENSE
+2 -2
View File
@@ -1,9 +1,9 @@
--- ---
name: "@azure/storage-common" name: "@azure/storage-common"
version: 12.1.1 version: 12.4.0
type: npm type: npm
summary: Azure Storage Common Client Library for JavaScript summary: Azure Storage Common Client Library for JavaScript
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-internal-avro/ homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/storage/storage-common/README.md
license: mit license: mit
licenses: licenses:
- sources: LICENSE - sources: LICENSE
+11
View File
@@ -0,0 +1,11 @@
---
name: "@nodable/entities"
version: 2.2.0
type: npm
summary: Entity parser for XML, HTML, External entites with security and NCR control
homepage:
license: mit
licenses:
- sources: README.md
text: MIT
notices: []
+2 -2
View File
@@ -1,9 +1,9 @@
--- ---
name: "@typespec/ts-http-runtime" name: "@typespec/ts-http-runtime"
version: 0.3.2 version: 0.3.6
type: npm type: npm
summary: Isomorphic client library for making HTTP requests in node.js and browser. summary: Isomorphic client library for making HTTP requests in node.js and browser.
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/ts-http-runtime/ homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/ts-http-runtime/README.md
license: mit license: mit
licenses: licenses:
- sources: LICENSE - sources: LICENSE
@@ -1,16 +1,17 @@
--- ---
name: undici name: anynum
version: 5.29.0 version: 1.0.1
type: npm type: npm
summary: An HTTP/1.1 client, written from scratch for Node.js summary: Normalize all Unicode decimal digits (Devanagari, Arabic, Thai, etc.) to
homepage: https://undici.nodejs.org ASCII numerals. Zero dependencies, performance-first.
homepage:
license: mit license: mit
licenses: licenses:
- sources: LICENSE - sources: LICENSE
text: | text: |
MIT License MIT License
Copyright (c) Matteo Collina and Undici contributors Copyright (c) 2026 Natural Intelligence
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+34
View File
@@ -0,0 +1,34 @@
---
name: balanced-match
version: 4.0.4
type: npm
summary: Match balanced character pairs, like "{" and "}"
homepage:
license: other
licenses:
- sources: LICENSE.md
text: |
(MIT)
Original code Copyright Julian Gruber <julian@juliangruber.com>
Port to TypeScript Copyright Isaac Z. Schlueter <i@izs.me>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []
@@ -1,6 +1,6 @@
--- ---
name: brace-expansion name: brace-expansion
version: 1.1.12 version: 1.1.15
type: npm type: npm
summary: Brace expansion as known from sh/bash summary: Brace expansion as known from sh/bash
homepage: https://github.com/juliangruber/brace-expansion homepage: https://github.com/juliangruber/brace-expansion
@@ -1,30 +1,34 @@
--- ---
name: "@fastify/busboy" name: brace-expansion
version: 2.1.1 version: 5.0.6
type: npm type: npm
summary: A streaming parser for HTML form data for node.js summary: Brace expansion as known from sh/bash
homepage: homepage:
license: mit license: other
licenses: licenses:
- sources: LICENSE - sources: LICENSE
text: |- text: |
Copyright Brian White. All rights reserved. MIT License
Copyright Julian Gruber <julian@juliangruber.com>
TypeScript port Copyright Isaac Z. Schlueter <i@izs.me>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to of this software and associated documentation files (the "Software"), to deal
deal in the Software without restriction, including without limitation the in the Software without restriction, including without limitation the rights
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
sell copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in all
all copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
IN THE SOFTWARE. SOFTWARE.
notices: [] notices: []
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: fast-xml-builder name: fast-xml-builder
version: 1.0.0 version: 1.2.0
type: npm type: npm
summary: Build XML from JSON without C/C++ based libraries summary: Build XML from JSON without C/C++ based libraries
homepage: homepage:
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: fast-xml-parser name: fast-xml-parser
version: 5.4.1 version: 5.9.3
type: npm type: npm
summary: Validate XML, Parse XML, Build XML without C/C++ based libraries summary: Validate XML, Parse XML, Build XML without C/C++ based libraries
homepage: homepage:
+35
View File
@@ -0,0 +1,35 @@
---
name: is-unsafe
version: 1.0.1
type: npm
summary: Zero-dependency, DOM-free, pure predicate for detecting unsafe strings across
HTML, XML, SVG, SQL, SHELL, and REGEX contexts
homepage:
license: mit
licenses:
- sources: LICENSE
text: |
MIT License
Copyright (c) 2026 Natural Intelligence
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- sources: README.md
text: MIT
notices: []
+66
View File
@@ -0,0 +1,66 @@
---
name: minimatch
version: 10.2.5
type: npm
summary: a glob matcher in javascript
homepage:
license: blueoak-1.0.0
licenses:
- sources: LICENSE.md
text: |
# Blue Oak Model License
Version 1.0.0
## Purpose
This license gives everyone as much permission to work with
this software as possible, while protecting contributors
from liability.
## Acceptance
In order to receive this license, you must agree to its
rules. The rules of this license are both obligations
under that agreement and conditions to your license.
You must not do anything with this software that triggers
a rule that you cannot or will not follow.
## Copyright
Each contributor licenses you to do everything with this
software that would otherwise infringe that contributor's
copyright in it.
## Notices
You must ensure that everyone who gets a copy of
any part of this software from you, with or without
changes, also gets the text of this license or a link to
<https://blueoakcouncil.org/license/1.0.0>.
## Excuse
If anyone notifies you in writing that you have not
complied with [Notices](#notices), you can keep your
license by taking all practical steps to comply within 30
days after the notice. If you do not do so, your license
ends immediately.
## Patent
Each contributor licenses you to do everything with this
software that would otherwise infringe any patent claims
they can license or become able to license.
## Reliability
No contributor can revoke this license.
## No Liability
**_As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim._**
notices: []
@@ -1,16 +1,16 @@
--- ---
name: "@azure/abort-controller" name: path-expression-matcher
version: 1.1.0 version: 1.6.0
type: npm type: npm
summary: Microsoft Azure SDK for JavaScript - Aborter summary: Efficient path tracking and pattern matching for XML/JSON parsers
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/abort-controller/README.md homepage: https://github.com/NaturalIntelligence/path-expression-matcher#readme
license: mit license: mit
licenses: licenses:
- sources: LICENSE - sources: LICENSE
text: | text: |
The MIT License (MIT) MIT License
Copyright (c) 2020 Microsoft Copyright (c) 2024
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
-26
View File
@@ -1,26 +0,0 @@
---
name: semver
version: 6.3.1
type: npm
summary: The semantic version parser used by npm.
homepage:
license: isc
licenses:
- sources: LICENSE
text: |
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
notices: []
@@ -1,6 +1,6 @@
--- ---
name: semver name: semver
version: 7.7.3 version: 7.8.5
type: npm type: npm
summary: The semantic version parser used by npm. summary: The semantic version parser used by npm.
homepage: homepage:
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: strnum name: strnum
version: 2.1.2 version: 2.4.1
type: npm type: npm
summary: Parse String to Number based on configuration summary: Parse String to Number based on configuration
homepage: homepage:
@@ -1,6 +1,6 @@
--- ---
name: undici name: undici
version: 6.23.0 version: 6.27.0
type: npm type: npm
summary: An HTTP/1.1 client, written from scratch for Node.js summary: An HTTP/1.1 client, written from scratch for Node.js
homepage: https://undici.nodejs.org homepage: https://undici.nodejs.org
+12
View File
@@ -0,0 +1,12 @@
---
name: xml-naming
version: 0.1.0
type: npm
summary: Validates XML name productions — Name, NCName, QName, NMToken, NMTokens —
for XML 1.0 and 1.1
homepage:
license: mit
licenses:
- sources: README.md
text: MIT
notices: []
-11
View File
@@ -1,11 +0,0 @@
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
module.exports = {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: false,
arrowParens: 'avoid'
};
+10
View File
@@ -0,0 +1,10 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"arrowParens": "avoid"
}
+6
View File
@@ -9,6 +9,12 @@ This action sets up a Go environment for use in GitHub Actions by:
- Optionally caching Go modules and build outputs - Optionally caching Go modules and build outputs
- Registering problem matchers for error output - Registering problem matchers for error output
## What's new in V7
The V7 edition of the action includes:
- Migrated action internals to ESM for compatibility with latest `@actions/*` packages. No changes to action inputs, outputs, or behavior.
## Breaking changes in V6 ## Breaking changes in V6
The V6 edition of the action includes: The V6 edition of the action includes:
+67 -16
View File
@@ -1,18 +1,65 @@
import * as cache from '@actions/cache'; import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import * as core from '@actions/core';
import * as glob from '@actions/glob';
import fs from 'fs'; import fs from 'fs';
import * as cacheRestore from '../src/cache-restore'; jest.unstable_mockModule('@actions/cache', () => ({
import * as cacheUtils from '../src/cache-utils'; saveCache: jest.fn(),
import {PackageManagerInfo} from '../src/package-managers'; restoreCache: jest.fn(),
isFeatureAvailable: jest.fn()
}));
jest.unstable_mockModule('@actions/glob', () => ({
create: jest.fn(),
hashFiles: jest.fn()
}));
jest.unstable_mockModule('@actions/core', () => ({
info: jest.fn(),
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
notice: jest.fn(),
setFailed: jest.fn(),
setOutput: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getMultilineInput: jest.fn(),
addPath: jest.fn(),
exportVariable: jest.fn(),
saveState: jest.fn(),
getState: jest.fn(),
setSecret: jest.fn(),
isDebug: jest.fn(() => false),
startGroup: jest.fn(),
endGroup: jest.fn(),
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}));
// Import real cache-utils (with mocked @actions) before mocking it
const realCacheUtils = await import('../src/cache-utils.js');
jest.unstable_mockModule('../src/cache-utils.js', () => ({
...realCacheUtils,
getCacheDirectoryPath: jest.fn()
}));
const cache = await import('@actions/cache');
const core = await import('@actions/core');
const glob = await import('@actions/glob');
const cacheRestore = await import('../src/cache-restore.js');
const cacheUtils = await import('../src/cache-utils.js');
import type {PackageManagerInfo} from '../src/package-managers.js';
describe('restoreCache', () => { describe('restoreCache', () => {
let hashFilesSpy: jest.SpyInstance; let hashFilesSpy: jest.Mock<typeof glob.hashFiles>;
let getCacheDirectoryPathSpy: jest.SpyInstance; let getCacheDirectoryPathSpy: jest.Mock<
let restoreCacheSpy: jest.SpyInstance; typeof cacheUtils.getCacheDirectoryPath
let infoSpy: jest.SpyInstance; >;
let setOutputSpy: jest.SpyInstance; let restoreCacheSpy: jest.Mock<typeof cache.restoreCache>;
let infoSpy: jest.Mock<typeof core.info>;
let setOutputSpy: jest.Mock<typeof core.setOutput>;
const versionSpec = '1.13.1'; const versionSpec = '1.13.1';
const packageManager = 'default'; const packageManager = 'default';
@@ -24,11 +71,15 @@ describe('restoreCache', () => {
originalWorkspace = process.env.GITHUB_WORKSPACE; originalWorkspace = process.env.GITHUB_WORKSPACE;
process.env.GITHUB_WORKSPACE = '/test/workspace'; process.env.GITHUB_WORKSPACE = '/test/workspace';
//Arrange //Arrange
hashFilesSpy = jest.spyOn(glob, 'hashFiles'); hashFilesSpy = glob.hashFiles as jest.Mock<typeof glob.hashFiles>;
getCacheDirectoryPathSpy = jest.spyOn(cacheUtils, 'getCacheDirectoryPath'); getCacheDirectoryPathSpy = cacheUtils.getCacheDirectoryPath as jest.Mock<
restoreCacheSpy = jest.spyOn(cache, 'restoreCache'); typeof cacheUtils.getCacheDirectoryPath
infoSpy = jest.spyOn(core, 'info'); >;
setOutputSpy = jest.spyOn(core, 'setOutput'); restoreCacheSpy = cache.restoreCache as jest.Mock<
typeof cache.restoreCache
>;
infoSpy = core.info as jest.Mock<typeof core.info>;
setOutputSpy = core.setOutput as jest.Mock<typeof core.setOutput>;
getCacheDirectoryPathSpy.mockImplementation( getCacheDirectoryPathSpy.mockImplementation(
(PackageManager: PackageManagerInfo) => { (PackageManager: PackageManagerInfo) => {
+192
View File
@@ -0,0 +1,192 @@
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
jest.unstable_mockModule('@actions/cache', () => ({
saveCache: jest.fn(),
restoreCache: jest.fn(),
isFeatureAvailable: jest.fn()
}));
jest.unstable_mockModule('@actions/core', () => ({
info: jest.fn(),
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
setFailed: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getState: jest.fn(),
saveState: jest.fn()
}));
const realFs = (await import('fs')).default;
const fsExports = {...realFs, existsSync: jest.fn()};
jest.unstable_mockModule('fs', () => ({...fsExports, default: fsExports}));
// Import real cache-utils (with mocked @actions) before mocking it
const realCacheUtils = await import('../src/cache-utils.js');
jest.unstable_mockModule('../src/cache-utils.js', () => ({
...realCacheUtils,
getCacheDirectoryPath: jest.fn()
}));
const cache = await import('@actions/cache');
const core = await import('@actions/core');
const fs = (await import('fs')).default;
const cacheUtils = await import('../src/cache-utils.js');
const {run} = await import('../src/cache-save.js');
const {State} = await import('../src/constants.js');
describe('cache-save', () => {
const primaryKey = 'primary-key';
let primaryKeyValue: string;
let matchedKeyValue: string;
let getBooleanInputSpy: jest.Mock<typeof core.getBooleanInput>;
let getStateSpy: jest.Mock<typeof core.getState>;
let infoSpy: jest.Mock<typeof core.info>;
let warningSpy: jest.Mock<typeof core.warning>;
let debugSpy: jest.Mock<typeof core.debug>;
let setFailedSpy: jest.Mock<typeof core.setFailed>;
let saveCacheSpy: jest.Mock<typeof cache.saveCache>;
let getCacheDirectoryPathSpy: jest.Mock<
typeof cacheUtils.getCacheDirectoryPath
>;
let existsSpy: jest.Mock<typeof fs.existsSync>;
beforeEach(() => {
primaryKeyValue = primaryKey;
matchedKeyValue = 'matched-key';
getBooleanInputSpy = core.getBooleanInput as jest.Mock<
typeof core.getBooleanInput
>;
getBooleanInputSpy.mockReturnValue(true);
getStateSpy = core.getState as jest.Mock<typeof core.getState>;
getStateSpy.mockImplementation((key: string) => {
if (key === State.CachePrimaryKey) {
return primaryKeyValue;
}
if (key === State.CacheMatchedKey) {
return matchedKeyValue;
}
return '';
});
infoSpy = core.info as jest.Mock<typeof core.info>;
infoSpy.mockImplementation(() => undefined);
warningSpy = core.warning as jest.Mock<typeof core.warning>;
warningSpy.mockImplementation(() => undefined);
debugSpy = core.debug as jest.Mock<typeof core.debug>;
debugSpy.mockImplementation(() => undefined);
setFailedSpy = core.setFailed as jest.Mock<typeof core.setFailed>;
setFailedSpy.mockImplementation(() => undefined);
saveCacheSpy = cache.saveCache as jest.Mock<typeof cache.saveCache>;
saveCacheSpy.mockImplementation(() => Promise.resolve(0));
getCacheDirectoryPathSpy = cacheUtils.getCacheDirectoryPath as jest.Mock<
typeof cacheUtils.getCacheDirectoryPath
>;
getCacheDirectoryPathSpy.mockImplementation(() =>
Promise.resolve(['cache_directory_path', 'cache_directory_path'])
);
existsSpy = fs.existsSync as jest.Mock<typeof fs.existsSync>;
existsSpy.mockImplementation(() => true);
});
afterEach(() => {
jest.clearAllMocks();
});
it('does not save cache when the cache input is false', async () => {
getBooleanInputSpy.mockReturnValue(false);
await run();
expect(saveCacheSpy).not.toHaveBeenCalled();
expect(warningSpy).not.toHaveBeenCalled();
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('does not save cache when there are no cache folders on the disk', async () => {
existsSpy.mockImplementation(() => false);
await run();
expect(warningSpy).toHaveBeenCalledWith(
'There are no cache folders on the disk'
);
expect(saveCacheSpy).not.toHaveBeenCalled();
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('does not save cache when the primary key was not generated', async () => {
primaryKeyValue = '';
await run();
expect(infoSpy).toHaveBeenCalledWith(
'Primary key was not generated. Please check the log messages above for more errors or information'
);
expect(saveCacheSpy).not.toHaveBeenCalled();
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('does not save cache when a cache hit occurred on the primary key', async () => {
matchedKeyValue = primaryKey;
await run();
expect(infoSpy).toHaveBeenCalledWith(
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
);
expect(saveCacheSpy).not.toHaveBeenCalled();
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('saves cache when the primary key differs from the matched key', async () => {
await run();
expect(saveCacheSpy).toHaveBeenCalled();
expect(infoSpy).toHaveBeenCalledWith(
`Cache saved with the key: ${primaryKey}`
);
expect(warningSpy).not.toHaveBeenCalled();
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('save with -1 cacheId , should not fail workflow', async () => {
saveCacheSpy.mockImplementation(() => Promise.resolve(-1));
await run();
expect(saveCacheSpy).toHaveBeenCalled();
expect(debugSpy).toHaveBeenCalledWith(
`Cache was not saved for the key: ${primaryKey}`
);
expect(infoSpy).not.toHaveBeenCalledWith(
`Cache saved with the key: ${primaryKey}`
);
expect(warningSpy).not.toHaveBeenCalled();
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('saves with error from toolkit, should not fail workflow', async () => {
saveCacheSpy.mockImplementation(() =>
Promise.reject(new Error('Unable to reach the service'))
);
await run();
expect(saveCacheSpy).toHaveBeenCalled();
expect(warningSpy).toHaveBeenCalledWith('Unable to reach the service');
expect(setFailedSpy).not.toHaveBeenCalled();
});
});
+68 -39
View File
@@ -1,22 +1,60 @@
import * as exec from '@actions/exec'; import {jest, describe, it, expect, beforeEach, afterAll} from '@jest/globals';
import * as cache from '@actions/cache';
import * as core from '@actions/core'; jest.unstable_mockModule('@actions/exec', () => ({
import * as cacheUtils from '../src/cache-utils'; exec: jest.fn(),
import {PackageManagerInfo} from '../src/package-managers'; getExecOutput: jest.fn()
}));
jest.unstable_mockModule('@actions/cache', () => ({
saveCache: jest.fn(),
restoreCache: jest.fn(),
isFeatureAvailable: jest.fn()
}));
jest.unstable_mockModule('@actions/core', () => ({
info: jest.fn(),
warning: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
notice: jest.fn(),
setFailed: jest.fn(),
setOutput: jest.fn(),
getInput: jest.fn(),
getBooleanInput: jest.fn(),
getMultilineInput: jest.fn(),
addPath: jest.fn(),
exportVariable: jest.fn(),
saveState: jest.fn(),
getState: jest.fn(),
setSecret: jest.fn(),
isDebug: jest.fn(() => false),
startGroup: jest.fn(),
endGroup: jest.fn(),
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
toPlatformPath: jest.fn((p: string) => p),
toWin32Path: jest.fn((p: string) => p),
toPosixPath: jest.fn((p: string) => p)
}));
const exec = await import('@actions/exec');
const cache = await import('@actions/cache');
const core = await import('@actions/core');
const cacheUtils = await import('../src/cache-utils.js');
import type {PackageManagerInfo} from '../src/package-managers.js';
describe('getCommandOutput', () => { describe('getCommandOutput', () => {
//Arrange //Arrange
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput'); const getExecOutputSpy = exec.getExecOutput as jest.Mock<
typeof exec.getExecOutput
>;
it('should return trimmed stdout in case of successful exit code', async () => { it('should return trimmed stdout in case of successful exit code', async () => {
//Arrange //Arrange
const stdoutResult = ' stdout '; const stdoutResult = ' stdout ';
const trimmedStdout = stdoutResult.trim(); const trimmedStdout = stdoutResult.trim();
getExecOutputSpy.mockImplementation((commandLine: string) => { getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => { return {exitCode: 0, stdout: stdoutResult, stderr: ''};
resolve({exitCode: 0, stdout: stdoutResult, stderr: ''});
});
}); });
//Act + Assert //Act + Assert
@@ -29,10 +67,8 @@ describe('getCommandOutput', () => {
//Arrange //Arrange
const stderrResult = 'error message'; const stderrResult = 'error message';
getExecOutputSpy.mockImplementation((commandLine: string) => { getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => { return {exitCode: 10, stdout: '', stderr: stderrResult};
resolve({exitCode: 10, stdout: '', stderr: stderrResult});
});
}); });
//Act + Assert //Act + Assert
@@ -70,7 +106,9 @@ describe('getPackageManagerInfo', () => {
describe('getCacheDirectoryPath', () => { describe('getCacheDirectoryPath', () => {
//Arrange //Arrange
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput'); const getExecOutputSpy = exec.getExecOutput as jest.Mock<
typeof exec.getExecOutput
>;
const validPackageManager: PackageManagerInfo = { const validPackageManager: PackageManagerInfo = {
dependencyFilePattern: 'go.mod', dependencyFilePattern: 'go.mod',
@@ -79,10 +117,8 @@ describe('getCacheDirectoryPath', () => {
it('should return path to the cache folders which specified package manager uses', async () => { it('should return path to the cache folders which specified package manager uses', async () => {
//Arrange //Arrange
getExecOutputSpy.mockImplementation((commandLine: string) => { getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => { return {exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''};
resolve({exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''});
});
}); });
const expectedResult = ['path/to/cache/folder', 'path/to/cache/folder']; const expectedResult = ['path/to/cache/folder', 'path/to/cache/folder'];
@@ -95,16 +131,12 @@ describe('getCacheDirectoryPath', () => {
it('should return path to the cache folder if one command return empty str', async () => { it('should return path to the cache folder if one command return empty str', async () => {
//Arrange //Arrange
getExecOutputSpy.mockImplementationOnce((commandLine: string) => { getExecOutputSpy.mockImplementationOnce(async (commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => { return {exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''};
resolve({exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''});
});
}); });
getExecOutputSpy.mockImplementationOnce((commandLine: string) => { getExecOutputSpy.mockImplementationOnce(async (commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => { return {exitCode: 0, stdout: '', stderr: ''};
resolve({exitCode: 0, stdout: '', stderr: ''});
});
}); });
const expectedResult = ['path/to/cache/folder']; const expectedResult = ['path/to/cache/folder'];
@@ -116,10 +148,8 @@ describe('getCacheDirectoryPath', () => {
}); });
it('should throw if the both commands return empty str', async () => { it('should throw if the both commands return empty str', async () => {
getExecOutputSpy.mockImplementation((commandLine: string) => { getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => { return {exitCode: 10, stdout: '', stderr: ''};
resolve({exitCode: 10, stdout: '', stderr: ''});
});
}); });
//Act + Assert //Act + Assert
@@ -129,10 +159,8 @@ describe('getCacheDirectoryPath', () => {
}); });
it('should throw if the specified package name is invalid', async () => { it('should throw if the specified package name is invalid', async () => {
getExecOutputSpy.mockImplementation((commandLine: string) => { getExecOutputSpy.mockImplementation(async (commandLine: string) => {
return new Promise<exec.ExecOutput>(resolve => { return {exitCode: 10, stdout: '', stderr: 'Error message'};
resolve({exitCode: 10, stdout: '', stderr: 'Error message'});
});
}); });
//Act + Assert //Act + Assert
@@ -144,8 +172,10 @@ describe('getCacheDirectoryPath', () => {
describe('isCacheFeatureAvailable', () => { describe('isCacheFeatureAvailable', () => {
//Arrange //Arrange
const isFeatureAvailableSpy = jest.spyOn(cache, 'isFeatureAvailable'); const isFeatureAvailableSpy = cache.isFeatureAvailable as jest.Mock<
const warningSpy = jest.spyOn(core, 'warning'); typeof cache.isFeatureAvailable
>;
const warningSpy = core.warning as jest.Mock<typeof core.warning>;
it('should return true when cache feature is available', () => { it('should return true when cache feature is available', () => {
//Arrange //Arrange
@@ -211,10 +241,9 @@ describe('isCacheFeatureAvailable', () => {
}); });
describe('isGhes', () => { describe('isGhes', () => {
const pristineEnv = process.env; const pristineEnv = {...process.env};
beforeEach(() => { beforeEach(() => {
jest.resetModules();
process.env = {...pristineEnv}; process.env = {...pristineEnv};
}); });
+156 -79
View File
@@ -1,17 +1,98 @@
import * as core from '@actions/core'; import {
import * as io from '@actions/io'; jest,
import * as tc from '@actions/tool-cache'; describe,
it,
expect,
beforeAll,
beforeEach,
afterEach,
afterAll
} from '@jest/globals';
import fs from 'fs'; import fs from 'fs';
import cp from 'child_process'; import cp from 'child_process';
import osm, {type} from 'os';
import path from 'path';
import * as main from '../src/main';
import * as im from '../src/installer';
import * as httpm from '@actions/http-client';
import goJsonData from './data/golang-dl.json'; import goJsonData from './data/golang-dl.json' with {type: 'json'};
import matchers from '../matchers.json'; import matchers from '../matchers.json' with {type: 'json'};
import goTestManifest from './data/versions-manifest.json'; import goTestManifest from './data/versions-manifest.json' with {type: 'json'};
import type {IGoVersion} from '../src/installer.js';
import type {IToolRelease} from '@actions/tool-cache';
const httpClientGetJson = jest.fn();
const realCore = await import('@actions/core');
jest.unstable_mockModule('@actions/core', () => ({
...realCore,
getInput: jest.fn(),
getBooleanInput: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
exportVariable: jest.fn()
}));
const realOs = (await import('os')).default;
const osPlatformMock = jest.fn();
const osArchMock = jest.fn();
const osExports = {
...realOs,
platform: osPlatformMock,
arch: osArchMock
};
jest.unstable_mockModule('os', () => ({...osExports, default: osExports}));
const realPath = (await import('path')).default;
const pathJoinMock = jest.fn();
const pathExports = {
...realPath,
join: pathJoinMock
};
jest.unstable_mockModule('path', () => ({
...pathExports,
default: pathExports
}));
jest.unstable_mockModule('@actions/io', () => ({
which: jest.fn(),
mkdirP: jest.fn(),
rmRF: jest.fn(),
mv: jest.fn(),
cp: jest.fn()
}));
const realTc = await import('@actions/tool-cache');
jest.unstable_mockModule('@actions/tool-cache', () => ({
...realTc,
find: jest.fn(),
downloadTool: jest.fn(),
extractTar: jest.fn(),
extractZip: jest.fn(),
cacheDir: jest.fn(),
getManifestFromRepo: jest.fn()
}));
const realHttp = await import('@actions/http-client');
jest.unstable_mockModule('@actions/http-client', () => ({
...realHttp,
HttpClient: jest.fn().mockImplementation(() => ({
getJson: httpClientGetJson
}))
}));
jest.unstable_mockModule('../src/go-version-fetch.js', () => ({
getVersionsDist: jest.fn()
}));
const core = await import('@actions/core');
const io = await import('@actions/io');
const tc = await import('@actions/tool-cache');
const vf = await import('../src/go-version-fetch.js');
const main = await import('../src/main.js');
const im = await import('../src/installer.js');
const osm = (await import('os')).default;
const path = (await import('path')).default;
const matcherPattern = matchers.problemMatcher[0].pattern[0]; const matcherPattern = matchers.problemMatcher[0].pattern[0];
const matcherRegExp = new RegExp(matcherPattern.regexp); const matcherRegExp = new RegExp(matcherPattern.regexp);
const win32Join = path.win32.join; const win32Join = path.win32.join;
@@ -23,32 +104,31 @@ describe('setup-go', () => {
let inputs = {} as any; let inputs = {} as any;
let os = {} as any; let os = {} as any;
let inSpy: jest.SpyInstance; let inSpy: jest.Mock<typeof core.getInput>;
let getBooleanInputSpy: jest.SpyInstance; let getBooleanInputSpy: jest.Mock<typeof core.getBooleanInput>;
let exportVarSpy: jest.SpyInstance; let exportVarSpy: jest.Mock<typeof core.exportVariable>;
let findSpy: jest.SpyInstance; let findSpy: jest.Mock;
let cnSpy: jest.SpyInstance; let cnSpy: jest.SpiedFunction<typeof process.stdout.write>;
let logSpy: jest.SpyInstance; let logSpy: jest.Mock;
let getSpy: jest.SpyInstance; let getSpy: jest.Mock;
let platSpy: jest.SpyInstance; let platSpy: jest.Mock;
let archSpy: jest.SpyInstance; let archSpy: jest.Mock;
let joinSpy: jest.SpyInstance; let joinSpy: jest.Mock<typeof path.join>;
let dlSpy: jest.SpyInstance; let dlSpy: jest.Mock;
let extractTarSpy: jest.SpyInstance; let extractTarSpy: jest.Mock;
let extractZipSpy: jest.SpyInstance; let extractZipSpy: jest.Mock;
let cacheSpy: jest.SpyInstance; let cacheSpy: jest.Mock;
let dbgSpy: jest.SpyInstance; let dbgSpy: jest.Mock;
let whichSpy: jest.SpyInstance; let whichSpy: jest.Mock;
let existsSpy: jest.SpyInstance; let existsSpy: jest.SpiedFunction<typeof fs.existsSync>;
let readFileSpy: jest.SpyInstance; let readFileSpy: jest.SpiedFunction<typeof fs.readFileSync>;
let mkdirpSpy: jest.SpyInstance; let mkdirpSpy: jest.Mock;
let mkdirSpy: jest.SpyInstance; let mkdirSpy: jest.SpiedFunction<typeof fs.mkdir>;
let symlinkSpy: jest.SpyInstance; let symlinkSpy: jest.SpiedFunction<typeof fs.symlinkSync>;
let execSpy: jest.SpyInstance; let execSpy: jest.SpiedFunction<typeof cp.execSync>;
let execFileSpy: jest.SpyInstance; let execFileSpy: jest.SpiedFunction<typeof cp.execFileSync>;
let getManifestSpy: jest.SpyInstance; let getManifestSpy: jest.Mock;
let getAllVersionsSpy: jest.SpyInstance; let httpmGetJsonSpy: jest.Mock;
let httpmGetJsonSpy: jest.SpyInstance;
beforeAll(async () => { beforeAll(async () => {
process.env['GITHUB_ENV'] = ''; // Stub out Environment file functionality so we can verify it writes to standard out (toolkit is backwards compatible) process.env['GITHUB_ENV'] = ''; // Stub out Environment file functionality so we can verify it writes to standard out (toolkit is backwards compatible)
@@ -59,17 +139,19 @@ describe('setup-go', () => {
// @actions/core // @actions/core
inputs = {}; inputs = {};
inSpy = jest.spyOn(core, 'getInput'); inSpy = core.getInput as jest.Mock<typeof core.getInput>;
inSpy.mockImplementation(name => inputs[name]); inSpy.mockImplementation(name => inputs[name]);
getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput'); getBooleanInputSpy = core.getBooleanInput as jest.Mock<
typeof core.getBooleanInput
>;
getBooleanInputSpy.mockImplementation(name => inputs[name]); getBooleanInputSpy.mockImplementation(name => inputs[name]);
exportVarSpy = jest.spyOn(core, 'exportVariable'); exportVarSpy = core.exportVariable as jest.Mock<typeof core.exportVariable>;
// node // node
os = {}; os = {};
platSpy = jest.spyOn(osm, 'platform'); platSpy = osm.platform as jest.Mock;
platSpy.mockImplementation(() => os['platform']); platSpy.mockImplementation(() => os['platform']);
archSpy = jest.spyOn(osm, 'arch'); archSpy = osm.arch as jest.Mock;
archSpy.mockImplementation(() => os['arch']); archSpy.mockImplementation(() => os['arch']);
execSpy = jest.spyOn(cp, 'execSync'); execSpy = jest.spyOn(cp, 'execSync');
execFileSpy = jest.spyOn(cp, 'execFileSync'); execFileSpy = jest.spyOn(cp, 'execFileSync');
@@ -78,7 +160,7 @@ describe('setup-go', () => {
}); });
// switch path join behaviour based on set os.platform // switch path join behaviour based on set os.platform
joinSpy = jest.spyOn(path, 'join'); joinSpy = path.join as jest.Mock<typeof path.join>;
joinSpy.mockImplementation((...paths: string[]): string => { joinSpy.mockImplementation((...paths: string[]): string => {
if (os['platform'] == 'win32') { if (os['platform'] == 'win32') {
return win32Join(...paths); return win32Join(...paths);
@@ -88,23 +170,22 @@ describe('setup-go', () => {
}); });
// @actions/tool-cache // @actions/tool-cache
findSpy = jest.spyOn(tc, 'find'); findSpy = tc.find as jest.Mock;
dlSpy = jest.spyOn(tc, 'downloadTool'); dlSpy = tc.downloadTool as jest.Mock;
extractTarSpy = jest.spyOn(tc, 'extractTar'); extractTarSpy = tc.extractTar as jest.Mock;
extractZipSpy = jest.spyOn(tc, 'extractZip'); extractZipSpy = tc.extractZip as jest.Mock;
cacheSpy = jest.spyOn(tc, 'cacheDir'); cacheSpy = tc.cacheDir as jest.Mock;
getSpy = jest.spyOn(im, 'getVersionsDist'); getSpy = vf.getVersionsDist as jest.Mock;
getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo'); getManifestSpy = tc.getManifestFromRepo as jest.Mock;
getAllVersionsSpy = jest.spyOn(im, 'getManifest');
// httm // httm
httpmGetJsonSpy = jest.spyOn(httpm.HttpClient.prototype, 'getJson'); httpmGetJsonSpy = httpClientGetJson;
// io // io
whichSpy = jest.spyOn(io, 'which'); whichSpy = io.which as jest.Mock;
existsSpy = jest.spyOn(fs, 'existsSync'); existsSpy = jest.spyOn(fs, 'existsSync');
readFileSpy = jest.spyOn(fs, 'readFileSync'); readFileSpy = jest.spyOn(fs, 'readFileSync');
mkdirpSpy = jest.spyOn(io, 'mkdirP'); mkdirpSpy = io.mkdirP as jest.Mock;
// fs // fs
mkdirSpy = jest.spyOn(fs, 'mkdir'); mkdirSpy = jest.spyOn(fs, 'mkdir');
@@ -112,25 +193,16 @@ describe('setup-go', () => {
symlinkSpy.mockImplementation(() => {}); symlinkSpy.mockImplementation(() => {});
// gets // gets
getManifestSpy.mockImplementation(() => <tc.IToolRelease[]>goTestManifest); getManifestSpy.mockImplementation(() => goTestManifest as IToolRelease[]);
// writes // writes
cnSpy = jest.spyOn(process.stdout, 'write'); cnSpy = jest.spyOn(process.stdout, 'write');
logSpy = jest.spyOn(core, 'info'); logSpy = core.info as jest.Mock;
dbgSpy = jest.spyOn(core, 'debug'); dbgSpy = core.debug as jest.Mock;
getSpy.mockImplementation(() => <im.IGoVersion[] | null>goJsonData); getSpy.mockImplementation(() => goJsonData as IGoVersion[] | null);
cnSpy.mockImplementation(line => { cnSpy.mockImplementation(() => true);
// uncomment to debug logSpy.mockImplementation(() => {});
// process.stderr.write('write:' + line + '\n'); dbgSpy.mockImplementation(() => {});
});
logSpy.mockImplementation(line => {
// uncomment to debug
//process.stderr.write('log:' + line + '\n');
});
dbgSpy.mockImplementation(msg => {
// uncomment to see debug output
// process.stderr.write(msg + '\n');
});
}); });
afterEach(() => { afterEach(() => {
@@ -138,6 +210,10 @@ describe('setup-go', () => {
delete process.env[im.GOTOOLCHAIN_ENV_VAR]; delete process.env[im.GOTOOLCHAIN_ENV_VAR];
delete process.env['GO_DOWNLOAD_BASE_URL']; delete process.env['GO_DOWNLOAD_BASE_URL'];
// reset the exit code that core.setFailed sets on the error-path tests so
// that a passing run does not leak a non-zero process exit code
process.exitCode = 0;
//jest.resetAllMocks(); //jest.resetAllMocks();
jest.clearAllMocks(); jest.clearAllMocks();
//jest.restoreAllMocks(); //jest.restoreAllMocks();
@@ -171,8 +247,10 @@ describe('setup-go', () => {
}); });
it('should return manifest from raw URL if repo fetch fails', async () => { it('should return manifest from raw URL if repo fetch fails', async () => {
getManifestSpy.mockRejectedValue(new Error('Fetch failed')); (getManifestSpy as jest.Mock<any>).mockRejectedValue(
httpmGetJsonSpy.mockResolvedValue({ new Error('Fetch failed')
);
(httpmGetJsonSpy as jest.Mock<any>).mockResolvedValue({
result: goTestManifest result: goTestManifest
}); });
const manifest = await im.getManifest(undefined); const manifest = await im.getManifest(undefined);
@@ -211,7 +289,7 @@ describe('setup-go', () => {
os.arch = 'x64'; os.arch = 'x64';
// spec: 1.13.0 => 1.13 // spec: 1.13.0 => 1.13
const match: im.IGoVersion | undefined = await im.findMatch('1.13.0'); const match: IGoVersion | undefined = await im.findMatch('1.13.0');
expect(match).toBeDefined(); expect(match).toBeDefined();
const version: string = match ? match.version : ''; const version: string = match ? match.version : '';
expect(version).toBe('go1.13'); expect(version).toBe('go1.13');
@@ -224,7 +302,7 @@ describe('setup-go', () => {
os.arch = 'x64'; os.arch = 'x64';
// spec: 1.13 => 1.13.7 (latest) // spec: 1.13 => 1.13.7 (latest)
const match: im.IGoVersion | undefined = await im.findMatch('1.13'); const match: IGoVersion | undefined = await im.findMatch('1.13');
expect(match).toBeDefined(); expect(match).toBeDefined();
const version: string = match ? match.version : ''; const version: string = match ? match.version : '';
expect(version).toBe('go1.13.7'); expect(version).toBe('go1.13.7');
@@ -237,7 +315,7 @@ describe('setup-go', () => {
os.arch = 'x64'; os.arch = 'x64';
// spec: ^1.13.6 => 1.13.7 // spec: ^1.13.6 => 1.13.7
const match: im.IGoVersion | undefined = await im.findMatch('^1.13.6'); const match: IGoVersion | undefined = await im.findMatch('^1.13.6');
expect(match).toBeDefined(); expect(match).toBeDefined();
const version: string = match ? match.version : ''; const version: string = match ? match.version : '';
expect(version).toBe('go1.13.7'); expect(version).toBe('go1.13.7');
@@ -250,7 +328,7 @@ describe('setup-go', () => {
os.arch = 'x32'; os.arch = 'x32';
// spec: 1 => 1.13.7 (latest) // spec: 1 => 1.13.7 (latest)
const match: im.IGoVersion | undefined = await im.findMatch('1'); const match: IGoVersion | undefined = await im.findMatch('1');
expect(match).toBeDefined(); expect(match).toBeDefined();
const version: string = match ? match.version : ''; const version: string = match ? match.version : '';
expect(version).toBe('go1.13.7'); expect(version).toBe('go1.13.7');
@@ -263,7 +341,7 @@ describe('setup-go', () => {
os.arch = 'x64'; os.arch = 'x64';
// spec: 1.14, stable=false => go1.14rc1 // spec: 1.14, stable=false => go1.14rc1
const match: im.IGoVersion | undefined = await im.findMatch('1.14.0-rc.1'); const match: IGoVersion | undefined = await im.findMatch('1.14.0-rc.1');
expect(match).toBeDefined(); expect(match).toBeDefined();
const version: string = match ? match.version : ''; const version: string = match ? match.version : '';
expect(version).toBe('go1.14rc1'); expect(version).toBe('go1.14rc1');
@@ -817,10 +895,9 @@ describe('setup-go', () => {
getManifestSpy.mockImplementation(() => { getManifestSpy.mockImplementation(() => {
throw new Error('Unable to download manifest'); throw new Error('Unable to download manifest');
}); });
httpmGetJsonSpy.mockRejectedValue( (httpmGetJsonSpy as jest.Mock<any>).mockRejectedValue(
new Error('Unable to download manifest from raw URL') new Error('Unable to download manifest from raw URL')
); );
getAllVersionsSpy.mockImplementationOnce(() => undefined);
dlSpy.mockImplementation(async () => '/some/temp/path'); dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/go/1.13.7/x64'); const toolPath = path.normalize('/cache/go/1.13.7/x64');
+2 -1
View File
@@ -1,4 +1,5 @@
import {isSelfHosted} from '../src/utils'; import {describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import {isSelfHosted} from '../src/utils.js';
describe('utils', () => { describe('utils', () => {
describe('isSelfHosted', () => { describe('isSelfHosted', () => {
+45 -26
View File
@@ -1,38 +1,57 @@
import fs from 'fs'; import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
import * as io from '@actions/io';
import * as tc from '@actions/tool-cache';
import path from 'path'; import path from 'path';
const statSyncMock = jest.fn(() => ({
isDirectory: () => true,
isFile: () => true
}));
const readdirSyncMock = jest.fn(() => [] as any);
const writeFileSyncMock = jest.fn();
const mkdirMock = jest.fn();
const symlinkSyncMock = jest.fn();
jest.unstable_mockModule('@actions/io', () => ({
which: jest.fn(),
mkdirP: jest.fn(() => Promise.resolve()),
rmRF: jest.fn(() => Promise.resolve()),
mv: jest.fn(() => Promise.resolve()),
cp: jest.fn(() => Promise.resolve())
}));
const realFs = (await import('fs')).default;
const fsExports = {
...realFs,
statSync: statSyncMock,
readdirSync: readdirSyncMock,
writeFileSync: writeFileSyncMock,
mkdir: mkdirMock,
symlinkSync: symlinkSyncMock
};
jest.unstable_mockModule('fs', () => ({...fsExports, default: fsExports}));
const io = await import('@actions/io');
const tc = await import('@actions/tool-cache');
describe('Windows performance workaround', () => { describe('Windows performance workaround', () => {
let mkdirSpy: jest.SpyInstance; let rmRFSpy: jest.Mock;
let symlinkSpy: jest.SpyInstance; let mkdirPSpy: jest.Mock;
let statSpy: jest.SpyInstance; let cpSpy: jest.Mock;
let readdirSpy: jest.SpyInstance;
let writeFileSpy: jest.SpyInstance;
let rmRFSpy: jest.SpyInstance;
let mkdirPSpy: jest.SpyInstance;
let cpSpy: jest.SpyInstance;
let runnerToolCache: string | undefined; let runnerToolCache: string | undefined;
beforeEach(() => { beforeEach(() => {
mkdirSpy = jest.spyOn(fs, 'mkdir'); rmRFSpy = io.rmRF as jest.Mock;
symlinkSpy = jest.spyOn(fs, 'symlinkSync'); mkdirPSpy = io.mkdirP as jest.Mock;
statSpy = jest.spyOn(fs, 'statSync'); cpSpy = io.cp as jest.Mock;
readdirSpy = jest.spyOn(fs, 'readdirSync');
writeFileSpy = jest.spyOn(fs, 'writeFileSync');
rmRFSpy = jest.spyOn(io, 'rmRF');
mkdirPSpy = jest.spyOn(io, 'mkdirP');
cpSpy = jest.spyOn(io, 'cp');
// default implementations // default implementations
// @ts-ignore - not implement unused methods statSyncMock.mockImplementation(() => ({
statSpy.mockImplementation(() => ({ isDirectory: () => true,
isDirectory: () => true isFile: () => true
})); }));
readdirSpy.mockImplementation(() => []); readdirSyncMock.mockImplementation(() => []);
writeFileSpy.mockImplementation(() => {}); writeFileSyncMock.mockImplementation(() => {});
mkdirSpy.mockImplementation(() => {}); mkdirMock.mockImplementation(() => {});
symlinkSpy.mockImplementation(() => {}); symlinkSyncMock.mockImplementation(() => {});
rmRFSpy.mockImplementation(() => Promise.resolve()); rmRFSpy.mockImplementation(() => Promise.resolve());
mkdirPSpy.mockImplementation(() => Promise.resolve()); mkdirPSpy.mockImplementation(() => Promise.resolve());
cpSpy.mockImplementation(() => Promise.resolve()); cpSpy.mockImplementation(() => Promise.resolve());
+60514 -80351
View File
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
{
"type": "module"
}
+64741 -85847
View File
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
{
"type": "module"
}
+74
View File
@@ -0,0 +1,74 @@
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
import js from '@eslint/js';
import tsParser from '@typescript-eslint/parser';
import tsPlugin from '@typescript-eslint/eslint-plugin';
import jest from 'eslint-plugin-jest';
import n from 'eslint-plugin-n';
import prettier from 'eslint-config-prettier';
import globals from 'globals';
export default [
{
ignores: ['**/*', '!src/**', '!__tests__/**']
},
js.configs.recommended,
{
files: ['**/*.ts'],
languageOptions: {
parser: tsParser,
ecmaVersion: 2022,
sourceType: 'module',
globals: {
...globals.node,
...globals.es2015
}
},
plugins: {
'@typescript-eslint': tsPlugin,
n
},
rules: {
...tsPlugin.configs.recommended.rules,
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/ban-ts-comment': [
'error',
{
'ts-ignore': 'allow-with-description'
}
],
'no-console': 'error',
yoda: 'error',
'prefer-const': [
'error',
{
destructuring: 'all'
}
],
'no-control-regex': 'off',
'no-constant-condition': ['error', {checkLoops: false}],
'no-undef': 'off',
'no-useless-assignment': 'off',
'n/no-extraneous-import': 'error'
}
},
{
files: ['**/*{test,spec}.ts'],
plugins: {jest},
languageOptions: {
globals: {
...globals.jest
}
},
rules: {
...jest.configs['flat/recommended'].rules,
'@typescript-eslint/no-unused-vars': 'off',
'jest/no-standalone-expect': 'off',
'jest/no-conditional-expect': 'off',
'no-console': 'off'
}
},
prettier
];
-11
View File
@@ -1,11 +0,0 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: true
}
+24
View File
@@ -0,0 +1,24 @@
export default {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
roots: ['<rootDir>'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.ts$': [
'ts-jest',
{
useESM: true,
diagnostics: {
ignoreCodes: [151002]
}
}
]
},
extensionsToTreatAsEsm: ['.ts'],
transformIgnorePatterns: ['node_modules/(?!(@actions)/)'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1'
},
verbose: true
};
+2552 -2474
View File
File diff suppressed because it is too large Load Diff
+32 -30
View File
@@ -1,6 +1,7 @@
{ {
"name": "setup-go", "name": "setup-go",
"version": "6.2.0", "version": "7.0.0",
"type": "module",
"private": true, "private": true,
"description": "setup go action", "description": "setup go action",
"main": "lib/setup-go.js", "main": "lib/setup-go.js",
@@ -9,11 +10,11 @@
}, },
"scripts": { "scripts": {
"build": "tsc && ncc build -o dist/setup src/setup-go.ts && ncc build -o dist/cache-save src/cache-save.ts", "build": "tsc && ncc build -o dist/setup src/setup-go.ts && ncc build -o dist/cache-save src/cache-save.ts",
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write \"**/*.{ts,yml,yaml}\"", "format": "prettier --no-error-on-unmatched-pattern --write \"**/*.{ts,yml,yaml}\"",
"format-check": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --check \"**/*.{ts,yml,yaml}\"", "format-check": "prettier --no-error-on-unmatched-pattern --check \"**/*.{ts,yml,yaml}\"",
"lint": "eslint --config ./.eslintrc.js \"**/*.ts\"", "lint": "eslint \"**/*.ts\"",
"lint:fix": "eslint --config ./.eslintrc.js \"**/*.ts\" --fix", "lint:fix": "eslint \"**/*.ts\" --fix",
"test": "jest --coverage", "test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --runInBand --coverage",
"pre-checkin": "npm run format && npm run lint:fix && npm run build && npm test" "pre-checkin": "npm run format && npm run lint:fix && npm run build && npm test"
}, },
"repository": { "repository": {
@@ -28,31 +29,32 @@
"author": "GitHub", "author": "GitHub",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "^5.0.1", "@actions/cache": "^6.2.0",
"@actions/core": "^1.11.1", "@actions/core": "^3.0.1",
"@actions/exec": "^1.1.1", "@actions/exec": "^3.0.0",
"@actions/glob": "^0.5.0", "@actions/glob": "^0.7.0",
"@actions/http-client": "^2.2.1", "@actions/http-client": "^4.0.1",
"@actions/io": "^1.0.2", "@actions/io": "^3.0.2",
"@actions/tool-cache": "^2.0.2", "@actions/tool-cache": "^4.0.0",
"semver": "^7.7.3" "semver": "^7.8.5"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.14", "@eslint/js": "^10.0.1",
"@types/node": "^24.1.0", "@jest/globals": "^30.4.1",
"@types/semver": "^7.7.1", "@types/node": "^24.0.0",
"@typescript-eslint/eslint-plugin": "^8.31.1", "@types/semver": "^7.7.0",
"@typescript-eslint/parser": "^8.35.1", "@typescript-eslint/eslint-plugin": "^8.62.0",
"@vercel/ncc": "^0.38.1", "@typescript-eslint/parser": "^8.62.0",
"eslint": "^8.57.0", "@vercel/ncc": "^0.44.0",
"eslint-config-prettier": "^10.1.8", "eslint": "^10.5.0",
"eslint-plugin-jest": "^29.0.1", "eslint-config-prettier": "^10.0.0",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-jest": "^29.15.2",
"jest": "^29.7.0", "eslint-plugin-n": "^18.1.0",
"jest-circus": "^29.7.0", "globals": "^17.7.0",
"nock": "^10.0.6", "jest": "^30.4.2",
"prettier": "^2.8.4", "nock": "^14.0.0",
"ts-jest": "^29.3.2", "prettier": "^3.8.4",
"typescript": "^5.8.3" "ts-jest": "^29.4.11",
"typescript": "^6.0.3"
} }
} }
+3 -3
View File
@@ -4,9 +4,9 @@ import * as glob from '@actions/glob';
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
import {State, Outputs} from './constants'; import {State, Outputs} from './constants.js';
import {PackageManagerInfo} from './package-managers'; import {PackageManagerInfo} from './package-managers.js';
import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils'; import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils.js';
export const restoreCache = async ( export const restoreCache = async (
versionSpec: string, versionSpec: string,
+6 -2
View File
@@ -1,8 +1,8 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as cache from '@actions/cache'; import * as cache from '@actions/cache';
import fs from 'fs'; import fs from 'fs';
import {State} from './constants'; import {State} from './constants.js';
import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils'; import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils.js';
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in // Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to // @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
@@ -81,6 +81,10 @@ const cachePackages = async () => {
const cacheId = await cache.saveCache(cachePaths, primaryKey); const cacheId = await cache.saveCache(cachePaths, primaryKey);
if (cacheId === -1) { if (cacheId === -1) {
// saveCache returns -1 without throwing when the cache was not saved, e.g.
// a reserve collision or a read-only token (fork PR). @actions/cache has
// already logged the reason at the appropriate severity, so just trace it.
core.debug(`Cache was not saved for the key: ${primaryKey}`);
return; return;
} }
core.info(`Cache saved with the key: ${primaryKey}`); core.info(`Cache saved with the key: ${primaryKey}`);
+4 -1
View File
@@ -1,7 +1,10 @@
import * as cache from '@actions/cache'; import * as cache from '@actions/cache';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import {supportedPackageManagers, PackageManagerInfo} from './package-managers'; import {
supportedPackageManagers,
PackageManagerInfo
} from './package-managers.js';
export const getCommandOutput = async (toolCommand: string) => { export const getCommandOutput = async (toolCommand: string) => {
let {stdout, stderr, exitCode} = await exec.getExecOutput( let {stdout, stderr, exitCode} = await exec.getExecOutput(
+13
View File
@@ -0,0 +1,13 @@
import * as httpm from '@actions/http-client';
import type {IGoVersion} from './installer.js';
export async function getVersionsDist(
dlUrl: string
): Promise<IGoVersion[] | null> {
// this returns versions descending so latest is first
const http: httpm.HttpClient = new httpm.HttpClient('setup-go', [], {
allowRedirects: true,
maxRedirects: 3
});
return (await http.getJson<IGoVersion[]>(dlUrl)).result;
}
+14 -23
View File
@@ -3,13 +3,14 @@ import * as core from '@actions/core';
import * as path from 'path'; import * as path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import * as httpm from '@actions/http-client'; import * as httpm from '@actions/http-client';
import * as sys from './system'; import * as sys from './system.js';
import crypto from 'crypto'; import crypto from 'crypto';
import cp from 'child_process'; import cp from 'child_process';
import fs from 'fs'; import fs from 'fs';
import os from 'os'; import os from 'os';
import {StableReleaseAlias, isSelfHosted} from './utils'; import {StableReleaseAlias, isSelfHosted} from './utils.js';
import {Architecture} from './types'; import {Architecture} from './types.js';
import {getVersionsDist} from './go-version-fetch.js';
export const GOTOOLCHAIN_ENV_VAR = 'GOTOOLCHAIN'; export const GOTOOLCHAIN_ENV_VAR = 'GOTOOLCHAIN';
export const GOTOOLCHAIN_LOCAL_VAL = 'local'; export const GOTOOLCHAIN_LOCAL_VAL = 'local';
@@ -167,12 +168,14 @@ export async function getGo(
if (err instanceof tc.HTTPError && err.httpStatusCode === 404) { if (err instanceof tc.HTTPError && err.httpStatusCode === 404) {
throw new Error( throw new Error(
`The requested Go version ${versionSpec} is not available for platform ${osPlat}/${arch}. ` + `The requested Go version ${versionSpec} is not available for platform ${osPlat}/${arch}. ` +
`Download URL returned HTTP 404: ${downloadUrl}` `Download URL returned HTTP 404: ${downloadUrl}`,
{cause: err}
); );
} }
throw new Error( throw new Error(
`Failed to download Go ${versionSpec} for platform ${osPlat}/${arch} ` + `Failed to download Go ${versionSpec} for platform ${osPlat}/${arch} ` +
`from ${downloadUrl}: ${err}` `from ${downloadUrl}: ${err}`,
{cause: err}
); );
} }
} else { } else {
@@ -218,7 +221,9 @@ export async function getGo(
core.info('Install from dist'); core.info('Install from dist');
downloadPath = await installGoVersion(info, undefined, arch); downloadPath = await installGoVersion(info, undefined, arch);
} catch (err) { } catch (err) {
throw new Error(`Failed to download version ${versionSpec}: ${err}`); throw new Error(`Failed to download version ${versionSpec}: ${err}`, {
cause: err
});
} }
} }
} }
@@ -569,9 +574,7 @@ export async function findMatch(
let result: IGoVersion | undefined; let result: IGoVersion | undefined;
let match: IGoVersion | undefined; let match: IGoVersion | undefined;
const candidates: IGoVersion[] | null = await module.exports.getVersionsDist( const candidates: IGoVersion[] | null = await getVersionsDist(dlUrl);
dlUrl
);
if (!candidates) { if (!candidates) {
throw new Error(`golang download url did not return results`); throw new Error(`golang download url did not return results`);
} }
@@ -607,17 +610,6 @@ export async function findMatch(
return result; return result;
} }
export async function getVersionsDist(
dlUrl: string
): Promise<IGoVersion[] | null> {
// this returns versions descending so latest is first
const http: httpm.HttpClient = new httpm.HttpClient('setup-go', [], {
allowRedirects: true,
maxRedirects: 3
});
return (await http.getJson<IGoVersion[]>(dlUrl)).result;
}
// //
// Convert the go version syntax into semver for semver matching // Convert the go version syntax into semver for semver matching
// 1.13.1 => 1.13.1 // 1.13.1 => 1.13.1
@@ -686,9 +678,8 @@ async function resolveStableVersionDist(
) { ) {
const archFilter = sys.getArch(arch); const archFilter = sys.getArch(arch);
const platFilter = sys.getPlatform(); const platFilter = sys.getPlatform();
const candidates: IGoVersion[] | null = await module.exports.getVersionsDist( const candidates: IGoVersion[] | null =
GOLANG_DOWNLOAD_URL await getVersionsDist(GOLANG_DOWNLOAD_URL);
);
if (!candidates) { if (!candidates) {
throw new Error(`golang download url did not return results`); throw new Error(`golang download url did not return results`);
} }
+10 -5
View File
@@ -1,14 +1,15 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as io from '@actions/io'; import * as io from '@actions/io';
import * as installer from './installer'; import * as installer from './installer.js';
import * as semver from 'semver'; import * as semver from 'semver';
import path from 'path'; import path from 'path';
import {restoreCache} from './cache-restore'; import {fileURLToPath} from 'url';
import {isCacheFeatureAvailable} from './cache-utils'; import {restoreCache} from './cache-restore.js';
import {isCacheFeatureAvailable} from './cache-utils.js';
import cp from 'child_process'; import cp from 'child_process';
import fs from 'fs'; import fs from 'fs';
import os from 'os'; import os from 'os';
import {Architecture} from './types'; import {Architecture} from './types.js';
export async function run() { export async function run() {
try { try {
@@ -91,7 +92,11 @@ export async function run() {
} }
// add problem matchers // add problem matchers
const matchersPath = path.join(__dirname, '../..', 'matchers.json'); const matchersPath = path.join(
path.dirname(fileURLToPath(import.meta.url)),
'../..',
'matchers.json'
);
core.info(`##[add-matcher]${matchersPath}`); core.info(`##[add-matcher]${matchersPath}`);
// output the version actually being used // output the version actually being used
+1 -1
View File
@@ -1,3 +1,3 @@
import {run} from './main'; import {run} from './main.js';
run(); run();
+1 -1
View File
@@ -1,5 +1,5 @@
import os from 'os'; import os from 'os';
import {Architecture} from './types'; import {Architecture} from './types.js';
export function getPlatform(): string { export function getPlatform(): string {
// darwin and linux match already // darwin and linux match already
+4 -4
View File
@@ -2,8 +2,8 @@
"compilerOptions": { "compilerOptions": {
/* Basic Options */ /* Basic Options */
// "incremental": true, /* Enable incremental compilation */ // "incremental": true, /* Enable incremental compilation */
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "target": "ES2022", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "module": "NodeNext", /* Specify module code generation. */
// "allowJs": true, /* Allow javascript files to be compiled. */ // "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */ // "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
@@ -38,7 +38,7 @@
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */ /* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "moduleResolution": "NodeNext", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
@@ -61,5 +61,5 @@
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
}, },
"exclude": ["node_modules", "**/*.test.ts"] "exclude": ["node_modules", "**/*.test.ts", "jest.config.ts"]
} }