Some time ago, the company reconstructed a Flutter project, and Jenkins was used for automatic packaging. During this process, the page encountered some problems, so I wrote an article to save us some detours. Take a look at the finished package:

  • IOS needs a separate Mac for packaging, because It requires Xcode, and Docker does not have Xcode environment
  • Android is best packaged on this Mac, too, because you’ll have problems reading and writing files if you want to use Docker
  • Build the Flutter development environment
  • Ensure that local packaging is successful. For details about local packaging, see iOS and Android

Jenkins environment Configuration

1. Install the JRE environment

Jenkins runs on the Java environment. If Jenkins is not installed, please download and install it on the official website

2. Install the Jenkins

By default, Jenkins will be installed in the /Users/Shared directory. You will encounter permissions when packing, so we strongly recommend using Brew to install Jenkins.

  1. Install Jenkins

    brew install jenkins

  2. Command line to start Jenkins

    java -jar /usr/local/Cellar/jenkins/${your Jenkins version}/ libexec/Jenkins. War -- -- httpPort = 8080 or JenkinsCopy the code
  3. Open your browser and type localhost:8080 to see Jenkins’ Web interface

  4. Jenkins startup

    Jenkins installed by command line does not have its own startup function, so it needs to be started by command line after every restart, which is very troublesome. The following steps can automatically pull up a Jenkins command line after every startup.

    1. Create the boot script jenkinsboot.sh

    2. Add boot Jenkins code

    3. Setting Script Permissions

      sudo chmod 777 xxxx/jenkinsBoot.sh

    4. Set the script opening mode

    5. Set the script reference so that the script can execute chmod +x XXXX/jenkinsboot.sh

    6. The login entry of the added user

    7. If you restart the computer, the jenkinsboot. sh script is automatically executed.

3. Jenkins configuration

The first time you open Jenkins, you need to unlock Jenkins, and the page you see looks like this

Copy the password to the input box in the red font path and click Continue

Then click a module on the left to enter the download page, it may take a long time, wait patiently

To customize the user name and password, click “Save and complete” to enter the following page.

  1. Keychains and Provisioning Profiles Management
  2. Xcode Integration (iOS only)
  3. Gradle Plugin (Android only)
  4. Description setter Plugin (Sets the description of each build based on the RegEx of the build log file. Such as fir upload address)

4. Project engineering configuration

iOS

  1. New project

  1. Project Build Configuration

Type of packaging (note: AdHoc needs to be configured in your project to Google yourself)

Packaging branch

Source code management

Add the SSH private key

Certificate and description file configuration

The iOS certificate and description file must be set up and uploaded in System Administration ->Keychains and Provisioning Profiles Management before you can add it to your project

The login.keychain file in this case may need to be copied to the desktop and suffixes changed, since it is hidden

Description file should be uploaded here, actually path can write/Users/XXXX/Library/MobileDevice/Provisioning Profiles path, this is to keep the Xcode description file path, the upload can also go to this path to upload

After everything is ready, we can choose the certificate and description file in the project configuration. At this time, we may not be able to choose the Code Signing Identity when we add keychain for the first time. We need to save it and then we can choose it

Here we use shell scripts to build so that we can upload the build to FIR.

Script code

 security set-key-partition-list -S apple-tool:,apple: -s -k "Boot password" ~/Library/Keychains/login.keychain-db
Assume the script is placed in the same path as the project
project_path=$(pwd)
# Flutter environment variable Settings
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
export PATH=/Users/yongjianhe/flutter/bin:$PATH
flutter build ios
cd $project_path/ios
Take the current time string to add to the end of the file
now=$(date +"%Y_%m_%d_%H:%M")
# Specify the scheme name of the project
scheme="Runner"
Specify the configuration name to package
configuration=${BUILD_TYPE}
# Specify the output method to use for packaging, currently supporting app-Store, package, ad-hoc, Enterprise, Development, and developer-ID, the method parameter for XcodeBuild
if [ $BUILD_TYPE= ="Release" ]
then
   	export_method="app-store"
elif [ $BUILD_TYPE= ="AdHoc" ]
then
   	export_method="ad-hoc"
else
	export_method="development"
fi
# specify the project address
workspace_path="${project_path}/ios/Runner.xcodeproj"
# specify the output path
rm -rf "${project_path}/ipa"
mkdir -p "${project_path}/ipa"
output_path="${project_path}/ipa"
Output archive file address
archive_path="$output_path/zaihui_crm_${export_method}_${now}.xcarchive"
Output IPA address
ipa_path="$output_path/zaihui_crm_${BUILD_TYPE}_${BUILD_BRANCH}_${BUILD_REPOSITORY}_${now}.ipa"
Output IPA name
ipa_name="zaihui_crm_${BUILD_TYPE}_${BUILD_BRANCH}_${now}.ipa"
commit_msg="The $1"
Print the value of the set variable
echo "===workspace path: ${workspace_path}= = ="
echo "===archive path: ${archive_path}= = ="
echo "===ipa path: ${ipa_path}= = ="
echo "===export method: ${export_method}= = ="
echo "===commit msg: The $1= = ="
# Clear an unprecedented build first
fastlane gym --scheme ${scheme} --clean --configuration ${configuration} --archive_path ${archive_path} --export_method ${export_method} --output_directory ${output_path} --output_name ${ipa_name}
Upload to FIR
if [ ${export_method}! ="app-store" ]
then
fir publish ${ipa_path} -T "fir API token" -c $commit_msg
fi
Copy the code

Since I’m packing with the Fastlane command, the packaged PC needs fastlane installed

One important point to note here is that when a package failure occurs, it is due to the error of running the Flutter script. This may be because your current flutter version runs the Flutter build iOS. The FLUTTER_BUILD_MODE parameter is not Generated in Generated. This parameter is required to run the FLUTTER script, but it’s ok. You just need to add another script to your project file.

Finally, you need to set up the description file in your project (make the description file of the corresponding environment, download and open it, debug corresponds to the development certificate, adhoc and release corresponds to the production certificate). The reason is that the certificate uploaded above is just to save the Code Signing Identity so that you can access it in login.keychain, not to save it. I think the same is true for the description file, so we need to set the path of the description file

Build name sets the project name + package mode + branch name

To display fir address successfully, first set up the Html

That’s when you can launch your iOS package

Android

Android packaging is much easier than iOS

  1. New project
  2. Project Build Configuration
If you have additional questions about iOS certificates and description files, as well as Android, check out these two articles:
  • React Native Jenkins pack
  • Build Android continuous integration platform with Jenkins+Docker

The copyright of this article belongs to Zaihui RESEARCH and development team, welcome to reprint, reprint please reserve source. @xqqlv