name: SDLC / SDK Update run-name: "SDK ${{inputs.run-mode == 'Update' && format('Update - {0}', inputs.sdk-version) || format('Test #{0} - {1}', inputs.pr-id, inputs.sdk-version)}}" on: workflow_dispatch: inputs: run-mode: description: "Run Mode" type: choice options: - Test # used for testing sdk-internal repo PRs - Update # opens a PR in this repo updating the SDK default: Test sdk-package: description: "SDK Package ID" required: true default: "com.bitwarden:sdk-android.dev" sdk-version: description: "SDK Version" required: true default: "1.0.0-2686-km-update-kdf-sdk" pr-id: description: "Pull Request ID" env: _BOT_NAME: "bw-ghapp[bot]" _BOT_EMAIL: "178206702+bw-ghapp[bot]@users.noreply.github.com" jobs: update: name: Update and PR if: ${{ inputs.run-mode == 'Update' }} runs-on: ubuntu-24.04 permissions: id-token: write 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: Log out from Azure uses: bitwarden/gh-actions/azure-logout@main - name: Generate GH App token uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1 id: app-token with: app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }} private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }} permission-pull-requests: write permission-actions: read permission-contents: write - name: Check out repo uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: token: ${{ steps.app-token.outputs.token }} fetch-depth: 0 persist-credentials: true - name: Log inputs to job summary uses: ./.github/actions/log-inputs with: inputs: ${{ toJson(inputs) }} - name: Switch to branch id: switch-branch run: | BRANCH_NAME="sdlc/sdk-update" echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT" if git switch "$BRANCH_NAME"; then echo "✅ Switched to existing branch: $BRANCH_NAME" echo "updating_existing_branch=true" >> "$GITHUB_OUTPUT" else echo "📝 Creating new branch: $BRANCH_NAME" git switch -c "$BRANCH_NAME" echo "updating_existing_branch=false" >> "$GITHUB_OUTPUT" fi - name: Prevent updating the branch when the last committer isn't the bot if: ${{ steps.switch-branch.outputs.updating_existing_branch == 'true' }} env: GH_TOKEN: ${{ steps.app-token.outputs.token }} _BRANCH_NAME: ${{ steps.switch-branch.outputs.branch_name }} run: | LATEST_COMMIT_AUTHOR=$(git log -1 --format='%ae' "$_BRANCH_NAME") echo "Latest commit author in branch ($_BRANCH_NAME): $LATEST_COMMIT_AUTHOR" echo "Expected bot email: $_BOT_EMAIL" if [ "$LATEST_COMMIT_AUTHOR" != "$_BOT_EMAIL" ]; then echo "::error::Branch $_BRANCH_NAME has a commit not made by the bot." \ "This indicates manual changes have been made to the branch," \ "PR has to be merged or closed before running this workflow again." echo "👀 Fetching existing PR..." gh pr list --head "$_BRANCH_NAME" --base main --state open --json number --jq '.[0].number // empty' EXISTING_PR=$(gh pr list --head "$_BRANCH_NAME" --base main --state open --json number --jq '.[0].number // empty') if [ -z "$EXISTING_PR" ]; then echo "::error::Couldn't find an existing PR for branch $_BRANCH_NAME." exit 1 fi PR_URL="https://github.com/${{ github.repository }}/pull/$EXISTING_PR" echo "## ❌ Merge or close: $PR_URL" >> "$GITHUB_STEP_SUMMARY" exit 1 fi echo "✅ Branch tip commit was made by the bot. Safe to proceed." # Using main to retrieve the changelog on consecutive updates of the same PR. - name: Get current SDK version from main branch id: get-current-sdk run: | git show origin/main:gradle/libs.versions.toml SDK_VERSION=$(git show origin/main:gradle/libs.versions.toml | grep "bitwardenSdk =" | cut -d'"' -f2) if [ -z "$SDK_VERSION" ]; then echo "::error::Failed to get current SDK version from main branch." exit 1 fi GIT_REF=$(echo "$SDK_VERSION" | cut -d'-' -f3-) # handles both commit hashes and branch names echo "Current SDK version (from main): $SDK_VERSION" echo "Current SDK git ref: $GIT_REF" echo "version=$SDK_VERSION" >> "$GITHUB_OUTPUT" echo "git_ref=$GIT_REF" >> "$GITHUB_OUTPUT" - name: Update SDK Version env: _SDK_PACKAGE: ${{ inputs.sdk-package }} _SDK_VERSION: ${{ inputs.sdk-version }} run: | ./scripts/update-sdk-version.sh "$_SDK_PACKAGE" "$_SDK_VERSION" - name: Create branch and commit env: _SDK_PACKAGE: ${{ inputs.sdk-package }} _SDK_VERSION: ${{ inputs.sdk-version }} _BRANCH_NAME: ${{ steps.switch-branch.outputs.branch_name }} run: | echo "👀 Committing SDK version update..." git config user.name "$_BOT_NAME" git config user.email "$_BOT_EMAIL" git add gradle/libs.versions.toml git commit -m "SDK Update - $_SDK_PACKAGE $_SDK_VERSION" git push origin "$_BRANCH_NAME" - name: Create or Update Pull Request env: GH_TOKEN: ${{ steps.app-token.outputs.token }} _BRANCH_NAME: ${{ steps.switch-branch.outputs.branch_name }} _SDK_PACKAGE: ${{ inputs.sdk-package }} _SDK_VERSION: ${{ inputs.sdk-version }} _OLD_SDK_VERSION: ${{ steps.get-current-sdk.outputs.version }} _OLD_SDK_GIT_REF: ${{ steps.get-current-sdk.outputs.git_ref }} run: | NEW_SDK_GIT_REF=$(echo "$_SDK_VERSION" | cut -d'-' -f3-) CHANGELOG=$(./scripts/get-repo-changelog.sh "bitwarden/sdk-internal" "$_OLD_SDK_GIT_REF" "$NEW_SDK_GIT_REF") PR_BODY="Updates the SDK version from \`$_OLD_SDK_VERSION\` to \`$_SDK_PACKAGE $_SDK_VERSION\` ## What's Changed $CHANGELOG" EXISTING_PR=$(gh pr list --head "$_BRANCH_NAME" --base main --state open --json number --jq '.[0].number // empty') if [ -n "$EXISTING_PR" ]; then echo "🔄 Updating existing PR #$EXISTING_PR..." echo -e "$PR_BODY" | gh pr edit "$EXISTING_PR" \ --title "Update SDK to $_SDK_VERSION" \ --body-file - PR_URL="https://github.com/${{ github.repository }}/pull/$EXISTING_PR" echo "## ✅ Updated PR: $PR_URL" >> "$GITHUB_STEP_SUMMARY" else echo "📝 Creating new PR..." PR_URL=$(echo -e "$PR_BODY" | gh pr create \ --title "Update SDK to $_SDK_VERSION" \ --body-file - \ --base main \ --head "$_BRANCH_NAME" \ --label "automated-pr" \ --label "t:deps") echo "## 🚀 Created PR: $PR_URL" >> "$GITHUB_STEP_SUMMARY" fi test: name: Test Update if: ${{ inputs.run-mode == 'Test' }} runs-on: ubuntu-24.04 permissions: contents: read packages: read steps: - name: Check out repo uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: persist-credentials: false - name: Log inputs to job summary uses: ./.github/actions/log-inputs with: inputs: ${{ toJson(inputs) }} - name: Setup Android Build uses: ./.github/actions/setup-android-build - name: Update SDK Version env: _SDK_PACKAGE: ${{ inputs.sdk-package }} _SDK_VERSION: ${{ inputs.sdk-version }} run: | ./scripts/update-sdk-version.sh "$_SDK_PACKAGE" "$_SDK_VERSION" - name: Build env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Used in settings.gradle.kts to download the SDK from GitHub Maven Packages run: | ./gradlew assembleDebug --warn