Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Automated Android CI, how hard can it be? by Nicolas Fränkel

Riga Dev Day
March 13, 2016
25

Automated Android CI, how hard can it be? by Nicolas Fränkel

Riga Dev Day

March 13, 2016
Tweet

Transcript

  1. WHAT WE DID Ø Analyzed the config of an exisXng job

    Ø Divided it into snippets Ø Created Puppet template for each Ø Assembled and filled in snippets through classes
  2. Y U ROBOLECTRIC? public class RobolectricTestRunner { protected DependencyResolver getJarResolver()

    { if (dependencyResolver == null) { if (Boolean.getBoolean("robolectric.offline")) { String dependencyDir = System.getProperty( "robolectric.dependency.dir", "."); dependencyResolver = new LocalDependencyResolver( new File(dependencyDir)); } else { File cacheDir = new File(new File( System.getProperty("java.io.tmpdir")), "robolectric"); if (cacheDir.exists() || cacheDir.mkdir()) { Logger.info( "Dependency cache location: %s", cacheDir.getAbsolutePath()); dependencyResolver = new CachedDependencyResolver( new MavenDependencyResolver(), cacheDir, 60 * 60 * 24 * 1000); } else { dependencyResolver = new MavenDependencyResolver(); } } } }
  3. Y U ROBOLECTRIC? <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

    http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.robolectric</groupId> <artifactId>robolectric-parent</artifactId> <version>3.1-SNAPSHOT</version> </parent> <artifactId>robolectric</artifactId> <dependencies> ... <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-ant-tasks</artifactId> <version>2.1.3</version> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
  4. Y U ROBOLECTRIC? “Robolectric downloads a version of Android at

    runXme that's built specifically for running tests. Each API level is ~40mb, so producing a single jar file that includes everything would be prohibiXve. All of the arXfacts are available on maven central under the coordinates: org.robolectric:android-all. You can grab the API levels from maven central and use them with offline mode.” hlps://groups.google.com/forum/#!topic/robolectric/ nJgHtdbkpi8
  5. Y U ROBOLECTRIC? Ø Uses a custom class loader Ø Either: • Download

    dependencies beforehand • Override method • Pass through proxy K
  6. YOUR OWN TEST RUNNER @Override protected DependencyResolver getJarResolver() { if

    (this.dependencyResolver == null) { if (Boolean.getBoolean("robolectric.offline")) { String cacheDir = System.getProperty( "robolectric.dependency.dir", "."); this.dependencyResolver = new LocalDependencyResolver( new File(cacheDir)); } else { this.dependencyResolver = new MyResolver(); } } return this.dependencyResolver; }
  7. YOUR OWN RESOLVER public class MyResolver extends MavenDependencyResolver { @Override

    protected void configureMaven( DependenciesTask task) { RemoteRepository remoteRepository = new RemoteRepository(); remoteRepository.setId("My Maven repo"); remoteRepository.setUrl(BuildConfig.NEXUS_URL); task.addConfiguredRemoteRepository( remoteRepository); } }
  8. ANDROID SDK --HELP Action "update sdk": Updates the SDK by

    suggesting new platforms to install if available. Options: -f --force : Forces replacement of a package or its parts, even if something has been modified. -n --dry-mode : Simulates the update but does not download or install anything. --proxy-host: HTTP/HTTPS proxy host (overrides settings if defined) -s --no-https : Uses HTTP instead of HTTPS (the default) for downloads. -t --filter : A filter that limits the update to the specified types of packages in the form of a comma-separated list of [platform, system-image, tool, platform-tool, doc, sample, source]. This also accepts the identifiers returned by 'list sdk --extended'. -u --no-ui : Updates from command-line (does not display the GUI) --proxy-port: HTTP/HTTPS proxy port (overrides settings if defined) -p --obsolete : Deprecated. Please use --all instead. -a --all : Includes all packages (such as obsolete and non-dependent ones.)
  9. (VERY) SIMPLE EXPECT SCRIPT #!/usr/bin/expect eval spawn jot -r 1

    0 1 expect { "0" { puts "zero" } "1" { puts "one" } }
  10. THE “REAL” SCRIPT #!/bin/bash expect -d -c ' log_file /var/log/update-android.log

    set timeout -1 spawn <%= @android_sdk_dir %>/tools/android -v update sdk -a -u -f --proxy-host\ <%= @proxy_host %> --proxy-port <%= @proxy_port %> -t <%= @joined_packages %> while {1} { expect { "Login:" { send "<%= @proxy_user %>\r" } "Password:" { send "<%= @proxy_password %>\r" } "Workstation:" { send "\r" } "Domain:" { send "\r" } -re ".*\[y\/n\]:" { send "y\r" } } }' Handles the proxy Handles license agreements