Skip to content

Commit 4ac30a8

Browse files
committed
Merge branch 'main' into ps/PM-29492-api-middleware-support
# Conflicts: # support/generate-api-bindings-ci.sh
2 parents e6ecfe2 + c830ffa commit 4ac30a8

File tree

11 files changed

+439
-89
lines changed

11 files changed

+439
-89
lines changed

.github/workflows/update-api-bindings.yml

Lines changed: 216 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1-
name: Update API Bindings
1+
name: Update Bindings
22

33
on:
44
workflow_dispatch:
5+
inputs:
6+
binding_type:
7+
description: "Which bindings do you want to update?"
8+
required: true
9+
type: choice
10+
options:
11+
- api
12+
- identity
13+
- both
14+
default: "both"
515
schedule:
6-
- cron: "0 4 * * 1" # Every Monday at 4 AM UTC
16+
# Runs every Monday at 4 AM UTC
17+
# Note: schedule triggers don't have inputs, so binding_type will be null and default to 'both'
18+
- cron: "0 4 * * 1"
719

820
permissions:
921
contents: read
@@ -14,7 +26,7 @@ env:
1426

1527
jobs:
1628
download:
17-
name: Update API Bindings
29+
name: Update Bindings
1830
runs-on: ubuntu-24.04
1931
permissions:
2032
actions: read
@@ -37,6 +49,13 @@ jobs:
3749
fetch-depth: 0
3850
persist-credentials: true
3951

52+
- name: Capture base commit
53+
id: base-commit
54+
run: |
55+
BASE_SHA=$(git rev-parse HEAD)
56+
echo "sha=$BASE_SHA" >> $GITHUB_OUTPUT
57+
echo "📌 Base commit: $BASE_SHA"
58+
4059
- name: Log in to Azure
4160
uses: bitwarden/gh-actions/azure-login@main
4261
with:
@@ -62,50 +81,7 @@ jobs:
6281
private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }}
6382
permission-pull-requests: write
6483

65-
- name: Switch to branch
66-
id: switch-branch
67-
run: |
68-
BRANCH_NAME="sdlc/api-update"
69-
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
70-
71-
if git switch $BRANCH_NAME; then
72-
echo "✅ Switched to existing branch: $BRANCH_NAME"
73-
echo "updating_existing_branch=true" >> $GITHUB_OUTPUT
74-
else
75-
echo "📝 Creating new branch: $BRANCH_NAME"
76-
git switch -c $BRANCH_NAME
77-
echo "updating_existing_branch=false" >> $GITHUB_OUTPUT
78-
fi
79-
80-
- name: Prevent updating the branch when the last committer isn't the bot
81-
if: ${{ steps.switch-branch.outputs.updating_existing_branch == 'true' }}
82-
env:
83-
_BRANCH_NAME: ${{ steps.switch-branch.outputs.branch_name }}
84-
run: |
85-
LATEST_COMMIT_AUTHOR=$(git log -1 --format='%ae' $_BRANCH_NAME)
86-
87-
echo "Latest commit author in branch ($_BRANCH_NAME): $LATEST_COMMIT_AUTHOR"
88-
echo "Expected bot email: $_BOT_EMAIL"
89-
90-
if [ "$LATEST_COMMIT_AUTHOR" != "$_BOT_EMAIL" ]; then
91-
echo "::error::Branch $_BRANCH_NAME has a commit not made by the bot." \
92-
"This indicates manual changes have been made to the branch," \
93-
"PR has to be merged or closed before running this workflow again."
94-
echo "👀 Fetching existing PR..."
95-
gh pr list --head $_BRANCH_NAME --base main --state open --json number --jq '.[0].number // empty'
96-
EXISTING_PR=$(gh pr list --head $_BRANCH_NAME --base main --state open --json number --jq '.[0].number // empty')
97-
if [ -z "$EXISTING_PR" ]; then
98-
echo "::error::Couldn't find an existing PR for branch $_BRANCH_NAME."
99-
exit 1
100-
fi
101-
PR_URL="https://github.com/${{ github.repository }}/pull/$EXISTING_PR"
102-
echo "## ❌ Merge or close: $PR_URL" >> $GITHUB_STEP_SUMMARY
103-
exit 1
104-
fi
105-
106-
echo "✅ Branch tip commit was made by the bot. Safe to proceed."
107-
108-
- name: Download json artifacts
84+
- name: Download json artifacts from server for updated bindings
10985
uses: bitwarden/gh-actions/download-artifacts@main
11086
with:
11187
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -160,57 +136,227 @@ jobs:
160136
- name: NPM setup
161137
run: npm ci
162138

