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

Android の静的解析における SARIF ファイルの活用

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Hiroyuki Kusu Hiroyuki Kusu
January 31, 2024

Android の静的解析における SARIF ファイルの活用

Android Test Night #9 ( https://testnight.connpass.com/event/305270 ) の資料

Avatar for Hiroyuki Kusu

Hiroyuki Kusu

January 31, 2024
Tweet

More Decks by Hiroyuki Kusu

Other Decks in Technology

Transcript

  1. ຊ೔ͷ಺༰ • GitHub code scanning ͷ֓ཁ • CIʢGitHub ActionsʣͰ֤छ ੩తղੳπʔϧͱ

    GitHub code scanning Λ ࿈ܞ͢Δํ๏ͷઆ໌ • Android Lint • ktlint • mobsfscan • Qodana • CodeQL • GitHub code scanning Λ࢖Θͳ͍৔߹ͷ SARIF ϑΝΠϧͷ׆༻ 
  2.  GitHub code scanning • ϦϙδτϦ಺ͷίʔυΛ෼ੳͯ͠ɺηΩϡϦςΟͷ੬ऑੑͱίʔσΟϯά ΤϥʔΛݟ͚ͭΔ͜ͱ͕Ͱ͖Δػೳ • CodeQLʢGitHub ͕։ൃͨ͠ίʔυ෼ੳΤϯδϯʣΛ࢖༻ͯ͠ίʔυΛ

    ෼ੳ͠ɺ݁ՌΛΞϥʔτͱͯ͠දࣔ͢Δ͜ͱ͕ग़དྷΔ • private ϦϙδτϦͰ͸ GitHub Advanced Security ͷϥΠηϯεʢ༗ྉʣ ͕ඞཁ
  3.  • CodeQL Ҏ֎ͷ੩తղੳπʔϧͰ΋ར༻Ͱ͖Δ • CI Ͱ SARIF ܗࣜͷϨϙʔτΛΞοϓϩʔυ͢Ε͹Α͍ •

    SARIFɿ Static Analysis Results Interchange Format ͷུ GitHub code scanning
  4.  { "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", "version": "2.1.0", "runs": [ { "originalUriBaseIds":

    { "%SRCROOT%": { "uri": "file:///home/runner/" } }, "results": [ { "level": "error", "locations": [ { "physicalLocation": { "artifactLocation": { "uri": “work/your-ropo/your-repo/app/src/main/java/com/example/myapp/android/MyApplicationTheme.kt”, "uriBaseId": "%SRCROOT%" }, "region": { "startColumn": 5, "startLine": 19 } } } ], "message": { "text": "Function name should start with a lowercase letter (except factory methods) and use camel case" }, "ruleId": "standard:function-naming" }, … ], "tool": { "driver": { "downloadUri": "https://github.com/pinterest/ktlint/releases/tag/1.0.1", "fullName": "ktlint", "informationUri": "https://github.com/pinterest/ktlint/", "language": "en", "name": "ktlint", "organization": "pinterest", "rules": [], "semanticVersion": "1.0.1", "version": "1.0.1" } } } ] } ktlint ͷ SARIF ϑΝΠϧͷྫ Schema ͷόʔδϣϯʢcode scanning ͸ 2.1.0 Λαϙʔτʣ ݕग़͞Εͨ໰୊ ࢖༻ͨ͠੩తղੳπʔϧͷ৘ใ πʔϧʹΑͬͯ͸ rules ཝʢͦΕҎ֎ͷ৔ॴͷ৔߹΋͋Δʣʹɺ֤ݕग़ϧʔϧ ͷิ଍৘ใ͕ॻ͔Ε͍ͯΔ
  5.  "results": [ { "level": "error", "locations": [ { "physicalLocation":

    { "artifactLocation": { "uri": “work/your-ropo/your-repo/app/src/main/java/com/example/myapp/android/MyApplicationTheme.kt”, "uriBaseId": "%SRCROOT%" }, "region": { "startColumn": 5, "startLine": 19 } } } ], "message": { "text": "Function name should start with a lowercase letter (except factory methods) and use camel case" }, "ruleId": "standard:function-naming" }, … ], ໰୊͕͋ΔϑΝΠϧͷύε ΤϥʔϨϕϧɻ͜͜Ͱ͸ͳ͘ rules ཝ౳ʹॻ͔Ε͍ͯΔ৔߹΋͋Δ ໰୊ͷίʔυͷҐஔɻπʔϧʹΑͬͯ͸։࢝Ґஔ͚ͩͰ ͳ͘ऴྃҐஔ΋ॻ͔Ε͍ͯΔ৔߹΋͋Δ ໰୊ͷ಺༰ͷςΩετ ݕग़ʹར༻ͨ͠ϧʔϧͷIDɻ͜ͷ ID ʹؔ͢Δิ଍৘ใ͕ rules ཝ౳ ʹॻ͔Ε͍ͯΔ৔߹͕͋Δ results ཝΛ֦େ
  6.  android { ... lint { sarifReport = true checkDependencies

    = true } } • SARIF ܗࣜͰϨϙʔτΛग़ྗ͢Δઃఆ • ϚϧνϞδϡʔϧߏ੒ͷ৔߹Ͱ΋ɺϧʔτͷϞδϡʔϧͰ checkDependencies = true Λࢦఆ͢Ε͹ɺαϒϞδϡʔϧࠐΈͷϨϙʔτ͕࡞੒͞ΕΔ Android Lint × GitHub code scanning app/build.gradle.kts
  7.  name: CI on: push: branches: [main] pull_request: branches: [main]

    jobs: analyze: runs-on: ubuntu-latest permissions: security-events: write actions: read contents: read steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v3 with: distribution: zulu java-version: 17 - run: ./gradlew app:lintDebug continue-on-error: true - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ./app/build/reports/lint-results-debug.sarif category: android-lint:debug Android Lint × GitHub code scanning github/codeql-action/upload-sarif action ͷ࣮ߦͰඞཁͳ permission code scanning ͕ར༻Ͱ͖ΔϦϙδτϦͰͳ͍৔߹͸͜ͷ step ͸ΤϥʔͱͳΓ·͢
  8.  - run: ./gradlew app:lintDebug continue-on-error: true Android Lint ×

    GitHub code scanning • ʢղੳॲཧ͕ਖ਼ৗʹऴΘͬͯ΋ʣ໰୊Λݕग़ͨ͠৔߹ʹऴྃίʔυ͕ 0 Ҏ֎ͱͳΔ੩తղੳ πʔϧͷ৔߹͸ continue-on-error: true Λࢦఆ • ϫʔΫϑϩʔ͕ fail εςʔλεͷ৔߹ɺcode scanning ͸ ղੳॲཧʹࣦഊ ͨ͠ͱΈͳ͢ • πʔϧଆͷઃఆͰɺͦ΋ͦ΋ҟৗऴྃ͠ͳ͍Α͏ʹͯ͠΋Α͍ • ྫ͑͹ Android Lint ͷ৔߹͸ abortOnError = false • ΋͘͠͸ ./gradlew app:lintDebug || true ͷΑ͏ʹͯ͠ҟৗऴྃΛѲΓ௵͢
  9.  Android Lint × GitHub code scanning - uses: github/codeql-action/upload-sarif@v3

    with: sarif_file: ./app/build/reports/lint-results-debug.sarif category: android-lint:debug • category ʹ͸೚ҙͷจࣈྻΛࢦఆՄೳ • লུ͢ΔͱʮϫʔΫϑϩʔϑΝΠϧ໊:δϣϒ໊ʯͱͳΔ • ʢ޷Έͷ໰୊Ͱ͸͋Δ͕ʣ೦ͷͨΊলུͤͣʹࢦఆ͓͍ͯͨ͠ํ͕ແ೉ͱࢥΘΕΔ • কདྷతʹϫʔΫϑϩʔΛ੔ཧͨ݁͠Ռɺδϣϒ໊͕มΘͬͯ͠·͏͜ͱ΋͋ΓಘΔ • ্هͷྫͰ͸πʔϧ໊ʹՃ͑ͯɺͲͷόϦΞϯτʹର͢Δղੳͳͷ͔Λ : Ҏ߱Ͱදݱ͍ͯ͠Δ • ͨͩԾʹ్தͰ category ͕มΘͬͯ͠·ͬͯ΋ɺͳΜͱͳ͘͸ཤྺͷඥ͚ͮ͸͞ΕΔ
  10.  val ktlintCheck by tasks.registering(JavaExec::class) { group = LifecycleBasePlugin.VERIFICATION_GROUP description

    = "Check Kotlin code style" classpath = ktlint mainClass.set("com.pinterest.ktlint.Main") args( "--color", "--reporter=plain", "--reporter=sarif,output=${buildDir}/reports/ktlint-results.sarif", "**/src/**/*.kt", "**.kts", "!**/build/**", ) // isIgnoreExitValue = true ҟৗऴྃͤ͞ͳ͍৔߹ } build.gradle.ktsʢϓϥάΠϯΛ࢖༻ͤͣʹ ktlint Λಋೖ͍ͯ͠Δ৔߹ʣ ktlint × GitHub code scanning
  11.  ktlint × GitHub code scanning name: CI on: push:

    branches: [main] pull_request: branches: [main] jobs: analyze: runs-on: ubuntu-latest permissions: security-events: write actions: read contents: read steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v3 with: distribution: zulu java-version: 17 - run: ./gradlew ktlintCheck continue-on-error: true - run: | cat './app/build/reports/ktlint-results.sarif' \ | jq '.runs[].results[].locations[].physicalLocation.artifactLocation.uri |= ltrimstr(“work/your-repo/your-repo/“)’ \ > '${{ runner.temp }}/ktlint-results.sarif' - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ runner.temp }}/ktlint-results.sarif category: ktlint
  12.  ktlint × GitHub code scanning - run: | cat

    './app/build/reports/ktlint-results.sarif' \ | jq '.runs[].results[].locations[].physicalLocation.artifactLocation.uri |= ltrimstr(“work/your-repo/your-repo/“)’ \ > '${{ runner.temp }}/ktlint-results.sarif' "artifactLocation": { "uri": “work/your-ropo/your-repo/app/src/main/java/com/example/myapp/android/MyApplicationTheme.kt”, "uriBaseId": "%SRCROOT%" } SARIF ϑΝΠϧͷՃ޻͕ඞཁ "artifactLocation": { "uri": “app/src/main/java/com/example/myapp/android/MyApplicationTheme.kt”, "uriBaseId": "%SRCROOT%" } uri ͔Β work/your-repo/your-rep/ Λআڈ
  13.  ktlint × GitHub code scanning file:///home/runner/work/your-ropo/your-repo/app/src/main/java/com/example/myapp/android/MyApplicationTheme.kt or app/src/main/java/com/example/myapp/android/MyApplicationTheme.kt GitHub

    code scanning Ͱ uri ͷύεΛਖ਼͘͠ೝࣝͤ͞Δʹ͸ɺ fi le:// ͔Β࢝·Δ CI ্ͷઈରύεɺ ΋͘͠͸ϦϙδτϦ௚ԼΛϧʔτͱ͢Δ૬ରύεͷͲͪΒͷܗࣜͰ͋Δඞཁ͕͋Δ SARIF ϑΝΠϧ಺ͷ SRCROOT Ͱ uri ͷϕʔεͷύε͕ఆٛ͞Ε͍ͯΔʢϕʔεͱ߹Θͤͯઈରύ εͱͳΔʣ৔߹͕͋Δ͕ɺcode scanning ͸ SRCROOT Λݟ͍ͯͳ͍
  14.  ktlint × GitHub code scanning - run: ./gradlew ktlintCheck

    --continue continue-on-error: true - run: | cat './app/build/reports/ktlint-results.sarif' \ | jq '.runs[].results[].locations[].physicalLocation.artifactLocation.uri |= ltrimstr(“work/your-repo/your-repo/")' \ > '${{ runner.temp }}/ktlint-results.sarif' - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ runner.temp }}/ktlint-results.sarif category: ktlint:app - run: | cat './shared/build/reports/ktlint-results.sarif' \ | jq '.runs[].results[].locations[].physicalLocation.artifactLocation.uri |= ltrimstr("work/your-repo/your-repo/")' \ > '${{ runner.temp }}/ktlint-results.sarif' - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ runner.temp }}/ktlint-results.sarif category: ktlint:shared 1ͭͷϞδϡʔϧͰҟৗऴ͕ྃ͋ͬͯ΋ܧଓ͢ΔΑ͏ʹ conitue Λࢦఆ ʢktlint ͷઃఆͰͦ΋ͦ΋ҟৗऴྃ͠ͳ͍Α͏ʹͯ͠΋Α͍ʣ ಉҰ job ͰಉҰπʔϧͷ݁ՌΛΞοϓϩʔυ͢Δ৔߹͸ category Λ ม͑Δඞཁ͕͋Δʢaction ͕ΤϥʔͱͳΔ ϚϧνϞδϡʔϧߏ੒ͷ৔߹
  15.  mobsfscan is a static analysis tool that can fi

    nd insecure code patterns in your Android and iOS source code. Supports Java, Kotlin, Android XML, Swift and Objective C Code. mobsfscan uses MobSF static analysis rules and is powered by semgrep and libsast pattern matcher. mobsfscan × GitHub code scanning README Ͱͷઆ໌
  16.  mobsfscan × GitHub code scanning name: CI on: push:

    branches: [main] pull_request: branches: [main] jobs: analyze: runs-on: ubuntu-latest permissions: security-events: write actions: read contents: read steps: - uses: actions/checkout@v4 - uses: MobSF/mobsfscan@main with: args: . --sarif --output results.sarif continue-on-error: true - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif category: mobsfscan
  17. mobsfscan × GitHub code scanning  • ݕग़Ͱ͖Δ໰୊͕Ҏ֎ʹগͳ͍ʁ • େ͖ͳϓϩδΣΫτͰ͸ࢼ͍ͤͯͳ͍͕ɺࢼ͠ʹ

    google/iosched ͷΞ ϓϦΛର৅ʹݕࠪͯ͠΋ 9 ݅ͷݕग़ͩͬͨ • ൺֱͱͯ͠ɺQodana ʹΑΔݕग़͸ 2,800 ݅ • ΋͔ͯ͜͠͠ΕͰ΋े෼ͳݕࠪ͸͞Ε͍ͯΔͷ͔΋͠Εͳ͍͕ɺ಺༰ͷ ਫ਼ࠪ͸ඞཁͦ͏
  18. Qodana × GitHub code scanning  • JVMʢJava / KotlinʣɺAndroid

    ͸ Community ϓϥϯʢແྉʣͰ΋࢖͑Δ • ଞͷ༗ྉϓϥϯͱͷػೳࠩ͸গ͋͠Δ • Community ϓϥϯ૬౰ͷػೳʢڪΒ͘ʣΛར༻͢ΔݶΓͰ͸ɺ JetBrains ΞΧ΢ϯτͳ͠ʹ GitHub Actions ͷϫʔΫϑϩʔͰར༻Ͱ͖Δ • ϫʔΫϑϩʔͱμογϡϘʔυʢQodana Cloudɻར༻ʹ͸ JetBrains ΞΧ΢ϯτ͕ඞཁʣΛ࿈ܞ͢Δ৔߹͸ɺCloud ଆͰൃߦ͞ΕͨτʔΫϯ ΛϫʔΫϑϩʔ΁ઃఆ͢Δඞཁ͕͋Δ
  19. version: "1.0" linter: jetbrains/qodana-jvm-android:2023.3 profile: name: qodana.recommended projectJDK: 17 Qodana

    × GitHub code scanning  ϦϙδτϦ௚Լʹ qodana.yaml ϑΝΠϧΛ഑ஔ
  20. Qodana × GitHub code scanning  name: CI on: push:

    branches: [main] pull_request: branches: [main] jobs: analyze: runs-on: ubuntu-latest permissions: security-events: write actions: read contents: read steps: - uses: actions/checkout@v4 - uses: JetBrains/[email protected] with: post-pr-comment: false use-annotations: false pr-mode: false - run: | cat '${{ runner.temp }}/qodana/results/qodana.sarif.json' \ | jq 'del(.runs[].automationDetails)' \ > '${{ runner.temp }}/qodana.sarif' - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ runner.temp }}/qodana.sarif category: qodana:jvm-android Qodana ͷϓϧϦΫ࿈ܞͷػೳ͸શͯ off ʹʢมߋߦʹର͢Δ annotation ͕ code scanning ͷ΋ͷͱඃΔͷͰʣ
  21.  Qodana × GitHub code scanning SARIF ϑΝΠϧͷՃ޻͕ඞཁ - run:

    | cat '${{ runner.temp }}/qodana/results/qodana.sarif.json' \ | jq 'del(.runs[].automationDetails)' \ > '${{ runner.temp }}/qodana.sarif' - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ runner.temp }}/qodana.sarif category: qodana:jvm-android .runs[].automationDetails ཝΛ࡟আ
  22.  Qodana × GitHub code scanning ʢલϖʔδͷଓ͖ʣcategory ΁ࢦఆͨ͠จࣈྻΑΓ΋ SARIF ಺ͷ

    .runs[].automationDetails.id ͷ จࣈྻ͕༏ઌ͞Ε code scanning ΁౉͞ΕΔɻຊདྷ͸ͦΕͰ΋Α͍͕ݱঢ়ɺQodana ͕ੜ੒͢Δ SARIF ϑΝΠϧͰ͸ϓϧϦΫͱ push ΠϕϯτͰ id ͷ಺༰͕ҟͳΔҝɺcode scanning ͷը໘Ͱ ܯࠂ͕දࣔ͞Εͯ͠·͏ Αͬͯࣄલʹ .runs[].automationDetails ཝΛ࡟আ͠ɺϫʔΫϑϩʔͰࢦఆͨ͠ category Λద༻ͤ͞Δ
  23.  Qodana × GitHub code scanning - uses: JetBrains/[email protected] env:

    QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} with: post-pr-comment: false use-annotations: false pr-mode: false Qodana ͷμογϡϘʔυʢQodana Cloudʣͱ࿈ܞ͢Δ৔߹ Cloud ଆͰൃߦ͞ΕͨτʔΫϯΛઃఆ
  24.  Qodana × GitHub code scanning • Android Lint ͱॏෳ͢Δݕ͕ࠪଟ͍͔΋͠Εͳ͍

    • ಉ࣌ʹϨϙʔτ͢Δͱ։ൃऀ͕ࠞཚͯ͠͠·͏Մೳੑ • Qodana ͱ Android Lint ͷݕࠪͷΧόʔൣғΛͦΕͧΕ֬ೝͨ͠ํ͕Α ͍͔΋ • ৔߹ʹΑͬͯ͸ Qodana ΁ҰຊԽ͢Δʁ
  25.  steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses:

    JetBrains/[email protected] with: post-pr-comment: true use-annotations: true pr-mode: true - run: | cat '${{ runner.temp }}/qodana/results/qodana.sarif.json' \ | jq 'del(.runs[].automationDetails)' \ > '${{ runner.temp }}/qodana.sarif' - uses: actions/checkout@v4 - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ runner.temp }}/qodana.sarif category: qodana:jvm-android σϑΥϧτ஋Ͳ͓ΓͳͷͰࢦఆͳ͠Ͱ΋Α͍ ʢuse-annotation Ҏ֎͸ push ΠϕϯτͰ͸ແࢹ͞ΕΔʣ Qodana × GitHub code scanningʢิ଍ʣ Ծʹ JetBrains/qodana-action ͷ pr-mode Λར༻͢Δ৔߹ɺϫʔΫεϖʔεͷ Git ͷঢ়ଶ͕ม Θͬͯ͠·͍ޙଓͷ github/codeql-action/upload-sarif ͕͏·͘ಈ͔ͳ͘ͳΔͷͰɺ࠶νΣοΫ Ξ΢τ౳Ͱ Git ͷঢ়ଶΛ໭͓ͯ͘͠ඞཁ͕͋Δ ԾʹϓϧϦΫͰ pr-mode Λར༻͢Δ৔߹ 0 ʹ͠ͳ͍ͱ pr-mode ͕ద༻͞Εͳ͍ ·ͨ post-pr-comment ͸ pull-requests: write permission ͕ɺ use-annotations ͸ checks: write permission ͕ඞཁ ͜͜Ͱ࠶νΣοΫΞ΢τ͕ඞཁʂ
  26.  Qodana × GitHub code scanningʢิ଍ʣ ʢલϖʔδͷଓ͖ʣQodana ʹ͸ GitHub Actions

    ͷ cache Λར༻ͨ͠Ϧιʔεͷ࠶ར༻ͷ࢓૊Έ ͕͋Δ͕ɺΩϟογϡ͕ແ͍ঢ়ଶͰ JetBrains/qodana-action Λ࢖༻͢Δͱɺͳ͔ͥݕग़݅਺͕ গͳ͘ͳΔݱ৅͕ΈΒΕͨɻকདྷతʹվળ͞ΕΔ͔΋͠Εͳ͍ɻ cache ͸σϑΥϧτͰ͸ϒϥϯνຖʹ࡞੒͞ΕΔɻmain ϒϥϯνͷΑ͏ͳ௕͘ར༻͞ΕΔϒϥϯ νͰ͸աڈͷ cache ͕͋Δҝ΄΅໰୊ͱ͸Βͳ͍͕ɺϓϧϦΫͷ৔߹͸ open ࣌͸ cache ͕ແ͍ ঢ়ଶͱͳͬͯ͠·͏ҝɺຊ action ͷ additional-cache-key ʹʮqodana-2023.3-ʯ౳ͷ cache Ωʔ Λࢦఆͯ͠ɺϚʔδઌͷϒϥϯν ·ͨ͸ σϑΥϧτϒϥϯνͷ cache Λ open ࣌ʹ΋ద༻͞ΕΔ Α͏ʹͨ͠ํ͕Α͍͔΋͠Εͳ͍ɻʢͨͩ cache ͷ෭࡞༻తͳ΋ͷ͸ؾʹͳΔͱ͜Ζ͕ͩɻʣ
  27. CodeQL × GitHub code scanning  name: CI on: push:

    branches: [main] pull_request: branches: [main] jobs: analyze: runs-on: ubuntu-latest permissions: security-events: write actions: read contents: read steps: - uses: actions/checkout@v4 - uses: github/codeql-action/init@v3 with: languages: java-kotlin - uses: actions/setup-java@v3 with: distribution: zulu java-version: 17 - run: ./gradlew assembleDebug - uses: github/codeql-action/analyze@v3 with: category: codeql:java-kotlin ͜ͷ action Ͱ SARIF ͷΞοϓϩʔυ·ͰߦΘΕΔ java-kotlin Λࢦఆ
  28. CodeQL × GitHub code scanning • ͦ΋ͦ΋ GitHub code scanning

    ͱ࿈ܞ͢Δ΋ͷͳͷͰ͢ΜͳΓಋೖͰ͖ Δʢ͸ͣʣ • ݕग़Ͱ͖Δ໰୊͕Ҏ֎ʹগͳ͍ʁ • େ͖ͳϓϩδΣΫτͰ͸ࢼ͍ͤͯͳ͍͕ɺࢼ͠ʹ google/iosched ͷΞ ϓϦΛର৅ʹݕࠪͯ͠΋ 1 ݅ͷݕग़ͩͬͨ • ൺֱͱͯ͠ɺQodana ʹΑΔݕग़͸ 2,800 ݅ • ݱ࣌఺Ͱ·ͩ ϕʔλ൛ ͔ͩΒ͔΋ʁ 
  29. GitHub code scanning Λ࢖Θͳ͍৔߹ • GitHub code scanning ͸ private

    ϦϙδτϦͰ͸ GitHub Advanced Security ͷϥΠηϯεʢ༗ྉʣ͕ඞཁ • ۀ຿ͷϓϩδΣΫτ͸େ֓ private ͳͷͰར༻͢Δʹ͸ෑډ͕͋Δ • ݱ࣌఺Ͱ͸ʢࢲͷ؍ଌൣғͰ͸ʣSARIF ϑΝΠϧ͔Βద੾ͳϨϙʔτΛ͠ ͯ͘ΕΔผͷαʔϏε΍πʔϧ౳͸ݟ͔ͭΒͳ͔ͬͨ • ͦ΋ͦ΋ SARIF ϑΝΠϧΛར༻͢Δඞཁ͕͋Δ͔ʁͱ͍͏͜ͱʹ͍ͭͯ ͸ɺ֤੩తղੳπʔϧΛ౷Ұతʹӡ༻͍ͨ͠ͱ͍͏χʔζʹର͢Δڞ௨ ϑΥʔϚοτͱͯ͠ɺ͜ΕΛར༻͢ΔҰఆͷҙٛ͸͋Δʢͱࢥ͏ʣ 
  30. GitHub code scanning Λ࢖Θͳ͍৔߹ • SARIF ͸ JSON ܗࣜͰ΋͋ͷͰɺ؆୯ʹσʔλΛύʔεͰ͖̎࣍ར༻͠΍ ͍͢

    • GitHub Actions ͷϫʔΫϑϩʔͰ͋Ε͹ jq ͕σϑΥϧτͰ࢖͑Δ • JavaScript Ͱ͋Ε͹ͦͷ·· JSON.parse() ͕Մೳ  .. ݱ࣌఺Ͱ͸ࣗલͰ SARIF ϑΝΠϧΛύʔεͯ͠ར༻͢ΔΑ͏ͳεΫϦϓτ Λ༻ҙ͢Δͷ͕ྑͦ͞͏
  31. GitHub code scanning Λ࢖Θͳ͍৔߹  ͜͜ͰɺCodeQL ʹ͍ͭͯ.. • GitHub code

    scanning ͕༗ޮͰͳ͍ϦϙδτϦͰ͸ github/codeql- action ܥͷҰ੾ͷ action ͕ΤϥʔͱͳΔ • ͜ΕΒͷ action Λར༻͠ͳ͘ͱ΋ɺCodeQL CLI Λར༻͢Ε͹ SARIF ϑΝΠϧͷग़ྗ·Ͱ͸ग़དྷͦ͏͕ͩɺֶज़ݚڀ౳ͷ໨తͰͳ͍ ৔߹͸ن໿ҧ൓ͱͳͬͯ͠·͏ • ͭ·ΓɺCodeQL ͸ GitHub code scanning ͱηοτͰར༻͢Δඞཁ ͕͋Δ Αͬͯ͜ΕҎ߱ͷ࿩͸ɺCodeQL Ҏ֎ͷ੩తղੳπʔϧͰͷ࿩ͱͳΓ·͢
  32.  - run: ./gradlew ktlintCheck continue-on-error: true - run: |

    cat './app/build/reports/ktlint-results.sarif' \ | jq '.runs[].results[].locations[].physicalLocation.artifactLocation.uri |= ltrimstr(“work/your-repo/your-repo/“)’ \ > '${{ runner.temp }}/ktlint-results.sarif' - run: | file='${{ runner.temp }}/ktlint-results.sarif' results="$(cat "$file" | jq -c '.runs[].results[] | { level, location: .locations[0].physicalLocation.artifactLocation.uri, line: .locations[0].physicalLocation.region.startLine, message: .message.text, ruleId }')" IFS=$'\n' for result in $results ; do level="$(echo "$result" | jq -r '.level')" location="$(echo "$result" | jq -r '.location')" line="$(echo "$result" | jq '.line')" message="$(echo "$result" | jq -r '.message')" ruleId="$(echo "$result" | jq -r '.ruleId')" case "$level" in 'error') message_level='error';; 'warning') message_level='warning';; 'note') message_level='notice';; *) # default message_level='warning' esac echo "::${message_level} file=${location},line=${line},title=${ruleId}::${message}" done ktlint ͷ SARIF ͷ಺༰Λ annotation ʹ͢Δྫ ※ ੩తղੳπʔϧʹΑͬͯ͸ level ͸ ruleId ΛΩʔͱͯ͠ rules ཝ౳͔Βऔಘ͢Δඞཁ͕͋Γ·͢ɻ·ͨΤϥʔͷৄࡉ಺ ༰΋ rules ཝ౳͔Βऔಘͨ͠ํ͕ΑΓΑ͍Ͱ͢
  33.  ϓϧϦΫͷ Files changed λϒͰͷදࣔ ktlint ͷ SARIF ͷ಺༰Λ annotation

    ʹ͢Δྫ ※ ຊདྷ͸։ൃऀ͕มߋͨ͠ߦͷΈʹ annotation ͢ΔΑ͏ͳ࣮૷Λͨ͠ํ͕Α͍Ͱ͢ ※ annotation ͷݸ਺ʹ͸੍ݶ͕͋Γ·͢ ※ ·ͨϨϏϡʔίϝϯτͱͯ͠ͷฦ৴΋Ͱ͖ͳ͍ͷͰɺannotation Ͱͳ͘ϓϧϦΫͷίϝϯτʹͨ͠ํ͕Α͍͔΋ Job Summaries Ͱͷදࣔ
  34.  - run: ./gradlew ktlintCheck continue-on-error: true - run: |

    cat './app/build/reports/ktlint-results.sarif' \ | jq '.runs[].results[].locations[].physicalLocation.artifactLocation.uri |= ltrimstr(“work/your-repo/your-repo/“)’ \ > '${{ runner.temp }}/ktlint-results.sarif' - run: | { file='${{ runner.temp }}/ktlint-results.sarif' results="$(cat "$file" | jq -c '.runs[].results[] | { level, location: .locations[0].physicalLocation.artifactLocation.uri, line: .locations[0].physicalLocation.region.startLine, message: .message.text, ruleId }')" IFS=$'\n' for result in $results ; do level="$(echo "$result" | jq -r '.level')" location="$(echo "$result" | jq -r '.location')" line="$(echo "$result" | jq '.line')" message="$(echo "$result" | jq -r '.message')" ruleId="$(echo "$result" | jq -r '.ruleId')" case "$level" in 'error') icon=':no_entry_sign:';; 'warning') icon=':warning:';; 'note') icon=':memo:';; *) # default icon=':warning:' esac location_url="https://github.com/${{ github.repository }}/blob/${{ github.sha }}/${location}#L${line}-${line}" echo "- ${icon} line ${line} in [${location}](${location_url})" echo " - **\`${ruleId}\`** ${message}" done } >> "$GITHUB_STEP_SUMMARY" ktlint ͷ SARIF ͷ಺༰Λ Job Summaries ΁ग़ྗ͢Δྫ ϚʔΫμ΢ϯܗࣜͰ Job Summaries ΁ग़ྗ
  35. • CodeQL Λআ͖ɺAndroid LintɺktlintɺmobsfscanɺQodana ͸ SARIF ܗࣜ Ҏ֎ʹ΋ HTML ܗࣜͰͷϨϙʔτग़ྗʹରԠ͍ͯ͠Δ

    • HTML Λ CI Ͱ GitHub Pages ΁σϓϩΠͯ͠Ӿཡ͢Δ • ීஈ Danger Λར༻͍ͯ͠Δ৔߹͸ danger-sarif ͱ͍͏ϓϥάΠϯ͕͋Δ • https://github.com/irgaly/danger-sarif • Qodana ͸ code scanning ͱ࿈ܞ͠ͳͯ͘΋͜Ε୯ମͰ݁ߏ͔ͭ͑Δ • Android Ͱ͋Ε͹ Community ϓϥϯʢແྉʣͰ࢖͑Δ • μογϡϘʔυʢQodana Cloudʣ࿈ܞ • ϓϧϦΫ࿈ܞʢannotation ΍αϚϦʔͷ౤ߘʣ  ͦͷଞͷબ୒ࢶ
  36. ͦͷ΄͔ࢀߟ৘ใ • detekt ΋ SARIF ͱ HTML ܗࣜͰͷϨϙʔτʹରԠ͍ͯ͠Δ • Dart

    Analyzerʢͱ Flutter AnalyzerʣͷϨϙʔτΛ SARIF ܗࣜ΁ม׵͢Δ GitHub custom action • https://github.com/marketplace/actions/dart-analyzer-sarif • JUnit ͷϨϙʔτΛ GitHub ͷ annotation ʹ͢Δ GitHub custom action • https://github.com/mikepenz/action-junit-report • ʢࠓճͷ SARIF ͷ࿩ͱ͸ؔ܎͋Γ·ͤΜ͕ʣ੩తղੳͱڞʹϓϧϦΫͷ CI ΁ಋ ೖ͢Δͱศརͩͱࢥ͍·͢