Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DEVOPS-1525] swift workflow for package publishing #268

Closed
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
378e04d
Add initial workflow
mimartin12 Sep 18, 2023
db8517b
Merge branch 'master' into DEVOPS-1525-swift-workflow-for-package-pub…
mimartin12 Oct 5, 2023
c9ecd14
prettier
mimartin12 Oct 5, 2023
a6a7b0c
Merge branch 'master' into DEVOPS-1525-swift-workflow-for-package-pub…
mimartin12 Oct 9, 2023
7abb657
Push changed files to sdk-swift on release
mimartin12 Oct 9, 2023
10666d5
Linting
mimartin12 Oct 9, 2023
adfcdf2
Use stable commit
mimartin12 Oct 19, 2023
962590b
Switch to bash script
mimartin12 Oct 23, 2023
b23e9aa
Add back in trigger for testing
mimartin12 Oct 23, 2023
35a251a
Update path for build.sh
mimartin12 Oct 23, 2023
6092c9a
Add artifact upload
mimartin12 Oct 24, 2023
04d6f06
Add branch, along with commit sha
mimartin12 Oct 24, 2023
6bb7087
Remove trigger filter
mimartin12 Oct 27, 2023
2b55e24
Update package.swift with url and update tag
mimartin12 Oct 30, 2023
09da1bd
Refactor release swift workflow
mimartin12 Apr 16, 2024
3ea7b7c
Switch back to hotfix-rc
mimartin12 Apr 16, 2024
3dc5f12
Fix SHA
mimartin12 Apr 16, 2024
8ebc7a7
Use step to get short sha
mimartin12 Apr 16, 2024
f8bc51e
Merge branch 'main' into DEVOPS-1525-swift-workflow-for-package-publi…
mimartin12 Apr 16, 2024
49ad024
Pull version from bws
mimartin12 Apr 17, 2024
3d799a5
Update install rust step
mimartin12 Apr 17, 2024
4327e76
Apply suggestions from code review
mimartin12 Apr 24, 2024
e336370
Update .github/workflows/build-swift.yml
mimartin12 Apr 24, 2024
a15a57a
Automatically push main commits to sdk-swift
mimartin12 Apr 30, 2024
1e1294d
Linting
mimartin12 Apr 30, 2024
86d4d72
Remove unneeded permission set
mimartin12 Jun 6, 2024
a57b82f
Merge branch 'main' into DEVOPS-1525-swift-workflow-for-package-publi…
mimartin12 Jun 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions .github/workflows/build-swift.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
---
name: Build Swift Package

on:
push:
branches:
- "rc"
- "hotfix-rc-swift"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about master? We currently don't "release" the swift sdk so the pressing concern is to get master snapshots automated since we have to do those manually currently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was having a discussion around that in slack, in the CloudOps channel. I want to figure this out as well.

For all GitHub release artifacts, those will need to be sourced from the deployment branch. Which is rc or hotifx-rc-swift. GitHub release artifacts have to come from a tag, and then we create a GitHub release with the artifact attached.

To get master builds into a public place to source them in package.swift. Those would be stored in an Azure storage account.

Or if the idea was to release straight from master automatically, and have every build be a "GitHub Release" we can go that route for hosting the artifact.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want every merge into master to be a new release.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My request / feedback in Slack was to get full releases working first with all this, then to look at what master artifacts look like (perhaps in parallel). I understand the GitHub release is noisy for every merge and that's not the path, but I want to keep our maintenance burden as low as possible since GitHub Packages doesn't exist for Swift.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so releases from merges into master isn't the way we want to go.

Do either of you all like the route of rc or hotfix/hotfix-rc as the release branch, just like how it's currently structured in the workflow?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming the need to get artifacts for every master merge is unneeded at the moment, I like the unification of process of using rc or similar to prep and ship a release with artifacts.

Copy link
Member

@Hinton Hinton Nov 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our requirement today is snapshot releases. I.e. commits on master. We don't have any needs or plans on publishing stable releases for the swift SDK for a fairly long time.

paths:
- "languages/swift/**"
mimartin12 marked this conversation as resolved.
Show resolved Hide resolved

jobs:
version:
name: Get Version
runs-on: ubuntu-22.04
outputs:
package_version: ${{ steps.retrieve-version.outputs.package_version }}
steps:
- name: Checkout repo
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0

