Skip to content

Commit 322502b

Browse files
committed
build: iOS XCode framework build and upload
1 parent b7dfd33 commit 322502b

File tree

4 files changed

+140
-25
lines changed

4 files changed

+140
-25
lines changed

.travis.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ matrix:
6363
- go run build/ci.go install
6464
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds
6565

66-
# Build the Android archives and upload them to Maven Central
66+
# Build the iOS framework and upload it to CocoaPods and Azure
67+
- gem install cocoapods --pre
68+
- go run build/ci.go xcode -signer IOS_SIGNING_KEY -deploy trunk -upload gethstore/builds
69+
70+
# Build the Android archive and upload it to Maven Central and Azure
6771
- brew update
6872
- brew install android-sdk maven
6973
- export ANDROID_HOME=/usr/local/opt/android-sdk

build/ci.go

+112-23
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ Available commands are:
2929
importkeys -- imports signing keys from env
3030
debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package
3131
nsis -- creates a Windows NSIS installer
32-
aar [ -sign key-id ] [ -upload dest ] -- creates an android archive
32+
aar [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive
33+
xcode [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework
3334
xgo [ options ] -- cross builds according to options
3435
3536
For all commands, -n prevents execution of external programs (dry run mode).
@@ -130,6 +131,8 @@ func main() {
130131
doWindowsInstaller(os.Args[2:])
131132
case "aar":
132133
doAndroidArchive(os.Args[2:])
134+
case "xcode":
135+
doXCodeFramework(os.Args[2:])
133136
case "xgo":
134137
doXgo(os.Args[2:])
135138
default:
@@ -339,14 +342,21 @@ func archiveBasename(arch string, env build.Environment) string {
339342
if arch == "android" {
340343
platform = "android-all"
341344
}
342-
archive := platform + "-" + build.VERSION()
345+
if arch == "ios" {
346+
platform = "ios-all"
347+
}
348+
return platform + "-" + archiveVersion(env)
349+
}
350+
351+
func archiveVersion(env build.Environment) string {
352+
version := build.VERSION()
343353
if isUnstableBuild(env) {
344-
archive += "-unstable"
354+
version += "-unstable"
345355
}
346356
if env.Commit != "" {
347-
archive += "-" + env.Commit[:8]
357+
version += "-" + env.Commit[:8]
348358
}
349-
return archive
359+
return version
350360
}
351361

352362
func archiveUpload(archive string, blobstore string, signer string) error {
@@ -638,14 +648,15 @@ func doWindowsInstaller(cmdline []string) {
638648
if err := archiveUpload(installer, *upload, *signer); err != nil {
639649
log.Fatal(err)
640650
}
651+
}
641652

642653
// Android archives
643654

644655
func doAndroidArchive(cmdline []string) {
645656
var (
646657
signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. ANDROID_SIGNING_KEY)`)
647-
deploy = flag.String("deploy", "", `Where to upload the deploy the archive (usually "https://oss.sonatype.org")`)
648-
upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`)
658+
deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "https://oss.sonatype.org")`)
659+
upload = flag.String("upload", "", `Destination to upload the archive (usually "gethstore/builds")`)
649660
)
650661
flag.CommandLine.Parse(cmdline)
651662
env := build.Env()
@@ -656,13 +667,13 @@ func doAndroidArchive(cmdline []string) {
656667
build.MustRun(gomobileTool("bind", "--target", "android", "--javapkg", "org.ethereum", "-v", "github.com/ethereum/go-ethereum/mobile"))
657668

658669
meta := newMavenMetadata(env)
659-
build.Render("build/mvn.pom", meta.PackageString()+".pom", 0755, meta)
670+
build.Render("build/mvn.pom", meta.Package+".pom", 0755, meta)
660671

661672
// Skip Maven deploy and Azure upload for PR builds
662673
maybeSkipArchive(env)
663674

664675
// Sign and upload all the artifacts to Maven Central
665-
os.Rename("geth.aar", meta.PackageString()+".aar")
676+
os.Rename("geth.aar", meta.Package+".aar")
666677
if *signer != "" && *deploy != "" {
667678
// Import the signing key into the local GPG instance
668679
if b64key := os.Getenv(*signer); b64key != "" {
@@ -676,16 +687,16 @@ func doAndroidArchive(cmdline []string) {
676687
}
677688
// Upload the artifacts to Sonatype and/or Maven Central
678689
repo := *deploy + "/service/local/staging/deploy/maven2"
679-
if meta.Unstable {
690+
if meta.Develop {
680691
repo = *deploy + "/content/repositories/snapshots"
681692
}
682693
build.MustRunCommand("mvn", "gpg:sign-and-deploy-file",
683694
"-settings=build/mvn.settings", "-Durl="+repo, "-DrepositoryId=ossrh",
684-
"-DpomFile="+meta.PackageString()+".pom", "-Dfile="+meta.PackageString()+".aar")
695+
"-DpomFile="+meta.Package+".pom", "-Dfile="+meta.Package+".aar")
685696
}
686697
// Sign and upload the archive to Azure
687698
archive := "geth-" + archiveBasename("android", env) + ".aar"
688-
os.Rename(meta.PackageString()+".aar", archive)
699+
os.Rename(meta.Package+".aar", archive)
689700

690701
if err := archiveUpload(archive, *upload, *signer); err != nil {
691702
log.Fatal(err)
@@ -708,9 +719,9 @@ func gomobileTool(subcmd string, args ...string) *exec.Cmd {
708719
}
709720

710721
type mavenMetadata struct {
711-
Env build.Environment
712722
Version string
713-
Unstable bool
723+
Package string
724+
Develop bool
714725
Contributors []mavenContributor
715726
}
716727

@@ -740,23 +751,101 @@ func newMavenMetadata(env build.Environment) mavenMetadata {
740751
}
741752
}
742753
}
754+
// Render the version and package strings
755+
version := build.VERSION()
756+
if isUnstableBuild(env) {
757+
version += "-SNAPSHOT"
758+
}
743759
return mavenMetadata{
744-
Env: env,
745-
Version: build.VERSION(),
746-
Unstable: isUnstableBuild(env),
760+
Version: version,
761+
Package: "geth-" + version,
762+
Develop: isUnstableBuild(env),
747763
Contributors: contribs,
748764
}
749765
}
750766

751-
func (meta mavenMetadata) VersionString() string {
752-
if meta.Unstable {
753-
return meta.Version + "-SNAPSHOT"
767+
// XCode frameworks
768+
769+
func doXCodeFramework(cmdline []string) {
770+
var (
771+
signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. IOS_SIGNING_KEY)`)
772+
deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "trunk")`)
773+
upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`)
774+
)
775+
flag.CommandLine.Parse(cmdline)
776+
env := build.Env()
777+
778+
// Build the iOS XCode framework
779+
build.MustRun(goTool("get", "golang.org/x/mobile/cmd/gomobile"))
780+
build.MustRun(gomobileTool("init"))
781+
782+
archive := "geth-" + archiveBasename("ios", env)
783+
if err := os.Mkdir(archive, os.ModePerm); err != nil {
784+
log.Fatal(err)
754785
}
755-
return meta.Version
786+
bind := gomobileTool("bind", "--target", "ios", "--tags", "ios", "--prefix", "GE", "-v", "github.com/ethereum/go-ethereum/mobile")
787+
bind.Dir, _ = filepath.Abs(archive)
788+
build.MustRun(bind)
789+
build.MustRunCommand("tar", "-zcvf", archive+".tar.gz", archive)
790+
791+
// Skip CocoaPods deploy and Azure upload for PR builds
792+
maybeSkipArchive(env)
793+
794+
// Sign and upload the framework to Azure
795+
if err := archiveUpload(archive+".tar.gz", *upload, *signer); err != nil {
796+
log.Fatal(err)
797+
}
798+
// Prepare and upload a PodSpec to CocoaPods
799+
if *deploy != "" {
800+
meta := newPodMetadata(env)
801+
build.Render("build/pod.podspec", meta.Name+".podspec", 0755, meta)
802+
build.MustRunCommand("pod", *deploy, "push", meta.Name+".podspec")
803+
}
804+
}
805+
806+
type podMetadata struct {
807+
Name string
808+
Version string
809+
Commit string
810+
Contributors []podContributor
756811
}
757812

