workflow, fastlane: upload release artifacts new bucket (#9410)

* workflow, fastlane: upload release artifacts new bucket

Update release workflows and fastlane to support uploading release
artifacts to both buckets (current and new) at the same time. It'll
happen during a specific period for validaation / testing phase.

* workflows: adjust permissions to use oidc

* fastfile: only upload to new bucket in release

* workflow, fastlane: add new upload_s3 lane for fastlane
This commit is contained in:
Nuno Simões 2026-02-03 09:26:34 +01:00 committed by GitHub
parent 462d6d5052
commit 83e5b6026e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 175 additions and 9 deletions

View file

@ -24,6 +24,9 @@ jobs:
runs-on: ubuntu-22.04
needs:
- test
permissions:
id-token: write
contents: read
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@ -58,3 +61,21 @@ jobs:
with:
name: android-build-beta-${{ github.run_id }}
path: "*.apk"
# New AWS bucket deployment steps
- name: Configure AWS credentials new bucket
id: configure-aws-credentials-new-bucket
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
with:
aws-region: us-east-1
role-to-assume: ${{ secrets.MM_MOBILE_RELEASE_AWS_ROLE_TO_ASSUME }}
- name: ci/upload-android-beta-new-bucket
env:
AWS_NEW_BUCKET_NAME: "${{ secrets.MM_MOBILE_RELEASE_AWS_NEW_BUCKET_NAME }}"
MATTERMOST_WEBHOOK_URL: "${{ secrets.MM_MOBILE_BETA_MATTERMOST_WEBHOOK_URL }}"
run: |
echo "::group::Upload to new S3 bucket"
bundle exec fastlane android upload_artifacts_to_s3 --env android.beta
echo "::endgroup::"
working-directory: ./fastlane

View file

@ -24,6 +24,9 @@ jobs:
runs-on: ubuntu-22.04
needs:
- test
permissions:
id-token: write
contents: read
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@ -58,3 +61,19 @@ jobs:
with:
name: android-build-release-${{ github.run_id }}
path: "*.apk"
- name: Configure AWS credentials new bucket
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
with:
aws-region: us-east-1
role-to-assume: ${{ secrets.MM_MOBILE_RELEASE_AWS_ROLE_TO_ASSUME }}
- name: ci/upload-android-release-new-bucket
env:
AWS_NEW_BUCKET_NAME: "${{ secrets.MM_MOBILE_RELEASE_AWS_NEW_BUCKET_NAME }}"
MATTERMOST_WEBHOOK_URL: "${{ secrets.MM_MOBILE_RELEASE_MATTERMOST_WEBHOOK_URL }}"
run: |
echo "::group::Upload to new S3 bucket"
bundle exec fastlane android upload_artifacts_to_s3 --env android.release
echo "::endgroup::"
working-directory: ./fastlane

View file

@ -53,11 +53,30 @@ jobs:
name: ios-build-simulator-${{ github.run_id }}
path: Mattermost-simulator-x86_64.app.zip
# Logic for new bucket upload
- name: Configure AWS credentials new bucket
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
with:
aws-region: us-east-1
role-to-assume: ${{ secrets.MM_MOBILE_RELEASE_AWS_ROLE_TO_ASSUME }}
- name: ci/upload-ios-simulator-new-bucket
env:
TAG: "${{ github.ref_name }}"
AWS_NEW_BUCKET_NAME: "${{ secrets.MM_MOBILE_RELEASE_AWS_NEW_BUCKET_NAME }}"
MATTERMOST_WEBHOOK_URL: "${{ secrets.MM_MOBILE_BETA_MATTERMOST_WEBHOOK_URL }}"
GITHUB_TOKEN: "${{ secrets.MM_MOBILE_GITHUB_TOKEN }}"
run: bundle exec fastlane ios upload_artifacts_to_s3 --env ios.simulator output_file:"Mattermost-simulator-x86_64.app.zip"
working-directory: ./fastlane
build-and-deploy-ios-beta:
runs-on: macos-15-large
if: ${{ !contains(github.ref_name, 'beta-sim') }}
needs:
- test
permissions:
id-token: write
contents: read
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@ -100,3 +119,20 @@ jobs:
with:
name: ios-build-beta-${{ github.run_id }}
path: "*.ipa"
# Logic for new bucket upload
- name: Configure AWS credentials new bucket
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
with:
aws-region: us-east-1
role-to-assume: ${{ secrets.MM_MOBILE_RELEASE_AWS_ROLE_TO_ASSUME }}
- name: ci/upload-ios-beta-new-bucket
env:
AWS_NEW_BUCKET_NAME: "${{ secrets.MM_MOBILE_RELEASE_AWS_NEW_BUCKET_NAME }}"
MATTERMOST_WEBHOOK_URL: "${{ secrets.MM_MOBILE_BETA_MATTERMOST_WEBHOOK_URL }}"
run: |
echo "::group::Upload to new S3 bucket"
bundle exec fastlane ios upload_artifacts_to_s3 --env ios.beta
echo "::endgroup::"
working-directory: ./fastlane

View file

@ -27,6 +27,9 @@ jobs:
if: ${{ !contains(github.ref_name, 'release-sim') }}
needs:
- test
permissions:
id-token: write
contents: read
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@ -46,6 +49,7 @@ jobs:
env:
AWS_ACCESS_KEY_ID: "${{ secrets.MM_MOBILE_RELEASE_AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.MM_MOBILE_RELEASE_AWS_SECRET_ACCESS_KEY }}"
AWS_NEW_BUCKET_NAME: "${{ secrets.MM_MOBILE_RELEASE_AWS_NEW_BUCKET_NAME }}"
MATTERMOST_WEBHOOK_URL: "${{ secrets.MM_MOBILE_RELEASE_MATTERMOST_WEBHOOK_URL }}"
FASTLANE_TEAM_ID: "${{ secrets.MM_MOBILE_FASTLANE_TEAM_ID }}"
IOS_API_ISSUER_ID: "${{ secrets.MM_MOBILE_IOS_API_ISSUER_ID }}"
@ -70,6 +74,23 @@ jobs:
name: ios-build-release-${{ github.run_id }}
path: "*.ipa"
# Upload artifacts to new bucket
- name: Configure AWS credentials new bucket
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
with:
aws-region: us-east-1
role-to-assume: ${{ secrets.MM_MOBILE_RELEASE_AWS_ROLE_TO_ASSUME }}
- name: ci/upload-ios-release-to-new-bucket
env:
AWS_NEW_BUCKET_NAME: "${{ secrets.MM_MOBILE_RELEASE_AWS_NEW_BUCKET_NAME }}"
MATTERMOST_WEBHOOK_URL: "${{ secrets.MM_MOBILE_RELEASE_MATTERMOST_WEBHOOK_URL }}"
run: |
echo "::group::Build"
bundle exec fastlane ios upload_artifacts_to_s3 --env ios.release
echo "::endgroup::"
working-directory: ./fastlane
build-ios-simulator:
runs-on: macos-15-large
if: ${{ !contains(github.ref_name , 'release-ios') }}
@ -100,3 +121,18 @@ jobs:
with:
name: ios-build-simulator-${{ github.run_id }}
path: Mattermost-simulator-x86_64.app.zip
# Logic for new bucket upload
- name: Configure AWS credentials new bucket
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
with:
aws-region: us-east-1
role-to-assume: ${{ secrets.MM_MOBILE_RELEASE_AWS_ROLE_TO_ASSUME }}
- name: ci/upload-ios-simulator-new-bucket
env:
TAG: "${{ github.ref_name }}"
AWS_NEW_BUCKET_NAME: "${{ secrets.MM_MOBILE_BETA_AWS_NEW_BUCKET_NAME }}"
MATTERMOST_WEBHOOK_URL: "${{ secrets.MM_MOBILE_BETA_MATTERMOST_WEBHOOK_URL }}"
run: bundle exec fastlane ios simulator --env ios.simulator output_file:"Mattermost-simulator-x86_64.app.zip"
working-directory: ./fastlane

View file

@ -224,12 +224,19 @@ lane :link_sentry do |options|
end
end
# Uploads built files to S3
# It's currently uploading to two different buckets depending on the
# enable_s3_new_bucket option.
# Default, uploads to the legacy bucket using static credentials (AWS_BUCKET_NAME).
# To upload to the new bucket AWS_NEW_BUCKET_NAME (using IAM/OIDC), pass :enable_s3_new_bucket => true in options.
# Example: upload_file_to_s3({:os_type => "ios", :enable_s3_new_bucket => true})
desc 'Upload file to s3'
lane :upload_file_to_s3 do |options|
os_type = options[:os_type].downcase
extensions = os_type == "android" ? ["*.apk", "*.aab"] : ["*.ipa"]
build_folder_path = Dir[File.expand_path('..')].first
files = []
enable_s3_new_bucket = options[:enable_s3_new_bucket] == true
unless options[:file].nil? || options[:file].empty?
files.push("#{build_folder_path}/#{options[:file]}")
@ -259,6 +266,8 @@ lane :upload_file_to_s3 do |options|
s3_region = ENV['AWS_REGION']
s3_bucket_name = ENV['AWS_BUCKET_NAME']
s3_new_bucket_name = ENV['AWS_NEW_BUCKET_NAME']
bucket_name = enable_s3_new_bucket ? s3_new_bucket_name : s3_bucket_name
if is_build_pr
# Get the current git commit SHA (short version)
@ -267,8 +276,18 @@ lane :upload_file_to_s3 do |options|
else
s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
end
if enable_s3_new_bucket
# Client for new bucket assumes role via GitHub Actions OIDC
s3_client = Aws::S3::Client.new(region: s3_region)
UI.message("Set S3 Client to upload to new S3 bucket")
else
s3_client = Aws::S3::Client.new(
region: s3_region,
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
)
UI.message("Set S3 Client to upload to existing S3 bucket: #{s3_bucket_name}")
end
transfer_manager = Aws::S3::TransferManager.new(client: s3_client)
mutex = Mutex.new
threads = []
@ -288,7 +307,8 @@ lane :upload_file_to_s3 do |options|
filename = File.basename(file)
puts "[#{Thread.current["file_number"]}/#{total_files}] #{filename} uploading..."
s3_key = "#{s3_folder}/#{filename}"
transfer_manager.upload_file(file, bucket: s3_bucket_name, key: s3_key)
transfer_manager.upload_file(file, bucket: bucket_name, key: s3_key)
# Keep s3_bucket_name to support both buckets.
links.push("https://#{s3_bucket_name}/#{s3_key}")
end
}
@ -304,7 +324,7 @@ lane :upload_file_to_s3 do |options|
plist_body = ERB.new(plist_template).result(binding)
s3_client.put_object(
bucket: s3_bucket_name,
bucket: bucket_name,
key: "#{s3_folder}/#{plist_file}",
body: plist_body,
content_type: 'application/xml'
@ -313,13 +333,15 @@ lane :upload_file_to_s3 do |options|
install_url = "itms-services://?action=download-manifest&url=https://#{s3_bucket_name}/#{s3_folder}/#{plist_file}"
end
if enable_s3_new_bucket == false
qa_build_message({
:os_type => os_type,
:install_url => install_url
})
end
end
if options[:file]&.start_with?('Mattermost-simulator-') && options[:file]&.end_with?('.app.zip')
if options[:file]&.start_with?('Mattermost-simulator-') && options[:file]&.end_with?('.app.zip') && enable_s3_new_bucket == false
pretext = '#### New iOS build for VM/Simulator'
msg = "Download link: #{links.first}"
send_message_to_mattermost({
@ -445,6 +467,28 @@ platform :ios do
})
end
desc 'Upload artifacts to S3'
lane :upload_artifacts_to_s3 do |options|
output_file = options[:output_file]
UI.message("Uploading to new S3 bucket..." + (output_file ? " file: #{output_file}" : ""))
begin
if output_file && !output_file.empty?
upload_file_to_s3({
:os_type => "ios",
:file => output_file,
:enable_s3_new_bucket => true
})
else
upload_file_to_s3({
:os_type => "ios",
:enable_s3_new_bucket => true
})
end
rescue SyntaxError, StandardError
UI.error("Failed to upload to new S3 bucket")
end
end
lane :update_settings do
# Configure Main app settings
app_name = ENV['APP_NAME'] || 'Mattermost Beta'
@ -793,6 +837,16 @@ platform :android do
sh "mv #{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]} #{Pathname.new(File.expand_path(File.dirname(__FILE__))).parent.to_s}/Mattermost-unsigned.apk"
end
desc 'Upload artifacts to S3'
lane :upload_artifacts_to_s3 do
UI.message("Uploading to new S3 bucket...")
begin
upload_file_to_s3({:os_type => "android", :enable_s3_new_bucket => true})
rescue SyntaxError, StandardError
UI.error("Failed to upload to new S3 bucket")
end
end
lane :update_identifiers do
# Set the name for the app
app_name = ENV['APP_NAME'] || 'Mattermost Beta'