Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 6 additions & 3 deletions .buildkite/download-xcframework.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

set -euo pipefail

echo "--- :arrow_down: Downloading xcframework"
echo "--- :arrow_down: Downloading XCFramework"
buildkite-agent artifact download target/libwordpressFFI.xcframework.zip . --step "xcframework"
buildkite-agent artifact download 'native/swift/Sources/wordpress-api-wrapper/*.swift' . --step "xcframework"
unzip target/libwordpressFFI.xcframework.zip -d .
mkdir -p ./target/
unzip target/libwordpressFFI.xcframework.zip -d ./target/
rm target/libwordpressFFI.xcframework.zip

echo "--- :arrow_down: Downloading Native WordPress API Wrapper"
buildkite-agent artifact download 'native/swift/Sources/wordpress-api-wrapper/*.swift' . --step "xcframework"
15 changes: 12 additions & 3 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,21 @@ steps:
echo "--- :package: Installing Rust Toolchains"
make setup-rust

echo "--- :swift: Building xcframework"
make xcframework
zip -r target/libwordpressFFI.xcframework.zip target/libwordpressFFI.xcframework
echo "--- :ruby: Installing Ruby tools"
install_gems
echo "--- :xcode: Setting up code signing"
bundle exec fastlane set_up_signing_release

echo "--- :swift: Building XCFramework"
make xcframework-package
make xcframework-package-checksum
make xcframework-sign

