From 1960343bc639589a9867fa9c73856a9b614be99c Mon Sep 17 00:00:00 2001 From: Shivam Kumar Date: Wed, 16 Sep 2026 23:50:07 +0530 Subject: [PATCH 1/2] chore(ci): record published version in the SDK release catalog (SDK-7358) railsApp derives a version's tier (stable/outdated/deprecated) from the sdk_version_releases catalog. Without a callback from the release path the catalog only advances when someone re-runs the registry backfill, so a version published today looks missing and its age clock never starts. This service publishes from GitHub Actions rather than browserstack-cd, so the hook the other SDKs get from the Jenkins pipeline has to live here. Recorded under language `ecmascript` -- a separate catalog line from `node`. Driven off changesets' `published`/`publishedPackages` outputs rather than re-deriving the version, so it fires only when something was actually published -- not when the action opens the Version PR instead. Canary is excluded by the same gate. Never fails a release: continue-on-error, a guard for the missing credential, and version validation before the call. A failed write costs freshness, not correctness -- rake sdk_release_catalog:backfill recovers anything missed. Inert until the SDK_RELEASE_SERVICE_CREDS secret is provisioned; it logs a warning and exits 0. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/release.yml | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 12aa288a..00e7e6c3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,6 +97,7 @@ jobs: # Merge the "Version Packages" PR first: this publishes only when there are no pending # changesets. If any remain, the action safely opens/updates the Version PR instead. - name: Publish to npm + id: publish if: github.event_name == 'workflow_dispatch' && inputs.publish uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1 with: @@ -107,6 +108,56 @@ jobs: # No NPM_TOKEN: auth is OIDC via id-token: write above. NPM_CONFIG_PROVENANCE: 'true' + # railsApp derives a version's tier from the sdk_version_releases catalog; without this + # callback the catalog only advances when someone re-runs the registry backfill. + # Gated on steps.publish.outputs.published because the action opens the Version PR and + # publishes nothing when changesets are still pending. Serves both release lines — this + # workflow runs on main (v9) and on v8 — so no branch special-casing. + - name: Record release in the SDK version catalog + if: >- + github.event_name == 'workflow_dispatch' && inputs.publish + && steps.publish.outputs.published == 'true' + continue-on-error: true + env: + SDK_RELEASE_SERVICE_CREDS: ${{ secrets.SDK_RELEASE_SERVICE_CREDS }} + PUBLISHED_PACKAGES: ${{ steps.publish.outputs.publishedPackages }} + run: | + set -uo pipefail + + if [ -z "${SDK_RELEASE_SERVICE_CREDS:-}" ]; then + echo "::warning::sdk-release-service credential not configured; skipping catalog write" + exit 0 + fi + + VERSION="$(printf '%s' "$PUBLISHED_PACKAGES" \ + | jq -r '.[] | select(.name == "@wdio/browserstack-service") | .version' \ + | head -n1)" + + if ! printf '%s' "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+[0-9A-Za-z.+-]*$'; then + echo "::warning::'$VERSION' is not a release version; skipping catalog write" + exit 0 + fi + + printf '{"language":"ecmascript","version":"%s","release_date":"%s"}' \ + "$VERSION" "$(date -u +%F)" > /tmp/sdkrel_payload.json + + HTTP_CODE=$(curl -s -o /tmp/sdkrel_body.json -w '%{http_code}' \ + --max-time 20 --retry 2 --retry-delay 3 \ + -X POST "https://api.browserstack.com/sdk/v1/admin/releases" \ + -u "$SDK_RELEASE_SERVICE_CREDS" \ + -H 'Content-Type: application/json' \ + -d @/tmp/sdkrel_payload.json) + + echo "SDK release catalog responded $HTTP_CODE for ecmascript $VERSION" + cat /tmp/sdkrel_body.json 2>/dev/null || true + rm -f /tmp/sdkrel_payload.json /tmp/sdkrel_body.json + + case "$HTTP_CODE" in + 200|201) ;; + 409) echo "::warning::ecmascript $VERSION is already recorded with a DIFFERENT release_date. Investigate; do not force." ;; + *) echo "::warning::could not record ecmascript $VERSION (HTTP $HTTP_CODE). The publish succeeded; the catalog stays stale for this version until the next backfill." ;; + esac + # Canary (manual, workflow_dispatch with canary=true): snapshot-version the pending # changesets and publish a prerelease to the `canary` dist-tag via the SAME OIDC trusted # publisher. Validates OIDC + provenance end-to-end without touching `latest`. From c9cb4f4d5337474262ce9e1c0555a579d2e38d88 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2026 18:22:03 +0000 Subject: [PATCH 2/2] chore(changeset): auto-generate from PR template (patch) --- .changeset/pr-204.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pr-204.md diff --git a/.changeset/pr-204.md b/.changeset/pr-204.md new file mode 100644 index 00000000..982e6328 --- /dev/null +++ b/.changeset/pr-204.md @@ -0,0 +1,5 @@ +--- +"@wdio/browserstack-service": patch +--- + +- None — internal release tooling only.