feat: initial
Some checks failed
Test action / Test on registry.onstackit.cloud/devex-images/alpine:latest (push) Failing after 3s
Test action / Test on registry.onstackit.cloud/devex-images/ubuntu:act-latest (push) Successful in 34s

This commit is contained in:
Maximilian Jugl 2026-04-22 09:36:58 +02:00
commit f1cd1be14d
8 changed files with 444 additions and 0 deletions

View file

@ -0,0 +1,30 @@
name: Test action
on:
push:
branches:
- main
pull_request:
types:
- opened
- synchronize
- reopened
jobs:
test:
name: Test on ${{ matrix.image }}
runs-on: stackit-docker
strategy:
fail-fast: false
matrix:
image:
- registry.onstackit.cloud/devex-images/ubuntu:act-latest
- registry.onstackit.cloud/devex-images/alpine:latest
container:
image: ${{ matrix.image }}
steps:
- uses: actions/checkout@v6
- name: Test action
uses: ./
with:
version: "v0.61.0"

201
.gitignore vendored Normal file
View file

@ -0,0 +1,201 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.*
!.env.example
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
.output
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp directory
.temp
# Sveltekit cache directory
.svelte-kit/
# vitepress build output
**/.vitepress/dist
# vitepress cache directory
**/.vitepress/cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# Firebase cache directory
.firebase/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# pnpm
.pnpm-store
# yarn v3
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Vite files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.vite/
# General
.DS_Store
.localized
__MACOSX/
.AppleDouble
.LSOverride
Icon[ ]
# Resource forks
._*
# Files and directories that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
.com.apple.timemachine.supported
.PKInstallSandboxManager
.PKInstallSandboxManager-SystemSoftware
.hotfiles.btree
.vol
.file
.disk_label*
lost+found
.HFS+ Private Directory Data[ ]
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Mac OS 6 to 9
Desktop DB
Desktop DF
TheFindByContentFolder
TheVolumeSettingsFolder
.FBCIndex
.FBCSemaphoreFile
.FBCLockFolder
# Quota system
.quota.group
.quota.user
.quota.ops.group
.quota.ops.user
# TimeMachine
Backups.backupdb
.MobileBackups
.MobileBackups.trash
MobileBackups.trash
tmbootpicker.efi

3
.prettierrc Normal file
View file

@ -0,0 +1,3 @@
{
"printWidth": 120
}

5
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.tabSize": 2
}

29
README.md Normal file
View file

@ -0,0 +1,29 @@
# Install STACKIT CLI Action
This GitHub Action installs the STACKIT CLI on a GitHub Actions runner. It is designed to be compatible with both Ubuntu (apt-get) and Alpine Linux (apk) environments.
## Usage
To use this action in your workflow, reference it as a step. You can optionally specify a version.
### Simple usage
```yaml
- name: Install STACKIT CLI
uses: https://stackit-solutions.git.onstackit.cloud/actions/install-stackit-cli@v1
```
### Usage with a specific version
```yaml
- name: Install STACKIT CLI
uses: https://stackit-solutions.git.onstackit.cloud/actions/install-stackit-cli@v1
with:
version: "v0.61.0"
```
## Inputs
| Name | Description | Required | Default |
| ------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | ------- |
| version | The specific version of STACKIT CLI to install (e.g., v0.61.0). If left empty, the latest stable version will be installed. | No | "" |

143
action.yml Normal file
View file

