Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: (╯°□°)╯︵ uᴉǝssnH ɐɟɐʇsoW <[email protected]>
mostafahussein committed Sep 24, 2022
0 parents commit 8efed6d
Showing 24 changed files with 12,098 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report-feature-request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
name: Bug Report / Feature Request
about: Create a report to help us improve
title: ''
labels: need-to-triage
assignees: '@mostafahussein'
---
36 changes: 36 additions & 0 deletions .github/ISSUE_TEMPLATE/bugReportForm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Bug Report
description: File a bug report specifying all inputs you provided for the action, we will respond to this thread with any questions.
title: 'Bug: '
labels: ['bug', 'triage']
assignees: '@mostafahussein'
body:
- type: textarea
id: What-happened
attributes:
label: What happened?
description: Tell us what happened and how is it different from the expected?
placeholder: Tell us what you see!
validations:
required: true
- type: checkboxes
id: Version
attributes:
label: Version
options:
- label: I am using the latest version
required: true
- type: input
id: Runner
attributes:
label: Runner
description: What runner are you using?
placeholder: Mention the runner info (self-hosted, operating system)
validations:
required: true
- type: textarea
id: Logs
attributes:
label: Relevant log output
description: Run in debug mode for the most verbose logs. Please feel free to attach a screenshot of the logs
validations:
required: true
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: GitHub Action "setup-aws-iam-authenticator" Support
url: https://github.com/mostafahussein/setup-aws-iam-authenticator
about: Please ask and answer questions here.
13 changes: 13 additions & 0 deletions .github/ISSUE_TEMPLATE/featureRequestForm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Feature Request
description: File a Feature Request form, we will respond to this thread with any questions.
title: 'Feature Request: '
labels: ['Feature']
assignees: '@mostafahussein'
body:
- type: textarea
id: Feature_request
attributes:
label: Feature request
description: Provide example functionality and links to relevant docs
validations:
required: true
30 changes: 30 additions & 0 deletions .github/workflows/defaultLabels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: setting-default-labels

on:
schedule:
- cron: '0 0/3 * * *'

jobs:
label-issues:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
name: Setting issue as idle
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue is idle because it has been open for 14 days with no activity.'
stale-issue-label: 'idle'
days-before-stale: 14
days-before-close: -1
operations-per-run: 100
exempt-issue-labels: 'backlog'

- uses: actions/stale@v3
name: Setting PR as idle
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-pr-message: 'This PR is idle because it has been open for 14 days with no activity.'
stale-pr-label: 'idle'
days-before-stale: 14
days-before-close: -1
operations-per-run: 100
48 changes: 48 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Integration test for setup-aws-iam-authenticator
on: # rebuild any PRs and main branch changes
pull_request:
branches:
- main
- 'releases/*'
push:
branches:
- main
- 'releases/*'

jobs:
run-integration-test:
name: Validate release and master branch
runs-on: ubuntu-latest
env:
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
steps:
- uses: actions/checkout@v2
name: Checkout from PR branch

