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

actionlint の Linter 設計

actionlint の Linter 設計

GitHub Actions のワークフローをチェックする Linter である actionlint について,その紹介と設計方針の解説をします.

Lint Night #3 at DeNA

Linda_pp

June 06, 2024
Tweet

More Decks by Linda_pp

Other Decks in Technology

Transcript

  1. w IUUQTHJUIVCDPNSIZTE BDUJPOMJOU w (JU)VC"DUJPOTͷͨΊͷ-JOUFS w 8PSL fl PXϑΝΠϧ w

    3FVTBCMF8PSL fl PXϑΝΠϧ w ϩʔΧϧͷ"DUJPO w ϦϙδτϦͷϧʔτͰBDUJPOMJOUίϚ ϯυΛ࣮ߦ͢Δ͚ͩ w IUUQTHJUIVCDPNSIZTE BDUJPOMJOUUSFFNBJOEPDT BDUJPOMJOU 
  2. (JU)VC"DUJPOTϫʔΫϑϩʔؒҧ͍୳͠ʢ̒ݸʣ test.yaml:3:5: unexpected key "branch" for "push" section. expected one

    of "branches", "branches-ignore", "paths", "paths-ignore", "tags", "tags-ignore", "types", "workflows" [syntax-check] | 3 | branch: main | ^~~~~~~ test.yaml:9:30: label "linux-latest" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-22.04", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-14-xl", "macos-14-xlarge", "macos-14- large", "macos-14", "macos-14.0", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "macos-13.0", "macos-12-xl", "macos-12- xlarge", "macos-12-large", "macos-12", "macos-12.0", "macos-11", "macos-11.0", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file [runner-label] | 9 | os: [windows-latest, linux-latest] | ^~~~~~~~~~~~~ test.yaml:11:13: context "secrets" is not allowed here. available contexts are "github", "inputs", "needs", "vars". see https://docs.github.com/ en/actions/learn-github-actions/contexts#context-availability for more details [expression] | 11 | if: ${{ secrets.API_KEY != '' }} | ^~~~~~~~~~~~~~~ test.yaml:13:45: "github.event.head_commit.message" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions for more details [expression] | 13 | - run: echo "Run test for commit '${{ github.event.head_commit.message }}'" | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test.yaml:16:11: input "submodule" is not defined in action "actions/checkout@v4". available inputs are "clean", "fetch-depth", "fetch-tags", "filter", "github-server-url", "lfs", "path", "persist-credentials", "ref", "repository", "set-safe-directory", "show-progress", "sparse- checkout", "sparse-checkout-cone-mode", "ssh-key", "ssh-known-hosts", "ssh-strict", "ssh-user", "submodules", "token" [action] | 16 | submodule: recursive | ^~~~~~~~~~ test.yaml:18:36: got unexpected character '"' while lexing expression, expecting 'a'..'z', 'A'..'Z', '_', '0'..'9', ''', '}', '(', ')', '[', ']', '.', '!', '<', '>', '=', '&', '|', '*', ',', ' '. do you mean string literals? only single quotes are available for string delimiter [expression] | 18 | if: ${{ matrix.platform != "windows-latest" }} | ^~~~~~~~~~~~~~~~ 
  3. (JU)VC"DUJPOTϫʔΫϑϩʔؒҧ͍୳͠ʢ̒ݸʣ test.yaml:3:5: unexpected key "branch" for "push" section. expected one

    of "branches", "branches-ignore", "paths", "paths-ignore", "tags", "tags-ignore", "types", "workflows" [syntax-check] | 3 | branch: main | ^~~~~~~ test.yaml:9:30: label "linux-latest" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-22.04", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-14-xl", "macos-14-xlarge", "macos-14- large", "macos-14", "macos-14.0", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "macos-13.0", "macos-12-xl", "macos-12- xlarge", "macos-12-large", "macos-12", "macos-12.0", "macos-11", "macos-11.0", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file [runner-label] | 9 | os: [windows-latest, linux-latest] | ^~~~~~~~~~~~~ test.yaml:11:13: context "secrets" is not allowed here. available contexts are "github", "inputs", "needs", "vars". see https://docs.github.com/ en/actions/learn-github-actions/contexts#context-availability for more details [expression] | 11 | if: ${{ secrets.API_KEY != '' }} | ^~~~~~~~~~~~~~~ test.yaml:13:45: "github.event.head_commit.message" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions for more details [expression] | 13 | - run: echo "Run test for commit '${{ github.event.head_commit.message }}'" | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test.yaml:16:11: input "submodule" is not defined in action "actions/checkout@v4". available inputs are "clean", "fetch-depth", "fetch-tags", "filter", "github-server-url", "lfs", "path", "persist-credentials", "ref", "repository", "set-safe-directory", "show-progress", "sparse- checkout", "sparse-checkout-cone-mode", "ssh-key", "ssh-known-hosts", "ssh-strict", "ssh-user", "submodules", "token" [action] | 16 | submodule: recursive | ^~~~~~~~~~ test.yaml:18:36: got unexpected character '"' while lexing expression, expecting 'a'..'z', 'A'..'Z', '_', '0'..'9', ''', '}', '(', ')', '[', ']', '.', '!', '<', '>', '=', '&', '|', '*', ',', ' '. do you mean string literals? only single quotes are available for string delimiter [expression] | 18 | if: ${{ matrix.platform != "windows-latest" }} | ^~~~~~~~~~~~~~~~ CSBODIͰ͸ͳ͘CSBODIFT ʢߏจνΣοΫʣ MJOVYMBUFTUͱ͍͏ϥϕϧ͸ແ͍ ʢϥϕϧνΣοΫʣ TFDSFUT͸͜͜Ͱ͸࢖͑ͳ͍ ʢBWBJMBCMFDPOUFYUTνΣοΫʣ ͜ͷ஋͸SVOͷεΫϦϓτ಺ʹຒΊࠐΜͰ ͸͍͚ͳ͍ʢTDSJQUJOKFDUJPOνΣοΫʣ BDUJPOTDIFDLPVUͷJOQVU͸ TVCNPEVMFT͕ਖ਼͍͠ ʢ༗໊ΞΫγϣϯͷJOQVUνΣοΫʣ μϒϧΫΥʔτ͸จࣈྻϦςϥϧʹ࢖͑ͳ͍ʢࣜͷߏจνΣοΫʣ
  4. αϙʔτ͍ͯ͠ΔνΣοΫ߲໨ IUUQTHJUIVCDPNSIZTEBDUJPOMJOUCMPCNBJOEPDTDIFDLTNE w 6OFYQFDUFELFZT w .JTTJOHSFRVJSFELFZTPSLFZEVQMJDBUFT w 6OFYQFDUFEFNQUZNBQQJOHT w 6OFYQFDUFENBQQJOHWBMVFT

    w 4ZOUBYDIFDLGPSFYQSFTTJPOA\\^^A w 5ZQFDIFDLTGPSFYQSFTTJPOTZOUBYJOA\\^^A w $POUFYUTBOECVJMUJOGVODUJPOT w $POUFYUVBMUZQJOHGPSATUFQTTUFQ@JEAPCKFDUT w $POUFYUVBMUZQJOHGPSANBUSJYAPCKFDU w $POUFYUVBMUZQJOHGPSAOFFETAPCKFDU w 4USJDUUZQFDIFDLTGPSDPNQBSJTPOPQFSBUPST w TIFMMDIFDLJOUFHSBUJPOGPSASVOA w QZ fl BLFTJOUFHSBUJPOGPSASVOA w 4DSJQUJOKFDUJPOCZQPUFOUJBMMZVOUSVTUFEJOQVUT w +PCEFQFOEFODJFTWBMJEBUJPO w .BUSJYWBMVFT w 8FCIPPLFWFOUTWBMJEBUJPO w 8PSL fl PXEJTQBUDIFWFOUWBMJEBUJPO w (MPC fi MUFSQBUUFSOTZOUBYWBMJEBUJPO w $30/TZOUBYDIFDLBUATDIFEVMFA w 3VOOFSMBCFMT w "DUJPOGPSNBUJOAVTFTA w -PDBMBDUJPOJOQVUTWBMJEBUJPOBUAXJUIA w 1PQVMBSBDUJPOJOQVUTWBMJEBUJPOBUAXJUIA w 0VUEBUFEQPQVMBSBDUJPOTEFUFDUJPOBUAVTFTA w 4IFMMOBNFWBMJEBUJPOBUATIFMMA w +PC*%BOETUFQ*%VOJRVFOFTT w )BSEDPEFEDSFEFOUJBMT w &OWJSPONFOUWBSJBCMFOBNFT w 1FSNJTTJPOT w $IFDLJOQVUEF fi OJUJPOTPGAXPSL fl PX@DBMMAFWFOUJOSFVTBCMFXPSL fl PX w $IFDLXPSL fl PXDBMMTZOUBY w $IFDLUZQFTPGAJOQVUT ABOEATFDSFUT AJOSFVTBCMFXPSL fl PX w $IFDLPVUQVUTJOSFVTBCMFXPSL fl PX w $IFDLJOQVUTBOETFDSFUTJOXPSL fl PXDBMM w $IFDLPVUQVUTPGXPSL fl PXDBMMJOEPXOTUSFBNKPCT w *%OBNJOHDPOWFOUJPO w $POUFYUTBOETQFDJBMGVODUJPOTBWBJMBCJMJUZ w %FQSFDBUFEXPSL fl PXDPNNBOET w $POEJUJPOTBMXBZTFWBMVBUFEUPUSVFBUAJGA w "DUJPONFUBEBUBTZOUBYWBMJEBUJPO 
  5. ✅࣮ߦ͕ߴ଎ʢ(Pʣ ϫʔΫϑϩʔϑΝΠϧ͝ͱͷฒྻԽ ϫʔΫϑ ϩʔϑΝ Πϧݕࡧ fi MFZNM wΤϥʔ wΤϥʔ wΤϥʔ

    wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ 7JTJUPS fi MFZNM 7JTJUPS wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ fi MFZNM 7JTJUPS wΤϥʔ wΤϥʔ wΤϥʔ wΤϥʔ ೖྗ ग़ྗ ύʔε ύʔε ύʔε ૸ࠪ ૸ࠪ ૸ࠪ ऩू ऩू ऩू (PSPVUJOF (PSPVUJOF (PSPVUJOF HPZBNMͰύʔεͨ͠ :".-πϦʔΛϫʔΫϑ ϩʔߏจ໦ʹύʔε ϧʔϧ͝ͱʹ7JTJUPSΛ ࣮૷͠ɼύεͰߏจ໦ Λ૸ࠪͯ͠ΤϥʔΛ୳͢ YTZODFSSHSPVQΛ ࢖ͬͯɼෳ਺εϨουΛ ଴ͪ߹ΘͤΔ 
  6. ✅࣮ߦ͕ߴ଎ʢ(Pʣ ֎෦ϓϩηεʢTIFMMDIFDL QZ fl BLFTʣͷฒྻԽ 8PSL fl PX +PC 3VMF4IFMMDIFDL

    7JTJUPS SVO SVO SVO +PC SVO SVO SVO (PSPVUJOF ૸ࠪ (PSPVUJOF (PSPVUJOF (PSPVUJOF (PSPVUJOF (PSPVUJOF ฒྻͰTIFMMDIFDL ϓϩηεΛ࣮ߦ run:͝ͱʹϓϩηεΛ࣮ߦ͢Δ (SPVUJOFΛੜ੒͢Δ ᷓΕͨ(PSPVUJOF͸ ଴ͨͤΔ Τϥʔ Τϥʔ Τϥʔ Τϥʔ TIFMMDIFDLͷใࠂ ͨ͠ΤϥʔΛऩू w ֎෦ϓϩηεͷ࣮ߦ͸஗͍ͷͰɼ(PSPVUJOFʹ౤͛ͯߏจ໦ͷ૸ࠪΛࢭΊͳ͍ w (PSPVUJOF͸ࢠϓϩηεͷऴྃ·Ͱ৸ͯ͠·͏ͷͰɼࢠϓϩηε͝ͱʹ(PSPVUJOFΛੜ੒͢Δͱεέδϡʔϥ͸ࢠϓϩηεΛ͋Δ ͚࣮ͩߦ͠Α͏ͱͯ͠͠·͏ɽͦͷͨΊࣗલͰฒྻ਺Λ੍ݶ͢Δඞཁ͋ΓʢYTZODTFNBQIPSFʣ w ฒྻʹ࣮ߦ͢Δࢠϓϩηεͷ਺͕૿͑͗͢Δͱ஗͘ͳΔ͠04ʹࡴ͞ΕΔ͜ͱ΋ 
  7. ✅؆୯ʹ࣮ߦͰ͖Δଞπʔϧ࿈ܞ w SFWJFXEPH w 1SPCMFN.BUDIFST w $*࣮ߦதʹBDUJPOMJOU͕ใࠂͨ͠ΤϥʔΛऩूͯ͠ྑ͍ײ͡ʹ݁ՌΛΞϊςʔγϣϯͯ͘͠ΕΔ w QSFDPNNJU w

    (JUϑοΫͰࣗಈͰBDUJPOMJOUΛ࣮ߦͰ͖Δ w ֤छςΩετΤσΟλϓϥάΠϯͰϑΝΠϧอଘ࣌ͳͲʹࣗಈ࣮ߦ w -formatίϚϯυΦϓγϣϯʹςϯϓϨʔτΛ౉ͯ͠Τϥʔग़ྗΛ੔ܗʢUFYUUFNQMBUFܗࣜʣ w +40/Ͱग़ྗ͍ͨ͠ˠactionlint -format '{{json .}}' w 4"3*'ͳͲͷෳࡶͳϑΥʔϚοτʹ΋ରԠͰ͖Δʢ$PEF2-ʣ 
  8. ✅؆୯ʹ࣮ߦͰ͖Δ(P"1* w BDUJPOMJOUͷ಺෦࣮૷Λ(PϞδϡʔϧͱͯ͠ެ։ IUUQTQLHHPEFWHJUIVCDPNSIZTEBDUJPOMJOU w BDUJPOMJOUΛ(PϓϩάϥϜͷதʹຒΊࠐΊΔ w ಠࣗͷϧʔϧΛ௥Ճ͠ΧελϚΠζͨ͠BDUJPOMJOUΛ ϏϧυͰ͖Δ w

    ϫʔΫϑϩʔͷύʔα΍ࣜͷܕνΣοΧʔͳͲ֤ύʔ πΛ࠶ར༻Ͱ͖Δ w ༗໊ͳ044Ͱ࣮ࡍʹ࢖ΘΕ͍ͯΔ w BDUIUUQTHJUIVCDPNOFLUPTBDU w (JUFBIUUQTHJUIVCDPNHPHJUFBHJUFB w 4DPSFDBSEIUUQTHJUIVCDPNPTTGTDPSFDBSE