Skip to content

fix: Add GitHub token auth and cross-platform support to downloader script#34

Merged
kinyoklion merged 5 commits intomainfrom
devin/1772840289-fix-downloader-script
Mar 9, 2026
Merged

fix: Add GitHub token auth and cross-platform support to downloader script#34
kinyoklion merged 5 commits intomainfrom
devin/1772840289-fix-downloader-script

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot commented Mar 6, 2026

Requirements

  • I have added test coverage for new or changed functionality
  • I have followed the repository's pull request submission guidelines
  • I have validated my changes against all supported platform versions

Related issues

The downloader script's resolve_version() function calls the GitHub releases API without authentication, causing 403 rate-limit failures on shared CI runners. This was discovered while debugging contract test failures in launchdarkly/swift-eventsource#95. The equivalent script in sdk-test-harness already has token support.

Describe the solution you've provided

Rewrites downloader/run.sh to fix the auth bug and add observability and cross-platform support:

  1. GitHub token auth — passes GITHUB_TOKEN (via Authorization header) to all API and download requests, avoiding rate limiting.
  2. Cross-platform support — adds Windows detection (MSYS/MINGW/CYGWIN) with zip extraction, .exe extension handling, and normalizes aarch64arm64.
  3. HTTP request logging — new do_curl() helper logs the request URL, HTTP status line, content-type, and x-ratelimit-remaining for every request.
  4. Version resolution logging — lists all available versions and the resolved version during partial version resolution.
  5. Platform info — outputs OS type, architecture, and archive name at startup.
  6. Bug fix — changes exitreturn in resolve_version() so it doesn't kill the entire script when called from a $() subshell.
  7. Download-only modePARAMS is now optional. When omitted, the script downloads and extracts the binary without executing it.

Adds a new test-downloader.yml CI workflow that verifies the script on Linux x64, Linux arm64, macOS, and Windows — testing partial (v2) and full (v2.31.0) version resolution in download-only mode, plus a step that invokes the actual launchdarkly/gh-actions/actions/contract-tests action (with continue-on-error since no test service is running).

Suggested review checklist:

  • The do_curl() function uses eval to construct curl commands (needed for proper header quoting). This matches the sdk-test-harness pattern — verify this is acceptable.
  • On Windows, the [ ! -x "${EXECUTABLE}" ] check may always be true since MSYS doesn't set Unix execute bits on extracted .exe files — this would cause re-downloads but is not harmful. Worth considering.
  • The continue-on-error: true on the gh-actions/contract-tests CI step means a download failure there won't fail CI. The direct download steps (partial + full version) are the strict verification; the action step just confirms compatibility.
  • Making PARAMS optional is a behavioral change. Existing callers (like gh-actions/contract-tests) always pass PARAMS, so this should be safe, but confirm no consumers rely on the old error behavior.
  • All informational output goes to stderr (via log()). This is correct for command substitution but means CI logs interleave stderr/stdout.

Describe alternatives you've considered

Could have forked the gh-actions/contract-tests action to call a fixed downloader script, but that would leave the bug in this repo for anyone using the script directly.

Additional context


Open with Devin

Note

Medium Risk
Touches the release download/execution path and introduces OS-specific branching plus eval-based curl invocation, which could break downloads on some runners if edge cases were missed.

Overview
Fixes the downloader/run.sh release downloader to be more reliable on CI by supporting optional GITHUB_TOKEN auth for GitHub API and asset downloads and adding verbose HTTP logging (status, content-type, rate-limit remaining).

Expands the script to support Windows shells (MSYS/MINGW/CYGWIN) via OS/arch detection, zip extraction and .exe handling, normalizes aarch64arm64, and changes behavior so PARAMS is optional (download-only mode) while also fixing resolve_version() to return instead of exiting the whole script.

Adds a new GitHub Actions workflow test-downloader.yml that runs the downloader on Linux x64/arm64, macOS, and Windows, testing both partial (v2) and full (v2.31.0) version resolution, plus a best-effort compatibility check via launchdarkly/gh-actions/actions/contract-tests@main.

Written by Cursor Bugbot for commit 2a29832. This will update automatically on new commits. Configure here.

