Slide 1

Slide 1 text

GitHub Actions 의 다양한 기능 활용하기

Slide 2

Slide 2 text

당근마켓 SRE팀 리드 GitHub Stars Outsider

Slide 3

Slide 3 text

Agenda 01 02 03 04 05 06 07 workflow_dispatch workflow_run workflow_call Composite action environments repository_dispatch Metrics

Slide 4

Slide 4 text

Agenda 01 02 03 04 05 06 07 workflow_dispatch workflow_run workflow_call Composite action environments repository_dispatch Metrics ㅇㅇ GitHub Actions에는 수많은 기능이 있지만 이번 발표에서는 워크플로우를 연결하는 기능을 모아봤습니다. 이름도 비슷하고 기능도 비슷하면서 약간의 차이도 있어서 어떤 상황에서 어떤 기능을 써야할지 정리해보는 시간이면 좋겠습니다.

Slide 5

Slide 5 text

workflow_ dispatch name: Demo on: push: pull_request: workflow_dispatch: jobs: 수동 실행

Slide 6

Slide 6 text

workflow_ dispatch name: Demo on: push: pull_request: workflow_dispatch: jobs: 수동 실행 ㅇㅇ workflow_dispatch를 사용하면 수동실행을 할 수 있습니다.

Slide 7

Slide 7 text

workflow_ dispatch

Slide 8

Slide 8 text

workflow_ dispatch ㅇㅇ 워크플로우 화면에서 수동 실행 버튼이 생긴걸 볼 수 있습니다. 이를 미리 켜두면 디버깅이나 환경변수를 잘못 설정해서 재시도할 때 유용합니다.

Slide 9

Slide 9 text

workflow_ dispatch on: push: pull_request: workflow_dispatch: inputs: name: description: 'Name' required: true debug: description: 'Debug Mode' type: boolean jobs: test: runs-on: ubuntu-latest steps: - run: env: NAME: ${{ inputs.name }} DEBUG: ${{ inputs.debug }}

Slide 10

Slide 10 text

workflow_ dispatch

Slide 11

Slide 11 text

Workflow D Workflow C workflow_ run Workflow A Workflow B

Slide 12

Slide 12 text

Workflow D Workflow C workflow_ run Workflow A Workflow B ㅇㅇ workflow_run은 한 저장소내에서 워크플로우간 연결을 할 수 있는 기능입니다. 워크플로우에는 Job과 Step이 있지만 더 복잡한 경우에는 워크플로우를 연결할 수 있습니다.

Slide 13

Slide 13 text

workflow_ run name: Test on: push: jobs: # 생략 name: Report on: workflow_run: workflows: [Test] types: - completed jobs: # 생략

Slide 14

Slide 14 text

workflow_ run name: Test on: push: jobs: # 생략 name: Report on: workflow_run: workflows: [Test] types: - completed jobs: # 생략 ㅇㅇ Test 워크플로우가 완료(complted)되면 Report가 실행됩니다.

Slide 15

Slide 15 text

workflow_ run types - completed - requested - in_progress

Slide 16

Slide 16 text

workflow_ run types - completed - requested - in_progress ㅇㅇ type에는 3가지가 있는데 완료, 요청, 진행중이 있습니다. reqeusted는 워크플로우가 요청되었을 때고 요청된 후 실행될 때까지 시간이 좀 걸리기 때문에

Slide 17

Slide 17 text

name: Report on: workflow_run: workflows: [Test] types: - completed jobs: build: if: ${{ github.event.workflow_run.conclusion >= ‘success’ }} workflow_ run

Slide 18

Slide 18 text

name: Report on: workflow_run: workflows: [Test] types: - completed jobs: build: if: ${{ github.event.workflow_run.conclusion >= ‘success’ }} workflow_ run ㅇㅇ completed는 완료를 의미하고로 성공이든, 실패든 Report 워크플로우는 실행됩니다. 보통 성공이냐 실패냐 따라 다르게 동작하고 싶을 것인데 이는 job에서 if 조건으로 검사해야 합니다. 그래서 워크플로우는 무조건 실행되고 실행된 이후 조건이 안맞으면 job 실행을 건너뛰는

Slide 19

Slide 19 text

name: Report on: workflow_run: workflows: [Test] types: - completed jobs: build: if: ${{ github.event.workflow_run.conclusion >= ‘failure’ }} workflow_ run

