Skip to content

fix(website): fix install script version detection#2322

Merged
frewilhelm merged 31 commits into
open-component-model:mainfrom
frewilhelm:fix-install-script
Apr 20, 2026
Merged

fix(website): fix install script version detection#2322
frewilhelm merged 31 commits into
open-component-model:mainfrom
frewilhelm:fix-install-script

Conversation

@frewilhelm

@frewilhelm frewilhelm commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

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

  • Push and verify the live test workflow passes on this PR
  • Run bash website/static/install-cli.sh --help locally

Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
@frewilhelm frewilhelm requested a review from a team as a code owner April 17, 2026 13:29
@netlify

netlify Bot commented Apr 17, 2026

Copy link
Copy Markdown

Deploy Preview for ocm-website canceled.

Name Link
🔨 Latest commit d0398c0
🔍 Latest deploy log https://app.netlify.com/projects/ocm-website/deploys/69e62ac6f1058600083414d8

@coderabbitai

coderabbitai Bot commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a99da0c6-aeb4-477e-8c9f-87a297cf6499

📥 Commits

Reviewing files that changed from the base of the PR and between 0ddea74 and d0398c0.

📒 Files selected for processing (2)
  • .github/workflows/website-live-test-install-script.yml
  • website/static/install-cli.sh
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/website-live-test-install-script.yml

📝 Walkthrough

Walkthrough

The install script now discovers releases via GitHub Releases list, deriving OCM_VERSION by matching exact semantic tags; downloads use OCM_VERSION; attestation is skipped with a warning if gh is unauthenticated. A new GitHub Actions workflow live-tests authenticated and unauthenticated installs across two runners.

Changes

Cohort / File(s) Summary
Install Script
website/static/install-cli.sh
Derive OCM_VERSION from Releases list using exact TAG_PREFIXv<MAJOR>.<MINOR>.<PATCH> match; use OCM_VERSION when constructing asset URLs; skip attestation verification with a warning if gh is not authenticated; report OCM_VERSION in success logs.
CI: Live Test Workflow
.github/workflows/website-live-test-install-script.yml
Add workflow to resolve latest stable cli/vX.Y.Z release and run website/static/install-cli.sh on ubuntu-latest and ubuntu-24.04-arm; verify attestation-success path and unauthenticated skip path, and validate ocm version/ocm --help.

Sequence Diagram(s)

sequenceDiagram
    participant GHA as GitHub Actions
    participant API as GitHub Releases API
    participant Script as install-cli.sh
    participant GH as GitHub CLI (gh)
    participant CLI as ocm CLI
    participant Verifier as Test Verifier

    GHA->>API: Query releases (releases?per_page=100, paginated)
    API-->>GHA: Return release list with tags
    GHA->>Script: Invoke script with resolved OCM_VERSION
    Script->>API: Download release asset using OCM_VERSION
    Script->>GH: Check authentication
    GH-->>Script: Authenticated / Unauthenticated
    Script->>CLI: Install binary
    Verifier->>CLI: Run 'ocm version' and 'ocm --help'
    Verifier-->>GHA: Report verification results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

size/s

Suggested reviewers

  • jakobmoellerdev

Poem

🐰 I hopped through pages, found the numbered tag,
I fetched the binary, then gave a little wag.
If gh won't chatter, I tiptoe and skip,
Then dance through tests with a jubilant flip.
Happy release — a carrot-shaped victory lap!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.94% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: fixing the install script's version detection logic to prefer stable releases over pre-releases.
Description check ✅ Passed The description is well-structured, directly related to the changeset, and provides clear context about the problems fixed and testing performed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
@github-actions github-actions Bot added the component/github-actions Changes on GitHub Actions or within `.github/` directory label Apr 17, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
website/static/install-cli.sh (1)

140-151: Optional: /releases pagination may miss the latest stable.

The /releases list endpoint returns 30 entries per page by default, ordered by creation date. If more than 30 pre-releases (-rc.*) are created after the last stable, the most recent stable falls off page 1 and head -1 will find no match, making get_release_version fatal out even though a stable exists.

Low probability today, but trivial to harden:

