golang iOS 自動打包,上傳到蒲公英
阿新 • • 發佈:2019-01-03
新建一個配置類包含打包的內容
type buildInfo struct { Path string `json:"path"` Branch string `json:"branch"` Workspace string `json:"workspace"` Scheme string `json:"scheme"` ArchPath string `json:"archPath"` ExportPath string `json:"exportPath"` Config string `json:"config"` InstallType string `json:"installType"` Password string `json:"password"` UpdateDescription string `json:"updateDescription"` Upload bool `json:"upload"` }
根據配置資訊進行打包,主要用到xcodebuild工具的支援,另外就是利用golang對命令列進行呼叫。
func Archive(info buildInfo) { e := os.Chdir(info.Path) if e != nil { panic(e.Error()) } workspace := info.Workspace + ".xcworkspace" archCommand := exec.Command("xcodebuild", "archive", "-workspace", workspace, "-scheme", info.Scheme, "-archivePath", info.ArchPath) archCommand.Stdout = os.Stdout e = archCommand.Run() if e != nil { panic(e.Error()) } }
匯出成ipa 最新的xcode 9 需要一個配置檔案,可以手動匯出一次進行獲取
func Export(info buildInfo) { arch := info.ArchPath + ".xcarchive" export := exec.Command("xcodebuild", "-exportArchive", "-archivePath", arch, "-exportPath", info.ExportPath, "-exportOptionsPlist", info.Config) export.Stdout = os.Stdout e := export.Run() if e != nil { panic(e.Error()) } }
git分支的切換,可以新建一個分支專門對於這個程式的配合使用
func switchBranch(info buildInfo) {
e := os.Chdir(info.Path)
if e != nil {
panic(e.Error())
}
branch := info.Branch
println(branch)
if len(branch) > 0 {
git := exec.Command("git", "checkout", branch)
git.Stdout = os.Stdout
e = git.Run()
if e != nil {
panic(e.Error())
}
}
}
配置讀取,引數為config,對應配置Json檔案的路徑
func main() {
config := flag.String("config", "", "the path of the config file")
flag.Parse()
content, e := ioutil.ReadFile(*config)
if e != nil {
panic(e.Error())
}
var info buildInfo
e = json.Unmarshal(content, &info)
if e != nil {
panic(e.Error())
}
switchBranch(info)
Archive(info)
Export(info)
e = Upload(info)
if e != nil {
fmt.Println(e.Error())
}
}
蒲公英對應的上傳介面
const (
userKey = ""
apiKey = ""
apiURL = "https://qiniu-storage.pgyer.com/apiv1/app/upload"
)
func Upload(info buildInfo) error {
if !info.Upload {
println("will not upload to pgy")
return nil
}
file := info.ExportPath + info.Scheme + ".ipa"
buf := new(bytes.Buffer) // caveat IMO dont use this for large files, \
w := multipart.NewWriter(buf)
fw, err := w.CreateFormFile("file", file)
if err != nil {
fmt.Println("c")
return err
}
fd, err := os.Open(file)
if err != nil {
fmt.Println("d")
return err
}
defer fd.Close()
// Write file field from file to upload
_, err = io.Copy(fw, fd)
if err != nil {
fmt.Println("e")
return err
}
w.WriteField("uKey", userKey)
w.WriteField("_api_key", apiKey)
w.WriteField("installType", info.InstallType)
w.WriteField("password", info.Password)
w.WriteField("updateDescription", info.UpdateDescription)
e := w.Close()
if e != nil {
fmt.Println("e")
return e
}
request, e := http.NewRequest(http.MethodPost, apiURL, buf)
if e != nil {
fmt.Println("e")
return e
}
//這裡糾結了好久,發現設定了content-type之後貌似引數才能被伺服器取到
request.Header.Add("Content-Type", w.FormDataContentType())
request.Header.Set("enctype", "multipart/form-data")
client := &http.Client{}
resp, e := client.Do(request)
if e != nil {
fmt.Println("e")
return e
}
io.Copy(os.Stdout, resp.Body)
defer resp.Body.Close()
return nil
}
配置的json檔案內容
{
"path":"~/Desktop/demo",
"branch":"demo",
"workspace":"demo",
"scheme":"demo",
"archPath":"~/demo/demo",
"exportPath":"~/demo/ipas/",
"config":"~/demo/config.plist",
"password":"demo",
"updateDescription":"demo",
"installType":"2",
"upload":true
}
目錄結構
➜demo tree
.
├── config.plist
├── demo.json
└── ipas
1 directory, 2 files