Skip to content

Commit 1ac7f10

Browse files
committed
fix(workflow-cli): optimize client installation script.
1 parent 4f293ee commit 1ac7f10

2 files changed

Lines changed: 261 additions & 26 deletions

File tree

install-cli.ps1

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#!/usr/bin/env pwsh
2+
#Requires -Version 5.1
3+
4+
<#
5+
.SYNOPSIS
6+
Install Drycc Workflow CLI for Windows.
7+
8+
.DESCRIPTION
9+
This script downloads and installs the Drycc Workflow CLI (drycc.exe)
10+
to the specified directory.
11+
12+
Supports one-liner installation via:
13+
irm https://www.drycc.cc/install-cli.ps1 | iex
14+
15+
Environment variables:
16+
INSTALL_DRYCC_PATH - Override installation directory
17+
INSTALL_DRYCC_VERSION - Override version to install
18+
INSTALL_DRYCC_MIRROR - Set to "cn" for China mirror
19+
20+
.PARAMETER InstallPath
21+
The directory to install drycc.exe. Defaults to $env:LOCALAPPDATA\drycc.
22+
23+
.PARAMETER Version
24+
The version of drycc to install. Defaults to 'stable'.
25+
26+
.EXAMPLE
27+
.\install-cli.ps1
28+
29+
.EXAMPLE
30+
.\install-cli.ps1 -InstallPath "C:\Program Files\drycc"
31+
32+
.EXAMPLE
33+
$env:INSTALL_DRYCC_MIRROR="cn"; irm https://www.drycc.cc/install-cli.ps1 | iex
34+
#>
35+
36+
param(
37+
[string]$InstallPath = "$env:LOCALAPPDATA\drycc",
38+
[string]$Version = "stable"
39+
)
40+
41+
$ErrorActionPreference = "Stop"
42+
43+
# Support environment variables for one-liner installation
44+
if ($env:INSTALL_DRYCC_PATH) {
45+
$InstallPath = $env:INSTALL_DRYCC_PATH
46+
}
47+
if ($env:INSTALL_DRYCC_VERSION) {
48+
$Version = $env:INSTALL_DRYCC_VERSION
49+
}
50+
51+
# Support mirror for China users
52+
if ($env:INSTALL_DRYCC_MIRROR -eq "cn") {
53+
$script:DryccBinUrlBase = "https://github.com/drycc/workflow-cli/releases"
54+
} else {
55+
$script:DryccBinUrlBase = "https://github.com/drycc/workflow-cli/releases"
56+
}
57+
58+
function Get-Architecture {
59+
$arch = $env:PROCESSOR_ARCHITECTURE.ToLower()
60+
switch ($arch) {
61+
"amd64" { return "amd64" }
62+
"x86" { return "386" }
63+
"arm64" { return "arm64" }
64+
default {
65+
Write-Error "Unsupported architecture: $arch"
66+
exit 1
67+
}
68+
}
69+
}
70+
71+
function Get-LatestVersion {
72+
$releasesUrl = "$script:DryccBinUrlBase"
73+
try {
74+
$response = Invoke-WebRequest -Uri $releasesUrl -UseBasicParsing
75+
} catch {
76+
Write-Error "Could not fetch releases page from $releasesUrl"
77+
exit 1
78+
}
79+
80+
# FIX #1: The server may not return a Content-Type header, causing
81+
# Invoke-WebRequest to return $response.Content as System.Byte[] instead
82+
# of a decoded string. We must explicitly decode it before regex matching.
83+
$content = $response.Content
84+
if ($content -is [System.Byte[]]) {
85+
$content = [System.Text.Encoding]::UTF8.GetString($content)
86+
}
87+
88+
$version = $content |
89+
Select-String -Pattern '/drycc/workflow-cli/releases/tag/(v[0-9\.]+)' |
90+
ForEach-Object { $_.Matches[0].Groups[1].Value } |
91+
Select-Object -First 1
92+
93+
if (-not $version) {
94+
Write-Error "Could not extract version from $releasesUrl"
95+
exit 1
96+
}
97+
98+
return $version
99+
}
100+
101+
function Install-DryccCli {
102+
$platform = "windows"
103+
$arch = Get-Architecture
104+
$latestVersion = Get-LatestVersion
105+
106+
if ($Version -eq "stable") {
107+
$Version = $latestVersion
108+
}
109+
110+
# FIX #2: The release asset filenames on GitHub do NOT include a .exe
111+
# extension (e.g. "drycc-v1.10.2-windows-amd64"), but the script was
112+
# appending .exe to the download URL, causing a 404 Not Found.
113+
# We use the bare name for the download URL and rename locally.
114+
$assetName = "drycc-${Version}-${platform}-${arch}"
115+
$downloadUrl = "$script:DryccBinUrlBase/download/${Version}/${assetName}"
116+
$tempFile = [System.IO.Path]::GetTempFileName() + ".exe"
117+
118+
Write-Host "Downloading Drycc Workflow CLI ${Version} for ${platform}-${arch}..."
119+
Write-Host "URL: $downloadUrl"
120+
121+
try {
122+
Invoke-WebRequest -Uri $downloadUrl -OutFile $tempFile -UseBasicParsing
123+
} catch {
124+
Write-Error "Failed to download from $downloadUrl`n$($_.Exception.Message)"
125+
exit 1
126+
}
127+
128+
# Validate the downloaded file is actually a PE executable, not an error page
129+
$fileMagic = [System.IO.File]::ReadAllBytes($tempFile)[0..1]
130+
$magicString = [System.Text.Encoding]::ASCII.GetString($fileMagic)
131+
if ($magicString -ne 'MZ') {
132+
Write-Error "Downloaded file is not a valid Windows executable (got '$magicString' instead of 'MZ'). The release asset may not exist."
133+
Remove-Item -Path $tempFile -Force
134+
exit 1
135+
}
136+
137+
# Create install directory if it doesn't exist
138+
if (-not (Test-Path $InstallPath)) {
139+
New-Item -ItemType Directory -Path $InstallPath -Force | Out-Null
140+
}
141+
142+
$installExe = Join-Path $InstallPath "drycc.exe"
143+
Move-Item -Path $tempFile -Destination $installExe -Force
144+
145+
# Add to PATH if not already present
146+
$currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
147+
if ($currentPath -notlike "*$InstallPath*") {
148+
[Environment]::SetEnvironmentVariable("Path", "$currentPath;$InstallPath", "User")
149+
Write-Host "Added $InstallPath to your PATH."
150+
Write-Host "Please restart your terminal or run: refreshenv"
151+
}
152+
153+
Write-Host ""
154+
Write-Host "Drycc Workflow CLI (drycc) has been installed to: $installExe"
155+
Write-Host ""
156+
Write-Host "To learn more about Drycc Workflow, execute:"
157+
Write-Host " $installExe --help"
158+
Write-Host ""
159+
}
160+
161+
Install-DryccCli