Slide 20

Slide 20 text

name: Lint on: workflow_call: jobs: # 생략 workflow_ call Reusable Reusable Workflow

Slide 21

Slide 21 text

name: Lint on: workflow_call: jobs: # 생략 workflow_ call Reusable Reusable Workflow ㅇㅇ workflow_call은 워크플로우를 재사용하는 기능입니다.

Slide 22

Slide 22 text

name: CI on: push: jobs: test: runs-on: ubuntu-latest steps: # 생략 call-lint: uses: ./.github/workflows/lint.yaml@main workflow_ call Reusable Caller Workflow

Slide 23

Slide 23 text

name: CI on: push: jobs: test: runs-on: ubuntu-latest steps: # 생략 call-lint: uses: ./.github/workflows/lint.yaml@main workflow_ call Reusable Caller Workflow ㅇㅇ 재사용가능한 워크플로우는 사용하는 워크플로우(Caller 워크플로우)에서는 job에서 uses를 써서 다른 워크플로우 파일을 지정할 수 있습니다.

Slide 24

Slide 24 text

workflow_ call Reusable

Slide 25

Slide 25 text

workflow_ call Reusable ㅇㅇ workflow_call은 job 수준으로 정의하므로 job으로 실행됩니다.

Slide 26

Slide 26 text

Called D Called C Caller A Called B workflow_ call Reusable

Slide 27

Slide 27 text

Called D Called C Caller A Called B workflow_ call Reusable ㅇㅇ workflow_call은 4단계까지만 연결할 수 있고 그 이후로는 연결해도 실행되지 않습니다.

Slide 28

Slide 28 text

workflow_ call Settings Actions

Slide 29

Slide 29 text

workflow_ call Settings Actions ㅇㅇ 재사용가능한 워크플로우는 상황에 따라 보안위협이 될 수도 있으므로 저장소에서 모든걸 허용할지, org내에서의 재사용가능한 워크플로우만 사용할 지 등을 지정할 수 있습니다.

Slide 30

Slide 30 text

uses:./.github/workflows/lint.yaml@main uses:org/repo/.github/workflows/lint.yaml@main workflow_ call Reusable 같은 저장소나 접근할 수 있는 원격 저장소

Slide 31

Slide 31 text

uses:./.github/workflows/lint.yaml@main uses:org/repo/.github/workflows/lint.yaml@main workflow_ call Reusable 같은 저장소나 접근할 수 있는 원격 저장소 ㅇㅇ 상대경로로 지정할때는 같은 저장소내의 워크플로우이고 아니면 절대 경로로 다른 저장소의 워크플로우를 지정할 수도 있습니다. 가볍게 사용하려면 main을 쓰고 관리를 잘 하려면 v1, v2같은 브랜치나 태그로 사용할 수 있습니다.

Slide 32

Slide 32 text

name: Lint on: workflow_call: inputs: name: required: true type: string secrets: token: jobs: lint: steps: - run: | echo ${{ inputs.name }} echo ${{ secrets.token }} workflow_ call Reusable Reusable Workflow 입력값과 시크릿 전달

Slide 33

Slide 33 text

name: Lint on: workflow_call: inputs: name: required: true type: string secrets: token: jobs: lint: steps: - run: | echo ${{ inputs.name }} echo ${{ secrets.token }} workflow_ call Reusable Reusable Workflow 입력값과 시크릿 전달 ㅇㅇ 하드코딩된 워크플로우를 사용만 하는게 아니라 다양하게 사용하려면 Caller에서 제어가 가능해야 하므로 받을 inputs와 secret을 지정할 수 있습니다. 이렇게 넘겨받은 값은 jobs에서 사용할 수 있습니다.

Slide 34

Slide 34 text

name: CI on: push: jobs: test: runs-on: ubuntu-latest steps: # 생략 call-lint: uses: ./.github/w…s/lint.yaml@main with: name: outsider secrets: token: ${{ secrets.TOKEN }} workflow_ call Reusable Caller Workflow

Slide 35

Slide 35 text

name: CI on: push: jobs: test: runs-on: ubuntu-latest steps: # 생략 call-lint: uses: ./.github/w…s/lint.yaml@main with: name: outsider secrets: token: ${{ secrets.TOKEN }} workflow_ call Reusable Caller Workflow ㅇㅇ Caller에서는 input는 with로 secrets는 secrets로 원하는 값을 전달합니다.