139+
- name: Set Commit Info
140+
id: commit-info
141+
run: |
142+
API_HASH=$(cat ./artifacts/api.json | jq -r '.["x-git-commit"]')
143+
IDENTITY_HASH=$(cat ./artifacts/identity.json | jq -r '.["x-git-commit"]')
144+
145+
echo "API commit hash: $API_HASH"
146+
echo "Identity commit hash: $IDENTITY_HASH"
147+
148+
if [ "$API_HASH" != "$IDENTITY_HASH" ]; then
149+
echo "::error::Commit hash mismatch! API: $API_HASH, Identity: $IDENTITY_HASH"
150+
exit 1
151+
fi
152+
153+
echo "HASH=$API_HASH" >> $GITHUB_OUTPUT
154+
echo "✅ Using server commit: $API_HASH"
155+
156+
- name: Configure Git
157+
run: |
158+
git config user.name "$_BOT_NAME"
159+
git config user.email "$_BOT_EMAIL"
160+
161+
# API Bindings PR
162+
- name: Switch to API branch
163+
id: switch-api-branch
164+
if: ${{ inputs.binding_type == 'api' || inputs.binding_type == 'both' || !inputs.binding_type }}
165+
env:
166+
BRANCH_NAME: "api-bindings-update"
167+
BASE_SHA: ${{ steps.base-commit.outputs.sha }}
168+
run: |
169+
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
170+
171+
git fetch origin
172+
if git switch $BRANCH_NAME 2>/dev/null; then
173+
echo "✅ Switched to existing branch: $BRANCH_NAME"
174+
echo "updating_existing_branch=true" >> $GITHUB_OUTPUT
175+
else
176+
echo "📝 Creating new branch: $BRANCH_NAME from $BASE_SHA"
177+
git switch -c $BRANCH_NAME $BASE_SHA
178+
echo "updating_existing_branch=false" >> $GITHUB_OUTPUT
179+
fi
180+
181+
- name: Prevent updating API branch when last committer isn't the bot
182+
if: ${{ (inputs.binding_type == 'api' || inputs.binding_type == 'both' || !inputs.binding_type) && steps.switch-api-branch.outputs.updating_existing_branch == 'true' }}
183+
env:
184+
_BRANCH_NAME: ${{ steps.switch-api-branch.outputs.branch_name }}
185+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
186+
run: |
187+
LATEST_COMMIT_AUTHOR=$(git log -1 --format='%ae' $_BRANCH_NAME)
188+
189+
echo "Latest commit author in branch ($_BRANCH_NAME): $LATEST_COMMIT_AUTHOR"
190+
echo "Expected bot email: $_BOT_EMAIL"
191+
192+
if [ "$LATEST_COMMIT_AUTHOR" != "$_BOT_EMAIL" ]; then
193+
echo "::error::Branch $_BRANCH_NAME has a commit not made by the bot." \
194+
"This indicates manual changes have been made to the branch," \
195+
"PR has to be merged or closed before running this workflow again."
196+
EXISTING_PR=$(gh pr list --head $_BRANCH_NAME --base main --state open --json number --jq '.[0].number // empty')
197+
if [ -z "$EXISTING_PR" ]; then
198+
echo "::error::Couldn't find an existing PR for branch $_BRANCH_NAME."
199+
exit 1
200+
fi
201+
PR_URL="https://github.com/${{ github.repository }}/pull/$EXISTING_PR"
202+
echo "## ❌ Merge or close: $PR_URL" >> $GITHUB_STEP_SUMMARY
203+
exit 1
204+
fi
205+
206+
echo "✅ Branch tip commit was made by the bot. Safe to proceed."
207+
163208
- name: Generate API bindings
164-
run: ./support/build-api-ci.sh
209+
if: ${{ inputs.binding_type == 'api' || inputs.binding_type == 'both' || !inputs.binding_type }}
210+
run: ./support/generate-api-bindings-ci.sh
165211