install-cli.sh

Lines changed: 100 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,29 @@
22
set -eo pipefail
33
shopt -s expand_aliases
44

5+
PLATFORM="$(uname | tr '[:upper:]' '[:lower:]')"
6+
7+
if [[ "${INSTALL_DRYCC_MIRROR}" == "cn" ]] ; then
8+
DRYCC_BIN_URL_BASE="https://github.com/drycc/workflow-cli/releases"
9+
else
10+
DRYCC_BIN_URL_BASE="https://github.com/drycc/workflow-cli/releases"
11+
fi
12+
513
check_platform_arch() {
614
local supported="darwin-amd64 darwin-arm64 linux-amd64 linux-386 linux-arm linux-arm64 windows-386 windows-amd64"
715

8-
if ! echo "${supported}" | tr ' ' '\n' | grep -q "${PLATFORM}-${ARCH}"; then
16+
if ! echo "${supported}" | tr ' ' '\n' | grep -q "^${PLATFORM}-${ARCH}$"; then
917
cat <<EOF
1018
1119
The Drycc Workflow CLI (drycc) is not currently supported on ${PLATFORM}-${ARCH}.
1220
1321
See https://github.com/drycc/workflow-cli for more information.
1422
1523
EOF
24+
exit 1
1625
fi
1726
}
1827

