Skip to content

Commit 34c1617

Browse files
Fix lint findings in shell/workflow/powershell checks
- format linux/macos installers with shfmt style and add SC2016 suppressions for literal pwsh command strings - remove workflow run-block template interpolation in Action-Test verification steps to satisfy zizmor template-injection audit - add script-level suppressions for intentional Write-Host/empty-catch usage in windows installer - rename Get-GitHubApiHeaders to Get-GitHubApiHeader in verify script for singular noun rule
1 parent 2d3c379 commit 34c1617

5 files changed

Lines changed: 225 additions & 208 deletions

File tree

.github/workflows/Action-Test.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ jobs:
4141

4242
- name: Verify installed version
4343
shell: pwsh
44+
env:
45+
RequestedVersion: ${{ matrix.version }}
4446
run: |
45-
./tests/scripts/Verify-InstalledVersion.ps1 -RequestedVersion '${{ matrix.version }}' -GitHubToken '${{ env.TestGitHubToken }}'
47+
./tests/scripts/Verify-InstalledVersion.ps1 -RequestedVersion "$env:RequestedVersion" -GitHubToken "$env:TestGitHubToken"
4648
4749
ActionTestTokenUseCaseDefault:
4850
name: 'ubuntu-latest - [Token default behavior]'
@@ -63,8 +65,10 @@ jobs:
6365

6466
- name: Verify default token behavior
6567
shell: pwsh
68+
env:
69+
RequestedVersion: ${{ env.TestLatestVersion }}
6670
run: |
67-
./tests/scripts/Verify-InstalledVersion.ps1 -RequestedVersion '${{ env.TestLatestVersion }}' -GitHubToken '${{ env.TestGitHubToken }}'
71+
./tests/scripts/Verify-InstalledVersion.ps1 -RequestedVersion "$env:RequestedVersion" -GitHubToken "$env:TestGitHubToken"
6872
6973
ActionTestTokenUseCaseExplicit:
7074
name: 'ubuntu-latest - [Token explicit input]'
@@ -86,8 +90,10 @@ jobs:
8690

8791
- name: Verify explicit token input behavior
8892
shell: pwsh
93+
env:
94+
RequestedVersion: ${{ env.TestLatestVersion }}
8995
run: |
90-
./tests/scripts/Verify-InstalledVersion.ps1 -RequestedVersion '${{ env.TestLatestVersion }}' -GitHubToken '${{ env.TestGitHubToken }}'
96+
./tests/scripts/Verify-InstalledVersion.ps1 -RequestedVersion "$env:RequestedVersion" -GitHubToken "$env:TestGitHubToken"
9197
9298
ActionTestTokenUseCaseAnonymous:
9399
name: 'ubuntu-latest - [Token anonymous mode]'
@@ -108,5 +114,7 @@ jobs:
108114

109115
- name: Verify anonymous mode behavior
110116
shell: pwsh
117+
env:
118+
RequestedVersion: ${{ env.TestLatestVersion }}
111119
run: |
112-
./tests/scripts/Verify-InstalledVersion.ps1 -RequestedVersion '${{ env.TestLatestVersion }}'
120+
./tests/scripts/Verify-InstalledVersion.ps1 -RequestedVersion "$env:RequestedVersion"

scripts/linux/install.sh

Lines changed: 135 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -6,74 +6,75 @@ echo "Requested version: [$REQUESTED_VERSION]"
66
echo "Prerelease: [$PRERELEASE]"
77