@ -0,0 +1,143 @@
name: "Install STACKIT CLI"
description: "Installs the STACKIT CLI application."
inputs:
version:
description: "Version of STACKIT CLI to install, e.g. v0.59.0. If left empty, the latest version will be installed."
required: false
default: ""
runs:
using: "composite"
steps:
- name: Install requirements
shell: sh # alpine may not have bash pre-installed
run: |
set -e
if command -v curl >/dev/null 2>&1 && command -v jq >/dev/null 2>&1; then
echo "curl and jq are already installed, skipping installation."
else
if command -v apt-get >/dev/null 2>&1; then
apt-get -y update
apt-get -y install curl jq
elif command -v apk >/dev/null 2>&1; then
apk add --no-cache curl jq bash
else
echo "::error::No supported package manager (apt-get, apk) found."
exit 1
fi
fi
- name: Install STACKIT CLI
shell: bash
env:
STACKIT_CLI_VERSION: ${{ inputs.version }}
run: |
set -eo pipefail
REPO="stackitcloud/stackit-cli"
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
ARCH="$(uname -m)"
if [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "amd64" ]; then
ARCH="amd64"
elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
ARCH="arm64"
fi
CACHE_BASE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}/stackit-cli"
# try to load stackit cli from hosted tools cache
if [ -n "$STACKIT_CLI_VERSION" ]; then
TOOL_CACHE_FILE="$CACHE_BASE/$STACKIT_CLI_VERSION/$ARCH/stackit"
# if file exists in hosted tools cache, symlink it
if [ -x "$TOOL_CACHE_FILE" ]; then
echo "::group::Linking from hosted tool cache"
ln -sf "$TOOL_CACHE_FILE" /usr/local/bin/stackit
echo "::endgroup::"
exit 0
fi
fi
echo "::group::Determining STACKIT CLI version"
# if no version is provided, use latest
if [ -z "$STACKIT_CLI_VERSION" ]; then
API_URL="https://api.github.com/repos/$REPO/releases/latest"
else
API_URL="https://api.github.com/repos/$REPO/releases/tags/$STACKIT_CLI_VERSION"
fi
RELEASES_JSON="$(curl -s "$API_URL")"
VERSION="$(echo "$RELEASES_JSON" | jq -r '.tag_name')"
if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then
echo "Failed to fetch release information. Please check if the version exists."
exit 1
fi
echo "Installing STACKIT CLI $VERSION"
echo "::endgroup::"
# check if latest binary is already present on this runner
TOOL_CACHE_DIR="$CACHE_BASE/$VERSION/$ARCH"
TOOL_CACHE_FILE="$TOOL_CACHE_DIR/stackit"
if [ -x "$TOOL_CACHE_FILE" ]; then
echo "::group::Linking from hosted tool cache"
ln -sf "$TOOL_CACHE_FILE" /usr/local/bin/stackit
echo "::endgroup::"
exit 0
fi
# prepare binary download
DOWNLOAD_DIR="$(mktemp -d)"
# always delete download dir when script exits
trap 'rm -rf "$DOWNLOAD_DIR"' EXIT
cd "$DOWNLOAD_DIR"
RELEASE_ASSET="$(echo "$RELEASES_JSON" | jq -r --arg os "$OS" --arg arch "$ARCH" \
'.assets[] | select(.name | endswith($os + "_" + $arch + ".tar.gz"))')"
if [ -z "$RELEASE_ASSET" ] || [ "$RELEASE_ASSET" = "null" ]; then
echo "No matching release found for OS=$OS, ARCH=$ARCH."
exit 1
fi
ARCHIVE_NAME="$(echo "$RELEASE_ASSET" | jq -r '.name')"
ARCHIVE_DOWNLOAD_URL="$(echo "$RELEASE_ASSET" | jq -r '.browser_download_url')"
CHECKSUMS_DOWNLOAD_URL="$(echo "$RELEASES_JSON" | jq -r '.assets[] | select(.name | contains("checksums.txt")) | .browser_download_url')"
CHECKSUMS="checksums.txt"
if [ -z "$CHECKSUMS_DOWNLOAD_URL" ] || [ "$CHECKSUMS_DOWNLOAD_URL" = "null" ]; then
echo "No checksum file available in release assets."
exit 1
fi
echo "::group::Downloading assets and verifying integrity"
# download binary and checksums (-f for fail fast)
curl -fLO "$ARCHIVE_DOWNLOAD_URL"
curl -fLo "$CHECKSUMS" "$CHECKSUMS_DOWNLOAD_URL"
grep "$ARCHIVE_NAME" "$CHECKSUMS" | sha256sum -c -
echo "::endgroup::"
echo "::group::Installing into hosted tool cache"
mkdir stackit-cli
tar -xzvf "$ARCHIVE_NAME" -C stackit-cli
# save to tool cache
mkdir -p "$TOOL_CACHE_DIR"
mv ./stackit-cli/stackit "$TOOL_CACHE_FILE"
# symlink
ln -sf "$TOOL_CACHE_FILE" /usr/local/bin/stackit
echo "::endgroup::"
cd "$GITHUB_WORKSPACE"
- name: Print version
shell: sh
run: stackit --version

28
package-lock.json generated Normal file
View file

@ -0,0 +1,28 @@
{
"name": "install-stackit-cli",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"devDependencies": {
"prettier": "^3.8.3"
}
},
"node_modules/prettier": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz",
"integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
}
}
}

5
package.json Normal file
View file

@ -0,0 +1,5 @@
{
"devDependencies": {
"prettier": "^3.8.3"
}
}