$30 off During Our Annual Pro Sale. View Details »

サービスを継続させるために / What we can do to keep the serv...

Avatar for kubo-sr kubo-sr
October 13, 2020
48

サービスを継続させるために / What we can do to keep the service going

Avatar for kubo-sr

kubo-sr

October 13, 2020
Tweet

Transcript

  1. ϦϦʔε͍ͨ͠ʂ • ͦͷมߋΛϦϦʔε͢ΔͨΊʹϝΠϯϥΠϯ΁ͱऔΓࠐΉ (ΠϯςάϨʔγϣϯ) • Ϛʔδͱݺ͹ΕΔ (ৄࡉ͸ׂѪ) • Ϛʔδͯ͠ຊ൪؀ڥ͸ഁյ͞Εͳ͍͔ʁ •

    ϢʔβʔʹΤϥʔը໘Λදࣔ͢ΔͱମݧΛଛͶΔ • ৴༻ΛଛͶΔ৔߹΋͋Δ • e.g. Τϥʔ͕ͰΔ EC αΠτ͸࢖͍ͨ͘ͳ͍ • ͔ͨ͠ΊΑ͏ 5
  2. ςετࣗಈԽ • (ྫ) ߪೖॲཧΛ͔ͨ͠ΊΔ 1. ձһͱͯ͠ϩάΠϯ͢Δ 2. Χʔτʹ঎඼Λ௥Ճ͢Δ 3. ߪೖ׬ྃը໘·ͰਐΊΔ

    • ਓ͕ؒϒϥ΢βʔΛ࢖͏ͱ 5 ෼͸͔͔Δ • ػցͳΒॅॴೖྗ͙ͩͬͯ͢Ͱ͖Δ✨ • ͕͔͔࣌ؒͬͯ΋ਓؒ͸ଞͷ࡞ۀʹۈ͠ΊΔ 7
  3. ςετྫ import collection.mutable.Stack import org.scalatest._ import flatspec._ import matchers._ class

    ExampleSpec extends AnyFlatSpec with should.Matchers { "A Stack" should "pop values in last-in-first-out order" in { val stack = new Stack[Int] stack.push(1) stack.push(2) stack.pop() should be (2) stack.pop() should be (1) } it should "throw Exception if an empty stack is popped" in { val emptyStack = new Stack[Int] a [NoSuchElementException] should be thrownBy { emptyStack.pop() } } } should ΍ assert ͳͲ࢖ͬͯ݁ՌΛ֬ೝ 16
  4. ࣮ߦ $ scala -cp scalatest_2.13-3.2.0.jar org.scalatest.run ExampleSpec Discovery starting. Discovery

    completed in 21 milliseconds. Run starting. Expected test count is: 2 ExampleSpec: A Stack - should pop values in last-in-first-out order - should throw NoSuchElementException if an empty stack is popped Run completed in 76 milliseconds. Total number of tests run: 2 Suites: completed 1, aborted 0 Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 0 All tests passed. 17
  5. ςετ͠΍͍͢ϓϩάϥϜ def inEventSeason(dt: OffsetDateTime): Boolean = { val now =

    new OffsetDateTime() ??? } // ؔ਺Λมߋ͠ͳ͚Ε͹ (·ͨ͸ϦϑϨΫγϣϯͰ͕Μ͹Βͳ͚Ε͹) // Πϕϯτظؒத͔͠ true Λฦ͞ͳ͍ val odt: OffsetDateTime = ??? assert(inEventSeason(odt)) 19
  6. ςετ͠΍͍͢ϓϩάϥϜ def inEventSeason(dt: OffsetDateTime)(implicit now: OffsetDateTime): Boolean = { ???

    } val targetDate: OffsetDateTime = ??? // -- 10 ೥ޙ -- // ࣮ࡍͷϓϩάϥϜ inEventSeason(targetDate) // ςετ implicit val now = OffsetDateTime.parse("2007-12-03T10:15:30+01:00") assert(inEventSeason(targetDate)) 21
  7. ςετ͠΍͍͢ϓϩάϥϜ 2 • Twelve-Factor App (Beyond the Twelve-Factor App) •

    Ҡ২ੑɾ෮ݩྗ • ؀ڥΛ໰Θͣ࠶ݱͰ͖Δ • σϓϩΠઌʹґଘ͢Δίʔυ͸΍ΊΑ͏ 22
  8. ؀ڥґଘ // ❌ if ("prod" == sys.env("APP_ENV")) { doSomethingOnProduction("postgres://username:password@localhost:5432/prod") }

    else { doSomething("postgres://username:password@localhost:5432/dev") } // ⭕ doSomething(sys.env("DATABASE_URL")) 24
  9. ϨΨγʔ γεςϜʹٹ͍͸͋Δͷ͔ • ςετͮ͠Β͍ϓϩάϥϜ͹͔ΓͰςετΛ௥ՃͰ͖ͳ͍ • Headless Browser ͕૿͑ͨ • ͓ۚ

    (ͱ࣌ؒ) ͔͚͑͞Ε͹࣮ࡍʹॲཧΛ࣮ߦ͢Δςετ͕Ͱ͖Δ • ҰํͰ΋଍Γͳ͍γεςϜʹٹ͍͸ͳ͍ 25
  10. ࣮ݱํ๏ • ҰൠతͳϦϙδτϦ αʔϏεʹ͸ϒϥϯνΛอޢ͢Δػೳ͕͋Δ • GitHub ͷ Branch protection ͳͲ

    • ͜ΕΛ࢖ͬͯϝΠϯϥΠϯʹ௚઀ϚʔδͰ͖ͳ͍Α͏ʹ • Pull Request ͷϨϏϡʔΛཁٻ͢Δػೳ͕͋Δ • CI ػೳ΋͋Δ 27
  11. GitHub Actions • ͳΜΒ͔ͷʮλεΫʯΛ࣮ߦ͢Δ؀ڥ • YAML ϑΝΠϧʹઃఆΛॻ͘ • ͦΕͧΕͷ࡞ۀ͸εςοϓͱݺ͹ΕΔ •

    ࣮ମ͸ίϚϯυ࣮ߦ • ੒ޭ͢Ε͹࣍ͷεςοϓ͕࣮ߦ͞ΕΔ • ςετ࣮ߦεςοϓΛ༻ҙ͠Α͏ 29
  12. GitHub Actions • PHPUnit ͷ @Group ΍ ScalaTest ͷ TagɺJest

    ͷ Test Suite Λ࢖͓͏ • GitHub Actions ͷϦιʔε͸ແݶ͡Όͳ͍ • ͢΂ͯͰ͸ͳ͘Ұ෦ͷςετΛ࣮ߦ͢ΔΑ͏ʹ • Headless Browser ͳͲ͕͔͔࣌ؒΔ΋ͷ͸࣮ߦ͠ͳ͍ 30
  13. .github/workflows/test.yml name: Verify that the code is valid. on: pull_request:

    branches: - master types: - opened - ready_for_review - synchronize jobs: verify: runs-on: ubuntu-latest if: github.event.pull_request.draft == false steps: - uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: 7.4 - name: Cache Composer packages id: composer-cache uses: actions/cache@v2 with: path: vendor key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-php- - name: Install dependencies if: steps.composer-cache.outputs.cache-hit != 'true' run: composer install --prefer-dist --no-scripts --no-progress --no-suggest - name: Validate code styles run: vendor/bin/php-cs-fixer fix --config=.php_cs.dist --dry-run --quiet src - name: Validate code quality run: vendor/bin/phpstan analyze --configuration=phpstan.neon.dist --quiet src - name: Running tests run: vendor/bin/phpunit --stop-on-warning --bootstrap tests/bootstrap.php --configuration phpunit.xml.dist tests 31
  14. GitHub Actions • ࣮ߦϑΝΠϧ (Executable) Λ࣮ߦ͢Δ͚ͩ • ʮςετʯ͚ͩͰ͸ͳ͍ • ੩తղੳ

    • ίʔυ ϑΥʔϚοτ (ݕূ͚ͩ΍Ζ͏) • ܅͚ͩͷϫʔΫϑϩʔΛ࡞ΕΔͧʂ 37
  15. σϓϩΠྫ (Cloud Functions) % gcloud functions deploy send_stt_api --entry-point main

    \ --set-env-vars topic_name=$TOPIC_NAME,error_bucket=$error_audio_bucket \ --runtime python37 --timeout 540s --trigger-resource $staging_audio_bucket \ --trigger-event google.storage.object.finalize Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 entryPoint: main environmentVariables: topic_name: stt_queue error_audio_bucket: error-audio-files-2104bfec-5a12-9974-ba23-c146c60449b0 eventTrigger: eventType: google.storage.object.finalize failurePolicy: {} you resource: projects/_/buckets/staging-audio-files-2104bfec-5d72-4874-bf65-c247c60349b0 service: storage.googleapis.com labels: deployment-tool: cli-gcloud name: projects/project-id/locations/us-central1/functions/send_stt_api runtime: python37 serviceAccountEmail: [email protected] sourceUploadUrl: https://storage.googleapis.com/gcf-upload-us-central1-05a2f-..... status: ACTIVE timeout: 540s updateTime: '2019-08-02T20:40:23Z' versionId: '1' 40
  16. ϦϦʔε ϑϩʔ (Ұྫ) 1. GitHub ʹτϐοΫ (࡞ۀ) ϒϥϯνΛ push 2.

    σϑΥϧτ ϒϥϯν΁ͷ Pull Request Λ࡞੒ 1. ͜ͷλΠϛϯάͰςετ࣮ߦ 2. ςετ͕੒ޭ͠ͳ͚Ε͹ϚʔδͰ͖ͳ͍Α͏ʹ͢Δ 3. Ϛʔδ 4. ϦϦʔε (GitHub Releases)ɺλά௥Ճ 43
  17. σϓϩΠࣗಈԽ • ࠓͲ͖ͷΫϥ΢υ αʔϏε͸ίϚϯυϥΠϯͰσϓϩΠՄೳ • ࣗಈԽͷνϟϯε • GCP ͳΒެࣜΞΫγϣϯ͕༻ҙ͞Ε͍ͯΔ •

    Ϩϯλϧ αʔόʔ͸গ͠໘౗ • SFTP ΍ rsync(1) Λ࢖͕ͬͯΜ͹Ζ͏ • ࣮ߦλΠϛϯάʹ஫ҙʂ 44
  18. σϓϩΠࣗಈԽ • GitHub Releases ʹ৽͍͠ Release Λ௥Ճͨ͠ΒσϓϩΠ 1. Ϛʔδ 2.

    Release ࡞੒ 3. σϓϩΠ։࢝ • GitHub Actions ͰσϓϩΠ ίϚϯυΛ࣮ߦ͢Δ 45
  19. .github/workflows/deploy.yml name: Scala CI on: release: types: - released jobs:

    deploy: runs-on: ubuntu-latest env: GCP_REGION: asia-northeast1 steps: - uses: actions/checkout@v2 - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master with: version: '303.0.0' project_id: ${{ secrets.GCP_PROJECT_ID }} service_account_key: ${{ secrets.GCP_SA_KEY }} export_default_credentials: true - name: Deploying Function run: | sbt assembly gcloud functions deploy calculator --region=${{ env.GCP_REGION }} \ --entry-point com.github.kubosr.f.App --runtime java11 --memory 512MB --trigger-http --source=target/scala-2.13 46
  20. ͞Βʹ • GitHub Actions ͷΠϕϯτΛ࢖͑͹ PR ࣌ʹσϓϩΠ΋Ͱ͖Δ • ݕূ༻؀ڥΛ Google

    App Engine ʹσϓϩΠͳͲ • ܅͚ͩͷσϓϩΠϝϯτΛ࡞ΕΔͧ
  21. ·ͱΊ • ։ൃ଎౓Λҡ࣋͢ΔͨΊʹ • ςετɾσϓϩΠΛࣗಈԽͯ͠ҡ࣋͢Δ • ؀ڥʹґଘ͠ͳ͍ίʔυΛ໨ࢦ͢ • ࣗಈςετ͸ਓؒͷෛ୲ΛݮΒͤΔ (Մೳੑ͕͋Δ)

    • ׂʹ߹Θͳ͍͜ͱ͸΍ΊΑ͏ • ςετͷࣗಈԽίετʹؾΛ͚ͭΔ • Ϋϥ΢υ αʔϏε͢Β͍Βͳ͍ͱ͖΋ • CD ͸Ϋϥ΢υ αʔϏεͱ૬ੑ͕͍͍ 49