88
github_api_get() {
9-
local endpoint="$1"
10-
if command -v gh >/dev/null 2>&1 && [[ -n "$GH_TOKEN" ]]; then
11-
local gh_args=()
12-
if [[ -n "$GH_HOST" ]]; then
13-
gh_args+=(--hostname "$GH_HOST")
14-
fi
15-
gh api "${gh_args[@]}" -H "X-GitHub-Api-Version: 2022-11-28" "$endpoint"
16-
return
17-
fi
18-
19-
local auth_header=()
20-
if [[ -n "$GITHUB_TOKEN" ]]; then
21-
auth_header=(-H "Authorization: Bearer $GITHUB_TOKEN")
22-
fi
23-
24-
local api_base="https://api.github.com"
25-
if [[ -n "$GH_HOST" && "$GH_HOST" != "github.com" ]]; then
26-
api_base="https://${GH_HOST}/api/v3"
27-
fi
28-
29-
curl -s -f \
30-
-H "Accept: application/vnd.github+json" \
31-
"${auth_header[@]}" \
32-
-H "X-GitHub-Api-Version: 2022-11-28" \
33-
"${api_base}/${endpoint}"
9+
local endpoint="$1"
10+
if command -v gh >/dev/null 2>&1 && [[ -n "$GH_TOKEN" ]]; then
11+
local gh_args=()
12+
if [[ -n "$GH_HOST" ]]; then
13+
gh_args+=(--hostname "$GH_HOST")
14+
fi
15+
gh api "${gh_args[@]}" -H "X-GitHub-Api-Version: 2022-11-28" "$endpoint"
16+
return
17+
fi
18+
19+
local auth_header=()
20+
if [[ -n "$GITHUB_TOKEN" ]]; then
21+
auth_header=(-H "Authorization: Bearer $GITHUB_TOKEN")
22+
fi
23+
24+
local api_base="https://api.github.com"
25+
if [[ -n "$GH_HOST" && "$GH_HOST" != "github.com" ]]; then
26+
api_base="https://${GH_HOST}/api/v3"
27+
fi
28+
29+
curl -s -f \
30+
-H "Accept: application/vnd.github+json" \
31+
"${auth_header[@]}" \
32+
-H "X-GitHub-Api-Version: 2022-11-28" \
33+
"${api_base}/${endpoint}"
3434
}
3535

3636
# Only resolve to latest version if explicitly set to 'latest' (case-insensitive)
3737
case "${REQUESTED_VERSION:-}" in
38-
[Ll][Aa][Tt][Ee][Ss][Tt])
39-
if [[ "$PRERELEASE" == "true" ]]; then
40-
REQUESTED_VERSION=$(
41-
github_api_get 'repos/PowerShell/PowerShell/releases?per_page=100' |
42-
jq -r '[.[] | select(.prerelease == true)] | (.[0].tag_name // empty)' | sed 's/^v//'
43-
)
44-
if [[ -z "$REQUESTED_VERSION" ]]; then
45-
echo "Error: No prerelease PowerShell releases found when resolving latest prerelease."
46-
exit 1
47-
fi
48-
echo "Latest prerelease PowerShell version detected: $REQUESTED_VERSION"
49-
else
50-
REQUESTED_VERSION=$(
51-
github_api_get 'repos/PowerShell/PowerShell/releases/latest' |
52-
jq -r '.tag_name' | sed 's/^v//'
53-
)
54-
if [[ -z "$REQUESTED_VERSION" ]]; then
55-
echo "Error: Failed to resolve latest stable PowerShell release from GitHub."
56-
exit 1
57-
fi
58-
echo "Latest stable PowerShell release detected: $REQUESTED_VERSION"
59-
fi
60-
;;
61-
"")
62-
echo "Error: Version input is required (or use 'latest')"
63-
exit 1
64-
;;
38+
[Ll][Aa][Tt][Ee][Ss][Tt])
39+
if [[ "$PRERELEASE" == "true" ]]; then
40+
REQUESTED_VERSION=$(
41+
github_api_get 'repos/PowerShell/PowerShell/releases?per_page=100' |
42+
jq -r '[.[] | select(.prerelease == true)] | (.[0].tag_name // empty)' | sed 's/^v//'
43+
)
44+
if [[ -z "$REQUESTED_VERSION" ]]; then
45+
echo "Error: No prerelease PowerShell releases found when resolving latest prerelease."
46+
exit 1
47+
fi
48+
echo "Latest prerelease PowerShell version detected: $REQUESTED_VERSION"
49+
else
50+
REQUESTED_VERSION=$(
51+
github_api_get 'repos/PowerShell/PowerShell/releases/latest' |
52+
jq -r '.tag_name' | sed 's/^v//'
53+
)
54+
if [[ -z "$REQUESTED_VERSION" ]]; then
55+
echo "Error: Failed to resolve latest stable PowerShell release from GitHub."
56+
exit 1
57+
fi
58+
echo "Latest stable PowerShell release detected: $REQUESTED_VERSION"
59+
fi
60+
;;
61+
"")
62+
echo "Error: Version input is required (or use 'latest')"
63+
exit 1
64+
;;
6565
esac
6666

