Skip to content

Commit 6e8c618

Browse files
[PM-20288] New workflow to update the sdk (#1877)
Co-authored-by: Álison Fernandes <[email protected]>
1 parent bef5799 commit 6e8c618

File tree

4 files changed

+289
-5
lines changed

4 files changed

+289
-5
lines changed
Lines changed: 225 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,236 @@
11
name: SDLC / SDK Update
2+
run-name: "SDK ${{inputs.run-mode == 'Update' && format('Update - {0}', inputs.sdk-version) || format('Test #{0} - {1}', inputs.pr-id, inputs.sdk-version)}}"
23

34
on:
45
workflow_dispatch:
6+
inputs:
7+
run-mode:
8+
description: "Run Mode"
9+
type: choice
10+
options:
11+
- Test # used for testing sdk-internal repo PRs
12+
- Update # opens a PR in this repo updating the SDK
13+
default: Update
14+
sdk-version:
15+
description: "SDK Version"
16+
required: true
17+
default: "1.0.0-283-7b5d9db"
18+
sdk-swift-ref:
19+
description: "sdk-swift repo git ref"
20+
required: true
21+
default: "c2817139d7da49037841215d37a2f931525bf0fc"
22+
pr-id:
23+
description: "Pull Request ID (Test mode only)"
524

6-
permissions:
7-
contents: read
25+
env:
26+
_BOT_NAME: "bw-ghapp[bot]"
27+
_BOT_EMAIL: "178206702+bw-ghapp[bot]@users.noreply.github.com"
28+
_SDK_DEPENDENCY_NAME: "BitwardenSdk"
829

930
jobs:
1031
update:
11-
name: Update SDK
32+
name: Update and PR
33+
if: ${{ inputs.run-mode == 'Update' }}
1234
runs-on: ubuntu-24.04
35+
permissions:
36+
id-token: write
1337

1438
steps:
15-
- name: Placeholder
16-
run: echo ":feelsgood:" >> $GITHUB_STEP_SUMMARY
39+
- name: Log in to Azure
40+
uses: bitwarden/gh-actions/azure-login@main
41+
with:
42+
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
43+
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
44+
client_id: ${{ secrets.AZURE_CLIENT_ID }}
45+
46+
- name: Get Azure Key Vault secrets
47+
id: get-kv-secrets
48+
uses: bitwarden/gh-actions/get-keyvault-secrets@main
49+
with:
50+
keyvault: gh-org-bitwarden
51+
secrets: "BW-GHAPP-ID,BW-GHAPP-KEY"
52+
53+
- name: Log out from Azure
54+
uses: bitwarden/gh-actions/azure-logout@main
55+
56+
- name: Generate GH App token
57+
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
58+
id: app-token
59+
with:
60+
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
61+
private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }}
62+
permission-pull-requests: write
63+
permission-actions: read
64+
permission-contents: write
65+
66+
- name: Check out repo
67+
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
68+
with:
69+
token: ${{ steps.app-token.outputs.token }}
70+
fetch-depth: 0
71+
72+
- name: Log inputs to job summary
73+
uses: ./.github/actions/log-inputs
74+
with:
75+
inputs: ${{ toJson(inputs) }}
76+
77+
- name: Switch to branch
78+
id: switch-branch
79+
run: |
80+
BRANCH_NAME="sdlc/sdk-update"
81+
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
82+
83+
if git switch $BRANCH_NAME; then
84+
echo "✅ Switched to existing branch: $BRANCH_NAME"
85+
echo "updating_existing_branch=true" >> $GITHUB_OUTPUT
86+
else
87+
echo "📝 Creating new branch: $BRANCH_NAME"
88+
git switch -c $BRANCH_NAME
89+
echo "updating_existing_branch=false" >> $GITHUB_OUTPUT
90+
fi
91+
92+
- name: Prevent updating the branch when the last committer isn't the bot
93+
if: ${{ steps.switch-branch.outputs.updating_existing_branch == 'true' }}
94+
env:
95+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
96+
_BRANCH_NAME: ${{ steps.switch-branch.outputs.branch_name }}
97+
run: |
98+
LATEST_COMMIT_AUTHOR=$(git log -1 --format='%ae' $_BRANCH_NAME)
99+
100+
echo "Latest commit author in branch ($_BRANCH_NAME): $LATEST_COMMIT_AUTHOR"
101+
echo "Expected bot email: $_BOT_EMAIL"
102+
103+
if [ "$LATEST_COMMIT_AUTHOR" != "$_BOT_EMAIL" ]; then
104+
echo "::error::Branch $_BRANCH_NAME has a commit not made by the bot." \
105+
"This indicates manual changes have been made to the branch," \
106+
"PR has to be merged or closed before running this workflow again."
107+
echo "👀 Fetching existing PR..."
108+
gh pr list --head $_BRANCH_NAME --base main --state open --json number --jq '.[0].number // empty'
109+
EXISTING_PR=$(gh pr list --head $_BRANCH_NAME --base main --state open --json number --jq '.[0].number // empty')
110+
if [ -z "$EXISTING_PR" ]; then
111+
echo "::error::Couldn't find an existing PR for branch $_BRANCH_NAME."
112+
exit 1
113+
fi
114+
PR_URL="https://github.com/${{ github.repository }}/pull/$EXISTING_PR"
115+
echo "## ❌ Merge or close: $PR_URL" >> $GITHUB_STEP_SUMMARY
116+
exit 1
117+
fi
118+
119+
echo "✅ Branch tip commit was made by the bot. Safe to proceed."
120+
121+
# Using main to retrieve the changelog on consecutive updates of the same PR.
122+
- name: Get current SDK version from main branch
123+
id: get-current-sdk
124+
env:
125+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
126+
run: |
127+
SDK_SWIFT_REF=$(git show origin/main:project-common.yml | yq '.packages.BitwardenSdk.revision')
128+
if [ -z "$SDK_SWIFT_REF" ]; then
129+
echo "::error::Failed to get current SDK version from main branch."
130+
exit 1
131+
fi
132+
133+
echo "👀 sdk-swift ref: $SDK_SWIFT_REF"
134+
135+
COMMIT_MESSAGE=$(gh api "repos/bitwarden/sdk-swift/commits/$SDK_SWIFT_REF" --jq '.commit.message')
136+
echo "👀 sdk-swift ref commit message: \"$COMMIT_MESSAGE\""
137+
SDK_INTERNAL_REF=$(echo "$COMMIT_MESSAGE" | grep -oE '[a-f0-9]{40}')
138+
if [ -z "$SDK_INTERNAL_REF" ]; then
139+
echo "::error::Failed to parse sdk-internal ref from commit message."
140+
exit 1
141+
fi
142+
143+
echo ""
144+
echo "📋 Current sdk-swift ref (from main): $SDK_SWIFT_REF"
145+
echo "📋 Current sdk-internal ref (parsed from commit): $SDK_INTERNAL_REF"
146+
echo "sdk-swift-ref=$SDK_SWIFT_REF" >> $GITHUB_OUTPUT
147+
echo "sdk-internal-ref=$SDK_INTERNAL_REF" >> $GITHUB_OUTPUT
148+
149+
- name: Detect downgrade and prevent updating to the current version
150+
id: detect-downgrade
151+
env:
152+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
153+
_CURRENT_SDK_SWIFT_REF: ${{ steps.get-current-sdk.outputs.sdk-swift-ref }}
154+
_NEW_SDK_SWIFT_REF: ${{ inputs.sdk-swift-ref }}
155+
run: |
156+
if [ "$_CURRENT_SDK_SWIFT_REF" = "$_NEW_SDK_SWIFT_REF" ]; then
157+
echo "::error::Provided sdk-swift ref is the same as the current version in main."
158+
exit 1
159+
fi
160+
161+
COMPARE_RESULT=$(gh api "repos/bitwarden/sdk-swift/compare/$_CURRENT_SDK_SWIFT_REF...$_NEW_SDK_SWIFT_REF" --jq '.status')
162+
163+
if [ "$COMPARE_RESULT" = "behind" ]; then
164+
echo "::warning::The new SDK version ($_NEW_SDK_SWIFT_REF) is older than the current version ($_CURRENT_SDK_SWIFT_REF)"
165+
echo "downgrading=true" >> $GITHUB_OUTPUT
166+
else
167+
echo "✅ New SDK version is newer - proceeding with update"
168+
echo "downgrading=false" >> $GITHUB_OUTPUT
169+
fi
170+
171+
- name: Update SDK Version
172+
env:
173+
_SDK_VERSION: ${{ inputs.sdk-version }}
174+
_SDK_SWIFT_REF: ${{ inputs.sdk-swift-ref }}
175+
run: |
176+
./Scripts/update-sdk-version.sh "$_SDK_DEPENDENCY_NAME" "$_SDK_SWIFT_REF" "$_SDK_VERSION"
177+
178+
- name: Create branch and commit
179+
env:
180+
_SDK_VERSION: ${{ inputs.sdk-version }}
181+
_SDK_SWIFT_REF: ${{ inputs.sdk-swift-ref }}
182+
_BRANCH_NAME: ${{ steps.switch-branch.outputs.branch_name }}
183+
run: |
184+
echo "👀 Committing SDK version update..."
185+
_SDK_SWIFT_REF_SHORT="${_SDK_SWIFT_REF:0:7}"
186+
187+
git config user.name "$_BOT_NAME"
188+
git config user.email "$_BOT_EMAIL"
189+
190+
git add project-common.yml
191+
git commit -m "SDK Update - $_SDK_SWIFT_REF_SHORT ($_SDK_VERSION)"
192+
git push origin $_BRANCH_NAME
193+
194+
- name: Create or Update Pull Request
195+
env:
196+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
197+
_BRANCH_NAME: ${{ steps.switch-branch.outputs.branch_name }}
198+
_NEW_SDK_VERSION: ${{ inputs.sdk-version }}
199+
_NEW_SDK_SWIFT_REF: ${{ inputs.sdk-swift-ref }}
200+
_OLD_SDK_SWIFT_REF: ${{ steps.get-current-sdk.outputs.sdk-swift-ref }}
201+
_OLD_SDK_INTERNAL_REF: ${{ steps.get-current-sdk.outputs.sdk-internal-ref }}
202+
_DOWNGRADING: ${{ steps.detect-downgrade.outputs.downgrading }}
203+
run: |
204+
_NEW_SDK_INTERNAL_REF=$(echo "$_NEW_SDK_VERSION" | cut -d'-' -f3-)
205+
PR_BODY="Updates the SDK from \`$_OLD_SDK_SWIFT_REF\` to \`$_NEW_SDK_SWIFT_REF\`"
206+
207+
if [ "$_DOWNGRADING" = "true" ]; then
208+
PR_BODY="$PR_BODY\n\n## :warning: Downgrading SDK to an older version. :warning:"
209+
PR_TITLE_ACTION="Downgrading"
210+
else
211+
CHANGELOG=$(./Scripts/get-repo-changelog.sh "bitwarden/sdk-internal" "$_OLD_SDK_INTERNAL_REF" "$_NEW_SDK_INTERNAL_REF")
212+
PR_BODY="$PR_BODY\n\n## What's Changed\n\n$CHANGELOG"
213+
PR_TITLE_ACTION="Updating"
214+
fi
215+
216+
EXISTING_PR=$(gh pr list --head $_BRANCH_NAME --base main --state open --json number --jq '.[0].number // empty')
217+
_NEW_SDK_SWIFT_REF_SHORT="${_NEW_SDK_SWIFT_REF:0:7}"
218+
219+
if [ -n "$EXISTING_PR" ]; then
220+
echo "🔄 Updating existing PR #$EXISTING_PR..."
221+
echo -e "$PR_BODY" | gh pr edit $EXISTING_PR \
222+
--title "$PR_TITLE_ACTION SDK to $_NEW_SDK_SWIFT_REF_SHORT ($_NEW_SDK_VERSION)" \
223+
--body-file -
224+
PR_URL="https://github.com/${{ github.repository }}/pull/$EXISTING_PR"
225+
echo "## ✅ Updated PR: $PR_URL" >> $GITHUB_STEP_SUMMARY
226+
else
227+
echo "📝 Creating new PR..."
228+
PR_URL=$(echo -e "$PR_BODY" | gh pr create \
229+
--title "$PR_TITLE_ACTION SDK to $_NEW_SDK_SWIFT_REF_SHORT ($_NEW_SDK_VERSION)" \
230+
--body-file - \
231+
--base main \
232+
--head $_BRANCH_NAME \
233+
--label "automated-pr" \
234+
--label "t:ci")
235+
echo "## 🚀 Created PR: $PR_URL" >> $GITHUB_STEP_SUMMARY
236+
fi

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,6 @@ Configs/export_options.plist
8080
# LicensePlist
8181
Bitwarden/Application/Support/Settings.bundle/Acknowledgements.latest_result.txt
8282
Authenticator/Application/Support/Settings.bundle/Acknowledgements.latest_result.txt
83+
84+
# Backup files
85+
*.bak

