Skip to content

Commit 1526f31

Browse files
committed
feat: run command at the end
1 parent d433567 commit 1526f31

File tree

10 files changed

+132
-51
lines changed

10 files changed

+132
-51
lines changed

.editorconfig

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@ root = true
33
[*]
44
charset = utf-8
55
indent_style = space
6-
indent_size = 4
6+
indent_size = 2
77
insert_final_newline = true
88
trim_trailing_whitespace = true
99
end_of_line = lf
1010
max_line_length = 160
11-
12-
[*.{yaml,yml,json}]
13-
indent_size = 2

.env

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ ACTIONS_STEP_DEBUG=true
99

1010
# GitHub Actions inputs should follow `INPUT_<name>` format (case-sensitive).
1111
# Hyphens should not be converted to underscores!
12-
INPUT_MILLISECONDS=2400
12+
INPUT_VERSION=stable
1313

1414
# GitHub Actions default environment variables. These are set for every run of a
1515
# workflow and can be used in your actions. Setting the value here will override
1616
# any value set by the local-action tool.
1717
# https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
1818

19-
# CI="true"
19+
CI=true
2020
# GITHUB_ACTION=""
2121
# GITHUB_ACTION_PATH=""
2222
# GITHUB_ACTION_REPOSITORY=""
@@ -53,9 +53,9 @@ INPUT_MILLISECONDS=2400
5353
# GITHUB_WORKFLOW_REF=""
5454
# GITHUB_WORKFLOW_SHA=""
5555
# GITHUB_WORKSPACE=""
56-
# RUNNER_ARCH=""
56+
RUNNER_ARCH=X64
5757
# RUNNER_DEBUG=""
5858
# RUNNER_NAME=""
59-
# RUNNER_OS=""
59+
RUNNER_OS=Linux
6060
RUNNER_TEMP=.local/tmp
6161
RUNNER_TOOL_CACHE=.local/cache

.github/workflows/ci.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
env:
2-
RUNNER_DEBUG: 1
3-
41
name: 'CI'
52
on: # rebuild any PRs and main branch changes
63
pull_request:
@@ -19,7 +16,7 @@ jobs:
1916
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
2017
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
2118
with:
22-
node-version: '22'
19+
node-version-file: package.json
2320
- run: |
2421
npm install
2522
npm run all
@@ -32,9 +29,13 @@ jobs:
3229
strategy:
3330
matrix:
3431
os: [ubuntu-latest, macos-latest, windows-latest]
32+
env:
33+
RUNNER_DEBUG: 1
3534
steps:
3635
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
3736
- uses: ./
37+
with:
38+
version: 'latest'
3839
- name: Get the version
3940
run: stackit --version
4041
- uses: ./

__fixtures__/core.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type * as core from '@actions/core'
22
import { jest } from '@jest/globals'
33

4+
export const addPath = jest.fn<typeof core.addPath>()
45
export const debug = jest.fn<typeof core.debug>()
56
export const error = jest.fn<typeof core.error>()
67
export const info = jest.fn<typeof core.info>()

__tests__/main.test.ts

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@
55
* functions and objects. For example, the core module is mocked in this test,
66
* so that the actual '@actions/core' module is not imported.
77
*/
8+
9+
import fs from 'fs/promises'
10+
import os from 'os'
11+
import path from 'path'
12+
813
import { jest } from '@jest/globals'
914
import * as core from '../__fixtures__/core.js'
1015

16+
import { toolName, defaultVersion } from '../src/tool.js'
17+
1118
// Mocks should be declared before the module being tested is imported.
1219
jest.unstable_mockModule('@actions/core', () => core)
1320

@@ -16,26 +23,70 @@ jest.unstable_mockModule('@actions/core', () => core)
1623
const { run } = await import('../src/main.js')
1724