67+
# shellcheck disable=SC2016 # PowerShell expression is intentionally single-quoted for pwsh -Command.
6768
DETECTED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true)
6869
if [[ -n "$DETECTED_VERSION" ]]; then
69-
echo "Currently installed PowerShell version: $DETECTED_VERSION"
70+
echo "Currently installed PowerShell version: $DETECTED_VERSION"
7071
else
71-
echo "PowerShell is not currently installed"
72+
echo "PowerShell is not currently installed"
7273
fi
7374

7475
if [[ "$DETECTED_VERSION" == "$REQUESTED_VERSION" ]]; then
75-
echo "PowerShell $DETECTED_VERSION already installed. Skipping."
76-
exit 0
76+
echo "PowerShell $DETECTED_VERSION already installed. Skipping."
77+
exit 0
7778
fi
7879

7980
# Determine Linux distribution type
@@ -82,114 +83,115 @@ ARCH=$(dpkg --print-architecture 2>/dev/null || rpm --eval '%{_arch}' 2>/dev/nul
8283
# Query GitHub Releases API for the actual asset URLs to handle naming
8384
# convention differences across releases (e.g. powershell-preview_ vs powershell_).
8485
RELEASE_JSON=$(
85-
github_api_get "repos/PowerShell/PowerShell/releases/tags/v${REQUESTED_VERSION}"
86+
github_api_get "repos/PowerShell/PowerShell/releases/tags/v${REQUESTED_VERSION}"
8687
)
8788
if [[ -z "$RELEASE_JSON" ]]; then
88-
echo "Error: Failed to fetch release info for v${REQUESTED_VERSION} from GitHub."
89-
exit 1
89+
echo "Error: Failed to fetch release info for v${REQUESTED_VERSION} from GitHub."
90+
exit 1
9091
fi
9192

9293
# Determine if the requested version is a prerelease (contains a hyphen, e.g. 7.6.0-preview.6)
9394
IS_PRERELEASE=false
9495
if [[ "$REQUESTED_VERSION" == *-* ]]; then
95-
IS_PRERELEASE=true
96+
IS_PRERELEASE=true
9697
fi
9798

9899
if command -v apt-get >/dev/null || command -v dpkg >/dev/null; then
99-
# Debian/Ubuntu based
100-
echo "Detected Debian/Ubuntu based system..."
101-
if [[ "$IS_PRERELEASE" == "true" ]]; then
102-
# Prerelease .deb naming varies across releases:
103-
# Older: powershell-preview_7.4.0-preview.5-1.deb_amd64.deb
104-
# Newer: powershell_7.6.0-preview.6-1.deb_amd64.deb
105-
# Try powershell-preview_ first, then fall back to powershell_
106-
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
107-
'[.assets[] | select(.name | test("^powershell-preview_.*\\.deb_" + $arch + "\\.deb$"))] | .[0].browser_download_url // empty')
108-
if [[ -z "$URL" ]]; then
109-
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
110-
'[.assets[] | select(.name | test("^powershell_.*\\.deb_" + $arch + "\\.deb$"))] | .[0].browser_download_url // empty')
111-
fi
112-
else
113-
# For stable versions, select the powershell package (not powershell-lts or powershell-preview)
114-
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
115-
'[.assets[] | select(.name | test("^powershell_.*\\.deb_" + $arch + "\\.deb$"))] | .[0].browser_download_url // empty')
116-
fi
117-
if [[ -z "$URL" ]]; then
118-
echo "Error: No .deb package found for architecture '$ARCH' in release v${REQUESTED_VERSION}."
119-
exit 1
120-
fi
121-
DEB_NAME=$(basename "$URL")
122-
echo "Downloading from: $URL"
123-
wget -q "$URL" -O "$DEB_NAME"
124-
125-
# Remove all existing PowerShell packages to avoid dpkg conflicts
126-
# (powershell, powershell-lts, and powershell-preview all provide /usr/bin/pwsh)
127-
echo "Removing existing PowerShell packages to avoid conflicts..."
128-
sudo dpkg --remove powershell powershell-lts powershell-preview 2>/dev/null || true
129-
130-
echo "Starting installation of PowerShell [$REQUESTED_VERSION]..."
131-
sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y
100+
# Debian/Ubuntu based
101+
echo "Detected Debian/Ubuntu based system..."
102+
if [[ "$IS_PRERELEASE" == "true" ]]; then
103+
# Prerelease .deb naming varies across releases:
104+
# Older: powershell-preview_7.4.0-preview.5-1.deb_amd64.deb
105+
# Newer: powershell_7.6.0-preview.6-1.deb_amd64.deb
106+
# Try powershell-preview_ first, then fall back to powershell_
107+
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
108+
'[.assets[] | select(.name | test("^powershell-preview_.*\\.deb_" + $arch + "\\.deb$"))] | .[0].browser_download_url // empty')
109+
if [[ -z "$URL" ]]; then
110+
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
111+
'[.assets[] | select(.name | test("^powershell_.*\\.deb_" + $arch + "\\.deb$"))] | .[0].browser_download_url // empty')
112+
fi
113+
else
114+
# For stable versions, select the powershell package (not powershell-lts or powershell-preview)
115+
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
116+
'[.assets[] | select(.name | test("^powershell_.*\\.deb_" + $arch + "\\.deb$"))] | .[0].browser_download_url // empty')
117+
fi
118+
if [[ -z "$URL" ]]; then
119+
echo "Error: No .deb package found for architecture '$ARCH' in release v${REQUESTED_VERSION}."
120+
exit 1
121+
fi
122+
DEB_NAME=$(basename "$URL")
123+
echo "Downloading from: $URL"
124+
wget -q "$URL" -O "$DEB_NAME"
125+
126+
# Remove all existing PowerShell packages to avoid dpkg conflicts
127+
# (powershell, powershell-lts, and powershell-preview all provide /usr/bin/pwsh)
128+
echo "Removing existing PowerShell packages to avoid conflicts..."
129+
sudo dpkg --remove powershell powershell-lts powershell-preview 2>/dev/null || true
130+
131+
echo "Starting installation of PowerShell [$REQUESTED_VERSION]..."
132+
sudo dpkg -i "$DEB_NAME" || sudo apt-get -f install -y
132133
elif command -v rpm >/dev/null; then
133-
# RHEL/Fedora/CentOS based
134-
echo "Detected RHEL/Fedora/CentOS based system..."
135-
if [[ "$IS_PRERELEASE" == "true" ]]; then
136-
# Prerelease .rpm naming varies across releases:
137-
# Older: powershell-preview-7.4.0_preview.5-1.rh.x86_64.rpm
138-
# Newer: powershell-7.6.0_preview.6-1.rh.x86_64.rpm
139-
# Try powershell-preview first, then fall back to powershell-<version>
140-
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
141-
'[.assets[] | select(.name | test("^powershell-preview.*\\.rh\\." + (if $arch == "aarch64" then $arch else "x86_64" end) + "\\.rpm$"))] | .[0].browser_download_url // empty')
142-
if [[ -z "$URL" ]]; then
143-
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
144-
'[.assets[] | select(.name | test("^powershell-[0-9].*\\.rh\\." + (if $arch == "aarch64" then $arch else "x86_64" end) + "\\.rpm$"))] | .[0].browser_download_url // empty')
145-
fi
146-
else
147-
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
148-
'[.assets[] | select(.name | test("^powershell-[0-9].*\\.rh\\." + (if $arch == "aarch64" then $arch else "x86_64" end) + "\\.rpm$"))] | .[0].browser_download_url // empty')
149-
fi
150-
if [[ -z "$URL" ]]; then
151-
echo "Error: No .rpm package found for architecture '$ARCH' in release v${REQUESTED_VERSION}."
152-
exit 1
153-
fi
154-
RPM_NAME=$(basename "$URL")
155-
echo "Downloading from: $URL"
156-
wget -q "$URL" -O "$RPM_NAME"
157-
158-
# Remove existing PowerShell packages to avoid conflicts
159-
echo "Removing existing PowerShell packages to avoid conflicts..."
160-
sudo rpm -e powershell powershell-preview 2>/dev/null || true
161-
162-
echo "Starting installation of PowerShell [$REQUESTED_VERSION]..."
163-
sudo rpm -i "$RPM_NAME" || sudo yum install -y "$RPM_NAME"
134+
# RHEL/Fedora/CentOS based
135+
echo "Detected RHEL/Fedora/CentOS based system..."
136+
if [[ "$IS_PRERELEASE" == "true" ]]; then
137+
# Prerelease .rpm naming varies across releases:
138+
# Older: powershell-preview-7.4.0_preview.5-1.rh.x86_64.rpm
139+
# Newer: powershell-7.6.0_preview.6-1.rh.x86_64.rpm
140+
# Try powershell-preview first, then fall back to powershell-<version>
141+
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
142+
'[.assets[] | select(.name | test("^powershell-preview.*\\.rh\\." + (if $arch == "aarch64" then $arch else "x86_64" end) + "\\.rpm$"))] | .[0].browser_download_url // empty')
143+
if [[ -z "$URL" ]]; then
144+
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
145+
'[.assets[] | select(.name | test("^powershell-[0-9].*\\.rh\\." + (if $arch == "aarch64" then $arch else "x86_64" end) + "\\.rpm$"))] | .[0].browser_download_url // empty')
146+
fi
147+
else
148+
URL=$(echo "$RELEASE_JSON" | jq -r --arg arch "$ARCH" \
149+
'[.assets[] | select(.name | test("^powershell-[0-9].*\\.rh\\." + (if $arch == "aarch64" then $arch else "x86_64" end) + "\\.rpm$"))] | .[0].browser_download_url // empty')
150+
fi
151+
if [[ -z "$URL" ]]; then
152+
echo "Error: No .rpm package found for architecture '$ARCH' in release v${REQUESTED_VERSION}."
153+
exit 1
154+
fi
155+
RPM_NAME=$(basename "$URL")
156+
echo "Downloading from: $URL"
157+
wget -q "$URL" -O "$RPM_NAME"
158+
159+
# Remove existing PowerShell packages to avoid conflicts
160+
echo "Removing existing PowerShell packages to avoid conflicts..."
161+
sudo rpm -e powershell powershell-preview 2>/dev/null || true
162+
163+
echo "Starting installation of PowerShell [$REQUESTED_VERSION]..."
164+
sudo rpm -i "$RPM_NAME" || sudo yum install -y "$RPM_NAME"
164165
else
165-
echo "Unsupported Linux distribution. Cannot determine package format."
166-
exit 1
166+
echo "Unsupported Linux distribution. Cannot determine package format."
167+
exit 1
167168
fi
168169

