新規チームで新規開発を始める時にやること

 新規チームで新規開発を始める時にやること

DMM Android勉強会で発表した内容です

3c4e24fd827c789cb67a9f759f057b06?s=128

Shinnosuke Kugimiya

March 27, 2019
Tweet

Transcript

  1. !LHNZTIJO %.."OESPJEษڧձ ৽نνʔϜͰ৽ن։ൃΛ࢝ΊΔ࣌ʹ΍Δ͜ͱ

  2. X © DMM.com ࣗݾ঺հ

  3. X © DMM.com ࣗݾ঺հ w LHNZTIJOఝٶʢ͗͘Έ΍ʣ w "OESPJEΤϯδχΞ w $50ࣨॴଐ

  4. X © DMM.com ಥવͰ͕͢ɺ ৽نҊ݅ͷ։ൃΛਐΊ͍ͯ͘தͰ ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ

  5. X © DMM.com $*Λಋೖ͍ͯ͠ͳ͍ w ͦ΋ͦ΋#VJME௨ͬͯͳ͍ w NBTUFS΋#VJME͕௨ͬͯͳ͍ w ͍͔ͭΒ௨ͬͯͳ͍ͷ͔Θ͔Βͳ͍

    w νʔϜ͕ΪεΪε͢Δ
  6. X © DMM.com -JOUΛಋೖ͍ͯ͠ͳ͍ w Πϯσϯτ͕ w ϨϏϡʔ಺༰ͷ΄ͱΜͲ͕ʮϑΥʔϚοτ͔͚ͯʯͰࡁΉ w νʔϜ͕ΪεΪε͢Δ

  7. X © DMM.com $%Λಋೖ͍ͯ͠ͳ͍ w ඇ։ൃऀҎ֎ͷਓ͕ɺ։ൃதͷΞϓϦΛ͞ΘΕͳͯ͘ෆ҆ w ඇ։ൃऀͷਓͨͪ޲͚ʹɺQSPEʹ͍ۙ΍ͭΛ৮Ζ͏ͱͯ͠΋Βͬͯ QSPHVSBEʹ͸·Δ w

    QSPHVBSE͸௨͚ͬͨͲɺHTPO͋ͨΓͷLFFQOBNFTͷઃఆΛ๨Εͯɺ "1*ίʔϧ͕શ໓͢Δ w νʔϜ͕ΪεΪε͢Δ
  8. X © DMM.com ςετΛॻ͍ͯͳ͍ w ϦϑΝΫλͰ͖ͳ͍ w มߋޙͷίʔυͱมߋલͷίʔυ͕ಉ͡ಈ͖Λ͢Δͱ͍͏อূ͕ Ͱ͖ͳ͍ w

    Ͳ͏͍͏ಈ࡞Λਖ਼ͱͨ͠ϩδοΫͳͷ͔Θ͔Βͳ͍ͷͰɺϨϏϡʔ͸ͳ Μͱͳ͘େৎ෉΍ΖͰBQQSPWF w ͦ΋ͦ΋΄΅΄΅ಈ͍ͯͳ͍ʢಈ࡞֬ೝ͞Εͯͳ͍ʣ w νʔϜ͕ΪεΪε͢Δ
  9. X © DMM.com ઃܭํ਑ΛܾΊͯͳ͍ w ਓʹΑͬͯॻ͖ํ͕શ͘ҧ͏ w ʮ๻ͷॻ͍ͯΔ7JFX.PEFM͸999͍ͬͯ͏੹຿͚ͩͲɺ͋ͳͨͷ ॻ͍ͯΔ7JFX.PEFM͸ͳΜ͔ҧ͍·ͤΜ͔ʁʯ w

    νʔϜ͕ΪεΪε͢Δ w ʮΈΜͳ͸.71͚ͩͲɺ๻͸.77.Ͱॻ͖·͢Ͷʯ
  10. X © DMM.com ৽ن։ൃ࣌ʹɺ·ͣ͸։ൃपΓͷ੔උΛ͢Δ͜ͱ͕ॏཁ w ෺ʹΑͬͯ͸ɺ్த͔Βͷಋೖ͕೉͍͠΋ͷɺίετ͕େ͖͍΋ͷ͕͋ Δ w ઃܭํ਑ w

    ಛʹ৽نνʔϜͰ͸ॏཁ w ςετํ਑ w ஌Βͳ͍ਓɺ஌ͬͯΔ͚Ͳಇ͍ͨ͜ͱͳ͍ਓͱɺԿ΋޻෉΋ͳ͘ େ͖ͳ΋ͷΛ࡞Γ্͛Δͷ͸ࠔ೉ɻԿ͔͠Βͷτϥϒϧ͸͋Γ͑ ΔͷͰɺ͋Β͔͡Ί૝ఆͰ͖Δ΋ͷΛରॲ͓ͯ͜͠͏ɻ
  11. X © DMM.com ৽ن։ൃΛ࢝ΊΔͱ͖༻ νΣοΫϦετ

  12. X © DMM.com νΣοΫϦετ  <>ϑΥʔϚολ  <>$*  <>$%

     <>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <>HSBEMFपΓͷ੔ཧ  <>%BOHFS  <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  13. X © DMM.com ࣮ࡍʹ΍͖ͬͯ·͠ΐ͏

  14. X © DMM.com IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM ελΠϧɾϑΥʔϚοτͷઃఆ ΍Δ͜ͱ  "4ͷઃఆ͔ΒɺͦΕͧΕͷελΠϧΛઃఆ͢Δ  FEJUPSDPOpHΛઃఆ͢Δ

     ϑΥʔϚολҎ֎ͷίʔσΟϯάن໿͸EPDVNFOUͳͲʹ·ͱΊ͓ͯ͘  TIBQF΍TFMFDUPSͳͲͷϑΝΠϧ໊ͷ໋໊نଇͳͲ
  15. X © DMM.com <ࣗ෼ͷ৔߹>ελΠϧɾϑΥʔϚοτͷઃఆ 1SFGFSFODFT&EJUPS$PEF4UZMF͔Β+BWB,PUMJO9.-ͦΕͧΕΛ ઃఆͯ͠ɺԼهϑΝΠϧΛίϛοτ

  16. X © DMM.com <ࣗ෼ͷ৔߹>ελΠϧɾϑΥʔϚοτͷઃఆ FEJUPSDPOpH΋ઃఆ͠Α͏ root = true [*] insert_final_newline=true

    indent_size = 2 continuation_indent_size = 2 IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM
  17. X © DMM.com νΣοΫϦετ  <Y>ϑΥʔϚολ  <>$*  <>$%

     <>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <>HSBEMFपΓͷ੔ཧ  <>%BOHFS  <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  18. X © DMM.com HJUIVCͰϓϩδΣΫτΛ࡞ͬͨΒɺ·ͣਅͬઌʹಋೖ͢΂͠ w DJSDMFDJ w 5SBWJT$* w #JUSJTF

    w +FOLJOT $*ͷಋೖ
  19. X © DMM.com IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM <ࣗ෼ͷ৔߹>$*ͷಋೖ  DJSDMFDJΛ࢖༻  ͻͱ·ͣMJOUͱUFTU͚ͩ૸Β͓ͤͯ͘ ./gradlew

    lint test  DJSDMFDJCBEHF΋ઃఆ͓ͯ͘͠
  20. X © DMM.com <ࣗ෼ͷ৔߹>$*ͷಋೖ  HJUIVCͷઃఆ΋๨Εͣʹ

  21. X © DMM.com νΣοΫϦετ  <Y>ϑΥʔϚολ  <Y>$*  <>$%

     <>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <>HSBEMFपΓͷ੔ཧ  <>%BOHFS  <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  22. X © DMM.com ඇ։ൃऀͷํʹ޲͚ͯɺಛʹσβΠφʔ͞Μ͕৮ΕΔΑ͏ʹॳΊ͔Β༻ҙ ͓ͯ͘͠ͷ͕٢ɻ πʔϧ͸༧ࢉ΍࢖͍উखͰબΜͰ͍ͩ͘͞ɻ  EFQMPZHBUF  'BCSJDCFUB

     ʢࣗ࡞ʣ $%ͷಋೖ
  23. X © DMM.com <ࣗ෼ͷ৔߹>$%ͷಋೖ

  24. X © DMM.com <ࣗ෼ͷ৔߹>$%ͷಋೖ - run: | GIT_HASH=$(git rev-parse --short

    HEAD) GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) curl \ -F "token=$DEPLOY_GATE_API_KEY" \ -F "file=@app/build/outputs/apk/debug/app-debug.apk" \ -F "message=git:$GIT_HASH" \ -F "distribution_name=$GIT_BRANCH" \ https://deploygate.com/api/users/kgmyshin/apps IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEDPNNJUGGEGFBEGCDEBED $*ʹઃఆ
  25. X © DMM.com νΣοΫϦετ  <Y>ϑΥʔϚολ  <Y>$*  <Y>$%

     <>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <>HSBEMFपΓͷ੔ཧ  <>%BOHFS  <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  26. X © DMM.com -JOU ΍Δ͜ͱ  BOESPJEMJOUͷϧʔϧͷݟ௚͠  LUMJOUPSEFUFLUͷಋೖ

  27. X © DMM.com <ࣗ෼ͷ৔߹>-JOUͷઃఆBOESPJEMJOU <?xml version="1.0" encoding="UTF-8"?> <lint> <issue id="all">

    <ignore path="build" /> </issue> <issue id="GoogleAppIndexingWarning" severity="ignore" /> </lint> ઃఆϑΝΠϧΛͭ͘Δ
  28. X © DMM.com android { ... lintOptions { ... lintConfig

    file("${rootDir.absolutePath}/lint/lint.xml") } } HSBMEFʹઃఆ͢Δɻ <ࣗ෼ͷ৔߹>-JOUͷઃఆBOESPJEMJOU
  29. X © DMM.com <ࣗ෼ͷ৔߹>-JOUͷઃఆLUMJOU buildscript { repositories { … maven

    { url "https://plugins.gradle.org/m2/" } } dependencies { classpath "org.jmailen.gradle:kotlinter-gradle:1.22.0" … } } 5PQMFWFMͷCVJMEHSBMEFʹઃఆ͢Δɻ ˞LPUMJOUFSHSBEMFΛ࢖ͬͯ·͕͢ɺଞͷ෺Ͱ΋͍͍Ͱ͢ɻ·ͨLUMJOU͡Όͳͯ͘΋EFUFLUͰ΋0,Ͱ͢
  30. X © DMM.com <ࣗ෼ͷ৔߹>-JOUͷઃఆLUMJOU NPEVMFͷCVJMEHSBMEFʹઃఆ͢Δɻ apply plugin: "org.jmailen.kotlinter" kotlinter {

    ignoreFailures = true reporters = ['checkstyle', 'plain'] indentSize = 2 continuationIndentSize = 2 }
  31. X © DMM.com <ࣗ෼ͷ৔߹>-JOUͷઃఆ ./gradlew lint lintKotlin $*Ͱ࣍ͷίϚϯυΛୟ͘Α͏ʹͯ͠ɺઃఆ׬ྃ IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM

  32. X © DMM.com νΣοΫϦετ  <Y>ϑΥʔϚολ  <Y>$*  <Y>$%

     <Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <>HSBEMFपΓͷ੔ཧ  <>%BOHFS  <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  33. X © DMM.com HSBEMFपΓͷ੔ཧ ϚϧνϞδϡʔϧͳϓϩδΣΫτͰ΍Δ৔߹͸͍Δ͚ͲɺγϯάϧϞδϡʔ ϧͳϓϩδΣΫτͰ͸ෆཁ͔΋ɻ ΍Δ͜ͱ  όʔδϣϯͳͲΛҰݩ؅ཧ

  34. X © DMM.com <ࣗ෼ͷ৔߹>HSBEMFपΓͷ੔ཧ ext.kotlin_version = '1.3.21' ext.versions = [

    compileSdk: 28, minSdk : 21, targetSdk : 28, code : 1, name : "0.9.0" ] ext.deps = [ kotlin : [ core : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version", reflect: "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" ], 7FSTJPOܥΛ·ͱΊͯ͠·͏
  35. X © DMM.com <ࣗ෼ͷ৔߹>HSBEMFपΓͷ੔ཧ android { compileSdkVersion versions.compileSdk defaultConfig {

    minSdkVersion versions.minSdk targetSdkVersion versions.targetSdk versionCode versions.code versionName versions.name ... } ... } dependencies { implementation deps.kotlin.core implementation deps.androidx.appcompat implementation deps.androidx.constraintlayout implementation deps.androidx.lifecycle implementation deps.androidx.recyclerview ... ͜Μͳײ͡Ͱ͔͚Δ
  36. X © DMM.com <ࣗ෼ͷ৔߹>HSBEMFपΓͷ੔ཧ apply plugin: 'com.android.library' apply from: "${rootDir.absolutePath}/modules/android_partial.gradle"

    dependencies { … } apply from: "${rootDir.absolutePath}/modules/ktlint_partial.gradle" BOESPJEͰͷઃఆ΍ɺLUMJOUपΓ΋·ͱΊͯ͠·͑͹ɺ ֤ϞδϡʔϧͷCVJMEHSBEMFΛ͜Μͳײ͡ʹ͢Δ͜ͱ΋Ͱ͖Δ IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM
  37. X © DMM.com νΣοΫϦετ  <Y>ϑΥʔϚολ  <Y>$*  <Y>$%

     <Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <Y>HSBEMFपΓͷ੔ཧ  <>%BOHFS  <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  38. X © DMM.com %BOHFSͷઃఆ $PQZSJHIU D 0SUB5IFSPY 3FMFBTFEVOEFSUIF.*5MJDFOTF IUUQTHJUIVCDPNEBOHFSEFTJHOCMPCNBTUFS-*$&/4& IUUQTEBOHFSTZTUFNTHVJEFTHFUUJOH@TUBSUFEIUNM

    ΍Δ͜ͱ͸ɺHFUUJOH@TUBSUFEϖʔδΛݟͳ͕ΒηοτΞοϓ͢Δ͚ͩ
  39. X © DMM.com %BOHFSͷઃఆ # Warn when there is a

    big PR warn("a large PR") if git.lines_of_code > 1000 ### lint ### Dir.glob("**/lint-results.xml").each { |report| android_lint.filtering = true android_lint.report_file = report.to_s android_lint.lint(inline_mode: true) } զ͕Ոͷ%BOHFSpMFʢͷҰ෦ʣɻ ϚϧνϞδϡʔϧʹΑΔରԠ͕ೖΓ·͢ɻ IUUQTHJUIVCDPNLHNZTIJOOFXQSPKFDUBOESPJEQVMM
  40. X © DMM.com νΣοΫϦετ  <Y>ϑΥʔϚολ  <Y>$*  <Y>$%

     <Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <Y>HSBEMFपΓͷ੔ཧ  <Y>%BOHFS  <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  41. X © DMM.com ϝοηʔδςϯϓϨʔτ ΍Δ͜ͱ  HJUIVCܥͷςϯϓϨʔτΛ༻ҙ͢Δ  PQU ίϛοτϝοηʔδͷςϯϓϨʔτΛ༻ҙͯ͠΋͍͍͔΋

  42. X © DMM.com ϝοηʔδςϯϓϨʔτ IUUQTIFMQHJUIVCDPNFOBSUJDMFTBCPVUJTTVFBOEQVMMSFRVFTUUFNQMBUFT

  43. X © DMM.com ίϛοτϝοηʔδͷ౷Ұ

  44. X © DMM.com νΣοΫϦετ  <Y>ϑΥʔϚολ  <Y>$*  <Y>$%

     <Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <Y>HSBEMFपΓͷ੔ཧ  <Y>%BOHFS  <Y>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  45. X © DMM.com ઃܭํ਑ ΍Δ͜ͱ  ઃܭํ਑ΛΈΜͳͰڞ༗Ͱ͖ΔΑ͏EPDVNFOUͳͲʹॻ͖ى͜͢

  46. X © DMM.com ઃܭํ਑

  47. X © DMM.com ઃܭํ਑

  48. X © DMM.com ઃܭํ਑

  49. X © DMM.com νΣοΫϦετ  <Y>ϑΥʔϚολ  <Y>$*  <Y>$%

     <Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <Y>HSBEMFपΓͷ੔ཧ  <Y>%BOHFS  <Y>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <Y>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  50. X © DMM.com ςετํ਑ ΍Δ͜ͱ ԼهΛEPDVNFOUʹى͜͢  ͲͷϑϨʔϜϫʔΫΛ࢖͏ͷ͔  Ͳ͜ʹͲΜͳςετΛॻ͘ͷ͔

     ͦͷςετ͸ԿΛอূ͢Δͷ͔  ॻ͖ํ͕Θ͔Δαϯϓϧ
  51. X © DMM.com ςετํ਑

  52. X © DMM.com νΣοΫϦετ  <Y>ϑΥʔϚολ  <Y>$*  <Y>$%

     <Y>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <Y>HSBEMFपΓͷ੔ཧ  <Y>%BOHFS  <Y>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <Y>ઃܭํ਑  <Y>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  53. X © DMM.com ։ൃϑϩʔ ΍Δ͜ͱ  HJUqPX HJUIVCqPX  

    TQSJOUͷྲྀΕΛͲ͏࢖͏ʁ
  54. X © DMM.com ։ൃϑϩʔ TQSJOUͷྲྀΕ  ϓϥϯχϯάͷ೔  ϓϥϯχϯά͕ऴΘͬͨΒͦͷ··ू·ͬͯશͯͷλεΫͷΫϥεਤ Λख෼͚ͯ͠ॻ͘

     6TF$BTF͚ͩγʔέϯεਤ΋ॻ͘  ͦΕҎ֎ͷ೔͸ΫϥεਤɺγʔέϯεਤΛݩʹΨϦΨϦίʔσΟϯά͢ Δ͚ͩ
  55. X © DMM.com ։ൃϑϩʔ UBTLͷྲྀΕʢઃܭํ਑͕ೃછΉ·Ͱ͸ࡉ͔͘΍ͬͯͨʣ  ػೳ࣮૷ϒϥϯν࡞੒  ೿ੜͤͯ͞EPNBJO࣮૷Ͱ13ͭ 

    JOGSB࣮૷Ͱ13ͭ  7JFX.PEFM -JWF%BUBΛ࣮૷ͯ͠13ͭ  'SBHNFOUʢओʹσβΠϯʣΛ࣮૷ͯ͠13ͭ  6TF$BTFΛ࣮૷ͯ͠13̍ͭ  ࠷ޙʹ%*Ͱܨ͛ͯಈ࡞֬ೝ·Ͱ΍ͬͯ13ͭ
  56. X © DMM.com ·ͱΊ

  57. X © DMM.com νΣοΫϦετ  <>ϑΥʔϚολ  <>$*  <>$%

     <>-JOU BOESPJEMJOU LUMJOUPSEFUFLU   <>HSBEMFपΓͷ੔ཧ  <>%BOHFS  <>ϝοηʔδςϯϓϨʔτʢHJUIVC HJUʣ  <>ઃܭํ਑  <>ςετํ਑  <>։ൃϑϩʔ  PQU $SBTIMZUJDT  PQU σόοάϝχϡʔ
  58. X © DMM.com ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ  ଞʹ΋͜͏͍͏ͷ΍ͬͨΒ͍͍ͱࢥ͏ʂͬͯͷ͕͋Ε͹ɺͥͻڭ͑ͯ͘ ͍ͩ͞ʂ