…cript

- Pass GITHUB_TOKEN to GitHub API calls to avoid rate limiting on CI
- Add Windows support (MSYS/MINGW/CYGWIN) with zip extraction
- Normalize aarch64 to arm64 for consistent archive naming
- Log platform OS, arch, archive name, and HTTP response details
- List available versions and selected version during resolution
- Add CI workflow to verify downloads on Linux x64, Linux arm64, macOS, and Windows

Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

…ct-tests in CI

Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
@kinyoklion kinyoklion marked this pull request as ready for review March 6, 2026 23:48
@kinyoklion kinyoklion requested a review from a team as a code owner March 6, 2026 23:48
# Since no test service is running, the binary will fail - but the download
# succeeding is what we're verifying here.
continue-on-error: true
uses: launchdarkly/gh-actions/actions/contract-tests@main
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload.

To resolve this comment:

✨ Commit Assistant fix suggestion

Suggested change
uses: launchdarkly/gh-actions/actions/contract-tests@main
uses: launchdarkly/gh-actions/actions/contract-tests@5a43cd7f346ee16b21969c8cb0f1b2d6b7b6b498 # main branch as of 2024-06-28
View step-by-step instructions
  1. Replace uses: launchdarkly/gh-actions/actions/contract-tests@main with a reference pinned to a specific commit SHA.
  2. Find the latest commit SHA for launchdarkly/gh-actions/actions/contract-tests that corresponds to the main branch or the desired release (you can get this from https://github.com/launchdarkly/gh-actions/commits/main or by running: $ git ls-remote https://github.com/launchdarkly/gh-actions.git refs/heads/main).
  3. Update the line to: uses: launchdarkly/gh-actions/actions/contract-tests@<commit-sha>, replacing <commit-sha> with the full 40-character SHA from the previous step.
  4. Optionally, add a comment next to the SHA noting which branch or version it corresponds to for future maintainability, e.g., # main.

Pinning the action to a full commit SHA ensures that only that exact version of the action will be used and cannot be modified upstream.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by third-party-action-not-pinned-to-commit-sha.

You can view more details about this finding in the Semgrep AppSec Platform.

Copy link
Copy Markdown
Member

@kinyoklion kinyoklion Mar 6, 2026

Choose a reason for hiding this comment

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

/ar This is testing our own action and needs to use the main branch.

Copy link
Copy Markdown
Contributor Author

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 6 additional findings.

Open in Devin Review

…tion

Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Comment thread downloader/run.sh
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Comment thread downloader/run.sh Outdated
…etation

Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
@kinyoklion kinyoklion requested a review from keelerm84 March 9, 2026 15:47
@kinyoklion kinyoklion merged commit 7eea884 into main Mar 9, 2026
10 checks passed
@kinyoklion kinyoklion deleted the devin/1772840289-fix-downloader-script branch March 9, 2026 15:56
kinyoklion pushed a commit to launchdarkly/swift-eventsource that referenced this pull request Mar 9, 2026
**Requirements**

- [ ] I have added test coverage for new or changed functionality
- [ ] I have followed the repository's [pull request submission
guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests)
- [ ] I have validated my changes against all supported platform
versions

**Related issues**