758-
func (meta mavenMetadata) PackageString() string {
759-
return "geth-" + meta.VersionString()
813+
type podContributor struct {
814+
Name string
815+
Email string
816+
}
817+
818+
func newPodMetadata(env build.Environment) podMetadata {
819+
// Collect the list of authors from the repo root
820+
contribs := []podContributor{}
821+
if authors, err := os.Open("AUTHORS"); err == nil {
822+
defer authors.Close()
823+
824+
scanner := bufio.NewScanner(authors)
825+
for scanner.Scan() {
826+
// Skip any whitespace from the authors list
827+
line := strings.TrimSpace(scanner.Text())
828+
if line == "" || line[0] == '#' {
829+
continue
830+
}
831+
// Split the author and insert as a contributor
832+
re := regexp.MustCompile("([^<]+) <(.+>)")
833+
parts := re.FindStringSubmatch(line)
834+
if len(parts) == 3 {
835+
contribs = append(contribs, podContributor{Name: parts[1], Email: parts[2]})
836+
}
837+
}
838+
}
839+
name := "Geth"
840+
if isUnstableBuild(env) {
841+
name += "Develop"
842+
}
843+
return podMetadata{
844+
Name: name,
845+
Version: archiveVersion(env),
846+
Commit: env.Commit,
847+
Contributors: contribs,
848+
}
760849
}
761850

762851
// Cross compilation

build/mvn.pom

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>org.ethereum</groupId>
88
<artifactId>geth</artifactId>
9-
<version>{{.VersionString}}</version>
9+
<version>{{.Version}}</version>
1010
<packaging>aar</packaging>
1111

1212
<name>Android Ethereum Client</name>

build/pod.podspec

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Pod::Spec.new do |spec|
2+
spec.name = '{{.Name}}'
3+
spec.version = '{{.Version}}'
4+
spec.license = { :type => 'GNU Lesser General Public License, Version 3.0' }
5+
spec.homepage = 'https://github.com/ethereum/go-ethereum'
6+
spec.authors = { {{range .Contributors}}
7+
'{{.Name}}' => '{{.Email}}',{{end}}
8+
}
9+
spec.summary = 'iOS Ethereum Client'
10+
spec.source = { :git => 'https://github.com/ethereum/go-ethereum.git', :commit => '{{.Commit}}' }
11+
12+
spec.platform = :ios
13+
spec.ios.deployment_target = '9.0'
14+
spec.ios.vendored_frameworks = 'Frameworks/Geth.framework'
15+
16+
spec.prepare_command = <<-CMD
17+
curl https://gethstore.blob.core.windows.net/builds/geth-ios-all-{{.Version}}.tar.gz | tar -xvz
18+
mkdir Frameworks
19+
mv geth-ios-all-{{.Version}}/Geth.framework Frameworks
20+
rm geth-ios-all-{{.Version}}
21+
CMD
22+
end

0 commit comments

Comments
 (0)