166-
- name: Format
212+
- name: Format API bindings
213+
if: ${{ inputs.binding_type == 'api' || inputs.binding_type == 'both' || !inputs.binding_type }}
167214
env:
168215
RUST_NIGHTLY_TOOLCHAIN: ${{ steps.nightly-toolchain.outputs.RUST_NIGHTLY_TOOLCHAIN }}
169-
run: cargo +"${RUST_NIGHTLY_TOOLCHAIN}" fmt
216+
run: cargo +"${RUST_NIGHTLY_TOOLCHAIN}" fmt -p bitwarden-api-api
170217

171-
- name: Set Commit Info
172-
id: commit-info
218+
- name: Commit API bindings
219+
if: ${{ inputs.binding_type == 'api' || inputs.binding_type == 'both' || !inputs.binding_type }}
220+
env:
221+
_HASH: ${{ steps.commit-info.outputs.HASH }}
222+
_BRANCH_NAME: ${{ steps.switch-api-branch.outputs.branch_name }}
173223
run: |
174-
HASH=$(cat ./artifacts/identity.json | jq -r '.["x-git-commit"]')
175-
echo "HASH=$HASH" >> $GITHUB_OUTPUT
224+
echo "👀 Committing API bindings update..."
225+
git add crates/bitwarden-api-api
226+
git commit -m "Update API bindings to $_HASH" --no-verify || echo "No changes to commit for API"
227+
git push origin $_BRANCH_NAME
176228
177-
- name: Create branch and commit
229+
- name: Create or Update API Pull Request
230+
if: ${{ inputs.binding_type == 'api' || inputs.binding_type == 'both' || !inputs.binding_type }}
178231
env:
232+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
179233
_HASH: ${{ steps.commit-info.outputs.HASH }}
180-
_BRANCH_NAME: ${{ steps.switch-branch.outputs.BRANCH_NAME }}
234+
_BRANCH_NAME: ${{ steps.switch-api-branch.outputs.branch_name }}
181235
run: |
182-
echo "👀 Committing SDK version update..."
236+
PR_TITLE="Update API bindings to $_HASH"
237+
PR_BODY="Updates the API bindings to \`$_HASH\`"
183238
184-
git config user.name "$_BOT_NAME"
185-
git config user.email "$_BOT_EMAIL"
239+
# Set reviewer flag for scheduled runs
240+
if [ "${{ github.event_name }}" == "schedule" ]; then
241+
echo "🔔 Assigning team-platform-dev as reviewer for scheduled run"
242+
REVIEWER_FLAG="--reviewer bitwarden/team-platform-dev"
243+
else
244+
REVIEWER_FLAG=""
245+
fi
186246
187-
git add crates/bitwarden-api-api crates/bitwarden-api-identity
188-
git commit -m "Update API bindings - $_HASH" --no-verify
247+
EXISTING_PR=$(gh pr list --head $_BRANCH_NAME --base main --state open --json number --jq '.[0].number // empty')
248+
249+
if [ -n "$EXISTING_PR" ]; then
250+
echo "🔄 Updating existing API PR #$EXISTING_PR..."
251+
echo -e "$PR_BODY" | gh pr edit $EXISTING_PR \
252+
--title "$PR_TITLE" \
253+
--body-file -
254+
PR_URL="https://github.com/${{ github.repository }}/pull/$EXISTING_PR"
255+
echo "## ✅ Updated API PR: $PR_URL" >> $GITHUB_STEP_SUMMARY
256+
else
257+
echo "📝 Creating new API PR..."
258+
PR_URL=$(echo -e "$PR_BODY" | gh pr create \
259+
--title "$PR_TITLE" \
260+
--body-file - \
261+
--base main \
262+
--head $_BRANCH_NAME \
263+
$REVIEWER_FLAG)
264+
echo "## 🚀 Created API PR: $PR_URL" >> $GITHUB_STEP_SUMMARY
265+
fi
266+
267+
# Identity Bindings PR
268+
- name: Switch to Identity branch
269+
id: switch-identity-branch
270+
if: ${{ inputs.binding_type == 'identity' || inputs.binding_type == 'both' || !inputs.binding_type }}
271+
env:
272+
BRANCH_NAME: "identity-bindings-update"
273+
BASE_SHA: ${{ steps.base-commit.outputs.sha }}
274+
run: |
275+
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
276+
277+
git fetch origin
278+
if git switch $BRANCH_NAME 2>/dev/null; then
279+
echo "✅ Switched to existing branch: $BRANCH_NAME"
280+
echo "updating_existing_branch=true" >> $GITHUB_OUTPUT
281+
else
282+
echo "📝 Creating new branch: $BRANCH_NAME from $BASE_SHA"
283+
git switch -c $BRANCH_NAME $BASE_SHA
284+
echo "updating_existing_branch=false" >> $GITHUB_OUTPUT
285+
fi
286+
287+
- name: Prevent updating Identity branch when last committer isn't the bot
288+
if: ${{ (inputs.binding_type == 'identity' || inputs.binding_type == 'both' || !inputs.binding_type) && steps.switch-identity-branch.outputs.updating_existing_branch == 'true' }}
289+
env:
290+
_BRANCH_NAME: ${{ steps.switch-identity-branch.outputs.branch_name }}
291+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
292+
run: |
293+
LATEST_COMMIT_AUTHOR=$(git log -1 --format='%ae' $_BRANCH_NAME)
294+
295+
echo "Latest commit author in branch ($_BRANCH_NAME): $LATEST_COMMIT_AUTHOR"
296+
echo "Expected bot email: $_BOT_EMAIL"
297+
298+
if [ "$LATEST_COMMIT_AUTHOR" != "$_BOT_EMAIL" ]; then
299+
echo "::error::Branch $_BRANCH_NAME has a commit not made by the bot." \
300+
"This indicates manual changes have been made to the branch," \
301+
"PR has to be merged or closed before running this workflow again."
302+
EXISTING_PR=$(gh pr list --head $_BRANCH_NAME --base main --state open --json number --jq '.[0].number // empty')
303+
if [ -z "$EXISTING_PR" ]; then
304+
echo "::error::Couldn't find an existing PR for branch $_BRANCH_NAME."
305+
exit 1
306+
fi
307+
PR_URL="https://github.com/${{ github.repository }}/pull/$EXISTING_PR"
308+
echo "## ❌ Merge or close: $PR_URL" >> $GITHUB_STEP_SUMMARY
309+
exit 1
310+
fi
311+
312+
echo "✅ Branch tip commit was made by the bot. Safe to proceed."
313+
314+
- name: Generate Identity bindings
315+
if: ${{ inputs.binding_type == 'identity' || inputs.binding_type == 'both' || !inputs.binding_type }}
316+
run: ./support/generate-identity-bindings-ci.sh
317+
318+
- name: Format Identity bindings
319+
if: ${{ inputs.binding_type == 'identity' || inputs.binding_type == 'both' || !inputs.binding_type }}
320+
env:
321+
RUST_NIGHTLY_TOOLCHAIN: ${{ steps.nightly-toolchain.outputs.RUST_NIGHTLY_TOOLCHAIN }}
322+
run: cargo +"${RUST_NIGHTLY_TOOLCHAIN}" fmt -p bitwarden-api-identity
323+
324+
- name: Commit Identity bindings
325+
if: ${{ inputs.binding_type == 'identity' || inputs.binding_type == 'both' || !inputs.binding_type }}
326+
env:
327+
_HASH: ${{ steps.commit-info.outputs.HASH }}
328+
_BRANCH_NAME: ${{ steps.switch-identity-branch.outputs.branch_name }}
329+
run: |
330+
echo "👀 Committing Identity bindings update..."
331+
git add crates/bitwarden-api-identity
332+
git commit -m "Update Identity bindings to $_HASH" --no-verify || echo "No changes to commit for Identity"
189333
git push origin $_BRANCH_NAME
190334
191-
- name: Create or Update Pull Request
335+
- name: Create or Update Identity Pull Request
336+
if: ${{ inputs.binding_type == 'identity' || inputs.binding_type == 'both' || !inputs.binding_type }}
192337
env:
193338
GH_TOKEN: ${{ steps.app-token.outputs.token }}
194339
_HASH: ${{ steps.commit-info.outputs.HASH }}
195-
_BRANCH_NAME: ${{ steps.switch-branch.outputs.BRANCH_NAME }}
340+
_BRANCH_NAME: ${{ steps.switch-identity-branch.outputs.branch_name }}
196341
run: |
197-
PR_BODY="Updates the API bindings to \`$_HASH\`"
342+
PR_TITLE="Update Identity bindings to $_HASH"
343+
PR_BODY="Updates the Identity bindings to \`$_HASH\`"
198344
199345
EXISTING_PR=$(gh pr list --head $_BRANCH_NAME --base main --state open --json number --jq '.[0].number // empty')
200346
201347
if [ -n "$EXISTING_PR" ]; then
202-
echo "🔄 Updating existing PR #$EXISTING_PR..."
348+
echo "🔄 Updating existing Identity PR #$EXISTING_PR..."
203349
echo -e "$PR_BODY" | gh pr edit $EXISTING_PR \
204-
--title "Update API to $_HASH" \
350+
--title "$PR_TITLE" \
205351
--body-file -
206352
PR_URL="https://github.com/${{ github.repository }}/pull/$EXISTING_PR"
207-
echo "## ✅ Updated PR: $PR_URL" >> $GITHUB_STEP_SUMMARY
353+
echo "## ✅ Updated Identity PR: $PR_URL" >> $GITHUB_STEP_SUMMARY
208354
else
209-
echo "📝 Creating new PR..."
355+
echo "📝 Creating new Identity PR..."
210356
PR_URL=$(echo -e "$PR_BODY" | gh pr create \
211-
--title "Update API to $_HASH" \
357+
--title "$PR_TITLE" \
212358
--body-file - \
213359
--base main \
214360
--head $_BRANCH_NAME)
215-
echo "## 🚀 Created PR: $PR_URL" >> $GITHUB_STEP_SUMMARY
361+
echo "## 🚀 Created Identity PR: $PR_URL" >> $GITHUB_STEP_SUMMARY
216362
fi

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,11 @@ There are two ways to run the workflow:
159159

160160
1. Manually run the `Update API Bindings`
161161
[workflow](https://github.com/bitwarden/sdk-internal/actions/workflows/update-api-bindings.yml)
162-
in the `sdk-internal` repo.
163-
2. Wait for an automatic binding update to run, which is scheduled every 2 weeks.
162+
in the `sdk-internal` repo. You can choose whether to update the bindings for the API, Identity,
163+
or both. You will likely only need to update the API bindings for the majority of changes.
164164

165-
Both of these will generate a PR that will require approval from any teams whose owned code is
166-
affected by the binding updates.
165+
2. Wait for an automatic binding update to run, which is scheduled every 2 weeks. This update will
166+
generate bindings for both API and Identity and create two PRs.
167167

168168
A suggested workflow for incorporating server API changes into the SDK would be:
169169

0 commit comments

Comments
 (0)