Ports the relevant CI changes from
[launchdarkly/ios-client-sdk#481](launchdarkly/ios-client-sdk#481)
to swift-eventsource to reduce CI build times. Also incorporates the
contract test fix from branch
`devin/1772832423-fix-contract-test-version`.

The contract tests previously failed due to GitHub API rate limiting in
the `sse-contract-tests` downloader script. The root cause fix is in
[launchdarkly/sse-contract-tests#34](launchdarkly/sse-contract-tests#34).

**Describe the solution you've provided**

The monolithic `.github/actions/ci` composite action ran all builds,
tests, linting, and contract tests sequentially in a single job. This PR
breaks it into focused composite actions that run as **separate parallel
jobs** in `ci.yml`:

| New action | What it does |
|---|---|
| `lint` | `brew install swiftlint`, `pod lib lint --quick`, `swiftlint
lint` |
| `build-ios` | Build for iOS device + test on iOS Simulator |
| `build-macos` | Build & test on macOS + ARM64 build |
| `build-tvos` | Build for tvOS device + test on tvOS Simulator |
| `build-watchos` | Build for watchOS device + simulator |
| `test-swiftpm` | `swift test` via SwiftPM |
| `contract-tests` | Build service, start in background, run via
`launchdarkly/gh-actions/actions/contract-tests@main` |
| `build-docs` | (already existed, now its own job with `setup-xcode`) |

Other changes:
- **Mint removed** — `Mintfile` deleted; swiftlint installed directly
via `brew install swiftlint`
- **Simulator warmup** added for iOS/tvOS/watchOS (`xcrun simctl list
devices available`) to mitigate intermittent macos-15 runner issues
([actions/runner-images#12948](actions/runner-images#12948))
- **Pod lint** changed from `pod spec lint` to `pod lib lint
--allow-warnings --quick` (skips full build since dedicated jobs already
compile all platforms)
- **`setup-xcode`** moved to workflow level (each job sets up Xcode
explicitly)
- **Contract tests fixed** — uses the shared
`launchdarkly/gh-actions/actions/contract-tests@main` action
(intentionally `@main` — this is our own organization's action).
Configured with `branch: main` (since `sse-contract-tests` uses `main`,
not `v2`, as its default branch) and `enable_persistence_tests: false`
(SSE contract tests don't support that flag). Two known-flaky tests are
skipped via `extra_params`.
- **Release/publish workflows** (`release-please.yml`,
`manual-publish.yml`, `manual-publish-docs.yml`) updated to call
individual composite actions sequentially (these must remain sequential
since they gate the publish step)

**Checklist for human reviewer**


1. **SwiftLint version is no longer pinned** — Mintfile pinned
`realm/SwiftLint@0.56.2`; now `brew install swiftlint` pulls whatever
Homebrew provides. Verify this won't cause unexpected lint failures.
2. **Pod lint command changed** — switched from `pod spec lint` to `pod
lib lint` with `--allow-warnings --quick`. Confirm `lib lint` is
appropriate here (validates local podspec vs. published spec).
3. **Runner usage** — each parallel job spins up its own macOS runner (8
macOS jobs instead of 1). Wall clock time decreases but total
runner-minutes may increase.
4. **Contract test action uses `@main`** — uses
`launchdarkly/gh-actions/actions/contract-tests@main` (mutable ref)
rather than a pinned SHA. This is intentional per repo owner direction —
the action is from LaunchDarkly's own organization.

**Describe alternatives you've considered**

- Could have kept Mint with version pinning — chose to match
ios-client-sdk pattern which removed Mint.
- Could have created a matrix for multiple Xcode versions — kept single
version (16.4) to match current setup.

**Additional context**

- This is CI-only infrastructure; no application logic changed.
- Changes cannot be validated locally — require GitHub Actions run to
verify.
- Link to Devin Session:
https://app.devin.ai/sessions/2da8679d630649d4be8984e8cab6c980
- Requested by: rlamb@launchdarkly.com (via @kinyoklion)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> CI-only changes, but they restructure job orchestration, switch
lint/tool installation sources, and move contract testing to an external
action ref (`@main`), any of which can cause unexpected pipeline
failures or behavior changes.
> 
> **Overview**
> Refactors GitHub Actions CI from a single composite
(`.github/actions/ci`) into multiple focused composite actions (lint,
per-platform Xcode builds/tests, SwiftPM tests, and contract tests) and
updates `ci.yml` to run them as separate **parallel** jobs on `macos-15`
(with Xcode 16.4 setup per job) to reduce wall-clock time.
> 
> CI reliability and tooling are adjusted: adds simulator “warm-up”
(`xcrun simctl list devices available`) for iOS/tvOS/watchOS, switches
pod linting to `pod lib lint --allow-warnings --quick`, removes
Mint/`Mintfile` in favor of `brew install swiftlint`, and updates
contract tests to run via
`launchdarkly/gh-actions/actions/contract-tests@main` with specific
config and skipped cases.
> 
> Release/publish workflows (`manual-publish*`, `release-please`) are
updated to invoke the new actions sequentially (preserving gating before
publish).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b2e2d4b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants