-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·158 lines (126 loc) · 4.63 KB
/
setup.sh
File metadata and controls
executable file
·158 lines (126 loc) · 4.63 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env bash
set -euo pipefail
# Function to run commands only in debug mode
debug() {
if [[ "${RUNNER_DEBUG:-0}" == "1" ]]; then
"$@" | sed 's/^/DEBUG: /g'
fi
}
# Enable debug mode if RUNNER_DEBUG is 1
debug set -x
# 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}}"
ASSET_NAME_INPUT="${4:-${TOOL_NAME}}"
# 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)
if [[ ${PLATFORM} == "darwin" ]]; then
PLATFORM_PATTERN="(darwin|macos)"
else
PLATFORM_PATTERN="(${PLATFORM})"
fi
# 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="^${ASSET_NAME_INPUT}.+${PLATFORM_PATTERN}.+${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}"
debug unzip -l "${ASSET_NAME}"
unzip -q "${ASSET_NAME}"
elif [[ "${ASSET_NAME}" == *.tar.gz ]]; then
info "Extracting ${ASSET_NAME}"
debug 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}"