Skip to content

Commit 84047f0

Browse files
authored
fix(website): fix install script version detection (#2322)
## Summary - Fix `install-cli.sh` picking pre-release tags (e.g. `cli/v0.4.0-rc.2`) instead of the latest stable release (`cli/v0.3.0`) - Add a `gh auth status` check before attempting attestation verification - Add live integration test workflow that installs a real release and verifies attestation ## Problem The version extraction in `get_release_version()` matched any `cli/v`-prefixed tag. Since the API returns releases sorted by creation date, a pre-release like `cli/v0.4.0-rc.2` was picked over the latest stable `cli/v0.3.0`. Additionally, `verify_binary` would fail with a confusing error when `gh` was installed but not authenticated. ## Fix - Changed the grep filter to a strict stable-version pattern (`cli/vX.Y.Z` only - no `-rc`, no suffixes) - Added `gh auth status` check with user-friendly warning when not authenticated ## Testing Added `website-live-test-install-script.yml` that: - Resolves the latest stable CLI release via `actions/github-script` (Octokit) - Runs the real install script end-to-end with attestation verification on linux/amd64 and linux/arm64 - Verifies the installed binary version matches the resolved release - Tests the unauthenticated path (no `gh` auth) to ensure graceful skip - Triggers on PRs, new releases, and manual dispatch ## Test plan - [x] Push and verify the live test workflow passes on this PR - [x] Run `bash website/static/install-cli.sh --help` locally --------- Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
1 parent 8832538 commit 84047f0

2 files changed

Lines changed: 170 additions & 15 deletions

File tree

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
name: "Website: Live Test Install Script"
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
paths:
8+
- '.github/workflows/website-live-test-install-script.yml'
9+
- 'website/static/install-cli.sh'
10+
release:
11+
types: [published]
12+
workflow_dispatch:
13+
14+
concurrency:
15+
group: live-test-install-${{ github.ref }}
16+
cancel-in-progress: true
17+
18+
permissions:
19+
contents: read
20+
21+
jobs:
22+
resolve:
23+
runs-on: ubuntu-latest
24+
name: Resolve latest stable CLI release
25+
outputs:
26+
version: ${{ steps.find.outputs.version }}
27+
tag: ${{ steps.find.outputs.tag }}
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
31+
32+
- name: Find latest stable CLI release
33+
id: find
34+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
35+
with:
36+
script: |
37+
const { extractHighestPreviousReleaseVersion } = await import('${{ github.workspace }}/.github/scripts/release-versioning.js');
38+
const tagPrefix = 'cli/v';
39+
40+
const releases = (await github.rest.repos.listReleases({
41+
owner: context.repo.owner,
42+
repo: context.repo.repo,
43+
per_page: 100,
44+
})).data;
45+
46+
const version = extractHighestPreviousReleaseVersion(releases, tagPrefix);
47+
if (!version) {
48+
core.setFailed('No stable CLI release found');
49+
return;
50+
}
51+
52+
core.setOutput('version', version);
53+
core.setOutput('tag', `${tagPrefix}${version}`);
54+
core.info(`Resolved latest stable CLI release: ${tagPrefix}${version}`);
55+
56+
install:
57+
needs: resolve
58+
name: Install + verify (${{ matrix.runner }})
59+
runs-on: ${{ matrix.runner }}
60+
permissions:
61+
contents: read
62+
strategy:
63+
fail-fast: false
64+
matrix:
65+
runner: [ubuntu-latest, ubuntu-24.04-arm]
66+
env:
67+
OCM_VERSION: ${{ needs.resolve.outputs.version }}
68+
GH_TOKEN: ${{ github.token }}
69+
steps:
70+
- name: Checkout
71+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
72+
73+
- name: Run install script
74+
env:
75+
INSTALL_DIR: ${{ runner.temp }}/ocm-bin
76+
INSTALL_LOG: ${{ runner.temp }}/install.log
77+
run: |
78+
bash website/static/install-cli.sh "${INSTALL_DIR}" 2>&1 | tee "${INSTALL_LOG}"
79+
echo "${INSTALL_DIR}" >> "$GITHUB_PATH"
80+
81+
- name: Verify attestation was checked
82+
env:
83+
INSTALL_LOG: ${{ runner.temp }}/install.log
84+
run: |
85+
if ! grep -q "Attestation verification successful" "${INSTALL_LOG}"; then
86+
echo "::error::Attestation verification did not run or did not succeed"
87+
cat "${INSTALL_LOG}"
88+
exit 1
89+
fi
90+
91+
- name: Verify installed binary
92+
run: |
93+
version_json=$(ocm version 2>/dev/null)
94+
actual=$(echo "${version_json}" | jq -r '"\(.major).\(.minor).\(.patch)"')
95+
if [[ "${actual}" != "${OCM_VERSION}" ]]; then
96+
echo "::error::Version mismatch: expected ${OCM_VERSION}, got ${actual}"
97+
exit 1
98+
fi
99+
echo "Installed version ${actual} matches expected ${OCM_VERSION}"
100+
ocm --help > /dev/null
101+
102+
install-without-auth:
103+
needs: resolve
104+
name: Install without attestation
105+
runs-on: ubuntu-latest
106+
env:
107+
EXPECTED_VERSION: ${{ needs.resolve.outputs.version }}
108+
steps:
109+
- name: Checkout
110+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
111+
112+
- name: Run install script without gh auth
113+
env:
114+
INSTALL_DIR: ${{ runner.temp }}/ocm-bin
115+
INSTALL_LOG: ${{ runner.temp }}/install.log
116+
GH_TOKEN: ""
117+
GITHUB_TOKEN: ""
118+
GH_CONFIG_DIR: /nonexistent
119+
run: |
120+
bash website/static/install-cli.sh "${INSTALL_DIR}" 2>&1 | tee "${INSTALL_LOG}"
121+
echo "${INSTALL_DIR}" >> "$GITHUB_PATH"
122+
123+
- name: Verify attestation was skipped
124+
env:
125+
INSTALL_LOG: ${{ runner.temp }}/install.log
126+
run: |
127+
if ! grep -q "GitHub CLI is not authenticated. Skipping attestation verification." "${INSTALL_LOG}"; then
128+
echo "::error::Expected unauthenticated skip message not found"
129+
cat "${INSTALL_LOG}"
130+
exit 1
131+
fi
132+
133+
- name: Verify installed binary
134+
run: |
135+
version_json=$(ocm version 2>/dev/null)
136+
actual=$(echo "${version_json}" | jq -r '"\(.major).\(.minor).\(.patch)"')
137+
if [[ "${actual}" != "${EXPECTED_VERSION}" ]]; then
138+
echo "::error::Version mismatch: expected ${EXPECTED_VERSION}, got ${actual}"
139+
exit 1
140+
fi
141+
echo "Installed version ${actual} matches expected ${EXPECTED_VERSION}"
142+
ocm --help > /dev/null

website/static/install-cli.sh

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -132,25 +132,30 @@ setup_tmp() {
132132
trap cleanup INT EXIT
133133
}
134134

135+
# Extract a stable CLI version from a releases JSON file.
136+
# Returns the version string (e.g. "0.3.0") or empty if none found.
137+
extract_stable_version() {
138+
grep '"tag_name":' "$1" \
139+
| grep -E "\"${TAG_PREFIX}v[0-9]+\.[0-9]+\.[0-9]+\"" \
140+
| head -1 \
141+
| sed -E "s|.*\"${TAG_PREFIX}v([^\"]+)\".*|\1|" \
142+
|| true # grep returns non-zero when no lines match; prevent set -e from killing the subshell
143+
}
144+
135145
# Find version from Github metadata
136146
get_release_version() {
137-
if [[ -n "${OCM_VERSION:-}" ]]; then
138-
METADATA_URL="https://api.github.com/repos/${GITHUB_REPO}/releases/tags/${TAG_PREFIX}v${OCM_VERSION}"
139-
else
147+
if [[ -z "${OCM_VERSION:-}" ]]; then
140148
# Use the list endpoint so we can filter by TAG_PREFIX; /releases/latest may
141149
# point to a non-CLI release (e.g. a website or docs tag published more recently).
142-
METADATA_URL="https://api.github.com/repos/${GITHUB_REPO}/releases"
143-
fi
150+
METADATA_URL="https://api.github.com/repos/${GITHUB_REPO}/releases?per_page=100"
151+
info "Downloading metadata ${METADATA_URL}"
152+
download "${TMP_METADATA}" "${METADATA_URL}"
144153

145-
info "Downloading metadata ${METADATA_URL}"
146-
download "${TMP_METADATA}" "${METADATA_URL}"
154+
OCM_VERSION=$(extract_stable_version "${TMP_METADATA}")
155+
fi
147156

148-
# tag_name has the format "cli/v0.1.0" – strip the prefix and leading "v".
149-
# When OCM_VERSION is unset the response is a JSON array; grep the first
150-
# tag_name that starts with TAG_PREFIX to avoid picking a non-CLI release.
151-
VERSION_OCM=$(grep '"tag_name":' "${TMP_METADATA}" | grep "\"${TAG_PREFIX}v" | head -1 | sed -E "s|.*\"${TAG_PREFIX}v([^\"]+)\".*|\1|")
152-
if [[ -n "${VERSION_OCM}" ]]; then
153-
info "Using ${VERSION_OCM} as release"
157+
if [[ -n "${OCM_VERSION}" ]]; then
158+
info "Using ${OCM_VERSION} as release"
154159
else
155160
fatal "Unable to determine release version"
156161
fi
@@ -176,7 +181,7 @@ download() {
176181
# Download binary from Github URL
177182
# Assets follow the naming scheme: ocm-{OS}-{ARCH} (no version, no archive)
178183
download_binary() {
179-
BIN_URL="https://github.com/${GITHUB_REPO}/releases/download/${TAG_PREFIX}v${VERSION_OCM}/ocm-${OS}-${ARCH}"
184+
BIN_URL="https://github.com/${GITHUB_REPO}/releases/download/${TAG_PREFIX}v${OCM_VERSION}/ocm-${OS}-${ARCH}"
180185
info "Downloading binary ${BIN_URL}"
181186
download "${TMP_BIN}" "${BIN_URL}"
182187
}
@@ -198,6 +203,14 @@ verify_binary() {
198203
return 0
199204
fi
200205

206+
# Check if gh CLI is authenticated to github.com
207+
if ! gh auth status --hostname github.com &> /dev/null; then
208+
warn "GitHub CLI is not authenticated. Skipping attestation verification."
209+
warn "To verify the binary, run: gh auth login"
210+
warn "Or set OCM_SKIP_VERIFY=true to suppress this warning."
211+
return 0
212+
fi
213+
201214
info "Verifying binary attestation..."
202215
if gh attestation verify "${TMP_BIN}" --repo "${GITHUB_REPO}" 2>/dev/null; then
203216
info "Attestation verification successful"
@@ -230,5 +243,5 @@ setup_binary() {
230243
ensure_bin_dir
231244
setup_binary
232245
ensure_path
233-
info "OCM CLI v${VERSION_OCM} installed successfully"
246+
info "OCM CLI v${OCM_VERSION} installed successfully"
234247
}

0 commit comments

Comments
 (0)