Scripts/get-repo-changelog.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
3+
# Script to get changelog between two git refs from a given GitHub repo.
4+
# Usage: ./scripts/get-repo-changelog.sh <repo> <current-ref> <new-ref>
5+
6+
set -euo pipefail
7+
8+
if [ $# -lt 2 ]; then
9+
echo "Usage: $0 <repo> <current-ref> <new-ref>"
10+
echo "Example: $0 bitwarden/sdk-internal 9fe3aeda fix-wasm-import"
11+
exit 1
12+
fi
13+
14+
REPO="$1"
15+
CURRENT_REF="$2"
16+
NEW_REF="$3"
17+
18+
CHANGELOG=$(gh api "repos/$REPO/compare/$CURRENT_REF...$NEW_REF" \
19+
--jq '.commits[] | "- \(.commit.message | split("\n")[0])"' | head -20)
20+
21+
if [ -z "$CHANGELOG" ]; then
22+
echo "No changes found between $CURRENT_REF and $NEW_REF"
23+
exit 0
24+
fi
25+
26+
27+
# GitHub renders org/repo#123 as a link to a PR, removing the commit message when a PR ID is found
28+
# including the raw changelog in a collapsible section in case the pattern matching fails
29+
CLEANED_CHANGELOG=$(echo "$CHANGELOG" | sed -E "s|.*\(#([0-9]+)\).*|- $REPO#\1|")
30+
31+
echo "$CLEANED_CHANGELOG"
32+
echo
33+
echo "<details>
34+
<summary>Raw changelog</summary>
35+
36+
\`\`\`
37+
$CHANGELOG
38+
\`\`\`
39+
</details>
40+
"

Scripts/update-sdk-version.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
3+
# Update SDK revision in project-common.yml
4+
5+
set -euo pipefail
6+
7+
if [ $# -lt 3 ]; then
8+
echo "Usage: $0 <sdk-package> <sdk-swift-ref> <sdk-version>"
9+
echo "Example: $0 BitwardenSdk 2a6609428275c758fcda5383bfb6b3166ec29eda 1.0.0-281-a1611ee"
10+
exit 1
11+
fi
12+
13+
SDK_PACKAGE="$1"
14+
SDK_SWIFT_REF="$2"
15+
SDK_VERSION="$3"
16+
FILE="project-common.yml"
17+
18+
echo "🔧 Updating revision in $FILE..."
19+
yq -i ".packages[\"$SDK_PACKAGE\"].revision = \"$SDK_SWIFT_REF\" | .packages[\"$SDK_PACKAGE\"].revision line_comment = \"$SDK_VERSION\"" "$FILE"
20+
echo "✅ Updated revision line:"
21+
grep -A 3 "$SDK_PACKAGE:" "$FILE"

0 commit comments

Comments
 (0)