Slide 36

Slide 36 text

name: CI on: push: jobs: test: runs-on: ubuntu-latest steps: # 생략 call-lint: uses: ./.github/w…s/lint.yaml@main with: name: outsider secrets: token: ${{ secrets.TOKEN }} workflow_ call Reusable Caller Workflow ㅇㅇ 시크릿의 경우 항상 Caller쪽에서 넘겨야 합니다. 다른 저장소의 Reusable 워크플로우를 쓰는 경우 두 저장소에 모두 시크릿을 설정할 수 있는데 아마도 보안을 위해서 정책상 Reusable 워크플로우가 있는 저장소의 시크릿을 사용할 수 있는 기능은 존재하지 않습니다.

Slide 37

Slide 37 text

name: Composite inputs: name: outputs: result: value: ${{ steps.export.outputs.result }} runs: using: “composite” steps: - run: echo Hello ${{ inputs.name }} shell: bash - id: export run: echo “result=true” >> $GITHUB_OUTPUT shell: bash Composite action Reusable Reusable Workflow /action.yml /action.yaml

Slide 38

Slide 38 text

name: Composite inputs: name: outputs: result: value: ${{ steps.export.outputs.result }} runs: using: “composite” steps: - run: echo Hello ${{ inputs.name }} shell: bash - id: export run: echo “result=true” >> $GITHUB_OUTPUT shell: bash Composite action Reusable Reusable Workflow /action.yml /action.yaml ㅇㅇ Reusable 워크플로우에는 Composite action이란 것도 있습니다. 간단히 쓸 수 있는 reusable 워크플로우로 workflow_call과 composite action이 있고 이보다 더 복잡하면 javascript나 Dockerfile로 액션을 만들어야 합니다.

Slide 39

Slide 39 text

name: Composite inputs: name: outputs: result: value: ${{ steps.export.outputs.result }} runs: using: “composite” steps: - run: echo Hello ${{ inputs.name }} shell: bash - id: export run: echo “result=true” >> $GITHUB_OUTPUT shell: bash Composite action Reusable Reusable Workflow /action.yml /action.yaml ㅇㅇ workflow_call이 사용하고 있는 워크플로우를 다른 곳에서도 사용하게 하는 기능이라면 Composite action을 재사용되는 것만을 목적으로 한 액션입니다. 그래서 문법 자체가 다릅니다. 일단 저장소가 별도로 있어야 하고 루트에 action.yml 파일이 있어야 합니다.

Slide 40

Slide 40 text

jobs: test: runs-on: ubuntu-latest steps: - name: Caller’s build name: echo caller shell: bash - id: comp uses: outsieris/demo@main with: name: ‘Outsider’ - run: echo result = $RESULT shell: bash env: RESULT: ${{ steps.comp.outputs.result }} Composite action Reusable Caller Workflow

Slide 41

Slide 41 text

jobs: test: runs-on: ubuntu-latest steps: - name: Caller’s build name: echo caller shell: bash - id: comp uses: outsieris/demo@main with: name: ‘Outsider’ - run: echo result = $RESULT shell: bash env: RESULT: ${{ steps.comp.outputs.result }} Composite action Reusable Caller Workflow ㅇㅇ uses로 액션을 지정하는데 여기서는 step 단위에서 지정합니다.

Slide 42

Slide 42 text

Composite action Reusable

Slide 43

Slide 43 text

Composite action Reusable ㅇㅇ step에서 지정했으므로 workflow_call과는 다르게 다른 step과 섞여서 진행됩니다. 실제로는 composite action안에 여러 스탭이 존재하지만 caller쪽에서는 하나의 스탭으로 표시됩니다.

Slide 44

Slide 44 text

wokflow_call Job 으로 실행 Composite action Step 으로 실행 여러 Job을 포함할 수 있음 Job을 포함할 수 없음 최대 4단계 워크플로우 연결 가능 최대 10개 액션을 중첩 가능 시크릿 사용 가능 시크릿 사용 불가

Slide 45

Slide 45 text

on: push: jobs: build: runs-on: ubuntu-latest steps: # 생략 deploy-dev: needs: build steps: # 생략 deploy-prod: needs: deploy-dev steps: # 생략 needs

Slide 46

Slide 46 text

