golang iOS 自动打包,上传到蒲公英

本文介绍了一种使用Golang实现的iOS应用自动化打包及上传流程。通过定义配置类并利用xcodebuild工具完成从分支切换、项目构建到IPA文件导出的全过程,并最终将IPA文件上传至第三方平台。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

新建一个配置类包含打包的内容

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值