♻️ Proposed change
-        METADATA_URL="https://api.github.com/repos/${GITHUB_REPO}/releases"
+        METADATA_URL="https://api.github.com/repos/${GITHUB_REPO}/releases?per_page=100"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/static/install-cli.sh` around lines 140 - 151, The script can miss
stable releases due to GitHub's paginated /releases endpoint; update the logic
that builds METADATA_URL and computes VERSION_OCM so it paginates through
releases (e.g., request per_page=100 and iterate pages via &page=N until either
a matching stable tag is found or no more results) instead of relying on a
single download to TMP_METADATA and head -1; ensure you reuse TAG_PREFIX and
TMP_METADATA, append or aggregate page responses, and stop the loop when grep
for "\"${TAG_PREFIX}v[0-9]+\.[0-9]+\.[0-9]+\"" yields a match to set
VERSION_OCM, or exit gracefully if none found.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@website/static/install-cli.sh`:
- Around line 140-151: The script can miss stable releases due to GitHub's
paginated /releases endpoint; update the logic that builds METADATA_URL and
computes VERSION_OCM so it paginates through releases (e.g., request
per_page=100 and iterate pages via &page=N until either a matching stable tag is
found or no more results) instead of relying on a single download to
TMP_METADATA and head -1; ensure you reuse TAG_PREFIX and TMP_METADATA, append
or aggregate page responses, and stop the loop when grep for
"\"${TAG_PREFIX}v[0-9]+\.[0-9]+\.[0-9]+\"" yields a match to set VERSION_OCM, or
exit gracefully if none found.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 94759f90-d6ba-4a7f-b481-713b8c7e02d3

📥 Commits

Reviewing files that changed from the base of the PR and between 27bc07b and 07de207.

📒 Files selected for processing (3)
  • .github/workflows/website-test-install-script.yml
  • website/static/install-cli-test.sh
  • website/static/install-cli.sh

Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
@frewilhelm

Copy link
Copy Markdown
Contributor Author

I added a check to see if the user is authenticated or not which is required to check the attestation. If not an appropriate warning is returned.

IMO it is discussable if this is only a warning (that does not abort the script!). Meaning if the script is called from another script or the user oversees the warning for another reason, it would still install an unverified ocm binary

morri-son
morri-son previously approved these changes Apr 17, 2026
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
morri-son
morri-son previously approved these changes Apr 17, 2026
@frewilhelm

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 17, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@frewilhelm

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 17, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
website/static/install-cli-test.sh (2)

312-315: Status capture is unreliable under set -e.

output=$(verify_binary 2>&1) runs under set -euo pipefail. If verify_binary ever returns non-zero (e.g., a regression where the early-return guard is removed), the harness aborts immediately and local status=$? never executes — so a real regression would crash the harness rather than fail the assertion. The other fatal-path tests already use the safer (...) || status=$? form (Lines 134, 158, 182, 200, 293); please apply the same pattern here and in test_verify_skips_when_gh_not_authenticated (Lines 331-334).

♻️ Suggested change
-    local output
-    output=$(verify_binary 2>&1)
-    local status=$?
+    local status=0
+    verify_binary >/dev/null 2>&1 || status=$?
     assert_equals "verify_binary returns 0 when gh missing" "0" "${status}"