on: push: jobs: build: runs-on: ubuntu-latest steps: # 생략 deploy-dev: needs: build steps: # 생략 deploy-prod: needs: deploy-dev steps: # 생략 needs ㅇㅇ 앞에서 job은 병렬로 실행되는걸 봤는데 job간에 의존성을 지정하려면 needs를 사용할 수 있습니다.

Slide 47

Slide 47 text

needs

Slide 48

Slide 48 text

environments Settings Environments

Slide 49

Slide 49 text

environments Settings Environments ㅇㅇ CI용으로 만들어진 GitHub Actions도 발전하면서 CD를 위한 기능도 계속 추가되었고 배포관리를 위한 environments라는 기능도 들어왔습니다.

Slide 50

Slide 50 text

environments Settings Environments

Slide 51

Slide 51 text

environments Settings Environments ㅇㅇ job에서 environments를 사용하면 환경 변수나 시크릿은 별도로 사용할수도 있지만 특정 환경에서 리뷰어 등을 지정하면 승인했을때만 해당 Job이 실행되도록 할 수 있습니다.

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

on: repository_dispatch: workflows: [ trigger ] jobs: # 생략 repository_ dispatch

Slide 55

Slide 55 text

on: repository_dispatch: workflows: [ trigger ] jobs: # 생략 repository_ dispatch ㅇㅇ workflow_run은 같은 저장소내의 워크플로우끼리 연결할 수 있지만 repository_dispatch를 사용하면 다른 저장소나 외부 시스템과도 의존성을 연결할 수 있습니다.

Slide 56

Slide 56 text

on: repository_dispatch: workflows: [ trigger ] jobs: # 생략 repository_ dispatch ㅇㅇ 위 설정은 trigger라는 임의로 지정한 이벤트가 들어오면 해당 워크플로우가 실행되도록 설정했습니다. GitHub은 많은 부분이 이벤트 기반으로 동작하도록 되어 있고 사실 이 기능은 trigger라는 이벤트로

Slide 57

Slide 57 text

repository_ dispatch jobs: test: steps: - - run: | - gh api \ - /repos/outsideris/demo/dispatches \ -f event_type=’trigger’ env: GITHUB_TOKEN: ${{ secrets.PAT }}

Slide 58

Slide 58 text

repository_ dispatch jobs: test: steps: - - run: | - gh api \ - /repos/outsideris/demo/dispatches \ -f event_type=’trigger’ env: GITHUB_TOKEN: ${{ secrets.PAT }} ㅇㅇ 여기서는 gh CLI를 사용했는데 GitHub에 API로 dispatches 요청을 보낸 것입니다. 이벤트 타입을 trigger로 지정했으므로 해당 저장소의 워크플로우가 실행되고 권한이 필요하므로 토큰을 사용했습니다. 당연히 외부 시스템에서 웹훅을 보내도 똑같이 동작합니다.

Slide 59

Slide 59 text

on: repository_dispatch: workflows: [ trigger ] jobs: report: steps: - run: | echo \ ${{ github.event.client_payload.message }} repository_ dispatch

Slide 60

Slide 60 text

on: repository_dispatch: workflows: [ trigger ] jobs: report: steps: - run: | echo \ ${{ github.event.client_payload.message }} repository_ dispatch ㅇㅇ HTTP 웹훅이므로 이벤트 타입뿐 아니라 요청시 다양한 페이로드를 보낼 수 있고 워크플로우에서는 이 값에 따라 원하는 동작을 할 수 있습니다.

Slide 61

Slide 61 text

Action Usage Metrics Insights

Slide 62

Slide 62 text

Action Usage Metrics Insights ㅇㅇ 이건 번외로 최근에 추가되고 있는 액션 사용에 대한 메트릭입니다. 그동안은 org에서 액션을 전체적으로 파악할 수 있는 기능이 없었는데 Preview로 공개된 이 기능으로 어떤 저장소의 워크플로우가 많이 사용되고 있는지 어떤 OS나 러너가 사용되는지 볼 수

Slide 63

Slide 63 text

Action Performance Metrics Insights

Slide 64

Slide 64 text

Action Performance Metrics Insights ㅇㅇ 또한 최근엔 퍼포먼스 매트릭도 추가되어 각 워크플로우의 평균 실행시간이나 실패율을 볼 수 있어서 최적화해야할 워크플로우를 쉽게 찾을 수 있습니다.

Slide 65

Slide 65 text

outsideris [email protected] Thank you.