1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

ci: add SDK breaking change detection workflow (#17075)

* ci: add SDK breaking change detection workflow

Introduces GitHub Actions workflow that detects TypeScript breaking changes when SDK artifacts are updated. Workflow is triggered via repository_dispatch from SDK repository and runs npm test:types with newly built SDK artifacts.

The workflow downloads SDK build artifacts, installs them locally, and executes the existing TypeScript type checking process. Exit codes determine success/failure for SDK repository monitoring via gh run watch.

Addresses issue where breaking changes in SDK are discovered only when clients attempt SDK version updates, rather than during SDK development.

* review: add input validation for client payload fields

Add validation step early in the workflow to check for required
client_payload fields and prevent failures from malformed payloads.
This improvement was requested during code review to provide better
error handling and debugging information when the SDK workflow sends
incomplete data.

Validates SOURCE_REPO, SDK_VERSION, ARTIFACTS_RUN_ID, and ARTIFACT_NAME
before proceeding with artifact download and type checking.

* review: update action versions to match repository standards

Update GitHub Actions to consistent versions used across the clients
repository for better security and compatibility. This change was
requested during code review to align with existing patterns.

- actions/checkout: v4.2.2 → v5.0.0 with specific SHA hash
- actions/setup-node: v4.2.0 → v5.0.0 with specific SHA hash
- actions/create-github-app-token: v2.1.1 → v2.0.3 with specific SHA hash

Uses specific SHA hashes for all actions following repository security standards.

* review: add timeout to type checking command for faster failure detection

Wrap npm run test:types with 10-minute timeout to provide faster feedback
when type checking hangs and more predictable workflow behavior. This
improvement was requested during code review to prevent workflows from
running until the 15-minute job timeout.

Provides clearer indication when type checking itself fails versus other
workflow issues, improving debugging experience for developers.

* review: use CLIENT_LABEL environment variable in logging and output

Add CLIENT_LABEL to log messages and GitHub Step Summary output for
better traceability and debugging. This change
 was requested during
code review to make use of the defined CLIENT_LABEL environment
variable that was previously unused.

Improves workflow output clarity by showing which client type
(typescript, mobile, etc.) is being processed.

* review: add retry logic for npm ci command to handle network issues

Implement shell-based retry logic (3 attempts with 5-second delays) for
npm ci command to handle temporary network issues without adding external
dependencies. This improvement was requested during code review to make
the workflow more resilient to transient failures.

Continues with existing npm install approach while adding robustness
for dependency installation in GitHub Actions environment.

* review: improve shell script variable quoting for better practices

Update shell script to use proper variable quoting syntax throughout
(${VARIABLE} instead of $VARIABLE) for better shell scripting practices
and consistency. This change was requested during code review to follow
shell scripting best practices.

While this won't cause problems in practice, it prevents potential
word splitting issues and improves code maintainability.

* review: add back logging out of Azure

* review: adjust logic of retries for npm ci

* review: quote some strings

* review: add error catching around npm i

* review: remove unnecessary cleanup step

* review: use npm link and bitwarden/gh-actions/download-artifacts

* review: add underscores to job level env vars

* 🎨 fix artipacked zizmor issue and improved actionlint formatting

---------

Co-authored-by: Matt Andreko <mandreko@bitwarden.com>
This commit is contained in:
Addison Beck
2025-11-03 09:30:11 -05:00
committed by GitHub
parent b4420d770e
commit c1dec4032e

View File

@@ -0,0 +1,167 @@
# This workflow runs TypeScript compatibility checks when the SDK is updated.
# Triggered automatically by the SDK repository via repository_dispatch when SDK PRs are created/updated.
name: SDK Breaking Change Check
run-name: "SDK breaking change check (${{ github.event.client_payload.sdk_version }})"
on:
repository_dispatch:
types: [sdk-breaking-change-check]
permissions:
contents: read
actions: read
id-token: write
jobs:
type-check:
name: TypeScript compatibility check
runs-on: ubuntu-24.04
timeout-minutes: 15
env:
_SOURCE_REPO: ${{ github.event.client_payload.source_repo }}
_SDK_VERSION: ${{ github.event.client_payload.sdk_version }}
_ARTIFACTS_RUN_ID: ${{ github.event.client_payload.artifacts_info.run_id }}
_ARTIFACT_NAME: ${{ github.event.client_payload.artifacts_info.artifact_name }}
_CLIENT_LABEL: ${{ github.event.client_payload.client_label }}
steps:
- name: Log in to Azure
uses: bitwarden/gh-actions/azure-login@main
with:
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
client_id: ${{ secrets.AZURE_CLIENT_ID }}
- name: Get Azure Key Vault secrets
id: get-kv-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: gh-org-bitwarden
secrets: "BW-GHAPP-ID,BW-GHAPP-KEY"
- name: Generate GH App token
uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3
id: app-token
with:
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }}
- name: Log out from Azure
uses: bitwarden/gh-actions/azure-logout@main
- name: Validate inputs
run: |
echo "🔍 Validating required client_payload fields..."
if [ -z "${_SOURCE_REPO}" ] || [ -z "${_SDK_VERSION}" ] || [ -z "${_ARTIFACTS_RUN_ID}" ] || [ -z "${_ARTIFACT_NAME}" ]; then
echo "::error::Missing required client_payload fields"
echo "SOURCE_REPO: ${_SOURCE_REPO}"
echo "SDK_VERSION: ${_SDK_VERSION}"
echo "ARTIFACTS_RUN_ID: ${_ARTIFACTS_RUN_ID}"
echo "ARTIFACT_NAME: ${_ARTIFACT_NAME}"
echo "CLIENT_LABEL: ${_CLIENT_LABEL}"
exit 1
fi
echo "✅ All required payload fields are present"
- name: Check out clients repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Get Node Version
id: retrieve-node-version
run: |
NODE_NVMRC=$(cat .nvmrc)
NODE_VERSION=${NODE_NVMRC/v/''}
echo "node_version=$NODE_VERSION" >> "$GITHUB_OUTPUT"
- name: Set up Node
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: ${{ steps.retrieve-node-version.outputs.node_version }}
- name: Install Node dependencies
run: |
echo "📦 Installing Node dependencies with retry logic..."
RETRY_COUNT=0
MAX_RETRIES=3
while [ ${RETRY_COUNT} -lt ${MAX_RETRIES} ]; do
RETRY_COUNT=$((RETRY_COUNT + 1))
echo "🔄 npm ci attempt ${RETRY_COUNT} of ${MAX_RETRIES}..."
if npm ci; then
echo "✅ npm ci successful"
break
else
echo "❌ npm ci attempt ${RETRY_COUNT} failed"
[ ${RETRY_COUNT} -lt ${MAX_RETRIES} ] && sleep 5
fi
done
if [ ${RETRY_COUNT} -eq ${MAX_RETRIES} ]; then
echo "::error::npm ci failed after ${MAX_RETRIES} attempts"
exit 1
fi
- name: Download SDK artifacts
uses: bitwarden/gh-actions/download-artifacts@main
with:
github_token: ${{ steps.app-token.outputs.token }}
workflow: build-wasm-internal.yml
workflow_conclusion: success
run_id: ${{ env._ARTIFACTS_RUN_ID }}
artifacts: ${{ env._ARTIFACT_NAME }}
repo: ${{ env._SOURCE_REPO }}
path: ./sdk-internal
if_no_artifact_found: fail
- name: Override SDK using npm link
working-directory: ./
run: |
echo "🔧 Setting up SDK override using npm link..."
echo "📊 SDK Version: ${_SDK_VERSION}"
echo "📦 Artifact Source: ${_SOURCE_REPO} run ${_ARTIFACTS_RUN_ID}"
echo "📋 SDK package contents:"
ls -la ./sdk-internal/
echo "🔗 Creating npm link to SDK package..."
if ! npm link ./sdk-internal; then
echo "::error::Failed to link SDK package"
exit 1
fi
- name: Run TypeScript compatibility check
run: |
echo "🔍 Running TypeScript type checking for ${_CLIENT_LABEL} client with SDK version: ${_SDK_VERSION}"
echo "🎯 Type checking command: npm run test:types"
# Add GitHub Step Summary output
{
echo "## 📊 TypeScript Compatibility Check (${_CLIENT_LABEL})"
echo "- **Client**: ${_CLIENT_LABEL}"
echo "- **SDK Version**: ${_SDK_VERSION}"
echo "- **Source Repository**: ${_SOURCE_REPO}"
echo "- **Artifacts Run ID**: ${_ARTIFACTS_RUN_ID}"
echo ""
} >> "$GITHUB_STEP_SUMMARY"
TYPE_CHECK_START=$(date +%s)
# Run type check with timeout - exit code determines gh run watch result
if timeout 10m npm run test:types; then
TYPE_CHECK_END=$(date +%s)
TYPE_CHECK_DURATION=$((TYPE_CHECK_END - TYPE_CHECK_START))
echo "✅ TypeScript compilation successful for ${_CLIENT_LABEL} client (${TYPE_CHECK_DURATION}s)"
echo "✅ **Result**: TypeScript compilation successful" >> "$GITHUB_STEP_SUMMARY"
echo "No breaking changes detected in ${_CLIENT_LABEL} client for SDK version ${_SDK_VERSION}" >> "$GITHUB_STEP_SUMMARY"
else
TYPE_CHECK_END=$(date +%s)
TYPE_CHECK_DURATION=$((TYPE_CHECK_END - TYPE_CHECK_START))
echo "❌ TypeScript compilation failed for ${_CLIENT_LABEL} client after ${TYPE_CHECK_DURATION}s - breaking changes detected"
echo "❌ **Result**: TypeScript compilation failed" >> "$GITHUB_STEP_SUMMARY"
echo "Breaking changes detected in ${_CLIENT_LABEL} client for SDK version ${_SDK_VERSION}" >> "$GITHUB_STEP_SUMMARY"
exit 1
fi