@@ -67,6 +67,52 @@ shasum_bin() {
6767 echo " "
6868 fi
6969}
70+
71+ validate_repo () {
72+ repo=" $1 "
73+ if [ -z " ${repo:- } " ]; then
74+ error " FLOW_UPGRADE_REPO is empty"
75+ fi
76+
77+ owner=" ${repo%/* } "
78+ name=" ${repo#*/ } "
79+ if [ " $owner " = " $repo " ] || [ " $name " = " $repo " ]; then
80+ error " invalid repo '${repo} ' (expected owner/repo)"
81+ fi
82+ case " $owner " in * /* ) error " invalid repo '${repo} ' (expected owner/repo)" ;; esac
83+ case " $name " in * /* ) error " invalid repo '${repo} ' (expected owner/repo)" ;; esac
84+
85+ case " $owner " in * [!A-Za-z0-9._-]* )
86+ error " invalid repo owner '${owner} ' (allowed: A-Z a-z 0-9 . _ -)"
87+ ;;
88+ esac
89+ case " $name " in * [!A-Za-z0-9._-]* )
90+ error " invalid repo name '${name} ' (allowed: A-Z a-z 0-9 . _ -)"
91+ ;;
92+ esac
93+ }
94+
95+ validate_token () {
96+ token=" $1 "
97+ case " $token " in
98+ * [!A-Za-z0-9._-]* )
99+ error " invalid GitHub token characters (refusing to use it)"
100+ ;;
101+ esac
102+ }
103+
104+ validate_version () {
105+ version=" $1 "
106+ case " $version " in
107+ v* ) tag=" ${version# v} " ;;
108+ * ) tag=" $version " ;;
109+ esac
110+ case " $tag " in
111+ " " |* [!0-9A-Za-z._-]* )
112+ error " invalid release version '${version} '"
113+ ;;
114+ esac
115+ }
70116# endregion
71117
72118# region download helpers
@@ -75,7 +121,11 @@ download_file() {
75121 file=" $2 "
76122 if command -v curl > /dev/null 2>&1 ; then
77123 debug " >" curl -fsSL -o " $file " " $url "
78- curl -fsSL -o " $file " " $url "
124+ if [ " ${FLOW_DEBUG-} " = " true" ] || [ " ${FLOW_DEBUG-} " = " 1" ]; then
125+ curl -fsSL -o " $file " " $url "
126+ else
127+ curl -fsSL -o " $file " " $url " 2> /dev/null
128+ fi
79129 elif command -v wget > /dev/null 2>&1 ; then
80130 debug " >" wget -qO " $file " " $url "
81131 wget -qO " $file " " $url "
@@ -87,7 +137,20 @@ download_file() {
87137fetch_url () {
88138 url=" $1 "
89139 if command -v curl > /dev/null 2>&1 ; then
90- curl -fsSL " $url "
140+ case " $url " in
141+ https://api.github.com/* )
142+ token=" ${GITHUB_TOKEN:- ${GH_TOKEN:- ${FLOW_GITHUB_TOKEN:- } } } "
143+ if [ -n " ${token:- } " ]; then
144+ validate_token " $token "
145+ curl -fsSL -H " Authorization: Bearer $token " " $url "
146+ else
147+ curl -fsSL " $url "
148+ fi
149+ ;;
150+ * )
151+ curl -fsSL " $url "
152+ ;;
153+ esac
91154 elif command -v wget > /dev/null 2>&1 ; then
92155 wget -qO- " $url "
93156 else
@@ -96,17 +159,49 @@ fetch_url() {
96159}
97160
98161get_latest_version () {
99- url=" https://api.github.com/repos/nikitavoloboev/flow/releases/latest"
100- fetch_url " $url " | grep ' "tag_name":' | sed -E ' s/.*"([^"]+)".*/\1/'
162+ repo=" ${FLOW_UPGRADE_REPO:- } "
163+ if [ -z " ${repo:- } " ] && [ -n " ${FLOW_GITHUB_OWNER:- } " ] && [ -n " ${FLOW_GITHUB_REPO:- } " ]; then
164+ repo=" ${FLOW_GITHUB_OWNER} /${FLOW_GITHUB_REPO} "
165+ fi
166+ repo=" ${repo:- nikivdev/ flow} "
167+ validate_repo " $repo "
168+
169+ url=" https://api.github.com/repos/${repo} /releases/latest"
170+ version=" $( fetch_url " $url " | grep ' "tag_name":' | sed -E ' s/.*"([^"]+)".*/\1/' ) "
171+ validate_version " $version "
172+ echo " $version "
101173}
102174
103175get_checksum () {
104176 version=" $1 "
105177 target=" $2 "
106- url=" https://github.com/nikitavoloboev/flow/releases/download/${version} /checksums.txt"
178+ repo=" ${FLOW_UPGRADE_REPO:- } "
179+ if [ -z " ${repo:- } " ] && [ -n " ${FLOW_GITHUB_OWNER:- } " ] && [ -n " ${FLOW_GITHUB_REPO:- } " ]; then
180+ repo=" ${FLOW_GITHUB_OWNER} /${FLOW_GITHUB_REPO} "
181+ fi
182+ repo=" ${repo:- nikivdev/ flow} "
183+ validate_repo " $repo "
184+
185+ url=" https://github.com/${repo} /releases/download/${version} /checksums.txt"
107186 checksums=" $( fetch_url " $url " 2> /dev/null) " || return 1
108187 echo " $checksums " | grep " flow-${target} .tar.gz" | awk ' {print $1}'
109188}
189+
190+ get_checksum_for_file () {
191+ version=" $1 "
192+ file=" $2 "
193+ repo=" ${FLOW_UPGRADE_REPO:- } "
194+ if [ -z " ${repo:- } " ] && [ -n " ${FLOW_GITHUB_OWNER:- } " ] && [ -n " ${FLOW_GITHUB_REPO:- } " ]; then
195+ repo=" ${FLOW_GITHUB_OWNER} /${FLOW_GITHUB_REPO} "
196+ fi
197+ repo=" ${repo:- nikivdev/ flow} "
198+ validate_repo " $repo "
199+
200+ url=" https://github.com/${repo} /releases/download/${version} /checksums.txt"
201+ checksums=" $( fetch_url " $url " 2> /dev/null) " || return 1
202+ # checksums.txt format: "<sha256> <filename>"
203+ echo " $checksums " | awk -v f=" $file " ' $2==f {print $1}'
204+ }
110205# endregion
111206
112207install_flow () {
@@ -128,28 +223,61 @@ install_flow() {
128223 error " failed to fetch latest version"
129224 fi
130225 fi
226+ validate_version " $version "
131227 info " flow: version: $version "
132228
133229 # URLs - try CDN first, fallback to GitHub
134230 cdn_url=" https://cdn.myflow.sh/${version} /flow-${target} .tar.gz"
135- github_url=" https://github.com/nikitavoloboev/flow/releases/download/${version} /flow-${target} .tar.gz"
231+ repo=" ${FLOW_UPGRADE_REPO:- } "
232+ if [ -z " ${repo:- } " ] && [ -n " ${FLOW_GITHUB_OWNER:- } " ] && [ -n " ${FLOW_GITHUB_REPO:- } " ]; then
233+ repo=" ${FLOW_GITHUB_OWNER} /${FLOW_GITHUB_REPO} "
234+ fi
235+ repo=" ${repo:- nikivdev/ flow} "
236+ validate_repo " $repo "
237+ github_url=" https://github.com/${repo} /releases/download/${version} /flow-${target} .tar.gz"
136238
137239 download_dir=" $( mktemp -d) "
138240 tarball=" $download_dir /flow.tar.gz"
139241
242+ asset_file=" flow-${target} .tar.gz"
243+ legacy_os=" $os "
244+ if [ " $legacy_os " = " macos" ]; then
245+ legacy_os=" darwin"
246+ fi
247+ legacy_arch=" amd64"
248+ if [ " $arch " = " arm64" ]; then
249+ legacy_arch=" arm64"
250+ fi
251+ legacy_file=" flow_${version} _${legacy_os} _${legacy_arch} .tar.gz"
252+ legacy_url=" https://github.com/${repo} /releases/download/${version} /${legacy_file} "
253+
140254 # Try CDN first (faster)
141255 info " flow: downloading..."
142256 if command -v curl > /dev/null 2>&1 && curl -fsSL -o " $tarball " " $cdn_url " 2> /dev/null; then
143257 debug " flow: downloaded from CDN"
144258 else
145259 debug " flow: trying GitHub..."
146- download_file " $github_url " " $tarball " || error " download failed"
260+ if download_file " $github_url " " $tarball " ; then
261+ asset_file=" flow-${target} .tar.gz"
262+ elif download_file " $legacy_url " " $tarball " ; then
263+ asset_file=" $legacy_file "
264+ else
265+ error " download failed"
266+ fi
147267 fi
148268
149269 # Verify checksum if available
150270 shasum=" $( shasum_bin) "
151271 if [ -n " $shasum " ]; then
152- expected=" $( get_checksum " $version " " $target " 2> /dev/null) " || true
272+ expected=" $( get_checksum_for_file " $version " " $asset_file " 2> /dev/null) " || true
273+ if [ -z " ${expected:- } " ]; then
274+ # Back-compat: allow checksums.txt to contain either naming scheme.
275+ if [ " $asset_file " = " $legacy_file " ]; then
276+ expected=" $( get_checksum_for_file " $version " " flow-${target} .tar.gz" 2> /dev/null) " || true
277+ elif [ " $asset_file " = " flow-${target} .tar.gz" ]; then
278+ expected=" $( get_checksum_for_file " $version " " $legacy_file " 2> /dev/null) " || true
279+ fi
280+ fi
153281 if [ -n " ${expected:- } " ]; then
154282 debug " flow: verifying checksum..."
155283 actual=" $( $shasum " $tarball " | awk ' {print $1}' ) "
@@ -158,6 +286,8 @@ install_flow() {
158286 error " checksum mismatch"
159287 fi
160288 info " flow: checksum verified"
289+ else
290+ info " flow: warning: checksum not verified (checksums.txt missing or entry not found)"
161291 fi
162292 fi
163293
0 commit comments