一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp)
程序员的生活要一切自动化,更要幸福^_^。
转载请注明出处http://www.cnblogs.com/mrblue/p/3885043.html
感谢小波同学
概述
平台:mac
例子工程:基于cocos2dx引擎的项目
事实:就是一组shell脚本和一些工具
我的 目录结构
Work
|-----Project
|---------cocos2dx
|---------Game
|---------proj.ios
|---------Resoueces
|-----tool
|-----publish_package (这是我的打包工具存放目录)
|-------package
|-----------ios(ipa最终输出目录)
|-----------android(apk最终输出目录,我还没完成,请各路大神帮忙完善)
|-------script
|-------tool
|-------config.txt
|-------publish_ipa.sh
|-------upload_ftp.sh
一、配置文件 config.txt
说明:
1、这是所有配置,供其他脚本使用的一些常量,放这里统一管理
2、我们代码和资源svn目录是分开(这样有好有坏)
#! /bin/sh #根目录 CurrentDir=`dirname $0` #--------------------------------------SVN更新-------------------------------------- #SVN代码目录 SVN_Code=$CurrentDir/../.. #SVN资源目录 SVN_Resource=$CurrentDir/resource #要拷贝到的目标目录 Destiny_Dir_Resource=$SVN_Code/project/Game/Resources/resource #--------------------------------------压缩PNG-------------------------------------- CompressTool_Path=$CurrentDir/tool/ImageAlpha.app/Contents/Resources #--------------------------------------资源加密-------------------------------------- #加密工具目录 EncryptTool_Path=$CurrentDir/tool #png加密key PngEncryptKey=xxxxxxxxxxxxxxxxxxxxx #data加密key DataEncryptKey=xxxxxxxxxxxxxxxxxxxxxxxx #加密长度 EncryptDataLen=128 #--------------------------------------编译ipa-------------------------------------- ProjectRoot_Path=$SVN_Code/project #xcodeproj所在目录 XCodeProject_Path=$ProjectRoot_Path/Game/proj.ios #OutPut目录 TargetOutput_Path=$ProjectRoot_Path/bin/release/Game #Export目录 TargetExport_Path=$CurrentDir/package/ios #签名 IPA_SignIdentiy="xxxxxxxxxxxxxxxxxxx" IPA_ProvisionIdentiy="xxxxxxxxxxxxxxxxxxxxx" #要生成的Target名字 ProjectTargets_Array=("Game_91" "Game_kuaiyong" "Game_pp" "Game_tongbu")
二、发布脚本publish_ipa.sh
说明:
1、如果你只想打出ipa,不想上传ftp,那就直接运行这个脚本,然后ipa自动生成在package/ios下
2、可以模块化执行,比如本次你只执行更新svn,但不需要执行资源加密等过程(之前已经弄好过了),那就把一些函数用#注释掉
#! /bin/sh #根目录 RootDir=`dirname $0` #加载配置文件 . $RootDir/config.txt #加载自动更新SVN脚本 . $RootDir/script/update_svn.sh #加载拷贝资源脚本 . $RootDir/script/copy_resouce.sh #加载压缩PNG脚本 . $RootDir/script/compress_png.sh #加载压缩PNG脚本 . $RootDir/script/encrypt.sh #lua脚本编译成字节码 . $RootDir/script/compile_luajit.sh #加载编译工程函数库 . $RootDir/script/build_ipa.sh function main() { updateSvn copyResource compressPNG encryptPNG encryptTableData complieLuajit buildProject } main
3、更新svn script/update_svn.sh
4、拷贝资源 script/copy_resouce.sh
说明:把签出的resource拷贝到Game/Resouece下
5、压缩png script/compress_png.sh
说明:
1、使用的是pngquant,将全色png为256色的png8
2、工具所在目录是tool/ImageAlpha.app
#!/bin/sh #压缩纹理 Compress_ProcessPath_Resource=$DestinyPath_Resource #工具目录 Compress_ToolPath=$CompressTool_Path #压缩png function compressPNG() { echo "-------Start Compress PNG : " $Compress_ProcessPath_Resource " ---------------" cd $Compress_ToolPath imageNumber=0 tmpfilename=nill for filename in `find $Compress_ProcessPath_Resource -name "*.png"` do ./pngquant 256 --ext _tmp.png $filename rm -rf $filename imageNumber=$[imageNumber+1] done echo "start to rename Procedure!" for filename in `find $Compress_ProcessPath_Resource -name "*.png"` do tmpfilename=`echo ${filename%*_tmp*}` mv $filename $tmpfilename.png done echo "-------End Compress PNG with ImageNumber: " $imageNumber "Success Finished ! ---------------" cd $Script_RootDir }
6、加密png和数据文件 script/encrypt.sh
说明:
1、加密方式是简单的抑或加密
2、可执行文件目录是 tool/EncryptPacker
3、png使用前EncryptDataLen(见config.txt)的长度字节加密,数据文件全部加密
4、如果你要给png加密,需要自己手动修改加载png的源文件代码(cocos2dx的在bool initWithImageFile(const char * strPath, EImageFormat imageType = kFmtPng)等地方)
5、这里给出机密工具( tool/EncryptPacker)的c++代码文件(因为使用的抑或加密,所以加密和解密代码一样的)
// // main.cpp // EncryptPacker // // Created by Blue on 14-6-4. // Copyright (c) 2014年 Blue. All rights reserved. // #include <iostream> #include <string> #include <fstream> using namespace std; const char* g_pszDesc = "Usage: ./EncryptPacker inputfile key limitlength Desc: inputfile the soucre file which will be encrypted(it will be replaced after encrypting) key the secret key(at least one character) limitlength the length of this file'data will be encrypted(0 means full lenth of the file) Example: ./EncryptPacker a.txt xxxxxxxx 100 "; int main(int argc, const char * argv[]) { if (argc<4) { std::cout << g_pszDesc; return 0; } /* for (int i=1; i<argc; i++) { cout<<argv[i]<<endl; } */ const string strInputFile = argv[1]; FILE* fp = fopen(strInputFile.c_str(), "r"); if (!fp) { cout<<"read file ["<<strInputFile.c_str()<<"] failed"<<endl; return 0; } const string strKey = argv[2]; size_t nKeyLen = strKey.length(); if (strKey.empty()) { cout<<"input key"<<endl; return 0; } int nLimitlength = atoi(argv[3]); if (nLimitlength<0) { cout<<"limitlength must >= 0"<<endl; return 0; } fseek(fp,0,SEEK_END); long lLen = ftell(fp); fseek(fp,0,SEEK_SET); unsigned char* pBuffer = new unsigned char[lLen+1]; pBuffer[lLen] = '