(and analogously at Lines 331-334 and 348-351)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/static/install-cli-test.sh` around lines 312 - 315, The test captures
return status unreliably because output=$(verify_binary 2>&1) runs under set -e
and will abort on non-zero; change the capture to run the command in a subshell
and record the exit code using the safe pattern ( ... ) || status=$? so the
harness doesn't exit early; update the verify_binary invocation in this block
(where output and status are set) and do the same change in the related test
test_verify_skips_when_gh_not_authenticated to use (verify_binary 2>&1) ||
status=$? and then assign output from the subshell capture so assertions can run
reliably.

309-319: Mock cleanup not exception-safe.

unset -f command (Line 317) and unset -f gh (Line 336) only run if the prior assertions/commands all succeed under set -e. A future change that causes an early non-zero exit would leak these function overrides into subsequent tests, producing confusing cascading failures (e.g., a stubbed command or gh affecting later tests). Consider a per-test trap '...' RETURN (or a small cleanup helper invoked via trap) to guarantee restoration of the global state and removal of tmpdir.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/static/install-cli-test.sh` around lines 309 - 319, The test
temporarily overrides the shell functions/commands `command` and `gh` and
removes `tmpdir` but restores them only on the success path; make the cleanup
exception-safe by adding a per-test trap that always runs on function RETURN (or
use a small `cleanup` helper and trap it), e.g. register a trap at the start of
the test to unset the overridden functions (`unset -f command` and `unset -f
gh`) and remove `${tmpdir}` regardless of failures; ensure the trap references
the same identifiers used in the test (verify_binary, command, gh, tmpdir) so
restoration runs even if `set -e` causes an early exit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@website/static/install-cli-test.sh`:
- Around line 312-315: The test captures return status unreliably because
output=$(verify_binary 2>&1) runs under set -e and will abort on non-zero;
change the capture to run the command in a subshell and record the exit code
using the safe pattern ( ... ) || status=$? so the harness doesn't exit early;
update the verify_binary invocation in this block (where output and status are
set) and do the same change in the related test
test_verify_skips_when_gh_not_authenticated to use (verify_binary 2>&1) ||
status=$? and then assign output from the subshell capture so assertions can run
reliably.
- Around line 309-319: The test temporarily overrides the shell
functions/commands `command` and `gh` and removes `tmpdir` but restores them
only on the success path; make the cleanup exception-safe by adding a per-test
trap that always runs on function RETURN (or use a small `cleanup` helper and
trap it), e.g. register a trap at the start of the test to unset the overridden
functions (`unset -f command` and `unset -f gh`) and remove `${tmpdir}`
regardless of failures; ensure the trap references the same identifiers used in
the test (verify_binary, command, gh, tmpdir) so restoration runs even if `set
-e` causes an early exit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a57b38c6-d2ce-41f5-afa5-d1407061355b

📥 Commits

Reviewing files that changed from the base of the PR and between 07de207 and fbba6ce.

📒 Files selected for processing (2)
  • website/static/install-cli-test.sh
  • website/static/install-cli.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • website/static/install-cli.sh

Comment thread .github/workflows/website-live-test-install-script.yml Outdated
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
website/static/install-cli.sh (1)

247-260: ⚠️ Potential issue | 🟠 Major

Add the missing source guard around the installer entry point.

This block runs unconditionally, so source install-cli.sh triggers the install flow instead of only loading functions.

Proposed fix
 # Run the install process
-{
+main() {
     case "${1:-}" in -h|--help) usage ;; esac
     setup_verify_os
     setup_verify_arch
     verify_downloader curl || verify_downloader wget || fatal 'Can not find curl or wget for downloading files'
@@
     setup_binary
     ensure_path
     info "OCM CLI v${OCM_VERSION} installed successfully"
 }
+
+if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+    main "$@"
+fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/static/install-cli.sh` around lines 247 - 260, The installer entry
sequence (calls to usage, setup_verify_os, setup_verify_arch, verify_downloader,
setup_tmp, get_release_version, download_binary, verify_binary, ensure_bin_dir,
setup_binary, ensure_path, info) runs unconditionally and will execute when the
file is sourced; wrap that block in a "script is main" source guard so it only
runs when executed, e.g. enclose the existing sequence in an if-check that
compares BASH_SOURCE[0] to $0 (or uses [[ "${BASH_SOURCE[0]}" == "${0}" ]]) and
close with fi so sourcing the file only defines functions and running it
performs the install.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@website/static/install-cli.sh`:
- Around line 247-260: The installer entry sequence (calls to usage,
setup_verify_os, setup_verify_arch, verify_downloader, setup_tmp,
get_release_version, download_binary, verify_binary, ensure_bin_dir,
setup_binary, ensure_path, info) runs unconditionally and will execute when the
file is sourced; wrap that block in a "script is main" source guard so it only
runs when executed, e.g. enclose the existing sequence in an if-check that
compares BASH_SOURCE[0] to $0 (or uses [[ "${BASH_SOURCE[0]}" == "${0}" ]]) and
close with fi so sourcing the file only defines functions and running it
performs the install.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 434b5453-d16a-4351-9b45-3c839f250075

📥 Commits

Reviewing files that changed from the base of the PR and between 0ae0f9b and 0ddea74.

📒 Files selected for processing (1)
  • website/static/install-cli.sh

… limit

Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
@frewilhelm

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@frewilhelm frewilhelm requested a review from fabianburth April 20, 2026 13:46
@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@frewilhelm frewilhelm merged commit 84047f0 into open-component-model:main Apr 20, 2026
24 checks passed
ocmbot Bot pushed a commit that referenced this pull request Apr 20, 2026
## 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> 84047f0
@frewilhelm

Copy link
Copy Markdown
Contributor Author

I added a check to see if the user is authenticated or not which is required to check the attestation. If not an appropriate warning is returned.
IMO it is discussable if this is only a warning (that does not abort the script!). Meaning if the script is called from another script or the user oversees the warning for another reason, it would still install an unverified ocm binary

The script is mainly intended to be used as installation method for an enduser. If he does not care about warnings, he gets potentially an unverified version. We may add some more information into the comments at the beginning of the script, but I would not add more safe guards during execution.

I think the only way to get rid of the verification dependency to gh is by attaching the signature to the release artifact and verifying with this directly instead of going through gh attestations.

This is I think also a requirement to get the OpenSSF score higher

I added #2348 as a follow up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/github-actions Changes on GitHub Actions or within `.github/` directory kind/bugfix Bug size/m Medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants