mirror of
https://github.com/Azure/setup-helm.git
synced 2026-07-05 07:51:38 +00:00
Compare commits
120 Commits
releases/v3
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 017211e1b1 | |||
| 95ecf4967d | |||
| 4180b1c05c | |||
| 6949b7ff3e | |||
| 51ce767c78 | |||
| d6da4f47af | |||
| 7e2bc108ba | |||
| 64d6be9869 | |||
| 69214f9d74 | |||
| 9dad99fe3c | |||
| 29c884e1c8 | |||
| 381aa48d5b | |||
| dc716b1277 | |||
| 407a08ffb6 | |||
| 7b39664db5 | |||
| 3090233644 | |||
| 7202adf694 | |||
| 1e2e44e1bc | |||
| 3894c84c36 | |||
| ca66f3880d | |||
| 316ed5ab42 | |||
| bc9bc0ca28 | |||
| 16e3094bcb | |||
| 6e42753733 | |||
| 9651d9df52 | |||
| 658bff9449 | |||
| 331c81409c | |||
| d97dedf43b | |||
| e3ce81801f | |||
| c9feef90b0 | |||
| 73239af346 | |||
| f838c7624e | |||
| c357e9f852 | |||
| ed9b26085d | |||
| 66bd493dcc | |||
| d3968cd00b | |||
| c5faea29a6 | |||
| 95eab887c3 | |||
| 0400c1212d | |||
| 56c6cf6081 | |||
| 9522c92b52 | |||
| 1858547716 | |||
| 1e96d927b6 | |||
| 11cf983218 | |||
| da792be48c | |||
| 35f21158b9 | |||
| 9d84ec5754 | |||
| dd78250c1f | |||
| 9e7f762d6f | |||
| c096176d63 | |||
| 5e7287287e | |||
| fb8fa40706 | |||
| 0d097290a8 | |||
| 32bc12022d | |||
| 51463d68e8 | |||
| aff10941b2 | |||
| a10a5247d8 | |||
| 378ae69bda | |||
| 50d615e7a7 | |||
| 0147554077 | |||
| 4eee2cd0ed | |||
| 8527f3ee39 | |||
| c9a6a97d7f | |||
| 027e8cdfd7 | |||
| df342a2656 | |||
| 230641be01 | |||
| f57bbf1821 | |||
| 5b950139b7 | |||
| 28f285563b | |||
| d030d7f717 | |||
| 05502a08f2 | |||
| 24eca957cf | |||
| 56195efbb1 | |||
| babfb8676f | |||
| c757a812df | |||
| d5f1fcb584 | |||
| cc690771a5 | |||
| c4cd5ccdf7 | |||
| 740f020522 | |||
| 5976fc8a1b | |||
| 0e8654bb94 | |||
| b48e1dfac1 | |||
| 855ae7a03c | |||
| 124c6d88e7 | |||
| 048f4e7eae | |||
| 8618769467 | |||
| 4eb898eef0 | |||
| 7a2001c0f6 | |||
| e90c86ceea | |||
| 4675ea6b05 | |||
| df50d879fa | |||
| 08d7123a4a | |||
| 0a0c55a4c3 | |||
| d00ce1cb5e | |||
| 4c255dde26 | |||
| ec8dd7c209 | |||
| efbd96d464 | |||
| 859dc38e9a | |||
| 0788eb3317 | |||
| 208de6bd49 | |||
| 1f87a575d0 | |||
| d336b89352 | |||
| ac5ee1fca8 | |||
| 638a523e0c | |||
| 0a7ec47357 | |||
| 3419a8fa8f | |||
| f77071b246 | |||
| a4617735aa | |||
| 2dafda840c | |||
| b70d33f56d | |||
| 3c00c0152f | |||
| 22d14750db | |||
| a22741c887 | |||
| f850d12cb3 | |||
| 17cd77473c | |||
| 484a64052d | |||
| 6e32762c2e | |||
| 17c21ab68c | |||
| 7f0153c54c | |||
| a14110f6e6 |
+1
-1
@@ -1 +1 @@
|
||||
* @Azure/aks-atlanta
|
||||
* @Azure/cloud-native-github-action-owners
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
groups:
|
||||
actions:
|
||||
patterns:
|
||||
- '*'
|
||||
- package-ecosystem: github-actions
|
||||
directory: .github/workflows
|
||||
schedule:
|
||||
interval: weekly
|
||||
groups:
|
||||
actions:
|
||||
patterns:
|
||||
- '*'
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
- uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 #v10.3.0
|
||||
name: Setting issue as idle
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
operations-per-run: 100
|
||||
exempt-issue-labels: 'backlog'
|
||||
|
||||
- uses: actions/stale@v3
|
||||
- uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 #v10.3.0
|
||||
name: Setting PR as idle
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -7,15 +7,22 @@ on:
|
||||
jobs:
|
||||
trigger-integration-tests:
|
||||
name: Trigger Integration tests
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- ubuntu-24.04-arm
|
||||
- macos-latest # arm
|
||||
fail-fast: false
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
HELM_3_8_0: 'v3.8.0'
|
||||
HELM_3_7_2: 'v3.7.2'
|
||||
HELM_NO_V: '3.5.0'
|
||||
HELM_3_18_4: 'v3.18.4'
|
||||
HELM_3_18_0: 'v3.18.0'
|
||||
HELM_NO_V: '3.18.4'
|
||||
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- name: npm install and build
|
||||
id: action-npm-build
|
||||
run: |
|
||||
@@ -27,39 +34,57 @@ jobs:
|
||||
- name: Setup helm
|
||||
uses: ./
|
||||
with:
|
||||
version: ${{ env.HELM_3_8_0 }}
|
||||
- name: Validate helm 3.8.0
|
||||
version: ${{ env.HELM_3_18_4 }}
|
||||
- name: Validate helm 3.18.4
|
||||
run: |
|
||||
if [[ $(helm version) != *$HELM_3_8_0* ]]; then
|
||||
echo "HELM VERSION INCORRECT: HELM VERSION DOES NOT CONTAIN v3.8.0"
|
||||
if [[ $(helm version) != *$HELM_3_18_4* ]]; then
|
||||
echo "HELM VERSION INCORRECT: HELM VERSION DOES NOT CONTAIN v3.18.4"
|
||||
echo "HELM VERSION OUTPUT: $(helm version)"
|
||||
exit 1
|
||||
else
|
||||
echo "HELM VERSION $HELM_3_8_0 INSTALLED SUCCESSFULLY"
|
||||
echo "HELM VERSION $HELM_3_18_4 INSTALLED SUCCESSFULLY"
|
||||
fi
|
||||
- name: Setup helm 3.7.2
|
||||
- name: Setup helm 3.18.0
|
||||
uses: ./
|
||||
with:
|
||||
version: ${{ env.HELM_3_7_2 }}
|
||||
- name: Validate 3.7.2
|
||||
version: ${{ env.HELM_3_18_0 }}
|
||||
- name: Validate 3.18.0
|
||||
run: |
|
||||
if [[ $(helm version) != *$HELM_3_7_2* ]]; then
|
||||
echo "HELM VERSION INCORRECT: HELM VERSION DOES NOT CONTAIN v3.7.2"
|
||||
if [[ $(helm version) != *$HELM_3_18_0* ]]; then
|
||||
echo "HELM VERSION INCORRECT: HELM VERSION DOES NOT CONTAIN v3.18.0"
|
||||
echo "HELM VERSION OUTPUT: $(helm version)"
|
||||
exit 1
|
||||
else
|
||||
echo "HELM VERSION $HELM_3_7_2 INSTALLED SUCCESSFULLY"
|
||||
echo "HELM VERSION $HELM_3_18_0 INSTALLED SUCCESSFULLY"
|
||||
fi
|
||||
- name: Setup helm 3.5.0 with no v in version
|
||||
- name: Setup helm 3.18.4 with no v in version
|
||||
uses: ./
|
||||
with:
|
||||
version: ${{ env.HELM_NO_V }}
|
||||
- name: Validate 3.5.0 without v in version
|
||||
- name: Validate 3.18.4 without v in version
|
||||
run: |
|
||||
if [[ $(helm version) != *$HELM_NO_V* ]]; then
|
||||
echo "HELM VERSION INCORRECT: HELM VERSION DOES NOT CONTAIN v3.5.0"
|
||||
echo "HELM VERSION INCORRECT: HELM VERSION DOES NOT CONTAIN 3.18.4"
|
||||
echo "HELM VERSION OUTPUT: $(helm version)"
|
||||
exit 1
|
||||
else
|
||||
echo "HELM VERSION $HELM_3_5_0 INSTALLED SUCCESSFULLY"
|
||||
echo "HELM VERSION $HELM_NO_V INSTALLED SUCCESSFULLY"
|
||||
fi
|
||||
- name: Setup helm latest version
|
||||
uses: ./
|
||||
with:
|
||||
version: latest
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Validate latest
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
HELM_LATEST=$(curl -s https://get.helm.sh/helm-latest-version)
|
||||
|
||||
if [[ $(helm version) != *$HELM_LATEST* ]]; then
|
||||
echo "HELM VERSION INCORRECT: HELM VERSION DOES NOT CONTAIN $HELM_LATEST"
|
||||
echo "HELM VERSION OUTPUT: $(helm version)"
|
||||
exit 1
|
||||
else
|
||||
echo "HELM VERSION $HELM_LATEST INSTALLED SUCCESSFULLY"
|
||||
fi
|
||||
|
||||
@@ -10,9 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- name: Enforce Prettier
|
||||
uses: actionsx/prettier@v2
|
||||
with:
|
||||
args: --check .
|
||||
run: npx prettier --check .
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
name: Create release PR
|
||||
name: Release Project
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- CHANGELOG.md
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release:
|
||||
description: 'Define release version (ex: v1, v2, v3)'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
release-pr:
|
||||
uses: OliverMKing/javascript-release-workflow/.github/workflows/release-pr.yml@main
|
||||
release:
|
||||
permissions:
|
||||
actions: read
|
||||
contents: write
|
||||
uses: Azure/action-release-workflows/.github/workflows/release_js_project.yaml@3c677ba5ab58f5c5c1a6f0cfb176b333b1f27405 # v1.0.3
|
||||
with:
|
||||
release: ${{ github.event.inputs.release }}
|
||||
changelogPath: ./CHANGELOG.md
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
name: Tag and create release draft
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- releases/*
|
||||
|
||||
jobs:
|
||||
tag-and-release:
|
||||
uses: OliverMKing/javascript-release-workflow/.github/workflows/tag-and-release.yml@main
|
||||
@@ -11,9 +11,18 @@ on: # rebuild any PRs and main branch changes
|
||||
|
||||
jobs:
|
||||
build: # make sure build/ci works properly
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- ubuntu-24.04-arm
|
||||
- windows-latest
|
||||
- windows-11-arm
|
||||
- macos-latest # arm
|
||||
fail-fast: false
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- name: Run L0 tests.
|
||||
run: |
|
||||
|
||||
@@ -11,6 +11,8 @@ pids
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
@@ -62,3 +64,4 @@ node_modules
|
||||
coverage
|
||||
|
||||
# Transpiled JS
|
||||
lib/
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
npm test
|
||||
npm run format-check || {
|
||||
echo ""
|
||||
echo "❌ Formatting check failed."
|
||||
echo "💡 Run 'npm run format' or 'prettier --write .' to fix formatting issues."
|
||||
exit 1
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
# Change Log
|
||||
|
||||
## [5.0.1] - 2026-06-23
|
||||
|
||||
### Fixed
|
||||
|
||||
- #271 [Fix TypeScript 6.0 compatibility errors in run.ts](https://github.com/Azure/setup-helm/pull/271)
|
||||
- #278 [fix: use chmod 755 instead of 777 for downloaded helm binary and folder](https://github.com/Azure/setup-helm/pull/278)
|
||||
|
||||
### Changed
|
||||
|
||||
- #286 [Bump actions/checkout from 6.0.3 to 7.0.0 in /.github/workflows in the actions group](https://github.com/Azure/setup-helm/pull/286)
|
||||
- #285 [Bump the actions group with 2 updates](https://github.com/Azure/setup-helm/pull/285)
|
||||
- #284 [Bump undici](https://github.com/Azure/setup-helm/pull/284)
|
||||
- #283 [Bump the actions group with 5 updates](https://github.com/Azure/setup-helm/pull/283)
|
||||
- #280 [Bump actions/checkout from 6.0.2 to 6.0.3 in /.github/workflows in the actions group](https://github.com/Azure/setup-helm/pull/280)
|
||||
- #279 [Bump the actions group with 2 updates](https://github.com/Azure/setup-helm/pull/279)
|
||||
- #277 [Bump vitest from 4.1.7 to 4.1.8 in the actions group](https://github.com/Azure/setup-helm/pull/277)
|
||||
- #276 [chore: remove deprecated OliverMKing release workflow, pin to SHA](https://github.com/Azure/setup-helm/pull/276)
|
||||
- #275 [Bump actions/stale from 10.2.0 to 10.3.0 in /.github/workflows in the actions group](https://github.com/Azure/setup-helm/pull/275)
|
||||
- #274 [Bump the actions group with 3 updates](https://github.com/Azure/setup-helm/pull/274)
|
||||
- #273 [Bump the actions group with 2 updates](https://github.com/Azure/setup-helm/pull/273)
|
||||
- #269 [Bump the actions group across 1 directory with 7 updates](https://github.com/Azure/setup-helm/pull/269)
|
||||
- #268 [Bump vite from 8.0.0 to 8.0.5](https://github.com/Azure/setup-helm/pull/268)
|
||||
- #260 [Migrate to ESM with esbuild/vitest and upgrade to node24 (v5.0.0)](https://github.com/Azure/setup-helm/pull/260)
|
||||
|
||||
## [5.0.0] - 2026-03-23
|
||||
|
||||
### Changed
|
||||
|
||||
- #259 [Update Node.js runtime from node20 to node24](https://github.com/Azure/setup-helm/pull/259)
|
||||
- #263 [Bump undici](https://github.com/Azure/setup-helm/pull/263)
|
||||
- #257 [Bump undici and @actions/http-client](https://github.com/Azure/setup-helm/pull/257)
|
||||
- #256 [Bump minimatch](https://github.com/Azure/setup-helm/pull/256)
|
||||
- #248 [Bump the actions group with 2 updates](https://github.com/Azure/setup-helm/pull/248)
|
||||
- #247 [Bump the actions group with 3 updates](https://github.com/Azure/setup-helm/pull/247)
|
||||
- #246 [Bump @types/node from 25.0.2 to 25.0.3 in the actions group](https://github.com/Azure/setup-helm/pull/246)
|
||||
- #245 [Bump the actions group with 3 updates](https://github.com/Azure/setup-helm/pull/245)
|
||||
- #243 [Bump the actions group with 2 updates](https://github.com/Azure/setup-helm/pull/243)
|
||||
- #240 [Bump prettier from 3.6.2 to 3.7.3 in the actions group](https://github.com/Azure/setup-helm/pull/240)
|
||||
- #229 [Bump the actions group across 1 directory with 3 updates](https://github.com/Azure/setup-helm/pull/229)
|
||||
- #231 [Bump js-yaml from 3.14.1 to 3.14.2](https://github.com/Azure/setup-helm/pull/231)
|
||||
- #234 [Bump glob from 10.4.5 to 10.5.0](https://github.com/Azure/setup-helm/pull/234)
|
||||
- #225 [Fix build error](https://github.com/Azure/setup-helm/pull/225)
|
||||
- #222 [Bump @types/node from 24.7.2 to 24.8.1 in the actions group](https://github.com/Azure/setup-helm/pull/222)
|
||||
- #220 [Bump the actions group across 1 directory with 4 updates](https://github.com/Azure/setup-helm/pull/220)
|
||||
- #216 [Bump the actions group across 1 directory with 4 updates](https://github.com/Azure/setup-helm/pull/216)
|
||||
- #213 [Bump the actions group with 2 updates](https://github.com/Azure/setup-helm/pull/213)
|
||||
- #211 [Bump undici](https://github.com/Azure/setup-helm/pull/211)
|
||||
- #212 [Bump jest from 30.0.5 to 30.1.2 in the actions group](https://github.com/Azure/setup-helm/pull/212)
|
||||
- #210 [Bump @types/node from 24.2.1 to 24.3.0 in the actions group](https://github.com/Azure/setup-helm/pull/210)
|
||||
|
||||
## [4.3.1] - 2025-08-12
|
||||
|
||||
### Changed
|
||||
|
||||
- #167 [Pinning Action Dependencies for Security and Reliability](https://github.com/Azure/setup-helm/pull/167)
|
||||
- #181 [Fix types, and update node version.](https://github.com/Azure/setup-helm/pull/181)
|
||||
- #191 [chore(tests): Mock arch to make tests pass on arm host](https://github.com/Azure/setup-helm/pull/191)
|
||||
- #192 [chore: remove unnecessary prebuild script](https://github.com/Azure/setup-helm/pull/192)
|
||||
- #203 [Update helm version retrieval to use JSON output for latest version](https://github.com/Azure/setup-helm/pull/203)
|
||||
- #207 [ci(workflows): update helm version to v3.18.4 and add matrix for tests](https://github.com/Azure/setup-helm/pull/207)
|
||||
|
||||
### Added
|
||||
|
||||
- #197 [Add pre-commit hook](https://github.com/Azure/setup-helm/pull/197)
|
||||
|
||||
## [4.3.0] - 2025-02-15
|
||||
|
||||
- #152 feat: log when restoring from cache
|
||||
- #157 Dependencies Update
|
||||
- #137 Add dependabot
|
||||
|
||||
## [4.2.0] - 2024-04-15
|
||||
|
||||
- #124 Fix OS detection and download OS-native archive extension
|
||||
|
||||
## [4.1.0] - 2024-03-01
|
||||
|
||||
- #130 switches to use Helm published file to read latest version instead of using GitHub releases
|
||||
|
||||
## [4.0.0] - 2024-02-12
|
||||
|
||||
- #121 update to node20 as node16 is deprecated
|
||||
+3
-3
@@ -4,6 +4,6 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
|
||||
|
||||
Resources:
|
||||
|
||||
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
|
||||
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
|
||||
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
|
||||
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
|
||||
|
||||
@@ -4,17 +4,34 @@ Install a specific version of helm binary on the runner.
|
||||
|
||||
## Example
|
||||
|
||||
Acceptable values are latest or any semantic version string like v3.5.0 Use this action in workflow to define which version of helm will be used. v2 and v3 of this action only support Helm3.
|
||||
Acceptable values are latest or any semantic version string like v3.5.0 Use this action in workflow to define which version of helm will be used. v2+ of this action only support Helm3.
|
||||
|
||||
```yaml
|
||||
- uses: azure/setup-helm@v3
|
||||
- uses: azure/setup-helm@v5
|
||||
with:
|
||||
version: '<version>' # default is latest (stable)
|
||||
token: ${{ secrets.GITHUB_TOKEN }} # only needed if version is 'latest'
|
||||
id: install
|
||||
```
|
||||
|
||||
> Note: When using latest version you might hit the GitHub GraphQL API hourly rate limit of 5,000. The action will then return the hardcoded default stable version (currently v3.9.0). If you rely on a certain version higher than the default, you should use that version instead of latest.
|
||||
Alternatively, the version can be read from a [`.tool-versions`](https://asdf-vm.com/manage/configuration.html) file (the format used by [asdf](https://asdf-vm.com/) and [mise](https://mise.jdx.dev/)) via the `version-file` input:
|
||||
|
||||
```yaml
|
||||
- uses: azure/setup-helm@v5.0.0
|
||||
with:
|
||||
version-file: .tool-versions
|
||||
id: install
|
||||
```
|
||||
|
||||
The action reads the version declared for the `helm` tool, for example:
|
||||
|
||||
```
|
||||
helm 3.18.4
|
||||
```
|
||||
|
||||
If both `version` and `version-file` are set, an explicitly requested `version` takes precedence and `version-file` is ignored (a warning is emitted). Because `version` defaults to `latest`, `version-file` is only ignored when you set `version` to a specific value other than `latest`; if `version` is left at its default, the version from `version-file` is used.
|
||||
|
||||
> [!NOTE]
|
||||
> If something goes wrong with fetching the latest version the action will use the hardcoded default version (currently v3.18.4). If you rely on a certain version higher than the default, you should explicitly use that version instead of latest.
|
||||
|
||||
The cached helm binary path is prepended to the PATH environment variable as well as stored in the helm-path output variable.
|
||||
Refer to the action metadata file for details about all the inputs https://github.com/Azure/setup-helm/blob/master/action.yml
|
||||
|
||||
+7
-7
@@ -18,13 +18,13 @@ You should receive a response within 24 hours. If for some reason you do not, pl
|
||||
|
||||
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
||||
|
||||
- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
||||
- Full paths of source file(s) related to the manifestation of the issue
|
||||
- The location of the affected source code (tag/branch/commit or direct URL)
|
||||
- Any special configuration required to reproduce the issue
|
||||
- Step-by-step instructions to reproduce the issue
|
||||
- Proof-of-concept or exploit code (if possible)
|
||||
- Impact of the issue, including how an attacker might exploit the issue
|
||||
- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
||||
- Full paths of source file(s) related to the manifestation of the issue
|
||||
- The location of the affected source code (tag/branch/commit or direct URL)
|
||||
- Any special configuration required to reproduce the issue
|
||||
- Step-by-step instructions to reproduce the issue
|
||||
- Proof-of-concept or exploit code (if possible)
|
||||
- Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
This information will help us triage your report more quickly.
|
||||
|
||||
|
||||
+14
-5
@@ -3,16 +3,25 @@ description: 'Install a specific version of helm binary. Acceptable values are l
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version of helm'
|
||||
required: true
|
||||
default: 'latest'
|
||||
token:
|
||||
description: GitHub token. Required only if 'version' == 'latest'
|
||||
required: false
|
||||
default: 'latest'
|
||||
version-file:
|
||||
description: 'Path to a .tool-versions file to read the helm version from'
|
||||
required: false
|
||||
token:
|
||||
description: GitHub token. Used to be required to fetch the latest version
|
||||
required: false
|
||||
deprecationMessage: 'GitHub token is no longer required'
|
||||
default: '${{ github.token }}'
|
||||
downloadBaseURL:
|
||||
description: 'Set the download base URL'
|
||||
required: false
|
||||
default: 'https://get.helm.sh'
|
||||
outputs:
|
||||
helm-path:
|
||||
description: 'Path to the cached helm binary'
|
||||
branding:
|
||||
color: 'blue'
|
||||
runs:
|
||||
using: 'node16'
|
||||
using: 'node24'
|
||||
main: 'lib/index.js'
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
moduleFileExtensions: ['js', 'ts'],
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/*.test.ts'],
|
||||
transform: {
|
||||
'^.+\\.ts$': 'ts-jest'
|
||||
},
|
||||
verbose: true,
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
branches: 0,
|
||||
functions: 14,
|
||||
lines: 27,
|
||||
statements: 27
|
||||
}
|
||||
}
|
||||
}
|
||||
-11879
File diff suppressed because one or more lines are too long
Generated
+1675
-10800
File diff suppressed because it is too large
Load Diff
+20
-18
@@ -1,33 +1,35 @@
|
||||
{
|
||||
"name": "setuphelm",
|
||||
"version": "0.0.0",
|
||||
"version": "5.0.1",
|
||||
"private": true,
|
||||
"description": "Setup helm",
|
||||
"author": "Anumita Shenoy",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/io": "^1.1.2",
|
||||
"@actions/tool-cache": "2.0.1",
|
||||
"@octokit/auth-action": "^2.0.0",
|
||||
"@octokit/graphql": "^4.6.1",
|
||||
"semver": "^6.1.0"
|
||||
"@actions/core": "^3.0.1",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/io": "^3.0.2",
|
||||
"@actions/tool-cache": "4.0.0",
|
||||
"@octokit/action": "^8.0.4",
|
||||
"semver": "^7.8.5"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"build": "ncc build src/run.ts -o lib",
|
||||
"test": "jest",
|
||||
"test-coverage": "jest --coverage",
|
||||
"build": "tsc --noEmit && esbuild src/index.ts --bundle --platform=node --target=node20 --format=esm --outfile=lib/index.js --banner:js=\"import { createRequire } from 'module';const require = createRequire(import.meta.url);\"",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "vitest run",
|
||||
"test-coverage": "vitest run --coverage",
|
||||
"format": "prettier --write .",
|
||||
"format-check": "prettier --check ."
|
||||
"format-check": "prettier --check .",
|
||||
"prepare": "husky"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.0",
|
||||
"@types/node": "^12.0.10",
|
||||
"@vercel/ncc": "^0.34.0",
|
||||
"jest": "^26.0.1",
|
||||
"ts-jest": "^26.0.0",
|
||||
"typescript": "^3.5.2"
|
||||
"@types/node": "^26.0.0",
|
||||
"esbuild": "^0.28",
|
||||
"husky": "^9.1.7",
|
||||
"prettier": "^3.8.4",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
import {run} from './run.js'
|
||||
import * as core from '@actions/core'
|
||||
|
||||
run().catch(core.setFailed)
|
||||
+377
-143
@@ -1,105 +1,323 @@
|
||||
import * as run from './run'
|
||||
import {vi, describe, test, expect, afterEach} from 'vitest'
|
||||
import * as path from 'path'
|
||||
|
||||
// Mock os module
|
||||
vi.mock('os', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('os')>()
|
||||
return {
|
||||
...actual,
|
||||
platform: vi.fn(),
|
||||
arch: vi.fn()
|
||||
}
|
||||
})
|
||||
|
||||
// Mock fs module
|
||||
vi.mock('fs', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('fs')>()
|
||||
return {
|
||||
...actual,
|
||||
readdirSync: vi.fn(),
|
||||
statSync: vi.fn(),
|
||||
chmodSync: vi.fn(),
|
||||
readFileSync: vi.fn(),
|
||||
existsSync: vi.fn()
|
||||
}
|
||||
})
|
||||
|
||||
// Mock @actions/core
|
||||
vi.mock('@actions/core', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@actions/core')>()
|
||||
return {
|
||||
...actual,
|
||||
getInput: vi.fn(),
|
||||
info: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
warning: vi.fn(),
|
||||
startGroup: vi.fn(),
|
||||
endGroup: vi.fn(),
|
||||
addPath: vi.fn(),
|
||||
setOutput: vi.fn(),
|
||||
setFailed: vi.fn()
|
||||
}
|
||||
})
|
||||
|
||||
// Mock @actions/tool-cache
|
||||
vi.mock('@actions/tool-cache', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@actions/tool-cache')>()
|
||||
return {
|
||||
...actual,
|
||||
find: vi.fn(),
|
||||
downloadTool: vi.fn(),
|
||||
extractZip: vi.fn(),
|
||||
extractTar: vi.fn(),
|
||||
cacheDir: vi.fn()
|
||||
}
|
||||
})
|
||||
|
||||
import * as run from './run.js'
|
||||
import * as os from 'os'
|
||||
import * as toolCache from '@actions/tool-cache'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as core from '@actions/core'
|
||||
|
||||
describe('run.ts', () => {
|
||||
const downloadBaseURL = 'https://test.tld'
|
||||
|
||||
// Cleanup mocks after each test to ensure that subsequent tests are not affected by the mocks.
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
test('getExecutableExtension() - return .exe when os is Windows', () => {
|
||||
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
|
||||
vi.mocked(os.platform).mockReturnValue('win32')
|
||||
|
||||
expect(run.getExecutableExtension()).toBe('.exe')
|
||||
expect(os.type).toBeCalled()
|
||||
expect(os.platform).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('getExecutableExtension() - return empty string for non-windows OS', () => {
|
||||
jest.spyOn(os, 'type').mockReturnValue('Darwin')
|
||||
vi.mocked(os.platform).mockReturnValue('darwin')
|
||||
|
||||
expect(run.getExecutableExtension()).toBe('')
|
||||
expect(os.type).toBeCalled()
|
||||
expect(os.platform).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('getHelmDownloadURL() - return the URL to download helm for Linux', () => {
|
||||
jest.spyOn(os, 'type').mockReturnValue('Linux')
|
||||
jest.spyOn(os, 'arch').mockReturnValueOnce('unknown')
|
||||
const kubectlLinuxUrl = 'https://get.helm.sh/helm-v3.8.0-linux-amd64.zip'
|
||||
test('getHelmDownloadURL() - return the URL to download helm for Linux amd64', () => {
|
||||
vi.mocked(os.platform).mockReturnValue('linux')
|
||||
vi.mocked(os.arch).mockReturnValue('x64')
|
||||
const expected = 'https://test.tld/helm-v3.8.0-linux-amd64.tar.gz'
|
||||
|
||||
expect(run.getHelmDownloadURL('v3.8.0')).toBe(kubectlLinuxUrl)
|
||||
expect(os.type).toBeCalled()
|
||||
expect(os.arch).toBeCalled()
|
||||
|
||||
// arm64
|
||||
jest.spyOn(os, 'type').mockReturnValue('Linux')
|
||||
jest.spyOn(os, 'arch').mockReturnValueOnce('arm64')
|
||||
const kubectlLinuxArm64Url =
|
||||
'https://get.helm.sh/helm-v3.8.0-linux-arm64.zip'
|
||||
|
||||
expect(run.getHelmDownloadURL('v3.8.0')).toBe(kubectlLinuxArm64Url)
|
||||
expect(os.type).toBeCalled()
|
||||
expect(os.arch).toBeCalled()
|
||||
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
|
||||
expect(os.platform).toHaveBeenCalled()
|
||||
expect(os.arch).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('getHelmDownloadURL() - return the URL to download helm for Darwin', () => {
|
||||
jest.spyOn(os, 'type').mockReturnValue('Darwin')
|
||||
jest.spyOn(os, 'arch').mockReturnValueOnce('unknown')
|
||||
const kubectlDarwinUrl =
|
||||
'https://get.helm.sh/helm-v3.8.0-darwin-amd64.zip'
|
||||
test('getHelmDownloadURL() - return the URL to download helm for Linux arm64', () => {
|
||||
vi.mocked(os.platform).mockReturnValue('linux')
|
||||
vi.mocked(os.arch).mockReturnValue('arm64')
|
||||
const expected = 'https://test.tld/helm-v3.8.0-linux-arm64.tar.gz'
|
||||
|
||||
expect(run.getHelmDownloadURL('v3.8.0')).toBe(kubectlDarwinUrl)
|
||||
expect(os.type).toBeCalled()
|
||||
expect(os.arch).toBeCalled()
|
||||
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
|
||||
expect(os.platform).toHaveBeenCalled()
|
||||
expect(os.arch).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
// arm64
|
||||
jest.spyOn(os, 'type').mockReturnValue('Darwin')
|
||||
jest.spyOn(os, 'arch').mockReturnValueOnce('arm64')
|
||||
const kubectlDarwinArm64Url =
|
||||
'https://get.helm.sh/helm-v3.8.0-darwin-arm64.zip'
|
||||
test('getHelmDownloadURL() - return the URL to download helm for Darwin x64', () => {
|
||||
vi.mocked(os.platform).mockReturnValue('darwin')
|
||||
vi.mocked(os.arch).mockReturnValue('x64')
|
||||
const expected = 'https://test.tld/helm-v3.8.0-darwin-amd64.tar.gz'
|
||||
|
||||
expect(run.getHelmDownloadURL('v3.8.0')).toBe(kubectlDarwinArm64Url)
|
||||
expect(os.type).toBeCalled()
|
||||
expect(os.arch).toBeCalled()
|
||||
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
|
||||
expect(os.platform).toHaveBeenCalled()
|
||||
expect(os.arch).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('getHelmDownloadURL() - return the URL to download helm for Darwin arm64', () => {
|
||||
vi.mocked(os.platform).mockReturnValue('darwin')
|
||||
vi.mocked(os.arch).mockReturnValue('arm64')
|
||||
const expected = 'https://test.tld/helm-v3.8.0-darwin-arm64.tar.gz'
|
||||
|
||||
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
|
||||
expect(os.platform).toHaveBeenCalled()
|
||||
expect(os.arch).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('getHelmDownloadURL() - return the URL to download helm for Windows x64', () => {
|
||||
vi.mocked(os.platform).mockReturnValue('win32')
|
||||
vi.mocked(os.arch).mockReturnValue('x64')
|
||||
|
||||
const expected = 'https://test.tld/helm-v3.8.0-windows-amd64.zip'
|
||||
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
|
||||
expect(os.platform).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('getHelmDownloadURL() - return the URL to download helm for Windows arm64', () => {
|
||||
vi.mocked(os.platform).mockReturnValue('win32')
|
||||
vi.mocked(os.arch).mockReturnValue('arm64')
|
||||
|
||||
const expected = 'https://test.tld/helm-v3.8.0-windows-arm64.zip'
|
||||
expect(run.getHelmDownloadURL(downloadBaseURL, 'v3.8.0')).toBe(expected)
|
||||
expect(os.platform).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('getLatestHelmVersion() - return the latest version of HELM', async () => {
|
||||
const res = {
|
||||
status: 200,
|
||||
text: async () => 'v9.99.999'
|
||||
} as Response
|
||||
vi.stubGlobal('fetch', vi.fn().mockReturnValue(res))
|
||||
expect(await run.getLatestHelmVersion()).toBe('v9.99.999')
|
||||
})
|
||||
|
||||
test('getLatestHelmVersion() - return the stable version of HELM when simulating a network error', async () => {
|
||||
const errorMessage: string = 'Network Error'
|
||||
vi.stubGlobal(
|
||||
'fetch',
|
||||
vi.fn().mockRejectedValueOnce(new Error(errorMessage))
|
||||
)
|
||||
expect(await run.getLatestHelmVersion()).toBe(run.stableHelmVersion)
|
||||
})
|
||||
|
||||
test('getValidVersion() - return version with v prepended', () => {
|
||||
expect(run.getValidVersion('3.8.0')).toBe('v3.8.0')
|
||||
})
|
||||
|
||||
test('getHelmDownloadURL() - return the URL to download helm for Windows', () => {
|
||||
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
|
||||
|
||||
const kubectlWindowsUrl =
|
||||
'https://get.helm.sh/helm-v3.8.0-windows-amd64.zip'
|
||||
expect(run.getHelmDownloadURL('v3.8.0')).toBe(kubectlWindowsUrl)
|
||||
expect(os.type).toBeCalled()
|
||||
test('parseToolVersions() - return the helm version from .tool-versions content', () => {
|
||||
const content = ['nodejs 20.11.0', 'helm 3.14.0', 'terraform 1.7.0'].join(
|
||||
'\n'
|
||||
)
|
||||
expect(run.parseToolVersions(content)).toBe('3.14.0')
|
||||
})
|
||||
|
||||
test('getLatestHelmVersion() - return the stable version of HELM since its not authenticated', async () => {
|
||||
expect(await run.getLatestHelmVersion()).toBe('v3.9.0')
|
||||
test('parseToolVersions() - ignore comments and blank lines', () => {
|
||||
const content = ['# tools', '', ' helm 3.15.2 ', ''].join('\n')
|
||||
expect(run.parseToolVersions(content)).toBe('3.15.2')
|
||||
})
|
||||
|
||||
test('parseToolVersions() - return the first version when several are listed', () => {
|
||||
expect(run.parseToolVersions('helm 3.14.0 3.13.0')).toBe('3.14.0')
|
||||
})
|
||||
|
||||
test('parseToolVersions() - return empty string when helm is not declared', () => {
|
||||
expect(run.parseToolVersions('nodejs 20.11.0')).toBe('')
|
||||
})
|
||||
|
||||
test('getVersionFromToolVersionsFile() - read the helm version from a file', () => {
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('helm 3.14.0')
|
||||
|
||||
expect(run.getVersionFromToolVersionsFile('.tool-versions')).toBe(
|
||||
'3.14.0'
|
||||
)
|
||||
expect(fs.readFileSync).toHaveBeenCalledWith('.tool-versions', 'utf8')
|
||||
})
|
||||
|
||||
test('getVersionFromToolVersionsFile() - throw when the file does not exist', () => {
|
||||
vi.mocked(fs.existsSync).mockReturnValue(false)
|
||||
|
||||
expect(() =>
|
||||
run.getVersionFromToolVersionsFile('missing.tool-versions')
|
||||
).toThrow("The version-file 'missing.tool-versions' does not exist")
|
||||
})
|
||||
|
||||
test('getVersionFromToolVersionsFile() - throw when no helm version is present', () => {
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('nodejs 20.11.0')
|
||||
|
||||
expect(() =>
|
||||
run.getVersionFromToolVersionsFile('.tool-versions')
|
||||
).toThrow("No helm version found in '.tool-versions'")
|
||||
})
|
||||
|
||||
test('getVersionFromToolVersionsFile() - throw when the helm version is not semver-shaped', () => {
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('helm latest')
|
||||
|
||||
expect(() =>
|
||||
run.getVersionFromToolVersionsFile('.tool-versions')
|
||||
).toThrow(
|
||||
"The helm version 'latest' in '.tool-versions' is not a valid semantic version"
|
||||
)
|
||||
})
|
||||
|
||||
test('isSemVerShaped() - accept semver-shaped versions with or without a v prefix', () => {
|
||||
expect(run.isSemVerShaped('3.14.0')).toBe(true)
|
||||
expect(run.isSemVerShaped('v3.14.0')).toBe(true)
|
||||
expect(run.isSemVerShaped('3.14.0-rc.1')).toBe(true)
|
||||
})
|
||||
|
||||
test('isSemVerShaped() - reject values that are not semver-shaped', () => {
|
||||
expect(run.isSemVerShaped('latest')).toBe(false)
|
||||
expect(run.isSemVerShaped('3.14')).toBe(false)
|
||||
expect(run.isSemVerShaped('abc')).toBe(false)
|
||||
})
|
||||
|
||||
// Stubs the download chain so run() resolves to a cached helm binary,
|
||||
// letting these tests focus on version-vs-version-file resolution.
|
||||
const stubDownloadChain = () => {
|
||||
vi.mocked(os.platform).mockReturnValue('linux')
|
||||
vi.mocked(os.arch).mockReturnValue('x64')
|
||||
vi.mocked(toolCache.find).mockReturnValue('pathToCachedDir')
|
||||
vi.mocked(fs.chmodSync).mockImplementation(() => {})
|
||||
vi.mocked(fs.readdirSync).mockReturnValue([
|
||||
'helm' as unknown as fs.Dirent<NonSharedBuffer>
|
||||
])
|
||||
vi.mocked(fs.statSync).mockReturnValue({
|
||||
isDirectory: () => false
|
||||
} as fs.Stats)
|
||||
}
|
||||
|
||||
const inputs = (version: string, versionFile: string) =>
|
||||
vi.mocked(core.getInput).mockImplementation((name: string) => {
|
||||
if (name === 'version') return version
|
||||
if (name === 'version-file') return versionFile
|
||||
if (name === 'downloadBaseURL') return downloadBaseURL
|
||||
return ''
|
||||
})
|
||||
|
||||
test('run() - resolve the version from version-file when version is not set', async () => {
|
||||
stubDownloadChain()
|
||||
inputs('', '.tool-versions')
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('helm 3.14.0')
|
||||
|
||||
await run.run()
|
||||
|
||||
expect(core.warning).not.toHaveBeenCalled()
|
||||
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v3.14.0')
|
||||
expect(core.setOutput).toHaveBeenCalledWith(
|
||||
'helm-path',
|
||||
path.join('pathToCachedDir', 'helm')
|
||||
)
|
||||
})
|
||||
|
||||
test('run() - resolve the version from version-file when version is left at the latest default', async () => {
|
||||
stubDownloadChain()
|
||||
inputs('latest', '.tool-versions')
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('helm 3.14.0')
|
||||
|
||||
await run.run()
|
||||
|
||||
expect(core.warning).not.toHaveBeenCalled()
|
||||
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v3.14.0')
|
||||
})
|
||||
|
||||
test('run() - warn and prefer version over version-file when both are set', async () => {
|
||||
stubDownloadChain()
|
||||
inputs('3.5.0', '.tool-versions')
|
||||
|
||||
await run.run()
|
||||
|
||||
expect(core.warning).toHaveBeenCalledWith(
|
||||
`Both 'version' and 'version-file' inputs are specified, only 'version' will be used.`
|
||||
)
|
||||
expect(fs.readFileSync).not.toHaveBeenCalled()
|
||||
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v3.5.0')
|
||||
})
|
||||
|
||||
test('walkSync() - return path to the all files matching fileToFind in dir', () => {
|
||||
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => {
|
||||
vi.mocked(fs.readdirSync).mockImplementation((file, _?) => {
|
||||
if (file == 'mainFolder')
|
||||
return [
|
||||
'file1' as unknown as fs.Dirent,
|
||||
'file2' as unknown as fs.Dirent,
|
||||
'folder1' as unknown as fs.Dirent,
|
||||
'folder2' as unknown as fs.Dirent
|
||||
'file1' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'file2' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'folder1' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'folder2' as unknown as fs.Dirent<NonSharedBuffer>
|
||||
]
|
||||
if (file == path.join('mainFolder', 'folder1'))
|
||||
return [
|
||||
'file11' as unknown as fs.Dirent,
|
||||
'file12' as unknown as fs.Dirent
|
||||
'file11' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'file12' as unknown as fs.Dirent<NonSharedBuffer>
|
||||
]
|
||||
if (file == path.join('mainFolder', 'folder2'))
|
||||
return [
|
||||
'file21' as unknown as fs.Dirent,
|
||||
'file22' as unknown as fs.Dirent
|
||||
'file21' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'file22' as unknown as fs.Dirent<NonSharedBuffer>
|
||||
]
|
||||
return []
|
||||
})
|
||||
jest.spyOn(core, 'debug').mockImplementation()
|
||||
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
|
||||
vi.mocked(fs.statSync).mockImplementation((file) => {
|
||||
const isDirectory =
|
||||
(file as string).toLowerCase().indexOf('file') == -1 ? true : false
|
||||
return {isDirectory: () => isDirectory} as fs.Stats
|
||||
@@ -108,53 +326,55 @@ describe('run.ts', () => {
|
||||
expect(run.walkSync('mainFolder', null, 'file21')).toEqual([
|
||||
path.join('mainFolder', 'folder2', 'file21')
|
||||
])
|
||||
expect(fs.readdirSync).toBeCalledTimes(3)
|
||||
expect(fs.statSync).toBeCalledTimes(8)
|
||||
expect(fs.readdirSync).toHaveBeenCalledTimes(3)
|
||||
expect(fs.statSync).toHaveBeenCalledTimes(8)
|
||||
})
|
||||
|
||||
test('walkSync() - return empty array if no file with name fileToFind exists', () => {
|
||||
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => {
|
||||
vi.mocked(fs.readdirSync).mockImplementation((file, _?) => {
|
||||
if (file == 'mainFolder')
|
||||
return [
|
||||
'file1' as unknown as fs.Dirent,
|
||||
'file2' as unknown as fs.Dirent,
|
||||
'folder1' as unknown as fs.Dirent,
|
||||
'folder2' as unknown as fs.Dirent
|
||||
'file1' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'file2' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'folder1' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'folder2' as unknown as fs.Dirent<NonSharedBuffer>
|
||||
]
|
||||
if (file == path.join('mainFolder', 'folder1'))
|
||||
return [
|
||||
'file11' as unknown as fs.Dirent,
|
||||
'file12' as unknown as fs.Dirent
|
||||
'file11' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'file12' as unknown as fs.Dirent<NonSharedBuffer>
|
||||
]
|
||||
if (file == path.join('mainFolder', 'folder2'))
|
||||
return [
|
||||
'file21' as unknown as fs.Dirent,
|
||||
'file22' as unknown as fs.Dirent
|
||||
'file21' as unknown as fs.Dirent<NonSharedBuffer>,
|
||||
'file22' as unknown as fs.Dirent<NonSharedBuffer>
|
||||
]
|
||||
return []
|
||||
})
|
||||
jest.spyOn(core, 'debug').mockImplementation()
|
||||
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
|
||||
vi.mocked(fs.statSync).mockImplementation((file) => {
|
||||
const isDirectory =
|
||||
(file as string).toLowerCase().indexOf('file') == -1 ? true : false
|
||||
return {isDirectory: () => isDirectory} as fs.Stats
|
||||
})
|
||||
|
||||
expect(run.walkSync('mainFolder', null, 'helm.exe')).toEqual([])
|
||||
expect(fs.readdirSync).toBeCalledTimes(3)
|
||||
expect(fs.statSync).toBeCalledTimes(8)
|
||||
expect(fs.readdirSync).toHaveBeenCalledTimes(3)
|
||||
expect(fs.statSync).toHaveBeenCalledTimes(8)
|
||||
})
|
||||
|
||||
test('findHelm() - change access permissions and find the helm in given directory', () => {
|
||||
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {})
|
||||
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => {
|
||||
if (file == 'mainFolder') return ['helm.exe' as unknown as fs.Dirent]
|
||||
vi.mocked(fs.chmodSync).mockImplementation(() => {})
|
||||
vi.mocked(fs.readdirSync).mockImplementation((file, _?) => {
|
||||
if (file == 'mainFolder')
|
||||
return ['helm.exe' as unknown as fs.Dirent<NonSharedBuffer>]
|
||||
return []
|
||||
})
|
||||
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
|
||||
vi.mocked(fs.statSync).mockImplementation((file) => {
|
||||
const isDirectory =
|
||||
(file as string).indexOf('folder') == -1 ? false : true
|
||||
return {isDirectory: () => isDirectory} as fs.Stats
|
||||
})
|
||||
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
|
||||
vi.mocked(os.platform).mockReturnValue('win32')
|
||||
|
||||
expect(run.findHelm('mainFolder')).toBe(
|
||||
path.join('mainFolder', 'helm.exe')
|
||||
@@ -162,108 +382,122 @@ describe('run.ts', () => {
|
||||
})
|
||||
|
||||
test('findHelm() - throw error if executable not found', () => {
|
||||
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {})
|
||||
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => {
|
||||
vi.mocked(fs.chmodSync).mockImplementation(() => {})
|
||||
vi.mocked(fs.readdirSync).mockImplementation((file, _?) => {
|
||||
if (file == 'mainFolder') return []
|
||||
return []
|
||||
})
|
||||
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
|
||||
vi.mocked(fs.statSync).mockImplementation((file) => {
|
||||
return {isDirectory: () => true} as fs.Stats
|
||||
})
|
||||
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
|
||||
vi.mocked(os.platform).mockReturnValue('win32')
|
||||
|
||||
expect(() => run.findHelm('mainFolder')).toThrow(
|
||||
'Helm executable not found in path mainFolder'
|
||||
)
|
||||
})
|
||||
|
||||
test('downloadHelm() - download helm and return path to it', async () => {
|
||||
jest.spyOn(toolCache, 'find').mockReturnValue('')
|
||||
jest.spyOn(toolCache, 'downloadTool').mockResolvedValue('pathToTool')
|
||||
vi.mocked(toolCache.find).mockReturnValue('')
|
||||
vi.mocked(toolCache.downloadTool).mockResolvedValue('pathToTool')
|
||||
const response = JSON.stringify([{tag_name: 'v4.0.0'}])
|
||||
jest.spyOn(fs, 'readFileSync').mockReturnValue(response)
|
||||
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
|
||||
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {})
|
||||
jest
|
||||
.spyOn(toolCache, 'extractZip')
|
||||
.mockResolvedValue('pathToUnzippedHelm')
|
||||
jest.spyOn(toolCache, 'cacheDir').mockResolvedValue('pathToCachedDir')
|
||||
jest
|
||||
.spyOn(fs, 'readdirSync')
|
||||
.mockImplementation((file, _) => ['helm.exe' as unknown as fs.Dirent])
|
||||
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
|
||||
vi.mocked(fs.readFileSync).mockReturnValue(response)
|
||||
vi.mocked(os.platform).mockReturnValue('win32')
|
||||
vi.mocked(os.arch).mockReturnValue('x64')
|
||||
vi.mocked(fs.chmodSync).mockImplementation(() => {})
|
||||
vi.mocked(toolCache.extractZip).mockResolvedValue('extractedPath')
|
||||
vi.mocked(toolCache.cacheDir).mockResolvedValue('pathToCachedDir')
|
||||
vi.mocked(fs.readdirSync).mockImplementation((file, _?) => [
|
||||
'helm.exe' as unknown as fs.Dirent<NonSharedBuffer>
|
||||
])
|
||||
vi.mocked(fs.statSync).mockImplementation((file) => {
|
||||
const isDirectory =
|
||||
(file as string).indexOf('folder') == -1 ? false : true
|
||||
return {isDirectory: () => isDirectory} as fs.Stats
|
||||
})
|
||||
|
||||
expect(await run.downloadHelm('v4.0.0')).toBe(
|
||||
expect(await run.downloadHelm(downloadBaseURL, 'v4.0.0')).toBe(
|
||||
path.join('pathToCachedDir', 'helm.exe')
|
||||
)
|
||||
expect(toolCache.find).toBeCalledWith('helm', 'v4.0.0')
|
||||
expect(toolCache.downloadTool).toBeCalledWith(
|
||||
'https://get.helm.sh/helm-v4.0.0-windows-amd64.zip'
|
||||
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v4.0.0')
|
||||
expect(toolCache.downloadTool).toHaveBeenCalledWith(
|
||||
'https://test.tld/helm-v4.0.0-windows-amd64.zip'
|
||||
)
|
||||
expect(fs.chmodSync).toBeCalledWith('pathToTool', '777')
|
||||
expect(toolCache.extractZip).toBeCalledWith('pathToTool')
|
||||
expect(fs.chmodSync).toBeCalledWith(
|
||||
expect(fs.chmodSync).toHaveBeenCalledWith('pathToTool', '755')
|
||||
expect(toolCache.extractZip).toHaveBeenCalledWith('pathToTool')
|
||||
expect(fs.chmodSync).toHaveBeenCalledWith(
|
||||
path.join('pathToCachedDir', 'helm.exe'),
|
||||
'777'
|
||||
'755'
|
||||
)
|
||||
})
|
||||
|
||||
test('downloadHelm() - throw error if unable to download', async () => {
|
||||
jest.spyOn(toolCache, 'find').mockReturnValue('')
|
||||
jest.spyOn(toolCache, 'downloadTool').mockImplementation(async () => {
|
||||
vi.mocked(toolCache.find).mockReturnValue('')
|
||||
vi.mocked(toolCache.downloadTool).mockImplementation(async () => {
|
||||
throw 'Unable to download'
|
||||
})
|
||||
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
|
||||
vi.mocked(os.platform).mockReturnValue('win32')
|
||||
vi.mocked(os.arch).mockReturnValue('x64')
|
||||
|
||||
await expect(run.downloadHelm('v3.2.1')).rejects.toThrow(
|
||||
'Failed to download Helm from location https://get.helm.sh/helm-v3.2.1-windows-amd64.zip'
|
||||
)
|
||||
expect(toolCache.find).toBeCalledWith('helm', 'v3.2.1')
|
||||
expect(toolCache.downloadTool).toBeCalledWith(
|
||||
'https://get.helm.sh/helm-v3.2.1-windows-amd64.zip'
|
||||
const downloadUrl = 'https://test.tld/helm-v3.2.1-windows-amd64.zip'
|
||||
await expect(run.downloadHelm(downloadBaseURL, 'v3.2.1')).rejects.toThrow(
|
||||
`Failed to download Helm from location ${downloadUrl}`
|
||||
)
|
||||
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v3.2.1')
|
||||
expect(toolCache.downloadTool).toHaveBeenCalledWith(`${downloadUrl}`)
|
||||
})
|
||||
|
||||
test('downloadHelm() - return path to helm tool with same version from toolCache', async () => {
|
||||
jest.spyOn(toolCache, 'find').mockReturnValue('pathToCachedDir')
|
||||
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {})
|
||||
|
||||
expect(await run.downloadHelm('v3.2.1')).toBe(
|
||||
path.join('pathToCachedDir', 'helm.exe')
|
||||
)
|
||||
expect(toolCache.find).toBeCalledWith('helm', 'v3.2.1')
|
||||
expect(fs.chmodSync).toBeCalledWith(
|
||||
path.join('pathToCachedDir', 'helm.exe'),
|
||||
'777'
|
||||
)
|
||||
})
|
||||
|
||||
test('downloadHelm() - throw error is helm is not found in path', async () => {
|
||||
jest.spyOn(toolCache, 'find').mockReturnValue('')
|
||||
jest.spyOn(toolCache, 'downloadTool').mockResolvedValue('pathToTool')
|
||||
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
|
||||
jest.spyOn(fs, 'chmodSync').mockImplementation()
|
||||
jest
|
||||
.spyOn(toolCache, 'extractZip')
|
||||
.mockResolvedValue('pathToUnzippedHelm')
|
||||
jest.spyOn(toolCache, 'cacheDir').mockResolvedValue('pathToCachedDir')
|
||||
jest.spyOn(fs, 'readdirSync').mockImplementation((file, _) => [])
|
||||
jest.spyOn(fs, 'statSync').mockImplementation((file) => {
|
||||
vi.mocked(toolCache.find).mockReturnValue('pathToCachedDir')
|
||||
vi.mocked(toolCache.cacheDir).mockResolvedValue('pathToCachedDir')
|
||||
vi.mocked(toolCache.downloadTool).mockResolvedValue('pathToTool')
|
||||
vi.mocked(toolCache.extractZip).mockResolvedValue('extractedPath')
|
||||
vi.mocked(os.platform).mockReturnValue('win32')
|
||||
vi.mocked(os.arch).mockReturnValue('x64')
|
||||
vi.mocked(fs.chmodSync).mockImplementation(() => {})
|
||||
vi.mocked(fs.readdirSync).mockReturnValue([
|
||||
'helm.exe' as unknown as fs.Dirent<NonSharedBuffer>
|
||||
])
|
||||
vi.mocked(fs.statSync).mockImplementation((file) => {
|
||||
const isDirectory =
|
||||
(file as string).indexOf('folder') == -1 ? false : true
|
||||
return {isDirectory: () => isDirectory} as fs.Stats
|
||||
})
|
||||
|
||||
await expect(run.downloadHelm('v3.2.1')).rejects.toThrow(
|
||||
expect(await run.downloadHelm(downloadBaseURL, 'v3.2.1')).toBe(
|
||||
path.join('pathToCachedDir', 'helm.exe')
|
||||
)
|
||||
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v3.2.1')
|
||||
expect(fs.chmodSync).toHaveBeenCalledWith(
|
||||
path.join('pathToCachedDir', 'helm.exe'),
|
||||
'755'
|
||||
)
|
||||
})
|
||||
|
||||
test('downloadHelm() - throw error is helm is not found in path', async () => {
|
||||
vi.mocked(toolCache.find).mockReturnValue('')
|
||||
vi.mocked(toolCache.downloadTool).mockResolvedValue('pathToTool')
|
||||
vi.mocked(toolCache.cacheDir).mockResolvedValue('pathToCachedDir')
|
||||
vi.mocked(toolCache.downloadTool).mockResolvedValue('pathToTool')
|
||||
vi.mocked(toolCache.extractZip).mockResolvedValue('extractedPath')
|
||||
vi.mocked(os.platform).mockReturnValue('win32')
|
||||
vi.mocked(os.arch).mockReturnValue('x64')
|
||||
vi.mocked(fs.chmodSync).mockImplementation(() => {})
|
||||
vi.mocked(fs.readdirSync).mockImplementation((file, _?) => [])
|
||||
vi.mocked(fs.statSync).mockImplementation((file) => {
|
||||
const isDirectory =
|
||||
(file as string).indexOf('folder') == -1 ? false : true
|
||||
return {isDirectory: () => isDirectory} as fs.Stats
|
||||
})
|
||||
|
||||
await expect(run.downloadHelm(downloadBaseURL, 'v3.2.1')).rejects.toThrow(
|
||||
'Helm executable not found in path pathToCachedDir'
|
||||
)
|
||||
expect(toolCache.find).toBeCalledWith('helm', 'v3.2.1')
|
||||
expect(toolCache.downloadTool).toBeCalledWith(
|
||||
'https://get.helm.sh/helm-v3.2.1-windows-amd64.zip'
|
||||
expect(toolCache.find).toHaveBeenCalledWith('helm', 'v3.2.1')
|
||||
expect(toolCache.downloadTool).toHaveBeenCalledWith(
|
||||
'https://test.tld/helm-v3.2.1-windows-amd64.zip'
|
||||
)
|
||||
expect(fs.chmodSync).toBeCalledWith('pathToTool', '777')
|
||||
expect(toolCache.extractZip).toBeCalledWith('pathToTool')
|
||||
expect(fs.chmodSync).toHaveBeenCalledWith('pathToTool', '755')
|
||||
expect(toolCache.extractZip).toHaveBeenCalledWith('pathToTool')
|
||||
})
|
||||
})
|
||||
|
||||
+116
-106
@@ -1,5 +1,4 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import * as os from 'os'
|
||||
@@ -9,30 +8,45 @@ import * as fs from 'fs'
|
||||
|
||||
import * as toolCache from '@actions/tool-cache'
|
||||
import * as core from '@actions/core'
|
||||
import {graphql} from '@octokit/graphql'
|
||||
import {createActionAuth} from '@octokit/auth-action'
|
||||
import {create} from 'domain'
|
||||
|
||||
const helmToolName = 'helm'
|
||||
const stableHelmVersion = 'v3.9.0'
|
||||
export const stableHelmVersion = 'v3.18.4'
|
||||
|
||||
export async function run() {
|
||||
let version = core.getInput('version', {required: true})
|
||||
let version = core.getInput('version')
|
||||
const versionFile = core.getInput('version-file')
|
||||
|
||||
if (versionFile) {
|
||||
if (version && version !== 'latest') {
|
||||
core.warning(
|
||||
`Both 'version' and 'version-file' inputs are specified, only 'version' will be used.`
|
||||
)
|
||||
} else {
|
||||
version = getVersionFromToolVersionsFile(versionFile)
|
||||
core.info(`Resolved Helm version '${version}' from '${versionFile}'`)
|
||||
}
|
||||
}
|
||||
|
||||
if (!version) {
|
||||
version = 'latest'
|
||||
}
|
||||
|
||||
if (version !== 'latest' && version[0] !== 'v') {
|
||||
core.info('Getting latest Helm version')
|
||||
version = getValidVersion(version)
|
||||
core.info(`Normalized Helm version to '${version}'`)
|
||||
}
|
||||
if (version.toLocaleLowerCase() === 'latest') {
|
||||
version = await getLatestHelmVersion()
|
||||
}
|
||||
|
||||
core.startGroup(`Downloading ${version}`)
|
||||
const cachedPath = await downloadHelm(version)
|
||||
const downloadBaseURL = core.getInput('downloadBaseURL', {required: false})
|
||||
|
||||
core.startGroup(`Installing ${version}`)
|
||||
const cachedPath = await downloadHelm(downloadBaseURL, version)
|
||||
core.endGroup()
|
||||
|
||||
try {
|
||||
if (!process.env['PATH'].startsWith(path.dirname(cachedPath))) {
|
||||
if (!process.env['PATH']?.startsWith(path.dirname(cachedPath))) {
|
||||
core.addPath(path.dirname(cachedPath))
|
||||
}
|
||||
} catch {
|
||||
@@ -48,120 +62,118 @@ export function getValidVersion(version: string): string {
|
||||
return 'v' + version
|
||||
}
|
||||
|
||||
// Gets the latest helm version or returns a default stable if getting latest fails
|
||||
export async function getLatestHelmVersion(): Promise<string> {
|
||||
try {
|
||||
const auth = createActionAuth()
|
||||
const graphqlAuthenticated = graphql.defaults({
|
||||
request: {hook: auth.hook}
|
||||
})
|
||||
const {repository} = await graphqlAuthenticated(
|
||||
`
|
||||
{
|
||||
repository(name: "helm", owner: "helm") {
|
||||
releases(first: 100, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
nodes {
|
||||
tagName
|
||||
isLatest
|
||||
isDraft
|
||||
isPrerelease
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
const latestValidRelease: string = repository.releases.nodes.find(
|
||||
({tagName, isLatest, isDraft, isPreRelease}) =>
|
||||
isValidVersion(tagName) && isLatest && !isDraft && !isPreRelease
|
||||
)?.tagName
|
||||
// Matches a semantic version (major.minor.patch) with an optional leading 'v'
|
||||
// and optional pre-release / build-metadata suffixes, e.g. '3.14.0', 'v3.14.0',
|
||||
// '3.14.0-rc.1'.
|
||||
const semVerShape = /^v?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/
|
||||
|
||||
if (latestValidRelease) return latestValidRelease
|
||||
} catch (err) {
|
||||
core.warning(
|
||||
`Error while fetching latest Helm release: ${err.toString()}. Using default version ${stableHelmVersion}`
|
||||
)
|
||||
return stableHelmVersion
|
||||
// Returns true when version looks like a semantic version
|
||||
export function isSemVerShaped(version: string): boolean {
|
||||
return semVerShape.test(version)
|
||||
}
|
||||
|
||||
// Reads a .tool-versions file and returns the helm version declared in it
|
||||
export function getVersionFromToolVersionsFile(filePath: string): string {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new Error(`The version-file '${filePath}' does not exist`)
|
||||
}
|
||||
|
||||
core.warning(
|
||||
`Could not find valid release. Using default version ${stableHelmVersion}`
|
||||
)
|
||||
return stableHelmVersion
|
||||
const content = fs.readFileSync(filePath, 'utf8')
|
||||
const version = parseToolVersions(content)
|
||||
if (!version) {
|
||||
throw new Error(`No helm version found in '${filePath}'`)
|
||||
}
|
||||
if (!isSemVerShaped(version)) {
|
||||
throw new Error(
|
||||
`The helm version '${version}' in '${filePath}' is not a valid semantic version`
|
||||
)
|
||||
}
|
||||
return version
|
||||
}
|
||||
|
||||
// isValidVersion checks if verison is a stable release
|
||||
function isValidVersion(version: string): boolean {
|
||||
return version.indexOf('rc') == -1
|
||||
}
|
||||
|
||||
export function getExecutableExtension(): string {
|
||||
if (os.type().match(/^Win/)) {
|
||||
return '.exe'
|
||||
// Parses .tool-versions content (asdf/mise format) and returns the first
|
||||
// helm version, or an empty string when none is declared. Lines look like
|
||||
// `helm 3.14.0`; comments (#) and blank lines are ignored.
|
||||
export function parseToolVersions(content: string): string {
|
||||
for (const line of content.split(/\r?\n/)) {
|
||||
const trimmed = line.trim()
|
||||
if (!trimmed || trimmed.startsWith('#')) {
|
||||
continue
|
||||
}
|
||||
const [tool, version] = trimmed.split(/\s+/)
|
||||
if (tool === helmToolName && version) {
|
||||
return version
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
const LINUX = 'Linux'
|
||||
const MAC_OS = 'Darwin'
|
||||
const WINDOWS = 'Windows_NT'
|
||||
const ARM64 = 'arm64'
|
||||
export function getHelmDownloadURL(version: string): string {
|
||||
const arch = os.arch()
|
||||
const operatingSystem = os.type()
|
||||
|
||||
switch (true) {
|
||||
case operatingSystem == LINUX && arch == ARM64:
|
||||
return util.format(
|
||||
'https://get.helm.sh/helm-%s-linux-arm64.zip',
|
||||
version
|
||||
)
|
||||
case operatingSystem == LINUX:
|
||||
return util.format(
|
||||
'https://get.helm.sh/helm-%s-linux-amd64.zip',
|
||||
version
|
||||
)
|
||||
|
||||
case operatingSystem == MAC_OS && arch == ARM64:
|
||||
return util.format(
|
||||
'https://get.helm.sh/helm-%s-darwin-arm64.zip',
|
||||
version
|
||||
)
|
||||
case operatingSystem == MAC_OS:
|
||||
return util.format(
|
||||
'https://get.helm.sh/helm-%s-darwin-amd64.zip',
|
||||
version
|
||||
)
|
||||
|
||||
case operatingSystem == WINDOWS:
|
||||
default:
|
||||
return util.format(
|
||||
'https://get.helm.sh/helm-%s-windows-amd64.zip',
|
||||
version
|
||||
)
|
||||
// Gets the latest helm version or returns a default stable if getting latest fails
|
||||
export async function getLatestHelmVersion(): Promise<string> {
|
||||
try {
|
||||
const response = await fetch('https://get.helm.sh/helm-latest-version')
|
||||
const release = (await response.text()).trim()
|
||||
return release
|
||||
} catch (err) {
|
||||
core.warning(
|
||||
`Error while fetching latest Helm release: ${err instanceof Error ? err.message : String(err)}. Using default version ${stableHelmVersion}`
|
||||
)
|
||||
return stableHelmVersion
|
||||
}
|
||||
}
|
||||
|
||||
export async function downloadHelm(version: string): Promise<string> {
|
||||
export function getArch(): string {
|
||||
return os.arch() === 'x64' ? 'amd64' : os.arch()
|
||||
}
|
||||
|
||||
export function getPlatform(): string {
|
||||
return os.platform() === 'win32' ? 'windows' : os.platform()
|
||||
}
|
||||
|
||||
export function getArchiveExtension(): string {
|
||||
return os.platform() === 'win32' ? 'zip' : 'tar.gz'
|
||||
}
|
||||
|
||||
export function getExecutableExtension(): string {
|
||||
return os.platform() === 'win32' ? '.exe' : ''
|
||||
}
|
||||
|
||||
export function getHelmDownloadURL(baseURL: string, version: string): string {
|
||||
const urlPath = `helm-${version}-${getPlatform()}-${getArch()}.${getArchiveExtension()}`
|
||||
const url = new URL(urlPath, baseURL)
|
||||
return url.toString()
|
||||
}
|
||||
|
||||
export async function downloadHelm(
|
||||
baseURL: string,
|
||||
version: string
|
||||
): Promise<string> {
|
||||
let cachedToolpath = toolCache.find(helmToolName, version)
|
||||
if (!cachedToolpath) {
|
||||
if (cachedToolpath) {
|
||||
core.info(`Restoring '${version}' from cache`)
|
||||
} else {
|
||||
core.info(`Downloading '${version}' from '${baseURL}'`)
|
||||
let helmDownloadPath
|
||||
try {
|
||||
helmDownloadPath = await toolCache.downloadTool(
|
||||
getHelmDownloadURL(version)
|
||||
getHelmDownloadURL(baseURL, version)
|
||||
)
|
||||
} catch (exception) {
|
||||
throw new Error(
|
||||
`Failed to download Helm from location ${getHelmDownloadURL(
|
||||
baseURL,
|
||||
version
|
||||
)}`
|
||||
)
|
||||
}
|
||||
|
||||
fs.chmodSync(helmDownloadPath, '777')
|
||||
const unzipedHelmPath = await toolCache.extractZip(helmDownloadPath)
|
||||
fs.chmodSync(helmDownloadPath, '755')
|
||||
const extractedPath =
|
||||
getPlatform() === 'windows'
|
||||
? await toolCache.extractZip(helmDownloadPath)
|
||||
: await toolCache.extractTar(helmDownloadPath)
|
||||
|
||||
cachedToolpath = await toolCache.cacheDir(
|
||||
unzipedHelmPath,
|
||||
extractedPath,
|
||||
helmToolName,
|
||||
version
|
||||
)
|
||||
@@ -174,13 +186,13 @@ export async function downloadHelm(version: string): Promise<string> {
|
||||
)
|
||||
}
|
||||
|
||||
fs.chmodSync(helmpath, '777')
|
||||
fs.chmodSync(helmpath, '755')
|
||||
return helmpath
|
||||
}
|
||||
|
||||
export function findHelm(rootFolder: string): string {
|
||||
fs.chmodSync(rootFolder, '777')
|
||||
var filelist: string[] = []
|
||||
fs.chmodSync(rootFolder, '755')
|
||||
let filelist: string[] = []
|
||||
walkSync(rootFolder, filelist, helmToolName + getExecutableExtension())
|
||||
if (!filelist || filelist.length == 0) {
|
||||
throw new Error(
|
||||
@@ -191,8 +203,8 @@ export function findHelm(rootFolder: string): string {
|
||||
}
|
||||
}
|
||||
|
||||
export var walkSync = function (dir, filelist, fileToFind) {
|
||||
var files = fs.readdirSync(dir)
|
||||
export function walkSync(dir, filelist, fileToFind) {
|
||||
const files = fs.readdirSync(dir)
|
||||
filelist = filelist || []
|
||||
files.forEach(function (file) {
|
||||
if (fs.statSync(path.join(dir, file)).isDirectory()) {
|
||||
@@ -206,5 +218,3 @@ export var walkSync = function (dir, filelist, fileToFind) {
|
||||
})
|
||||
return filelist
|
||||
}
|
||||
|
||||
run().catch(core.setFailed)
|
||||
|
||||
+10
-60
@@ -1,64 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
|
||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "./lib" /* Redirect output structure to the directory. */,
|
||||
"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
//"strict": true, /* Enable all strict type-checking options. */
|
||||
"noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */,
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "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'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
// "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
"skipLibCheck": true
|
||||
"target": "ES2020",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"noImplicitAny": false,
|
||||
"skipLibCheck": true,
|
||||
"noEmit": true,
|
||||
"types": ["node", "vitest/globals"]
|
||||
},
|
||||
"exclude": ["node_modules", "**/*.test.ts"]
|
||||
"exclude": ["node_modules", "**/*.test.ts", "vitest.config.ts"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import {defineConfig} from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'node',
|
||||
include: ['**/*.test.ts'],
|
||||
clearMocks: true
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user