- id: action-npm-build
name: npm install and build
run: |
echo $PR_BASE_REF
if [[ $PR_BASE_REF != releases/* ]]; then
npm install
npm run build
fi
- uses: actions/setup-python@v2
name: Install Python
with:
python-version: '3.x'

- name: Install requests library
run: pip install requests

- name: Setup aws-iam-authenticator
uses: ./
with:
version: 'v0.5.9'

- name: Fetch aws-iam-authenticator latest version dynamically and validate the setup
run: python test/validate-aws-iam-authenticator.py latest

- name: Set specific aws-iam-authenticator version and validate the setup
run: python test/validate-aws-iam-authenticator.py 'v0.5.9'
18 changes: 18 additions & 0 deletions .github/workflows/prettify-code.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: 'Run prettify'
on:
pull_request:
push:
branches: [main]

jobs:
prettier:
name: Prettier Check
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2

- name: Enforce Prettier
uses: actionsx/prettier@v2
with:
args: --check .
14 changes: 14 additions & 0 deletions .github/workflows/release-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Create release PR

on:
workflow_dispatch:
inputs:
release:
description: 'Define release version (ex: v1, v2, v3)'
required: true

jobs:
release-pr:
uses: mostafahussein/js-release-workflow/.github/workflows/release-pr.yml@main
with:
release: ${{ github.event.inputs.release }}
10 changes: 10 additions & 0 deletions .github/workflows/tag-and-draft.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: Tag and create release draft

on:
push:
branches:
- releases/*

jobs:
tag-and-release:
uses: mostafahussein/js-release-workflow/.github/workflows/tag-and-release.yml@main
21 changes: 21 additions & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: 'Run unit tests.'
on: # rebuild any PRs and main branch changes
pull_request:
branches:
- main
- 'releases/*'
push:
branches:
- main
- 'releases/*'

jobs:
build: # make sure build/ci works properly
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1

- name: Build and run L0 tests.
run: |
npm install
npm test
333 changes: 333 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,333 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# Visual Studio 2017 auto generated files
Generated\ Files/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# Benchmark Results
BenchmarkDotNet.Artifacts/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json

# StyleCop
StyleCopReport.xml

# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# Visual Studio Trace Files
*.e2e

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json

# Visual Studio code coverage results
*.coverage
*.coveragexml

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak

# SQL Server files
*.mdf
*.ldf
*.ndf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml

# CodeRush
.cr/

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config

# Tabs Studio
*.tss

# Telerik's JustMock configuration file
*.jmconfig

# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

# OpenCover UI analysis results
OpenCover/

# Azure Stream Analytics local run output
ASALocalRun/

# MSBuild Binary and Structured Log
*.binlog

# NVidia Nsight GPU debugger configuration file
*.nvuser

# MFractors (Xamarin productivity tool) working folder
.mfractor/
node_modules

# Transpiled JS
lib/
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# dependencies
/node_modules
coverage
/lib
8 changes: 8 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"trailingComma": "none",
"bracketSpacing": false,
"semi": false,
"tabWidth": 3,
"singleQuote": true,
"printWidth": 80
}
22 changes: 22 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
MIT License

Copyright (c) Microsoft Corporation.
Copyright (c) Mostafa Hussein.

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.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Setup aws-iam-authenticator

#### Sample workflow to install a specific version of aws-iam-authenticator binary on the runner.

Acceptable values are latest or any semantic version string like `0.5.9`. Use this action in workflow to define which version of aws-iam-authenticator will be used.

```yaml
- uses: mostafahussein/setup-aws-iam-authenticator@v1
with:
version: '<version>' # default is latest stable
id: install
```
Refer to the action metadata file for details about all the inputs https://github.com/mostafahussein/setup-aws-iam-authenticator/blob/main/action.yml
15 changes: 15 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: 'aws-iam-authenticator tool installer'
description: 'Install a specific version of aws-iam-authenticator binary. Acceptable values are latest or any semantic version string like 0.5.9'
inputs:
version:
description: 'Version of aws-iam-authenticator'
required: true
default: 'latest'
outputs:
aws-iam-authenticator-path:
description: 'Path to the cached aws-iam-authenticator binary'
branding:
color: 'orange'
runs:
using: 'node16'
main: 'lib/index.js'
18 changes: 18 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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
}
}
}
10,984 changes: 10,984 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "setup-aws-iam-authenticator-action",
"version": "0.0.0",
"private": true,
"main": "lib/index.js",
"scripts": {
"build": "ncc build src/run.ts -o lib",
"test": "jest",
"test-coverage": "jest --coverage",
"format": "prettier --write .",
"format-check": "prettier --check ."
},
"keywords": [
"actions",
"node",
"setup"
],
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.9.1",
"@actions/exec": "^1.0.0",
"@actions/tool-cache": "^1.0.0"
},
"devDependencies": {
"@types/jest": "^26.0.0",
"@types/node": "^12.0.4",
"@vercel/ncc": "^0.34.0",
"jest": "^26.0.1",
"prettier": "2.7.1",
"ts-jest": "^26.0.0",
"typescript": "3.9.2"
}
}
46 changes: 46 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as os from 'os'
import * as util from 'util'

export function getiamAuthArch(): string {
const arch = os.arch()
if (arch === 'x64') {
return 'amd64'
}
return arch
}

export function getiamAuthDownloadURL(version: string, arch: string): string {
switch (os.type()) {
case 'Linux':
return util.format(
'https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v%s/aws-iam-authenticator_%s_linux_%s',
version,
version,
arch
)

case 'Darwin':
return util.format(
'https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v%s/aws-iam-authenticator_%s_darwin_%s',
version,
version,
arch
)

case 'Windows_NT':
default:
return util.format(
'https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v%s/aws-iam-authenticator_%s_windows_%s.exe',
version,
version,
arch
)
}
}

export function getExecutableExtension(): string {
if (os.type().match(/^Win/)) {
return '.exe'
}
return ''
}
241 changes: 241 additions & 0 deletions src/run.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import * as run from './run'
import {
getiamAuthDownloadURL,
getiamAuthArch,
getExecutableExtension
} from './helpers'
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'
import * as util from 'util'

describe('Testing all functions in run file.', () => {
test('getExecutableExtension() - return .exe when os is Windows', () => {
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')

expect(getExecutableExtension()).toBe('.exe')
expect(os.type).toBeCalled()
})

test('getExecutableExtension() - return empty string for non-windows OS', () => {
jest.spyOn(os, 'type').mockReturnValue('Darwin')

expect(getExecutableExtension()).toBe('')
expect(os.type).toBeCalled()
})

test.each([
['arm', 'arm'],
['arm64', 'arm64'],
['x64', 'amd64']
])(
'getiamAuthArch() - return on %s os arch %s aws-iam-authenticator arch',
(osArch, iamAuthArch) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch)

expect(getiamAuthArch()).toBe(iamAuthArch)
expect(os.arch).toBeCalled()
}
)

test.each([['arm'], ['arm64'], ['amd64']])(
'getiamAuthDownloadURL() - return the URL to download %s aws-iam-authenticator for Linux',
(arch) => {
jest.spyOn(os, 'type').mockReturnValue('Linux')
const iamAuthLinuxUrl = util.format(
'https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v0.5.9/aws-iam-authenticator_0.5.9_linux_%s',
arch
)

expect(getiamAuthDownloadURL('0.5.9', arch)).toBe(iamAuthLinuxUrl)
expect(os.type).toBeCalled()
}
)

test.each([['arm'], ['arm64'], ['amd64']])(
'getiamAuthDownloadURL() - return the URL to download %s aws-iam-authenticator for Darwin',
(arch) => {
jest.spyOn(os, 'type').mockReturnValue('Darwin')
const iamAuthDarwinUrl = util.format(
'https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v0.5.9/aws-iam-authenticator_0.5.9_darwin_%s',
arch
)

expect(getiamAuthDownloadURL('0.5.9', arch)).toBe(iamAuthDarwinUrl)
expect(os.type).toBeCalled()
}
)

test.each([['arm'], ['arm64'], ['amd64']])(
'getiamAuthDownloadURL() - return the URL to download %s aws-iam-authenticator for Windows',
(arch) => {
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')

const iamAuthWindowsUrl = util.format(
'https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v0.5.9/aws-iam-authenticator_0.5.9_windows_%s.exe',
arch
)
expect(getiamAuthDownloadURL('0.5.9', arch)).toBe(iamAuthWindowsUrl)
expect(os.type).toBeCalled()
}
)

test('getStableiamAuthVersion() - download stable version file, read version and return it', async () => {
jest
.spyOn(toolCache, 'downloadTool')
.mockReturnValue(Promise.resolve('pathToTool'))
jest.spyOn(fs, 'readFileSync').mockReturnValue('{"tag_name":"v0.5.9"}')

expect(await run.getStableiamAuthVersion()).toBe('0.5.9')
expect(toolCache.downloadTool).toBeCalled()
expect(fs.readFileSync).toBeCalledWith('pathToTool', 'utf8')
})

test('getStableiamAuthVersion() - return default v0.5.9 if version read is empty', async () => {
jest
.spyOn(toolCache, 'downloadTool')
.mockReturnValue(Promise.resolve('pathToTool'))
jest.spyOn(fs, 'readFileSync').mockReturnValue('{}')

expect(await run.getStableiamAuthVersion()).toBe('0.5.9')
expect(toolCache.downloadTool).toBeCalled()
expect(fs.readFileSync).toBeCalledWith('pathToTool', 'utf8')
})

test('getStableiamAuthVersion() - return default v0.5.9 if unable to download file', async () => {
jest
.spyOn(toolCache, 'downloadTool')
.mockRejectedValue('Unable to download.')

expect(await run.getStableiamAuthVersion()).toBe('0.5.9')
expect(toolCache.downloadTool).toBeCalled()
})

test('downloadiamAuth() - download aws-iam-authenticator, add it to toolCache and return path to it', async () => {
jest.spyOn(toolCache, 'find').mockReturnValue('')
jest
.spyOn(toolCache, 'downloadTool')
.mockReturnValue(Promise.resolve('pathToTool'))
jest
.spyOn(toolCache, 'cacheFile')
.mockReturnValue(Promise.resolve('pathToCachedTool'))
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {})

expect(await run.downloadiamAuth('0.5.9')).toBe(
path.join('pathToCachedTool', 'aws-iam-authenticator.exe')
)
expect(toolCache.find).toBeCalledWith('aws-iam-authenticator', '0.5.9')
expect(toolCache.downloadTool).toBeCalled()
expect(toolCache.cacheFile).toBeCalled()
expect(os.type).toBeCalled()
expect(fs.chmodSync).toBeCalledWith(
path.join('pathToCachedTool', 'aws-iam-authenticator.exe'),
'775'
)
})

test('downloadiamAuth() - throw DownloadiamAuthFailed error when unable to download aws-iam-authenticator', async () => {
jest.spyOn(toolCache, 'find').mockReturnValue('')
jest
.spyOn(toolCache, 'downloadTool')
.mockRejectedValue('Unable to download aws-iam-authenticator.')

await expect(run.downloadiamAuth('0.5.9')).rejects.toThrow(
'DownloadiamAuthFailed'
)
expect(toolCache.find).toBeCalledWith('aws-iam-authenticator', '0.5.9')
expect(toolCache.downloadTool).toBeCalled()
})

test('downloadiamAuth() - throw aws-iam-authenticator not found error when receive 404 response', async () => {
const iamAuthVersion = '0.6.9'
const arch = 'arm128'

jest.spyOn(os, 'arch').mockReturnValue(arch)
jest.spyOn(toolCache, 'find').mockReturnValue('')
jest.spyOn(toolCache, 'downloadTool').mockImplementation((_) => {
throw new toolCache.HTTPError(404)
})

await expect(run.downloadiamAuth(iamAuthVersion)).rejects.toThrow(
util.format(
"aws-iam-authenticator '%s' for '%s' arch not found.",
iamAuthVersion,
arch
)
)
expect(os.arch).toBeCalled()
expect(toolCache.find).toBeCalledWith(
'aws-iam-authenticator',
iamAuthVersion
)
expect(toolCache.downloadTool).toBeCalled()
})

test('downloadiamAuth() - return path to existing cache of aws-iam-authenticator', async () => {
jest.spyOn(toolCache, 'find').mockReturnValue('pathToCachedTool')
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
jest.spyOn(fs, 'chmodSync').mockImplementation(() => {})
jest.spyOn(toolCache, 'downloadTool')

expect(await run.downloadiamAuth('0.5.9')).toBe(
path.join('pathToCachedTool', 'aws-iam-authenticator.exe')
)
expect(toolCache.find).toBeCalledWith('aws-iam-authenticator', '0.5.9')
expect(os.type).toBeCalled()
expect(fs.chmodSync).toBeCalledWith(
path.join('pathToCachedTool', 'aws-iam-authenticator.exe'),
'775'
)
expect(toolCache.downloadTool).not.toBeCalled()
})

test('run() - download specified version and set output', async () => {
jest.spyOn(core, 'getInput').mockReturnValue('0.5.9')
jest.spyOn(toolCache, 'find').mockReturnValue('pathToCachedTool')
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
jest.spyOn(fs, 'chmodSync').mockImplementation()
jest.spyOn(core, 'addPath').mockImplementation()
jest.spyOn(console, 'log').mockImplementation()
jest.spyOn(core, 'setOutput').mockImplementation()

expect(await run.run()).toBeUndefined()
expect(core.getInput).toBeCalledWith('version', {required: true})
expect(core.addPath).toBeCalledWith('pathToCachedTool')
expect(core.setOutput).toBeCalledWith(
'aws-iam-authenticator-path',
path.join('pathToCachedTool', 'aws-iam-authenticator.exe')
)
})

test('run() - get latest version, download it and set output', async () => {
jest.spyOn(core, 'getInput').mockReturnValue('latest')
jest
.spyOn(toolCache, 'downloadTool')
.mockReturnValue(Promise.resolve('pathToTool'))
jest.spyOn(fs, 'readFileSync').mockReturnValue('{"tag_name":"v0.5.9"}')
jest.spyOn(toolCache, 'find').mockReturnValue('pathToCachedTool')
jest.spyOn(os, 'type').mockReturnValue('Windows_NT')
jest.spyOn(fs, 'chmodSync').mockImplementation()
jest.spyOn(core, 'addPath').mockImplementation()
jest.spyOn(console, 'log').mockImplementation()
jest.spyOn(core, 'setOutput').mockImplementation()

expect(await run.run()).toBeUndefined()
expect(toolCache.downloadTool).toBeCalledWith(
'https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/latest',
undefined,
undefined,
{accept: 'application/json'}
)
expect(core.getInput).toBeCalledWith('version', {required: true})
expect(core.addPath).toBeCalledWith('pathToCachedTool')
expect(core.setOutput).toBeCalledWith(
'aws-iam-authenticator-path',
path.join('pathToCachedTool', 'aws-iam-authenticator.exe')
)
})
})
101 changes: 101 additions & 0 deletions src/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import * as path from 'path'
import * as util from 'util'
import * as fs from 'fs'

import * as toolCache from '@actions/tool-cache'
import * as core from '@actions/core'

import {
getiamAuthDownloadURL,
getiamAuthArch,
getExecutableExtension
} from './helpers'

const iamAuthToolName = 'aws-iam-authenticator'
const stableiamAuthVersion = '0.5.9'
const stableVersionUrl =
'https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/latest'

export async function run() {
let version = core.getInput('version', {required: true})
if (version.toLocaleLowerCase() === 'latest') {
version = await getStableiamAuthVersion()
} else if (version.startsWith('v')) {
version = version.slice(1)
}
const cachedPath = await downloadiamAuth(version)

core.addPath(path.dirname(cachedPath))

core.debug(
`aws-iam-authenticator tool version: '${version}' has been cached at ${cachedPath}`
)
core.setOutput('aws-iam-authenticator-path', cachedPath)
}

export async function getStableiamAuthVersion(): Promise<string> {
return toolCache
.downloadTool(stableVersionUrl, undefined, undefined, {
accept: 'application/json'
})
.then(
(downloadPath) => {
let version = JSON.parse(
fs.readFileSync(downloadPath, 'utf8')
).tag_name?.slice(1)
if (!version) {
version = stableiamAuthVersion
}
return version
},
(error) => {
core.debug(error)
core.warning('GetStableVersionFailed')
return stableiamAuthVersion
}
)
}

export async function downloadiamAuth(version: string): Promise<string> {
let cachedToolpath = toolCache.find(iamAuthToolName, version)
let iamAuthDownloadPath = ''
const arch = getiamAuthArch()
if (!cachedToolpath) {
try {
iamAuthDownloadPath = await toolCache.downloadTool(
getiamAuthDownloadURL(version, arch)
)
} catch (exception) {
if (
exception instanceof toolCache.HTTPError &&
exception.httpStatusCode === 404
) {
throw new Error(
util.format(
"aws-iam-authenticator '%s' for '%s' arch not found.",
version,
arch
)
)
} else {
throw new Error('DownloadiamAuthFailed')
}
}

cachedToolpath = await toolCache.cacheFile(
iamAuthDownloadPath,
iamAuthToolName + getExecutableExtension(),
iamAuthToolName,
version
)
}

const iamAuthPath = path.join(
cachedToolpath,
iamAuthToolName + getExecutableExtension()
)
fs.chmodSync(iamAuthPath, '775')
return iamAuthPath
}

run().catch(core.setFailed)
69 changes: 69 additions & 0 deletions test/validate-aws-iam-authenticator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import os
import sys
import json
import requests
import time


def get_latest_version():
response = None
time_to_sleep = 2
request_headers = { "Accept" : "application/json" }
for _ in range(10):
response = requests.get(
'https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/latest',headers=request_headers)
if response.status_code == 200:
break
print('Failed to obtain latest version info, retrying.')
time.sleep(time_to_sleep)
time_to_sleep *= 2
response_value = response.json()['tag_name'][1:]
return response_value


version_arg = sys.argv[1]
if version_arg.startswith("v"):
version_arg = version_arg[1:]
installed_version_info = None
PASSED = True

try:
print('aws-iam-authenticator version')
installed_version_info = json.load(
os.popen('aws-iam-authenticator version'))
print(
f'installed version: {installed_version_info["Version"]}')
except Exception as ex:
sys.exit('aws-iam-authenticator not installed')

try:
installed_version = installed_version_info['Version']
# NOT Match
if version_arg[0] == '!':
undesired_version = version_arg[1:]
print(f'undesired version: {undesired_version}')
if installed_version == undesired_version:
print(
f'installed version ({installed_version}) matches undesire {undesired_version} - FAIL')
PASSED = False
# Exact Match
else:
if version_arg == 'latest':
print('checking latest version')
desired_version = get_latest_version()
else:
desired_version = version_arg

print(f'desired version: {desired_version}')
if installed_version != desired_version:
print(
f'installed version ({installed_version}) does not match desired ({desired_version}) - FAIL')
PASSED = False
except Exception as ex:
print(f'Exception: {ex}')
pass

if not PASSED:
sys.exit('Setting up of '+version_arg+' aws-iam-authenticator failed')
print('Test passed')
sys.exit()
7 changes: 7 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs"
},
"exclude": ["node_modules", "test"]
}

0 comments on commit 8efed6d

Please sign in to comment.