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

Focus On What Matters By Automating The Small Things

Nate Ebel
August 14, 2019

Focus On What Matters By Automating The Small Things

How can your CI pipeline enable you to build more quickly and efficiently?

In this talk, you’ll learn what tools are available at every step of the development process; allowing you to automate the small things, and dedicate your time to what matters most.

Can you enforce coding format & style conventions?
Do you have daily, or per-branch, or per-commit builds?
Are you testing?
Is your apk getting too large?
How do you distribute for testing and release?

Nate Ebel

August 14, 2019
Tweet

More Decks by Nate Ebel

Other Decks in Programming

Transcript

  1. Focus On What Matters By
    Automating the Small Things
    Nate Ebel

    View full-size slide

  2. @n8ebel #AndroidSummit
    Why Automate?

    View full-size slide

  3. @n8ebel #AndroidSummit
    Consistently build the
    right thing at the right
    time

    View full-size slide

  4. @n8ebel #AndroidSummit
    Save time and energy
    for the real challenges

    View full-size slide

  5. @n8ebel #AndroidSummit
    Make projects more
    approachable

    View full-size slide

  6. @n8ebel #AndroidSummit
    What to Automate?

    View full-size slide

  7. @n8ebel #AndroidSummit
    Automate
    All The Things!

    View full-size slide

  8. @n8ebel #AndroidSummit
    What To Automate?
    QUALITY REVIEW DEPLOY
    BUILD
    Where are you losing time, energy, or joy?

    View full-size slide

  9. @n8ebel #AndroidSummit
    Automating Your Build

    View full-size slide

  10. @n8ebel #AndroidSummit
    Automating Your Build
    BUILD
    BUILD
    Assemble
    Test
    Quality
    Deploy
    Educate

    View full-size slide

  11. @n8ebel #AndroidSummit
    Automating Your Build
    CONFIG
    BUILD
    ASSEMBLE
    TEST
    DEPLOY

    View full-size slide

  12. @n8ebel #AndroidSummit
    Automating Your Build
    CircleCI Bitrise GCB Codemagic

    View full-size slide

  13. @n8ebel #AndroidSummit
    Building With CircleCI
    - Setup Account
    - Add project
    - Add configuration file
    - Push to master
    - Start building

    View full-size slide

  14. @n8ebel #AndroidSummit
    Building With CircleCI
    ...
    steps:
    - checkout:
    - run:
    name: Download Dependencies
    command: ./gradlew androidDependencies
    - run:
    name: Run Tests
    command: ./gradlew test
    - run:
    name: Assemble
    command: ./gradlew assemble
    .circleci/config.yml

    View full-size slide

  15. @n8ebel #AndroidSummit
    Building With CircleCI

    View full-size slide

  16. @n8ebel #AndroidSummit
    Enforcing Build Status Checks

    View full-size slide

  17. @n8ebel #AndroidSummit
    Building With CircleCI

    View full-size slide

  18. @n8ebel #AndroidSummit
    Enforcing Build Status Checks

    View full-size slide

  19. @n8ebel #AndroidSummit
    Enforcing Build Status Checks
    - Settings -> Branches
    - Click ‘Add Rule’
    - Require Status Checks To Pass Before Merging

    View full-size slide

  20. @n8ebel #AndroidSummit
    Enforcing Build Status Checks

    View full-size slide

  21. @n8ebel #AndroidSummit
    Now we have an
    automated build process

    View full-size slide

  22. @n8ebel #AndroidSummit
    Validating Code Quality

    View full-size slide

  23. @n8ebel #AndroidSummit
    Validating Code Quality
    ANDROID LINT
    CODE FORMATTING
    CODE SMELLS
    TESTS

    View full-size slide

  24. @n8ebel #AndroidSummit
    Validating code quality
    with your automated
    build

    View full-size slide

  25. @n8ebel #AndroidSummit
    Validating Code Formatting
    - Add/Configure formatting tool within project
    - Integrate with build script

    View full-size slide

  26. @n8ebel #AndroidSummit
    Validating Code Formatting With ktlint
    ...
    - run:
    name: Check Code Formatting
    command: ./gradlew ktlintCheck --continue
    Update build config to incorporate new build task
    .circleci/config.yml

    View full-size slide

  27. @n8ebel #AndroidSummit
    Validating Code Formatting With ktlint

    View full-size slide

  28. @n8ebel #AndroidSummit
    What’s the problem
    here?

    View full-size slide

  29. @n8ebel #AndroidSummit
    Failing builds require time and
    context switching

    View full-size slide

  30. @n8ebel #AndroidSummit
    Locally validating code
    quality

    View full-size slide

  31. @n8ebel #AndroidSummit
    Locally Validating Code Quality
    ● Reformat/Lint code using IDE
    ● Run ktlint, Android Lint, etc locally
    ● Avoid pushing code which fails the build

    View full-size slide

  32. @n8ebel #AndroidSummit
    Reformatting Code Using IDE
    ● Set project code style from pre-defined style
    ● Customize as desired
    ● Update .gitignore
    ● Ensure code styles included in repo
    ● Optimize imports on the fly

    View full-size slide

  33. @n8ebel #AndroidSummit
    Reformatting Code Using IDE
    # IDEA/Android Studio ignores
    *.iml
    /.idea/*
    # IDEA/Android Studio Ignore exceptions
    !/.idea/codeStyles/
    !/.idea/fileTemplates/
    !/.idea/inspectionProfiles/
    !/.idea/scopes/
    !/.idea/copyright/
    ...
    .gitignore

    View full-size slide

  34. @n8ebel #AndroidSummit
    Reformatting Code Using IDE
    - Add project code
    styles to git
    - Configure as
    desired to pass
    formatting checks

    View full-size slide

  35. @n8ebel #AndroidSummit
    Reformatting Code Using IDE

    View full-size slide

  36. @n8ebel #AndroidSummit
    Running ktlint Locally
    ● Have to remember to run before pushing code
    ● Can use git-hooks to run these checks

    View full-size slide

  37. @n8ebel #AndroidSummit
    Git hooks are scripts that Git executes
    before or after events such as:
    commit, push, and receive.

    View full-size slide

  38. @n8ebel #AndroidSummit
    Enforcing Code Quality With Git Hooks
    PRE-PUSH CHECK FORMATTING
    PRE-COMMIT DO SOMETHING

    View full-size slide

  39. @n8ebel #AndroidSummit
    Enforcing Code Quality With Git Hooks
    #!/bin/sh
    # Adapted from https://proandroiddev.com/ooga-chaka-git-hooks-to-enforce-code-quality-11ce8d0d23cb
    echo "Checking code formatting"
    ./gradlew app:ktlintCheck --daemon
    status=$?
    if [ "$status" = 0 ] ; then
    echo "No formatting issues were found"
    exit 0
    else
    echo 1>&2 "* There are code formatting issues that must be addressed"
    exit 1
    fi
    .git/hooks/pre-push

    View full-size slide

  40. @n8ebel #AndroidSummit
    Automating Git Hook Installation
    #!/bin/sh
    # Adapted from https://proandroiddev.com/ooga-chaka-git-hooks-to-enforce-code-quality-11ce8d0d23cb
    echo "Checking code formatting"
    ./gradlew app:ktlintCheck --daemon
    status=$?
    if [ "$status" = 0 ] ; then
    echo "No formatting issues were found"
    exit 0
    else
    echo 1>&2 "* There are code formatting issues that must be addressed"
    exit 1
    fi
    /scripts/git-hooks/pre-push.sh

    View full-size slide

  41. @n8ebel #AndroidSummit
    Enforcing Code Quality With Git Hooks
    task copyGitHooks(type: Copy) {
    description 'Copies the git hooks from scripts/git-hooks to the .git folder.'
    ...
    }
    task installGitHooks(type: Exec) {
    description 'Installs the git hooks from scripts/git-hooks.'
    ...
    }
    afterEvaluate {
    tasks['clean'].dependsOn installGitHooks // We install the hook at the first occasion
    }
    git-hooks.gradle

    View full-size slide

  42. @n8ebel #AndroidSummit
    Enforcing Code Quality With Git Hooks
    ...
    apply from: 'git-hooks.gradle'
    build.gradle

    View full-size slide

  43. @n8ebel #AndroidSummit
    Now We Can Prevent Pushes That Will
    Fail, And Share With The Team

    View full-size slide

  44. @n8ebel #AndroidSummit
    Reviewing Code

    View full-size slide

  45. @n8ebel #AndroidSummit
    Reviewing Code
    Validate Changes Discuss Approaches Learn

    View full-size slide

  46. @n8ebel #AndroidSummit
    Creating PR templates

    View full-size slide

  47. @n8ebel #AndroidSummit
    Creating PR Templates
    Want to Avoid This Lack Of Detail

    View full-size slide

  48. @n8ebel #AndroidSummit
    Creating PR Templates
    Favor and Encourage
    More Detail

    View full-size slide

  49. @n8ebel #AndroidSummit
    Creating PR Templates
    ### Related To-Do
    ** link **
    ### Proposed Changes
    * change 1
    * change 2
    ### Additional Info
    ** any additional useful context or info **
    ### Checklist
    - [ ] Tests
    - [ ] Translations
    ### Screenshots
    Original | Updated
    :-------------------------:|:-------------------------:
    ** original screenshot ** | ** updated screenshot **
    .github/pull_request_template.md
    ● Link to issue
    ● Describe changes
    ● Additional context
    ● Checklists
    ● Screenshots

    View full-size slide

  50. @n8ebel #AndroidSummit
    Creating PR Templates
    ● PR Sections
    Pre-Populated Based
    On Template
    ● Encourage
    Contributors To
    Provide Ample Detail

    View full-size slide

  51. @n8ebel #AndroidSummit
    Creating issue
    templates

    View full-size slide

  52. @n8ebel #AndroidSummit
    Creating Issue Templates
    ---
    name: Bug report
    about: Create a report to help us improve
    title: ''
    labels: bug
    assignees: ''
    ---
    **Description**
    A clear and concise description of what the bug is.
    **To Reproduce**
    Steps to reproduce the behavior:
    1. Go to '...'
    2. Click on '....'
    3. See error
    **Expected behavior**
    ...
    .github/ISSUE_TEMPLATE/bug_report.md

    View full-size slide

  53. @n8ebel #AndroidSummit
    Creating Issue Templates
    ---
    name: Feature request
    about: Suggest an idea for this project
    title: ''
    labels: enhancement
    assignees: ''
    ---
    **What problem are you trying to solve?**
    A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
    **Describe the solution you'd like**
    A clear and concise description of what you want to happen.
    **Describe alternatives you've considered**
    A clear and concise description of any alternative solutions or features you've considered.
    **Additional context**
    Add any other context or screenshots about the feature request here.
    .github/ISSUE_TEMPLATE/feature_request.md

    View full-size slide

  54. @n8ebel #AndroidSummit
    Using Issue Templates
    Choose a Template When Creating an Issue

    View full-size slide

  55. @n8ebel #AndroidSummit
    Using Issue Templates
    ● Issue Will
    Pre-Populate Based
    On Template
    ● Encourage
    Contributors To
    Provide Enough
    Information

    View full-size slide

  56. @n8ebel #AndroidSummit
    Referencing GitHub Issues
    Close issues via
    keyword in PR
    descriptions or
    commits
    ● ‘Closes’
    ● ‘Fixes’
    ● ‘Resolves’
    ● etc...

    View full-size slide

  57. @n8ebel #AndroidSummit
    Supercharging PRs with
    Danger

    View full-size slide

  58. @n8ebel #AndroidSummit
    Danger runs during your CI process, and gives
    teams the chance to automate common code
    review chores.

    View full-size slide

  59. @n8ebel #AndroidSummit
    What Is Danger?
    DANGER
    CHECK APK
    SIZE
    DEPENDENCY
    UPDATES
    INLINE LINT
    COMMENTS
    INFORMATIONAL
    MESSAGES
    ETC...

    View full-size slide

  60. @n8ebel #AndroidSummit
    What Is Danger?
    Add Useful Messages, Statistics, Warnings, etc to Your Pull Requests

    View full-size slide

  61. @n8ebel #AndroidSummit
    Adding Danger To Your Project
    source "https://rubygems.org"
    git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
    gem 'danger'
    Gemfile
    ● Update the Gemfile
    ● Run `bundle install`
    ● Run `bundle exec danger init`
    ● Follow the CLI setup process

    View full-size slide

  62. @n8ebel #AndroidSummit
    Adding Danger To Your Project
    ...
    - run:
    name: Install Gem
    command: bundle install
    - run:
    name: Danger
    command: bundle exec danger
    .circleci/config.yml

    View full-size slide

  63. @n8ebel #AndroidSummit
    Adding PR Comments With Danger
    # thank PR author
    message "Thanks @#{github.pr_author} "
    Dangerfile

    View full-size slide

  64. @n8ebel #AndroidSummit
    Warning For WIP PRs With Danger
    # Make it more obvious that a PR is a work in progress and shouldn't be merged yet
    warn("PR is a Work in Progress and not ready to merge") if github.pr_title.include? "[WIP]"
    Dangerfile

    View full-size slide

  65. @n8ebel #AndroidSummit
    Reporting APK Size With Danger
    # Notify of the release APK size.
    apk_size = (File.size('app/build/outputs/apk/release/app-release-unsigned.apk').to_f / 2**20).round(2)
    message "Release APK size: #{apk_size} MB"
    Dangerfile

    View full-size slide

  66. @n8ebel #AndroidSummit
    Enforcing Useful PR Descriptions With Danger
    # Encourage contributors to write useful descriptions
    warn("Please provide a Pull Request description ...") if github.pr_body.length < 20
    Dangerfile

    View full-size slide

  67. @n8ebel #AndroidSummit
    Reporting Dependency Updates With Danger
    - run:
    name: Check Dependency Versions
    command: ./gradlew dependencyUpdates
    .circleci/config.yml
    plugins {
    id "org.jlleitschuh.gradle.ktlint" version "7.1.0"
    id "com.github.ben-manes.versions" version "0.20.0"
    }
    build.gradle
    Gradle Versions Plugin

    View full-size slide

  68. @n8ebel #AndroidSummit
    Reporting Dependency Updates With Danger
    # Notify of outdated dependencies
    update_count = File.readlines("build/dependencyUpdates/report.txt").select { |line| line =~ /->/ }.count
    if update_count > 10
    # More than 10 libraries to update is cumbersome in a comment, so summarize
    warn "There are #{update_count} dependencies with new milestone versions."
    elsif update_count > 0
    file = File.open("build/dependencyUpdates/report.txt", "rb").read
    heading = "The following dependencies have later milestone versions:"
    warn file.slice(file.index(heading)..-1)
    end
    Dangerfile

    View full-size slide

  69. @n8ebel #AndroidSummit
    Reporting Dependency Updates With Danger

    View full-size slide

  70. @n8ebel #AndroidSummit
    Reporting Dependency Updates With Danger

    View full-size slide

  71. @n8ebel #AndroidSummit
    Reporting ktlint Errors With Danger
    gem 'danger'
    gem 'danger-checkstyle_format'
    Gemfile
    # Report inline ktlint issues
    checkstyle_format.base_path = Dir.pwd
    checkstyle_format.report 'app/build/reports/ktlint/ktlintMainSourceSetCheck.xml'
    Dangerfile

    View full-size slide

  72. @n8ebel #AndroidSummit
    Reporting ktlint Errors With Danger

    View full-size slide

  73. @n8ebel #AndroidSummit
    Reporting ktlint Errors With Danger
    # ignore inline messages that are outside of the current diff
    github.dismiss_out_of_range_messages
    Dangerfile

    View full-size slide

  74. @n8ebel #AndroidSummit
    Reporting With Danger
    And More…
    ● Android Lint
    ● Test Coverage
    ● String Translations
    ● Change In APK Size
    ● etc...

    View full-size slide

  75. @n8ebel #AndroidSummit
    Deploying Your App

    View full-size slide

  76. @n8ebel #AndroidSummit
    Deploying Your App
    ● Daily build
    ● Scheduled build
    ● Triggered build
    ● YOLO

    View full-size slide

  77. @n8ebel #AndroidSummit
    Customizing app
    deployment

    View full-size slide

  78. @n8ebel #AndroidSummit
    Customizing App Deployment
    Merge to Develop
    Distribute
    Test Build
    Merge to
    Master
    Upload to
    Google Play

    View full-size slide

  79. @n8ebel #AndroidSummit
    Deploying Test Builds On Merge
    Deploy Test Builds On Merge To Develop

    View full-size slide

  80. @n8ebel #AndroidSummit
    Deploying Test Builds On Merge
    Automating Release
    Notes For Test Builds

    View full-size slide

  81. @n8ebel #AndroidSummit
    Deploying Release Builds On Merge
    Deploy Release Builds With Gradle Play Publisher

    View full-size slide

  82. @n8ebel #AndroidSummit
    Deploying Release Builds On Merge
    ● Store Release Info In Repo
    ● Track Changes Over Time
    ● Full Internal Release By Merging To
    Master

    View full-size slide

  83. @n8ebel #AndroidSummit
    Automate the Small Things

    View full-size slide

  84. @n8ebel #AndroidSummit
    What To Automate?
    QUALITY REVIEW DEPLOY
    BUILD

    View full-size slide

  85. @n8ebel #AndroidSummit
    Losing time, energy, or
    joy to some task? … try
    automating it.

    View full-size slide

  86. @n8ebel #AndroidSummit
    Resources
    ● https://github.com/n8ebel/AutomationSandbox

    View full-size slide

  87. @n8ebel #AndroidSummit
    Resources
    ● https://proandroiddev.com/ooga-chaka-git-hooks-to-enforce-code-quality-11ce8d0d23cb
    ● https://help.github.com/en/articles/creating-a-pull-request-template-for-your-repository
    ● https://help.github.com/en/articles/closing-issues-using-keywords
    ● https://danger.systems/ruby/
    ● https://danger.systems/guides/getting_started.html#including-danger
    ● https://blog.bitrise.io/automating-code-review-tasks-for-multi-module-android-projects
    ● https://github.com/Triple-T/gradle-play-publisher
    ● https://try.crashlytics.com/beta/
    ● https://github.com/noboru-i/danger-checkstyle_format

    View full-size slide

  88. @n8ebel #AndroidSummit
    Thank You
    "n8ebel".apply {
    Twitter
    YouTube
    LinkedIn
    Instagram
    }
    Stay In Touch

    View full-size slide