GitHub Actions를 사용하여 모노 리포지토리에서 마이크로서비스용 CI 설정

이 기사에서는 단일 리포지토리로 구조화되고 Go로 작성된 여러 마이크로 서비스로 구성된 예제 애플리케이션에 대해 지속적 통합을 설정하는 방법을 설명합니다.

모노레포란?



마이크로 서비스의 맥락에서 애플리케이션을 모노 리포지토리로 구성한다는 것은 각 마이크로 서비스가 별도의 디렉터리에 상주하는 모든 마이크로 서비스에 대한 단일 리포지토리를 갖는 것을 의미합니다.

왜 모노레포인가?



명확하게 말하면, monorepo는 마이크로서비스 구조화를 위한 묘책이 아니며 고유한 이점과 단점이 있습니다. 일반적으로 이점에는 단순성, 일관성, 안정성 및 코드 재사용이 포함되는 반면 단점은 긴밀한 결합, git repo 확장성 및 코드 액세스 제어 부족으로 간주됩니다. 별도의 기사에서 마이크로서비스를 모노레포로 구성하는 것의 이점과 단점에 대해 더 깊이 파고들 것입니다.

예제 모노레포



monorepo로 구성된 example application을 살펴보겠습니다. 이것은 auth , usersarticles 의 세 가지 경로로 구성된 간단한 HTTP API입니다.

monorepo-actions-ci
└── routes
    ├── articles
    │   └── main.go
    ├── auth
    │   └── main.go
    └── users
        └── main.go

중요한 세부 사항은 각 경로가 자체 진입점main.go이 있는 독립적인 응용 프로그램이라는 것입니다.

routes/auth/main.go

package main

import "github.com/gin-gonic/gin"

func main() {
    router := gin.Default()

    router.GET("/auth", func(c *gin.Context) {
        c.String(200, "auth")
    })

    router.Run()
}



routes/users/main.go

package main

import "github.com/gin-gonic/gin"

func main() {
    router := gin.Default()

    router.GET("/users", func(c *gin.Context) {
        c.String(200, "users")
    })

    router.Run()
}



routes/articles/main.go

package main

import "github.com/gin-gonic/gin"

func main() {
    router := gin.Default()

    router.GET("/articles", func(c *gin.Context) {
        c.String(200, "articles")
    })

    router.Run()
}




GitHub 작업 설정



인증 경로.github/workflows/auth.yaml에 대한 간단한 작업 흐름을 만들어 보겠습니다.

name: "auth"

on:
  push:
    # run the workflow only on changes
    # to the auth route and auth workflow
    paths:
      - "routes/auth/**"
      - ".github/workflows/auth.yaml"

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1

      # run tests for route
      - name: Run tests
        run: |-
          cd routes/auth
          go test ./...

인증 경로가 변경되면 이 워크플로우가 실행됩니다go test. 또한 워크플로 파일이 변경될 때 실행되므로 워크플로 자체를 디버깅하는 데 유용합니다.

워크플로 생성 자동화



이제 다음 작업은 routes/usersroutes/articles 에 대해 동일한 워크플로우를 추가하는 것입니다. 그러나 이 경우 워크플로를 복제하는 것이 합리적인 접근 방식으로 보이지만 복잡한 워크플로와 많은 수의 경로가 있는 대규모 애플리케이션의 경우 문제가 됩니다.

대신 단일 워크플로 템플릿에서 워크플로를 자동으로 생성하는 것이 좋습니다. 한 끝점에서 다른 끝점으로 이동할 때 워크플로의 어떤 부분을 조정해야 하는지 결정하겠습니다.

name: "{{ROUTE}}"

on:
  push:
    paths:
      - "routes/{{ROUTE}}/**"
      - ".github/workflows/{{ROUTE}}.yaml"

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1

      - name: Run tests
        run: |-
          cd routes/{{ROUTE}}
          go test ./...


간단해 보인다. 이 템플릿을 .github/workflow-template.yaml에 넣고 이 템플릿에서 모든 엔드포인트에 대한 워크플로를 생성하는 bash 스크립트를 생성해 보겠습니다. 해당 스크립트를 workflows.sh에 넣겠습니다.

# read the workflow template
WORKFLOW_TEMPLATE=$(cat .github/workflow-template.yaml)

# iterate each route in routes directory
for ROUTE in $(ls routes); do
    echo "generating workflow for routes/${ROUTE}"

    # replace template route placeholder with route name
    WORKFLOW=$(echo "${WORKFLOW_TEMPLATE}" | sed "s/{{ROUTE}}/${ROUTE}/g")

    # save workflow to .github/workflows/{ROUTE}
    echo "${WORKFLOW}" > .github/workflows/${ROUTE}.yaml
done

파일을 생성한 후 스크립트를 실행 가능하게 만드는 것을 잊지 마십시오.

chmod +x ./workflows.sh

이제 스크립트를 실행하고 무슨 일이 일어나는지 봅시다:

monorepo-actions-ci
❯ ./workflows.sh
generating workflow for routes/articles
generating workflow for routes/auth
generating workflow for routes/users
.github/workflows를 간략히 살펴보면 스크립트가 /routes에 있는 각 경로에 대한 워크플로우를 자동으로 생성했음을 알 수 있습니다.

나무


├── .github
│   ├── workflow-template.yaml
│   └── workflows
│       ├── articles.yaml
│       ├── auth.yaml
│       └── users.yaml
├── routes
│   ├── articles
│   │   └── main.go
│   ├── auth
│   │   └── main.go
│   └── users
│       └── main.go
└── workflows.sh



.github/workflow/auth.yaml

name: "auth"

on:
  push:
    paths:
      - "routes/auth/**"
      - ".github/workflows/auth.yaml"

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1

      - name: Run tests
        run: |-
          cd routes/auth
          go test ./...



.github/workflow/users.yaml

name: "users"

on:
  push:
    paths:
      - "routes/users/**"
      - ".github/workflows/users.yaml"

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1

      - name: Run tests
        run: |-
          cd routes/users
          go test ./...




.github/workflow/articles.yaml

name: "articles"

on:
  push:
    paths:
      - "routes/articles/**"
      - ".github/workflows/articles.yaml"

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1

      - name: Run tests
        run: |-
          cd routes/articles
          go test ./...



작동합니까?



코드를 GitHub 리포지토리에 푸시하고 어떤 일이 발생하는지 살펴보겠습니다.

워크플로우가 시작됩니다:


워크플로 실행이 성공적으로 완료되었습니다.


인증 워크플로 세부정보:


각 워크플로 실행이 성공적으로 완료되었습니다. 성공! 🎉


이 글이 언젠가 도움이 되길 바랍니다. 아래 또는 의 의견에 귀하의 생각을 알려주십시오. 🖖

좋은 웹페이지 즐겨찾기