forked from isometry/setup-generic-tool
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·139 lines (111 loc) · 4.22 KB
/
setup.sh
File metadata and controls
executable file
·139 lines (111 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env bash
set -euo pipefail
# Function to print error and exit
error() {
echo "ERROR: $1" >&2
exit 1
}
# Function to print info
info() {
echo "INFO: $1"
}
# Check for required commands
command -v curl >/dev/null 2>&1 || error "curl is required but not installed"
command -v jq >/dev/null 2>&1 || error "jq is required but not installed"
# Get inputs
REPO_NAME="$1"
VERSION="${2:-latest}"
# Validate inputs
[[ -z "${REPO_NAME}" ]] && error "Missing required input: repository name"
# Split repository name
IFS='/' read -r OWNER REPO <<< "${REPO_NAME}"
[[ -z "${OWNER}" || -z "${REPO}" ]] && error "Invalid repository name"
# Set tool name if not provided as third argument
TOOL_NAME="${3:-${REPO}}"
# Validate tool name
[[ ! "${TOOL_NAME}" =~ ^[-A-Za-z0-9]+$ ]] && error "Invalid tool name"
# Determine platform and architecture
PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
# Convert architecture to common formats
case "${ARCH}" in
"aarch64"|"arm64")
ARCH=arm64
ARCH_PATTERN="(aarch64|arm64)"
;;
"x86_64")
ARCH=x64
ARCH_PATTERN="(64bit|amd64|x64|x86_64)"
;;
*)
error "Unsupported architecture: ${ARCH}"
;;
esac
v3_api_call() {
curl -sfL \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/$1"
}
download_release() {
local url="${1:?download url required}"
local out="${2:?asset name required}"
info "Downloading ${url} to ${out}"
curl -sSL -H "Authorization: token ${GH_TOKEN}" -o "${out}" "${url}"
}
# Get release information using GitHub CLI
if [[ "${VERSION}" = "latest" ]]; then
RELEASE_DATA=$(v3_api_call "repos/${OWNER}/${REPO}/releases/latest")
VERSION=$(jq -r '.tag_name' <<< "${RELEASE_DATA}")
info "Resolved latest version: ${VERSION}"
else
RELEASE_DATA=$(v3_api_call "repos/${OWNER}/${REPO}/releases/tags/${VERSION}")
fi
# Create cache directory
: "${RUNNER_TOOL_CACHE:=${HOME}/.cache/github-tools}"
mkdir -p "${RUNNER_TOOL_CACHE}"
TOOL_CACHE_DIR="${RUNNER_TOOL_CACHE}/${TOOL_NAME}/${VERSION#v}/${ARCH}"
if [[ -d "${TOOL_CACHE_DIR}" ]]; then
info "Found ${TOOL_NAME} ${VERSION} in ${TOOL_CACHE_DIR}"
else
info "Searching for ${TOOL_NAME} ${VERSION} for ${PLATFORM}/${ARCH}"
ASSET_PATTERN="^${TOOL_NAME}.+${PLATFORM}.+${ARCH_PATTERN}([.](tar[.]gz|zip))?\$"
mapfile -t ASSETS < <(jq -r --arg pattern "${ASSET_PATTERN}" '.assets[] | select(.name | test($pattern; "i")) | .name' <<< "${RELEASE_DATA}")
: "${ASSETS:?No matching release asset found}"
info "Matching assets: ${ASSETS[*]}"
# Take first matching asset (e.g. mikefarah/yq distributes both unarchived and .tar.gz assets)
ASSET_NAME="${ASSETS[0]}"
info "Found release asset: ${ASSET_NAME}"
# Create temporary directory
TMP_DIR=$(mktemp -d)
info "Temporary directory: ${TMP_DIR}"
cd "${TMP_DIR}"
# Download and extract asset using gh cli
info "Fetching ${ASSET_NAME} from ${OWNER}/${REPO}#${VERSION}"
DOWNLOAD_URL=$(jq -r --arg asset "${ASSET_NAME}" '.assets[] | select(.name == $asset) | .browser_download_url' <<< "${RELEASE_DATA}")
download_release "${DOWNLOAD_URL}" "${ASSET_NAME}"
if [[ "${ASSET_NAME}" == *.zip ]]; then
info "Extracting ${ASSET_NAME}"
unzip -q "${ASSET_NAME}"
elif [[ "${ASSET_NAME}" == *.tar.gz ]]; then
info "Extracting ${ASSET_NAME}"
tar tzf "${ASSET_NAME}"
tar xzf "${ASSET_NAME}"
fi
# Find tool binary
TOOL_PATH=$(find . -type f -name "${TOOL_NAME}*" -a \! -name "*.[0-9]" | grep -Ev '[.](tar[.]gz|zip)$' | head -n1)
info "Detected tool binary: ${TOOL_PATH}"
[[ -z "${TOOL_PATH}" ]] && error "Tool binary '${TOOL_NAME}' not found in extracted path"
# Copy to cache directory
mkdir -p "${TOOL_CACHE_DIR}"
cp "${TOOL_PATH}" "${TOOL_CACHE_DIR}/${TOOL_NAME}"
chmod +x "${TOOL_CACHE_DIR}/${TOOL_NAME}"
info "Installed ${TOOL_NAME} version ${VERSION} in ${TOOL_CACHE_DIR}"
# Cleanup
cd - > /dev/null
rm -rf "${TMP_DIR}"
fi
# Add to PATH
echo "${TOOL_CACHE_DIR}" >> "${GITHUB_PATH:-/dev/null}"
echo "version=${VERSION}" >> "${GITHUB_OUTPUT:-/dev/null}"