1825
describe('main.ts', () => {
19-
beforeEach(() => {
26+
const OLD_ENV = process.env
27+
28+
beforeEach(async () => {
2029
// Set the action's inputs as return values from core.getInput().
21-
core.getInput.mockImplementation(() => '500')
30+
core.getInput.mockImplementation(() => defaultVersion.replaceAll('v', ''))
31+
process.env = { ...OLD_ENV } // Make a copy
32+
33+
switch (os.type()) {
34+
case 'Linux':
35+
process.env.RUNNER_OS = 'Linux'
36+
break
37+
case 'Darwin':
38+
process.env.RUNNER_OS = 'macOS'
39+
break
40+
case 'Windows_NT':
41+
process.env.RUNNER_OS = 'Windows'
42+
break
43+
default:
44+
throw new Error(`Unsupported OS: ${os.type()}`)
45+
}
46+
47+
process.env.RUNNER_ARCH = 'X86_64'
48+
49+
process.env.RUNNER_TEMP = await fs.mkdtemp(
50+
path.join(os.tmpdir(), `${toolName}-runner-temp-`)
51+
)
52+
53+
process.env.RUNNER_TOOL_CACHE = await fs.mkdtemp(
54+
path.join(os.tmpdir(), `${toolName}-tool-cache-`)
55+
)
2256
})
2357

24-
afterEach(() => {
58+
afterEach(async () => {
59+
if (process.env.RUNNER_TOOL_CACHE) {
60+
await fs.rm(process.env.RUNNER_TOOL_CACHE, {
61+
recursive: true,
62+
force: true
63+
})
64+
}
65+
66+
if (process.env.RUNNER_TEMP) {
67+
await fs.rm(process.env.RUNNER_TEMP, {
68+
recursive: true,
69+
force: true
70+
})
71+
}
72+
2573
jest.resetAllMocks()
74+
process.env = OLD_ENV // Restore old environment
2675
})
2776

2877
it('Run main', async () => {
2978
await run()
3079

31-
/*
80+
// Verify that no errors were thrown.
81+
expect(core.setFailed).not.toHaveBeenCalled()
82+
3283
// Verify the time output was set.
3384
expect(core.setOutput).toHaveBeenNthCalledWith(
3485
1,
35-
'sops-path',
36-
// Simple regex to match a time string in the format HH:MM:SS.
37-
expect.stringMatching(/^sops/)
86+
'path',
87+
expect.stringMatching(
88+
new RegExp(`${toolName}[/\\\\]${defaultVersion.replaceAll('v', '')}`)
89+
)
3890
)
39-
*/
4091
})
4192
})

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export default {
2727
testEnvironment: 'node',
2828
testMatch: ['**/*.test.ts'],
2929
testPathIgnorePatterns: ['/dist/', '/node_modules/'],
30+
testTimeout: 30000,
3031
transform: {
3132
'^.+\\.ts$': [
3233
'ts-jest',

package-lock.json

Lines changed: 22 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,25 @@
88
"license": "MIT",
99
"dependencies": {
1010
"@actions/core": "^1.11.1",
11+
"@actions/exec": "^1.1.1",
1112
"@actions/http-client": "^2.2.1",
1213
"@actions/tool-cache": "^2.0.2",
1314
"semver": "^7.7.1"
1415
},
1516
"engines": {
16-
"node": ">=20"
17+
"node": "^20 || ^22"
1718
},
1819
"scripts": {
1920
"bundle": "npm run format:write && npm run package",
20-
"ci-test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest",
21+
"ci-test": "cross-env NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest",
2122
"coverage": "npx make-coverage-badge --output-path ./badges/coverage.svg",
2223
"format:write": "npx prettier --write .",
2324
"format:check": "npx prettier --check .",
2425
"lint": "npx eslint .",
2526
"local-action": "npx @github/local-action . src/main.ts .env",
2627
"package": "npx rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
2728
"package:watch": "npm run package -- --watch",
28-
"test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest",
29+
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest",
2930
"all": "npm run format:write && npm run lint && npm run test && npm run coverage && npm run package",
3031
"prepare": "husky"
3132
},
@@ -44,6 +45,7 @@
4445
"@types/semver": "^7.7.0",
4546
"@typescript-eslint/eslint-plugin": "^8.31.0",
4647
"@typescript-eslint/parser": "^8.31.0",
48+
"cross-env": "^7.0.3",
4749
"eslint": "^9.25.1",
4850
"eslint-config-prettier": "^10.1.2",
4951
"eslint-import-resolver-typescript": "^4.3.4",

src/main.ts

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
// Copyright (c) Microsoft Corporation.
2-
// Licensed under the MIT license.
1+
import fs from 'fs'
32

43
import * as core from '@actions/core'
4+
import { exec } from '@actions/exec'
55
import { HttpClient } from '@actions/http-client'
6+
import * as toolCache from '@actions/tool-cache'
7+
68
import {
79
binaryName,
810
githubRepository,
911
toolName,
1012
defaultVersion,
11-
extractBinary
13+
extractBinary,
14+
getVersionArguments,
1215
} from './tool.js'
13-
import * as toolCache from '@actions/tool-cache'
14-
import * as util from 'util'
15-
import fs from 'fs'
1616

1717
/**
1818
* Get the executable extension based on the OS.
@@ -108,26 +108,19 @@ async function download(version: string): Promise<string> {
108108
const runnerOs = getRunnerOS()
109109
const runnerArch = getRunnerArch()
110110
const binaryFileName = toolName + getExecutableExtension()
111-
const url = util.format(
112-
'https://github.com/%s/releases/download/%s/%s',
113-
githubRepository,
114-
version,
115-
binaryName(version, runnerOs, runnerArch)
116-
)
111+
const url = `https://github.com/${githubRepository}/releases/download/${version}/${binaryName(version, runnerOs, runnerArch)}`
117112

118113
let cachedToolPath = toolCache.find(toolName, version)
119-
if (!cachedToolPath) {
114+
if (cachedToolPath) {
115+
core.info(`Restoring '${version}' from cache`)
116+
} else {
117+
core.info(`Downloading '${version}' from '${url}'`)
120118
let downloadPath
121119
try {
122120
downloadPath = await toolCache.downloadTool(url)
123121
} catch (exception) {
124122
throw new Error(
125-
util.format(
126-
'Failed to download %s from location %s. Error: %s',
127-
toolName,
128-
url,
129-
exception
130-
)
123+
`Failed to download ${toolName} from location ${url}. Error: ${exception}`
131124
)
132125
}
133126

@@ -144,11 +137,7 @@ async function download(version: string): Promise<string> {
144137
cachedToolPath = toolCache.find(toolName, version)
145138
if (!cachedToolPath) {
146139
throw new Error(
147-
util.format(
148-
'%s executable not found in path %s',
149-
binaryFileName,
150-
cachedToolPath
151-
)
140+
`${binaryFileName} executable not found in path ${cachedToolPath}`
152141
)
153142
}
154143
}
@@ -164,7 +153,9 @@ async function download(version: string): Promise<string> {
164153
export async function run(): Promise<void> {
165154
try {
166155
let version = core.getInput('version', { required: true })
167-
if (version.toLocaleLowerCase() === 'latest') {
156+
if (version.toLocaleLowerCase() === 'stable') {
157+
version = defaultVersion
158+
} else if (version.toLocaleLowerCase() === 'latest') {
168159
version = await latestVersion(githubRepository, toolName, defaultVersion)
169160
} else if (!version.toLocaleLowerCase().startsWith('v')) {
170161
version = 'v' + version
@@ -177,6 +168,12 @@ export async function run(): Promise<void> {
177168
`${toolName} version: '${version}' has been cached at ${cachedPath}`
178169
)
179170
core.setOutput('path', cachedPath)
171+
172+
await exec(toolName + getExecutableExtension(), getVersionArguments(), {
173+
env: {
174+
PATH: `${cachedPath}`
175+
}
176+
})
180177
} catch (error) {
181178
// Fail the workflow run if an error occurs
182179
if (error instanceof Error) core.setFailed(error.message)

src/tool.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { clean } from 'semver'
2-
import { extractTar } from '@actions/tool-cache'
2+
import { extractTar, extractZip } from '@actions/tool-cache'
33

44
export const toolName = 'stackit'
55
export const githubRepository = 'stackitcloud/stackit-cli'
@@ -19,7 +19,17 @@ export async function extractBinary(
1919
os: string,
2020
_arch: string
2121
): Promise<string> {
22-
const extractedFolder = await extractTar(path)
22+
let extractedFolder
23+
24+
if (os === 'windows') {
25+
extractedFolder = await extractZip(path)
26+
} else {
27+
extractedFolder = await extractTar(path)
28+
}
2329

2430
return `${extractedFolder}/${toolName}${os === 'windows' ? '.exe' : ''}`
2531
}
32+
33+
export function getVersionArguments(): string[] {
34+
return ['--version']
35+
}

0 commit comments

Comments
 (0)