19-
PLATFORM="$(uname | tr '[:upper:]' '[:lower:]')"
20-
if [[ "${INSTALL_DRYCC_MIRROR}" == "cn" ]] ; then
21-
DRYCC_BIN_URL_BASE="https://github.com/drycc/workflow-cli/releases"
22-
else
23-
DRYCC_BIN_URL_BASE="https://github.com/drycc/workflow-cli/releases"
24-
fi
25-
2628
# initArch discovers the architecture for this system.
2729
init_arch() {
2830
ARCH=$(uname -m)
@@ -40,34 +42,106 @@ init_arch() {
4042

4143
init_latest_version() {
4244
VERSION=$(curl -Ls $DRYCC_BIN_URL_BASE|grep /drycc/workflow-cli/releases/tag/ | sed -E 's/.*\/drycc\/workflow-cli\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1)
45+
if [ -z "${VERSION}" ]; then
46+
echo "Error: unable to determine the latest drycc version from GitHub API." >&2
47+
echo "Please check your network connection or set VERSION manually." >&2
48+
exit 1
49+
fi
4350
}
4451

4552
init_arch
46-
init_latest_version
4753
check_platform_arch
54+
init_latest_version
4855

4956
DRYCC_CLI="drycc-${VERSION}-${PLATFORM}-${ARCH}"
5057
DRYCC_CLI_PATH="${DRYCC_CLI}"
5158
if [ "${VERSION}" != 'stable' ]; then
5259
DRYCC_CLI_PATH="${VERSION}/${DRYCC_CLI_PATH}"
5360
fi
5461

55-
echo "Downloading ${DRYCC_CLI} From Google Cloud Storage..."
56-
echo "Downloading binary from here: ${DRYCC_BIN_URL_BASE}/download/${DRYCC_CLI_PATH}"
57-
curl -fsSL -o drycc "${DRYCC_BIN_URL_BASE}/download/${DRYCC_CLI_PATH}"
58-
59-
chmod +x drycc
60-
61-
cat <<EOF
62+
# Install to ~/.local/bin (the XDG / systemd-recommended location for user binaries)
63+
INSTALL_DIR="$HOME/.local/bin"
64+
mkdir -p "$INSTALL_DIR"
6265

63-
The Drycc Workflow CLI (drycc) is now available in your current directory.
64-
65-
To learn more about Drycc Workflow, execute:
66-
67-
$ ./drycc --help
68-
69-
You can also move it to other directories, such as:
70-
71-
$ mv $PWD/drycc /usr/local/bin
66+
echo "Downloading ${DRYCC_CLI}..."
67+
echo "Downloading binary from here: ${DRYCC_BIN_URL_BASE}/download/${DRYCC_CLI_PATH}"
68+
curl -fsSL -o "${INSTALL_DIR}/drycc" "${DRYCC_BIN_URL_BASE}/download/${DRYCC_CLI_PATH}" < /dev/null
69+
chmod +x "${INSTALL_DIR}/drycc"
70+
71+
echo ""
72+
echo "The Drycc Workflow CLI (drycc) has been installed to: ${INSTALL_DIR}/drycc"
73+
74+
# Check whether ~/.local/bin is already in the *current* PATH.
75+
case ":${PATH}:" in
76+
*":${INSTALL_DIR}:"*)
77+
PATH_OK=1 ;;
78+
*)
79+
PATH_OK=0 ;;
80+
esac
81+
82+
if [ "${PATH_OK}" -eq 1 ]; then
83+
echo ""
84+
echo "To learn more about Drycc Workflow, execute:"
85+
echo ""
86+
echo " $ drycc --help"
87+
echo ""
88+
exit 0
89+
fi
7290

73-
EOF
91+
# ~/.local/bin is NOT in the current PATH.
92+
#
93+
# On many modern distros (Debian/Ubuntu via ~/.profile, Fedora/RHEL via ~/.bashrc)
94+
# ~/.local/bin is ALREADY wired into PATH on login. Two common reasons it is
95+
# missing from the *current* shell:
96+
# 1. The directory did not exist at login time (Debian/Ubuntu only add it with
97+
# `if [ -d "$HOME/.local/bin" ]`), and we just created it -> a re-login fixes it.
98+
# 2. The current shell is a non-login shell that never sourced the login files.
99+
#
100+
# So: first tell the user a re-login may be all that is needed, then give an
101+
# explicit, shell-correct fallback.
102+
103+
# Determine the user's *login* shell (NOT the shell running this script, which is
104+
# almost always bash when installed via `curl ... | bash`).
105+
USER_SHELL="$(basename "${SHELL:-}")"
106+
107+
echo ""
108+
echo "==> Next steps:"
109+
echo ""
110+
echo "'${INSTALL_DIR}' is not in your current PATH."
111+
echo ""
112+
echo "On most modern distributions this directory is added to PATH automatically"
113+
echo "on your next login (it simply did not exist when this session started)."
114+
echo "Try opening a new terminal or logging out and back in first."
115+
echo ""
116+
echo "If 'drycc' is still not found, add it to PATH manually:"
117+
echo ""
118+
119+
case "${USER_SHELL}" in
120+
fish)
121+
echo " # fish shell"
122+
echo " fish_add_path ${INSTALL_DIR}"
123+
echo ""
124+
echo " # (persists automatically; or add to ~/.config/fish/config.fish)"
125+
;;
126+
zsh)
127+
echo " echo 'export PATH=\"${INSTALL_DIR}:\$PATH\"' >> \"\$HOME/.zshrc\""
128+
echo " source \"\$HOME/.zshrc\""
129+
;;
130+
bash)
131+
# .bashrc covers non-login interactive shells (GUI terminals); .profile
132+
# covers login shells. Writing to .bashrc is the most reliable for desktop use.
133+
echo " echo 'export PATH=\"${INSTALL_DIR}:\$PATH\"' >> \"\$HOME/.bashrc\""
134+
echo " source \"\$HOME/.bashrc\""
135+
;;
136+
*)
137+
echo " # add to your shell's startup file, e.g. ~/.profile"
138+
echo " echo 'export PATH=\"${INSTALL_DIR}:\$PATH\"' >> \"\$HOME/.profile\""
139+
echo " source \"\$HOME/.profile\""
140+
;;
141+
esac
142+
143+
echo ""
144+
echo "Then verify with:"
145+
echo ""
146+
echo " $ drycc --help"
147+
echo ""

0 commit comments

Comments
 (0)