- name: Get Package Version
id: retrieve-version
run: |
VERSION=$(grep -o '^version = ".*"' crates/bitwarden/Cargo.toml | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+")
echo "package_version=$VERSION" >> $GITHUB_OUTPUT

build:
runs-on: macos-13
mimartin12 marked this conversation as resolved.
Show resolved Hide resolved
strategy:
fail-fast: false
matrix:
settings:
- target: aarch64-apple-ios-sim
- target: aarch64-apple-ios
- target: x86_64-apple-ios
steps:
- name: Checkout repo
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0

- name: Install rust
uses: dtolnay/rust-toolchain@5cb429dd810e16ff67df78472fa81cf760f4d1c0 # stable
with:
toolchain: 1.70.0

- name: Cache cargo registry
uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2.7.0
with:
key: ${{ matrix.settings.target }}-cargo

- name: Rustup target
run: rustup target install ${{ matrix.settings.target }}

- name: Build native library
env:
IPHONEOS_DEPLOYMENT_TARGET: 13.0
RUSTFLAGS: "-C link-arg=-Wl,-application_extension"
run: cargo build --package bitwarden-uniffi --target ${{ matrix.settings.target }} --release
working-directory: languages/swift

- name: Upload libbitwarden_uniffi.a artifact
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: libbitwarden_uniffi.a-${{ matrix.settings.target }}
path: ./target/${{ matrix.settings.target }}/release/libbitwarden_uniffi.a
if-no-files-found: error

- name: Upload libbitwarden_uniffi.dylib artifact
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: libbitwarden_uniffi.dylib-${{ matrix.settings.target }}
path: ./target/${{ matrix.settings.target }}/release/libbitwarden_uniffi.dylib
if-no-files-found: error

package:
name: Package
runs-on: macos-13
needs:
- build
- version
env:
_PKG_VERSION: ${{ needs.version.outputs.package_version }}
steps:
- name: Checkout repo
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0

- name: Install rust
uses: dtolnay/rust-toolchain@5cb429dd810e16ff67df78472fa81cf760f4d1c0 # stable
with:
toolchain: 1.70.0
mimartin12 marked this conversation as resolved.
Show resolved Hide resolved

- name: Cache cargo registry
uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2.7.0
with:
key: cargo-combine-cache

- name: Download artifacts
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
path: ./languages/swift/target

- name: Create universal libraries
working-directory: ./languages/swift
run: |
mkdir -p ${{ github.workspace }}/universal-ios-sim/release
lipo -create -output ${{ github.workspace }}/universal-ios-sim/release/libbitwarden_uniffi.a \
./target/libbitwarden_uniffi.a-aarch64-apple-ios-sim/libbitwarden_uniffi.a \
./target/libbitwarden_uniffi.a-x86_64-apple-ios/libbitwarden_uniffi.a

- name: Generate Swift bindings
working-directory: ./languages/swift
run: |
cargo run -p uniffi-bindgen generate \
./target/libbitwarden_uniffi.dylib-aarch64-apple-ios-sim/libbitwarden_uniffi.dylib \
--library \
--language swift \
--no-format \
--out-dir ./bindings

- name: Fit bindings for xcframework
working-directory: ./languages/swift
run: |
mkdir ./Headers
mv ./bindings/BitwardenFFI.h ./Headers/
mv ./bindings/BitwardenCoreFFI.h ./Headers/
cat ./bindings/BitwardenFFI.modulemap ./bindings/BitwardenCoreFFI.modulemap > ./Headers/module.modulemap

- name: Build xcframework
working-directory: ./languages/swift
run: |
xcodebuild -create-xcframework \
-library ./target/libbitwarden_uniffi.a-aarch64-apple-ios/libbitwarden_uniffi.a \
-headers ./Headers \
-library ${{ github.workspace }}/universal-ios-sim/release/libbitwarden_uniffi.a \
-headers ./Headers \
-output ./BitwardenFFI.xcframework
mimartin12 marked this conversation as resolved.
Show resolved Hide resolved

- name: Upload xcframework artifact
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: BitwardenFFI-${{ env._PKG_VERSION }}.xcframework
path: ./languages/swift/BitwardenFFI.xcframework
if-no-files-found: error
148 changes: 148 additions & 0 deletions .github/workflows/release-swift.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
name: Release Swift Package
run-name: Release Swift Package ${{ inputs.release_type }}

on:
workflow_dispatch:
inputs:
release_type:
description: "Release Options"
required: true
default: "Initial Release"
type: choice
options:
- Initial Release
- Redeploy
- Dry Run

jobs:
validate:
name: Validate Branch - Set Version
runs-on: ubuntu-22.04
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repo
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0

- name: Branch check
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
mimartin12 marked this conversation as resolved.
Show resolved Hide resolved
run: |
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc-swift" ]]; then
echo "==================================="
echo "[!] Can only release from the 'rc' or 'hotfix-rc-cli' branches"
echo "==================================="
exit 1
fi

- name: Get version
id: version
run: |
VERSION=$(grep -o '^version = ".*"' crates/bitwarden/Cargo.toml | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+")
echo "version=$VERSION" >> $GITHUB_OUTPUT

github-release:
name: GitHub Release
runs-on: ubuntu-22.04
needs: validate
env:
_PKG_VERSION: ${{ needs.validate.outputs.version }}
steps:
- name: Download BitwardenEFI artifact
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-swift.yml
artifacts: BitwardenFFI-${{ env._PKG_VERSION }}.xcframework
path: packages
workflow_conclusion: success
branch: ${{ github.event.inputs.release_type == 'Dry Run' && 'master' || github.ref_name }}

- name: Create release
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: ncipollo/release-action@6c75be85e571768fa31b40abf38de58ba0397db5 # v1.13.0
with:
artifacts: "packages/BitwardenFFI-${{ env._PKG_VERSION }}.xcframework"
commit: ${{ github.sha }}
tag: BitwardenFFI-v${{ env._PKG_VERSION }}
name: BitwardenFFI v${{ env._PKG_VERSION }}
body: "<insert release notes here>"
token: ${{ secrets.GITHUB_TOKEN }}
draft: true

repo-sync:
name: Push changed files to SDK Swift repo
runs-on: ubuntu-22.04
needs: validate
env:
_KEY_VAULT: "bitwarden-ci"
_BOT_EMAIL: 106330231+bitwarden-devops-bot@users.noreply.github.com
_BOT_NAME: bitwarden-devops-bot
_PKG_VERSION: ${{ needs.validate.outputs.version }}
steps:
- name: Checkout SDK repo
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
with:
path: sdk

- name: Checkout SDK-Swift repo
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
with:
repository: bitwarden/sdk-swift
path: sdk-swift
ref: main

- name: Login to Azure - Prod Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_CI_SERVICE_PRINCIPAL }}

- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: ${{ env._KEY_VAULT }}
secrets: "github-pat-bitwarden-devops-bot-repo-scope"

- name: Setup Git
working-directory: sdk-swift
run: |
git config --local user.email "${{ env._BOT_EMAIL }}"
git config --local user.name "${{ env._BOT_NAME }}"

- name: Update files
run: |
cp --verbose -rf sdk/languages/swift/README.md sdk-swift/README.md
cp --verbose -rf sdk/languages/swift/Package.swift sdk-swift/Package.swift
mimartin12 marked this conversation as resolved.
Show resolved Hide resolved
cp --verbose -rf sdk/languages/swift/Sources sdk-swift/Sources
cp --verbose -rf sdk/languages/swift/Tests sdk-swift/Tests

- name: Push changes
working-directory: sdk-swift
run: |
git add .
git commit -m "Update Swift SDK to ${{ github.sha }}"

if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then
mimartin12 marked this conversation as resolved.
Show resolved Hide resolved
echo "==================================="
echo "[!] Dry Run - Skipping push"
echo "==================================="
git ls-files -m
exit 0
else
git push origin main
fi

- name: Create release tag on SDK Swift repo
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
mimartin12 marked this conversation as resolved.
Show resolved Hide resolved
working-directory: sdk-swift
run: |
# Check if tag exists, set output then exit 0 if true.
if git log v${{ env._PKG_VERSION }} >/dev/null 2>&1; then
echo "==================================="
echo "[!] Tag v${{ env._PKG_VERSION }} already exists"
echo "==================================="
exit 1
fi

git tag v${{ env._PKG_VERSION }}
git push origin v${{ env._PKG_VERSION }}