artifact_paths:
- target/libwordpressFFI.xcframework.zip
- target/libwordpressFFI.xcframework.zip.checksum.txt
- native/swift/Sources/wordpress-api-wrapper/*.swift
plugins: [$CI_TOOLKIT]
agents:
queue: mac
- label: ":swift: Build Docs"
Expand Down
4 changes: 4 additions & 0 deletions .buildkite/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ make setup-rust
echo "--- :rubygems: Setting up Gems"
install_gems

echo "--- :closed_lock_with_key: Setting up Code Signing"
bundle exec fastlane set_up_signing_release

echo "--- :rust: Building XCFramework"
make xcframework-package
make xcframework-package-checksum
make xcframework-sign

release_version="$1"
echo "--- :rocket: Publish release $release_version"
Expand Down
11 changes: 8 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ swift_package_platform_ios = $(call swift_package_platform_version,ios)
swift_package_platform_watchos = $(call swift_package_platform_version,watchos)
swift_package_platform_tvos = $(call swift_package_platform_version,tvos)

certificate_name_release = Apple Distribution: Automattic, Inc. (PZYM8XX95Q)

# Required for supporting tvOS and watchOS. We can update the nightly toolchain version if needed.
rust_nightly_toolchain := nightly-2025-07-29

Expand Down Expand Up @@ -131,11 +133,14 @@ xcframework: xcframework-all
endif

xcframework-package: xcframework-all
rm -rf libwordpressFFI.xcframework.zip
ditto -c -k --sequesterRsrc --keepParent target/libwordpressFFI.xcframework/ libwordpressFFI.xcframework.zip
rm -rf target/libwordpressFFI.xcframework.zip
ditto -c -k --sequesterRsrc --keepParent target/libwordpressFFI.xcframework/ target/libwordpressFFI.xcframework.zip

xcframework-package-checksum:
swift package compute-checksum libwordpressFFI.xcframework.zip | tee libwordpressFFI.xcframework.zip.checksum.txt
swift package compute-checksum target/libwordpressFFI.xcframework.zip | tee libwordpressFFI.xcframework.zip.checksum.txt

xcframework-sign:
codesign --timestamp -v --sign "${certificate_name_release}" target/libwordpressFFI.xcframework
Copy link
Contributor

Choose a reason for hiding this comment

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


docker-image-web:
docker build -t wordpress-rs-web -f wp_rs_web/Dockerfile . --progress=plain
Expand Down
82 changes: 79 additions & 3 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ PROJECT_NAME = 'wordpress-rs'
# GlotPress configuration
GLOTPRESS_PROJECT_BASE_URL = 'https://translate.wordpress.com/projects/mobile/wordpress-rs'

# Code Signing
APPLE_TEAM_ID = 'PZYM8XX95Q'

ASC_API_KEY_ENV_VARS = %w[
APP_STORE_CONNECT_API_KEY_KEY_ID
APP_STORE_CONNECT_API_KEY_ISSUER_ID
APP_STORE_CONNECT_API_KEY_KEY
].freeze

CODE_SIGNING_STORAGE_ENV_VARS = %w[
MATCH_S3_ACCESS_KEY
MATCH_S3_SECRET_ACCESS_KEY
].freeze

# Supported locales mapping between GlotPress and project locale codes
# This list combines locales supported in the iOS and Android apps
SUPPORTED_LOCALES = [
Expand Down Expand Up @@ -81,6 +95,11 @@ SUPPORTED_LOCALES = [
{ glotpress: 'zh-tw', project: 'zh-TW' }
].freeze

before_all do
# Fixes issues with keychain in CI
setup_ci
end

lane :release do |options|
version = options[:version] || UI.user_error!('version is required')
lane_context[LANE_VALUE_VERSION] = version
Expand All @@ -90,7 +109,7 @@ lane :release do |options|

validate
update_swift_package
publish_github_release
publish_release_to_github
publish_to_s3
end

Expand Down Expand Up @@ -124,7 +143,7 @@ lane :update_swift_package do
File.open(file_path, 'w') { |file| file.puts lines }
end

lane :publish_github_release do
lane :publish_release_to_github do
version = lane_context[LANE_VALUE_VERSION] || UI.user_error!('Missing version lane context')
github_token = lane_context[LANE_VALUE_GITHUB_TOKEN] || UI.user_error!('Missing github token lane context')

Expand Down Expand Up @@ -232,7 +251,7 @@ lane :download_translations do |commit_changes: false|
updated_fluent_files = []

if downloaded_files.empty?
UI.message("No .po files were downloaded from GlotPress")
UI.message('No .po files were downloaded from GlotPress')
next
end

Expand Down Expand Up @@ -396,6 +415,22 @@ lane :generate_fluent_file_from_po do |file_path:|
fluent_file_path
end

desc 'Downloads all code signing certificates'
lane :set_up_signing do |readonly: true|
set_up_signing_development(readonly: readonly)
set_up_signing_release(readonly: readonly)
end

desc 'Download the development signing certificates to this machine'
lane :set_up_signing_development do |readonly: true|
set_up_certificate_in_keychain(type: 'development', readonly: readonly)
end

desc 'Download the release (distribution) signing certificates to this machine'
lane :set_up_signing_release do |readonly: true|
set_up_certificate_in_keychain(type: 'appstore', readonly: readonly)
end

# Utils

def xcframework_checksum
Expand Down Expand Up @@ -463,3 +498,44 @@ def only_date_headers_changed?(file_path)

changed_lines.all? { |l| l.include?('"POT-Creation-Date:') || l.include?('"PO-Revision-Date:') }
end

# Use this to ensure all env vars a lane requires are set.
#
# The best place to call this is at the start of a lane, to fail early.
def require_env_vars!(*keys)
keys.each { |key| get_required_env!(key) }
end

# Use this instead of getting values from `ENV` directly. It will throw an error if the requested value is missing.
def get_required_env!(key)
return ENV.fetch(key) if ENV.key?(key)

UI.user_error!("Environment variable `#{key}` is not set.")
end

def set_up_certificate_in_keychain(type:, readonly:)
require_env_vars!(*ASC_API_KEY_ENV_VARS, *CODE_SIGNING_STORAGE_ENV_VARS)

# This will fetch the certificate and provisioning profile for the given type from remote storage.
# It will then set them up in the local keychain, where 'codesign' looks for identities.
#
# Notice we do not need the provisioning profile because we sign with 'codesign' elsewhere.
# However, there is no other way to set up the certificate in the keychain.
# Fastlane offers a tool called cert, but it only downloads certificates.
sync_code_signing(
team_id: APPLE_TEAM_ID,
api_key: app_store_connect_api_key,
type: type,
storage_mode: 's3',
s3_region: 'us-east-2',
s3_bucket: 'a8c-fastlane-match',
readonly: readonly,
# We need to provide an app identifier, but remember we only care about the certificate that gets downloaded.
# The identifier is used to find a provisioning profile, but we don't care about it.
#
# Similar rationale for the platform argument,
# with the addition that it's required to identify the existing provisioning profile for the given app id.
app_identifier: 'com.automattic.hostmgr',
platform: 'macos'
)
end