fix: Add GitHub token auth and cross-platform support to downloader script#34
Conversation
…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 EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…ct-tests in CI Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
| # 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 |
There was a problem hiding this comment.
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
| 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
- Replace
uses: launchdarkly/gh-actions/actions/contract-tests@mainwith a reference pinned to a specific commit SHA. - Find the latest commit SHA for
launchdarkly/gh-actions/actions/contract-teststhat corresponds to themainbranch 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). - 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. - 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.
There was a problem hiding this comment.
/ar This is testing our own action and needs to use the main branch.
…tion Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
There was a problem hiding this comment.
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.
…etation Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
**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 -->
Requirements
Related issues
The downloader script's
resolve_version()function calls the GitHub releases API without authentication, causing403rate-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.shto fix the auth bug and add observability and cross-platform support:GITHUB_TOKEN(viaAuthorizationheader) to all API and download requests, avoiding rate limiting.zipextraction,.exeextension handling, and normalizesaarch64→arm64.do_curl()helper logs the request URL, HTTP status line, content-type, andx-ratelimit-remainingfor every request.exit→returninresolve_version()so it doesn't kill the entire script when called from a$()subshell.PARAMSis now optional. When omitted, the script downloads and extracts the binary without executing it.Adds a new
test-downloader.ymlCI 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 actuallaunchdarkly/gh-actions/actions/contract-testsaction (withcontinue-on-errorsince no test service is running).Suggested review checklist:
do_curl()function usesevalto construct curl commands (needed for proper header quoting). This matches thesdk-test-harnesspattern — verify this is acceptable.[ ! -x "${EXECUTABLE}" ]check may always be true since MSYS doesn't set Unix execute bits on extracted.exefiles — this would cause re-downloads but is not harmful. Worth considering.continue-on-error: trueon thegh-actions/contract-testsCI 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.PARAMSoptional is a behavioral change. Existing callers (likegh-actions/contract-tests) always passPARAMS, so this should be safe, but confirm no consumers rely on the old error behavior.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-testsaction to call a fixed downloader script, but that would leave the bug in this repo for anyone using the script directly.Additional context
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.shrelease downloader to be more reliable on CI by supporting optionalGITHUB_TOKENauth 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,
zipextraction and.exehandling, normalizesaarch64→arm64, and changes behavior soPARAMSis optional (download-only mode) while also fixingresolve_version()toreturninstead of exiting the whole script.Adds a new GitHub Actions workflow
test-downloader.ymlthat 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 vialaunchdarkly/gh-actions/actions/contract-tests@main.Written by Cursor Bugbot for commit 2a29832. This will update automatically on new commits. Configure here.