169170
# Determine the install directory and add to PATH before verification.
170171
# Preview builds install to /opt/microsoft/powershell/<major>-preview/
171172
# which is not on the default PATH after removing the old powershell package.
172173
MAJOR_VERSION=$(echo "$REQUESTED_VERSION" | cut -d'.' -f1)
173174
if [[ "$IS_PRERELEASE" == "true" ]]; then
174-
INSTALL_DIR="/opt/microsoft/powershell/${MAJOR_VERSION}-preview"
175+
INSTALL_DIR="/opt/microsoft/powershell/${MAJOR_VERSION}-preview"
175176
else
176-
INSTALL_DIR="/opt/microsoft/powershell/${MAJOR_VERSION}"
177+
INSTALL_DIR="/opt/microsoft/powershell/${MAJOR_VERSION}"
177178
fi
178179
if [[ -d "$INSTALL_DIR" ]]; then
179-
export PATH="$INSTALL_DIR:$PATH"
180+
export PATH="$INSTALL_DIR:$PATH"
180181
fi
181182

182183
# Verify installation succeeded
184+
# shellcheck disable=SC2016 # PowerShell expression is intentionally single-quoted for pwsh -Command.
183185
INSTALLED_VERSION=$(pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>/dev/null || true)
184186
if [[ "$INSTALLED_VERSION" != "$REQUESTED_VERSION" ]]; then
185-
echo "Error: Installation verification failed. Expected $REQUESTED_VERSION but got ${INSTALLED_VERSION:-nothing}."
186-
exit 1
187+
echo "Error: Installation verification failed. Expected $REQUESTED_VERSION but got ${INSTALLED_VERSION:-nothing}."
188+
exit 1
187189
fi
188190
echo "Installation complete. PowerShell [$REQUESTED_VERSION] is now available."
189191

190192
# For prerelease builds, add the install directory to GITHUB_PATH so subsequent
191193
# `shell: pwsh` steps resolve to the version we just installed.
192194
if [[ "$IS_PRERELEASE" == "true" && -d "$INSTALL_DIR" ]]; then
193-
echo "Adding install directory to GITHUB_PATH: $INSTALL_DIR"
194-
echo "$INSTALL_DIR" >> "$GITHUB_PATH"
195+
echo "Adding install directory to GITHUB_PATH: $INSTALL_DIR"
196+
echo "$INSTALL_DIR" >>"$GITHUB_PATH"
195197
fi

0 commit comments

Comments
 (0)