설치

brew install go-task

아주 간단한 사용법

 cat taskfile.yaml
version: '3'

tasks:
  hello:
    cmds:
      - echo 'Hello World from Task!'
    silent: true
 task hello
Hello World from Task!

말그대로 task들을 코드로 관리하는 도구

  • 챗지피티 설명Taskfile의 주요 장점은 다음과 같습니다:
    1. 간단하고 명확한 문법: Taskfile은 가독성이 높고 쓰기 쉬운 문법을 제공합니다. 이는 개발자가 작업을 빠르게 정의하고 이해할 수 있게 해줍니다.
    2. 로컬 및 원격 실행 지원: Taskfile은 로컬 개발 환경과 원격 CI/CD 파이프라인에서 동일한 작업을 실행할 수 있게 해줍니다. 이는 개발 및 배포 과정의 일관성을 보장합니다.
    3. 작업 의존성 관리: Taskfile을 사용하면 작업 간의 의존성을 쉽게 정의하고 관리할 수 있습니다. 이는 작업 실행 순서를 자동화하고 복잡한 작업 흐름을 구성하는 데 도움이 됩니다.
    4. 재사용성 및 모듈화: Taskfile을 통해 정의된 작업은 재사용 가능하고 모듈화되어 있어, 다른 프로젝트나 파이프라인에서 쉽게 재사용할 수 있습니다.
    5. 확장성: Taskfile은 단순한 작업 실행부터 복잡한 파이프라인 구성까지 다양한 요구 사항을 수용할 수 있도록 설계되었습니다. 개발자는 필요에 따라 작업을 확장하고 사용자 정의할 수 있습니다.
    6. 통합 용이성: Taskfile은 GitHub Actions, Jenkins, GitLab CI 등 다양한 CI/CD 도구와 쉽게 통합될 수 있습니다. 이를 통해 개발 팀은 파이프라인을 효율적으로 관리하고 자동화할 수 있습니다.
    Taskfile은 Makefile과 비교할 때 더 현대적이고 사용자 친화적인 대안으로, 개발자들이 작업을 더 효율적으로 관리하고 실행할 수 있게 해줍니다. 추가적인 질문이 있거나 더 자세한 정보가 필요하시면 언제든지 문의해 주세요.
  • Taskfile은 개발 과정에서 다양한 작업을 관리하기 위한 도구입니다. 이 도구를 사용하면 테스트 실행, 빌딩, 패키징, 배포 등의 작업을 선언적 방식으로 정의하고 자동화할 수 있습니다. Taskfile의 주요 목적은 작업 실행을 단순화하고, 개발자가 로컬 및 CI/CD 파이프라인 환경에서 동일한 작업을 쉽게 실행할 수 있도록 하는 것입니다.

msbuild라던가 gradle의 여러 버전별로 사용해야 할 때 파이프라인에서 각 gradle의 환경변수를 직접 잡아줄 필요 없이 task를 사용하면 손쉽게 버전별 도구를 사용할수있지 않을가 싶다.

version: '3'

tasks:
  gradle6.1:
    cmds:
      - gradle6.1 wrapper --gradle-version=6.1
      - ./gradlew build
    desc: "Build the project with Gradle 6.1"

  gradle7.2:
    cmds:
      - gradle7.2 wrapper --gradle-version=7.2
      - ./gradlew build
    desc: "Build the project with Gradle 7.2"

이외에도 docker compose up , down 조차도 어려워하는 고객들에게 task를 사용하여 명령어를 만들어주고 사용하라고 해도 좋을듯.

가장 베스트는 개발자들이 직접 이 taskfile이라는 도구를 사용하면서 개발(로컬피씨)환경과 빌드서버환경을 통일하면 가장 좋을듯하다.

사용법 : https://www.youtube.com/watch?v=_-bpnCY3-FE

'job > devops' 카테고리의 다른 글

kubewarden  (0) 2024.01.20
openfunction  (0) 2023.12.01
git common flow(또는 gitlab flow) 브랜치 전략에 대한 설명  (0) 2023.06.13

kubewarden

Kubewarden은 쿠버네티스(Kubernetes) 클러스터의 보안과 정책 준수를 관리하기 위한 도구입니다.

Kubewarden을 사용하면, 클러스터에 어떤 파드(Pod, 쿠버네티스에서 애플리케이션을 실행하는 단위)가 생성되거나 업데이트될 때 적용되는 규칙이나 정책을 설정할 수 있습니다.

  • Kubewarden은 WebAssembly(WASM)와 쿠버네티스 admission controllers를 결합한 도구로, 다양한 언어로 작성된 정책을 컴파일하여 쿠버네티스에서 실행할 수 있게 해줍니다.
    • 쿠버네티스의 Admission Controllers
      • 쿠버네티스의 Admission Controllers는 쿠버네티스 API 서버로의 요청을 가로채서 검사하고, 수정하거나 거부하는 역할을 합니다.
      • 이들은 쿠버네티스 클러스터에서 리소스(파드, 서비스 등)의 생성, 업데이트, 삭제 등의 요청이 처리되기 전에 특정 규칙이나 정책을 적용합니다.
      • 예를 들어, 특정 파드가 너무 많은 CPU 자원을 요청하는 것을 막거나, 특정 네임스페이스에서만 리소스를 생성할 수 있도록 제한하는 등의 작업을 수행합니다.
      • Admission Controllers는 쿠버네티스의 보안과 정책 준수를 강화하는 데 중요한 역할을 합니다.
  • Kubewarden을 사용하면 정의된 정책을 적용하고, 이 정책들이 쿠버네티스 API로의 요청을 수락, 거부 또는 변경할 수 있습니다.

    Kubewarden의 정책 모듈은 컨테이너 이미지로 참조되며, 이는 정책을 이미지에 저장하고 있다는 것을 의미합니다. 예를 들어, 특정 이미지가 권한 있는 파드의 실행을 방지하는 정책을 가지고 있을 수 있습니다. 
    • 예시
apiVersion: policies.kubewarden.io/v1
kind: ClusterAdmissionPolicy
metadata:
  name: validate-pod-security-standards
spec:
  module: registry://ghcr.io/kubewarden/policies/validate-pod-security-standards:v1.0.0
  rules:
  - apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
    operations:
    - CREATE
    - UPDATE
  mutating: false
  settings: 
    requiredLabels: # 파드에 반드시 존재해야 하는 레이블들을 정의합니다.
      - "app.kubernetes.io/name"
      - "app.kubernetes.io/version"
    requiredAnnotations: # 파드에 반드시 존재해야 하는 어노테이션을 정의합니다.
      - "kubewarden.policy/owner"
    enforceRunAsNonRoot: true # 파드가 Non-root 사용자로 실행되어야 한다는 요구사항을 설정합니다.
    allowedCapabilities: [] # 파드에서 허용되는 추가적인 리눅스 기능(capabilities)을 비어 있는 배열로 설정하여 모든 추가 기능을 금지합니다.

 

이 설정에 따르면:

  • module: registry://ghcr.io/kubewarden/policies/validate-pod-security-standards:v1.0.0: Kubewarden 정책 모듈은 쿠버네티스 클러스터에서 파드의 보안 표준을 검증하는 데 사용됩니다. 이 모듈의 주요 목적과 기능은 다음과 같습니다:
  • requiredLabels: 모든 파드에는 **app.kubernetes.io/name**과 app.kubernetes.io/version 레이블이 있어야 합니다. 이는 파드가 어떤 애플리케이션에 속하는지와 애플리케이션의 버전을 명시하는 데 사용됩니다.
  • requiredAnnotations: 모든 파드에는 kubewarden.policy/owner 어노테이션이 있어야 합니다. 이는 정책의 소유자 또는 관리자를 지정하는 데 사용될 수 있습니다.
  • enforceRunAsNonRoot: 이 값이 **true**로 설정되면, 모든 파드는 루트가 아닌 사용자로 실행되어야 합니다. 이는 보안 관행에 따른 것입니다.
  • allowedCapabilities: 이 배열이 비어 있기 때문에, 파드에서 어떠한 추가 리눅스 기능도 허용되지 않습니다. 이는 파드가 더 높은 권한을 가지는 것을 방지합니다.

 

  • Kubewarden 정책은 Artifact Hub에서 찾을 수 있으며, 이곳은 쿠버네티스 관련 거의 모든 것을 찾을 수 있는 장소입니다.
    • artifact hub

 

  • 사용자는 Kubewarden을 사용하여 사용자 정의 정책 모듈을 개발하고 적용할 수 있습니다. 예를 들어, 특정 크기의 SQL 클레임만을 허용하는 사용자 정의 정책을 만들 수 있습니다.
    • 사용자 정의 정책 생성 방법
      1. 정책 요구 사항 정의: 먼저, 이 정책이 해결하려는 문제를 정의합니다. 예를 들어, 클러스터에서 너무 큰 SQL 데이터베이스가 생성되는 것을 방지하고자 할 수 있습니다. 이를 위해 'small', 'medium', 'large'와 같은 특정 크기만을 허용하고자 하는 요구 사항을 정의합니다.
      2. 정책 로직 개발: 다음으로, 이 요구 사항을 구현하는 로직을 개발합니다. 이 과정에서는 Kubewarden 정책을 구현할 수 있는 프로그래밍 언어(예: Rust, Go 등)를 사용하여, SQL 클레임의 크기를 검사하고, 허용된 크기에 맞지 않는 클레임을 거부하는 코드를 작성합니다.
      3. WASM으로 컴파일: 개발한 정책 로직을 WebAssembly(WASM)로 컴파일합니다. WASM은 다양한 환경에서 실행될 수 있는 저수준 바이너리 포맷입니다. Kubewarden은 WASM 형식의 정책을 실행합니다.
      4. 정책 모듈 배포: 컴파일된 정책 모듈을 컨테이너 이미지로 패키징하고, Docker 레지스트리(예: Docker Hub, GHCR 등)에 배포합니다.
      5. Kubewarden 정책 설정: Kubewarden 정책을 쿠버네티스 클러스터에 적용합니다. 이때 정책 모듈의 위치와 해당 정책이 적용될 리소스 및 조건을 지정하는 YAML 파일을 작성하고 적용합니다.
      apiVersion: policies.kubewarden.io/v1
      kind: ClusterAdmissionPolicy
      metadata:
        name: sql-size-restriction
      spec:
        module: registry://myregistry.io/kubewarden/sql-size-restriction:v1.0.0
        rules:
        - apiGroups: [""]
          apiVersions: ["v1"]
          resources: ["sqlclaims"]
          operations:
          - CREATE
          - UPDATE
        mutating: false
        settings:
          allowedSizes:
            - small
            - medium
            - large
      
      이 예시에서, 정책은 **sqlclaims**라는 커스텀 리소스에 적용되며, 생성 또는 업데이트 시 'small', 'medium', 'large'라는 크기 제한을 강제합니다. 이를 통해 쿠버네티스 클러스터 내에서 자원 사용을 효과적으로 관리하고, 과도한 리소스 사용을 방지할 수 있습니다.
    • Kubewarden을 사용하여 사용자 정의 정책 모듈을 개발하고 적용하는 예시로, "특정 크기의 SQL 클레임만을 허용하는 정책"을 들 수 있습니다. 이런 종류의 정책은 쿠버네티스 클러스터에서 SQL 데이터베이스 리소스의 크기를 제한하는 데 사용될 수 있습니다. 여기에는 몇 가지 주요 단계가 있습니다:
  • Kubewarden의 장점 중 하나는 거의 모든 언어(WASM으로 컴파일될 수 있어야 함)로 정책을 작성할 수 있다는 것이며, 이는 다른 정책 도구와 구별되는 주요 특징입니다.
  • Kubewarden의 단점으로는 새 정책을 추가할 때마다 정책 서버가 재시작되어야 한다는 점과 쿠버네티스 표준을 따르지 않아 이벤트가 발생하지 않는다는 점이 있습니다.
    • 이벤트 미발생 예시
      • 쿠버네티스 클러스터에서 '파드 메모리 제한' 정책이 위반되어 파드 생성이 거부되었다고 가정해봅시다.
      • 쿠버네티스 표준을 따르는 시스템에서는 이러한 거부 사건이 '이벤트'로 기록되고, 시스템 관리자나 다른 애플리케이션에서 이를 감지할 수 있습니다.
      • 하지만 Kubewarden은 이러한 이벤트를 생성하지 않기 때문에, 관리자나 다른 시스템이 이러한 중요한 정보를 즉시 알 수 없을 수 있습니다.
    • 쿠버네티스에서는 보통 중요한 변화나 상태 변경 시 '이벤트'를 발생시켜 사용자나 다른 시스템 요소에 알립니다.하지만, Kubewarden은 쿠버네티스 표준 이벤트 생성을 지원하지 않아 이러한 알림이 발생하지 않습니다.

'job > devops' 카테고리의 다른 글

taskfile  (0) 2024.03.10
openfunction  (0) 2023.12.01
git common flow(또는 gitlab flow) 브랜치 전략에 대한 설명  (0) 2023.06.13

OpenFunction은 자체 서버리스 컴퓨팅 플랫폼으로 쿠버네티스 기반이다.

서버리스란 개발자들이 애플리케이션을 만들 때 서버를 직접 구축하고 관리하는 대신에 클라우드 공급자(예: AWS, Azure, Google Cloud)가 제공하는 서버리스 서비스를 사용하는 것을 의미합니다. 이는 개발자들이 애플리케이션 코드에 집중할 수 있도록 도와주며, 서버 관리와 같은 인프라 작업을 간소화합니다.

그러나 이 방법을 선택하면 약간의 제한사항이 발생할 수 있습니다. 예를 들어, 클라우드 공급자가 제공하는 서비스의 방식과 기능을 따라야 하기 때문에 개발자가 특정한 제한 사항을 갖게 될 수 있습니다. 이것이 바로 "벤더 락인" 또는 "공급자 종속성"이라고 불리는 현상입니다.

간단히 말해서, 서버리스를 사용하면 편리하고 빠른 개발이 가능하지만, 클라우드 공급자가 정한 규칙과 제한사항을 따라야 하므로 개발자가 자유롭게 원하는 대로 모든 것을 조절하는 것이 어려울 수 있습니다. 따라서 이러한 제한을 고려하여 개발 방향을 결정해야 합니다.

OpenFunction은 서버리스 컴퓨팅 플랫폼으로, 사용자가 애플리케이션의 비즈니스 로직에 집중할 수 있게 해주는 것을 목표로 합니다. 즉, 사용자는 기반 인프라나 운영 체제, 하드웨어 등에 대해 걱정할 필요 없이 애플리케이션 개발에만 집중할 수 있습니다.

그러나 실제로 OpenFunction을 사용하려면, 사용자가 스스로 이 플랫폼을 설정하고 유지 관리해야 합니다. 이것은 Kubernetes 클러스터의 설정 및 유지 관리, OpenFunction이 통합하는 다양한 구성 요소(예: 빌드 도구, 실행 환경)의 유지 관리, 그리고 OpenFunction 자체의 유지 관리를 포함합니다.

간단히 말해서, OpenFunction은 개발자가 애플리케이션 개발에만 집중할 수 있게 도와주는 플랫폼이지만, 이 플랫폼 자체를 운영하고 유지 관리하기 위해서는 기술적인 지식과 추가적인 노력이 필요하다는 것입니다. 따라서 비전공자나 기술적 지식이 부족한 사람이 OpenFunction을 효과적으로 사용하려면, 기술적인 부분을 관리할 수 있는 전문가의 도움이 필요할 수 있습니다.

강점으로는 서버리스 컴퓨팅의 이점, 다양한 도구와의 통합

단점으로는 불친절한 문서화, 특정 기술에 대한 깊은 이해가 필요하다는 점, 빌더가 자주 유지되지 않는다는 점

실제 사용 사례: 함수 생성, HTTP 트리거, 데이터베이스 연동, 스케일링 테스트 등을 포함합니다.

 

로컬 소스 코드에서 함수를 빌드 방법

컨테이너 이미지로 소스 코드 패키징: 로컬에 있는 소스 코드를 컨테이너 이미지로 패키징하고, 이 이미지를 컨테이너 레지스트리에 푸시합니다.

Dockerfile 사용: 소스 코드가 'samples' 디렉토리에 있다고 가정할 때, 아래와 같은 Dockerfile을 사용하여 소스 코드 번들 이미지를 빌드할 수 있습니다

dockerfileCopy code
FROM scratch
WORKDIR /
COPY samples samples/

 

이미지 빌드 및 푸시: 다음 명령어를 사용하여 소스 코드 번들 이미지를 빌드하고 푸시합니다.

bashCopy code
docker build -t <your registry name>/sample-source-code:latest -f </path/to/the/dockerfile> .
docker push <your registry name>/sample-source-code:latest

 

 

Scratch 이미지 사용 권장: 소스 코드 번들 이미지를 빌드할 때는 비어 있는 scratch 이미지를 기본 이미지로 사용하는 것이 좋습니다. 비어 있지 않은 기본 이미지는 소스 코드 복사에 실패할 수 있습니다.

 

Function 정의 변경: Git 저장소 방식으로 **spec.build.srcRepo.url**을 정의하는 것과 달리, 로컬 소스 코드를 사용할 때는 spec.build.srcRepo.bundleContainer.image 필드를 정의해야 합니다.

yamlCopy code
apiVersion: core.openfunction.io/v1beta2
kind: Function
metadata:
  name: logs-async-handler
spec:
  build:
    srcRepo:
      bundleContainer:
        image: openfunctiondev/sample-source-code:latest
      sourceSubPath: "/samples/functions/async/logs-handler-function/"

 

Cloud Native Buildpacks 사용: OpenFunction은 Cloud Native Buildpacks를 사용하여 Dockerfile 생성 없이 함수 이미지를 빌드하는 것을 지원합니다. 이는 Serverless Applications을 Dockerfile과 함께 빌드할 때도 사용될 수 있습니다​​.

 

Build 섹션 정의를 통한 함수 빌드: 사용자는 Git 저장소의 소스 코드나 로컬에 저장된 소스 코드에서 함수나 애플리케이션을 빌드할 수 있습니다. Function 정의에 빌드 섹션을 추가하면, 서빙 섹션도 정의되어 있다면 빌드가 완료되자마자 함수가 시작됩니다​​.

 

Pack CLI 사용: 디버그 목적이나 오프라인 환경에서는 로컬 소스 코드에서 직접 함수 이미지를 빌드하는 것이 필요할 수 있습니다. 이를 위해 Pack CLI를 사용할 수 있습니다. Pack는 Cloud Native Buildpacks 프로젝트에 의해 유지되며 빌드팩을 사용하여 애플리케이션을 빌드하는 기능을 제공합니다​​.

 

OpenFunction Builders: Cloud Native Buildpacks를 사용하여 함수 이미지를 빌드하려면 빌더 이미지가 필요합니다. OpenFunction 커뮤니티에서는 여러 인기 언어에 대한 빌더를 제공하고 있습니다​​.

git 리포지토리의 소스 코드에서 함수 빌드하기

아래와 같이 함수 정의에 빌드 섹션을 추가하기만 하면 함수 이미지를 빌드할 수 있습니다. 서빙 섹션이 함께 정의되어 있으면 빌드가 완료되는 즉시 함수가 실행됩니다.

apiVersion: core.openfunction.io/v1beta2
kind: Function
metadata:
  name: logs-async-handler
spec:
  version: "v2.0.0"
  image: openfunctiondev/logs-async-handler:v1
  imageCredentials:
    name: push-secret
  build:
    builder: openfunction/builder-go:latest
    env:
      FUNC_NAME: "LogsHandler"
      FUNC_CLEAR_SOURCE: "true"
      ## Customize functions framework version, valid for functions-framework-go for now
      ## Usually you needn't to do so because the builder will ship with the latest functions-framework
      # FUNC_FRAMEWORK_VERSION: "v0.4.0"
      ## Use FUNC_GOPROXY to set the goproxy
      # FUNC_GOPROXY: "https://goproxy.cn"
    srcRepo:
      url: "https://github.com/OpenFunction/samples.git"
      sourceSubPath: "functions/async/logs-handler-function/"
      revision: "main"

 

 

 

이외에도 아래와 같은 방법으로 빌드가 가능하다.

  1. Pack CLI 사용: 디버그 목적이나 오프라인 환경에서는 로컬 소스 코드에서 직접 함수 이미지를 빌드하는 것이 필요할 수 있습니다. 이를 위해 Pack CLI를 사용할 수 있습니다. Pack는 Cloud Native Buildpacks 프로젝트에 의해 유지되며 빌드팩을 사용하여 애플리케이션을 빌드하는 기능을 제공합니다​​.
  2. OpenFunction Builders: Cloud Native Buildpacks를 사용하여 함수 이미지를 빌드하려면 빌더 이미지가 필요합니다. OpenFunction 커뮤니티에서는 여러 인기 언어에 대한 빌더를 제공하고 있습니다​​.

 

 

 

-참고 URL

https://openfunction.dev/docs/introduction/

[Introduction

Overview OpenFunction is a cloud-native open source FaaS (Function as a Service) platform aiming to let you focus on your business logic without having to maintain the underlying runtime environment and infrastructure. You can generate event-driven and dyn

openfunction.dev](https://openfunction.dev/docs/introduction/)

'job > devops' 카테고리의 다른 글

taskfile  (0) 2024.03.10
kubewarden  (0) 2024.01.20
git common flow(또는 gitlab flow) 브랜치 전략에 대한 설명  (0) 2023.06.13

이 글의 목적 : git common flow(gitlab flow)를 제대로 사용할 수 있도록 공식 문서를 번역하고 이해하기

참고 URL : https://commonflow.org/spec/1.0.0-rc.5.html

 

 

Introduction

Common-Flow is an attempt to gather a sensible selection of the most common usage patterns of git into a single and concise specification. It is based on the original variant of GitHub Flow, while taking into account how a lot of open source projects most commonly use git.

In short, Common-Flow is essentially GitHub Flow with the addition of versioned releases, optional release branches, and without the requirement to deploy to production all the time.

 

Git에서 가장 흔히 사용되는 패턴들을 효과적으로 처리할수 있또록 Github flow에 기반하여 다른 브랜치 전략(git flow)의 장점을 모은 브랜치전략이다.

 

Summary

  • The "master" branch is the mainline branch with latest changes, and must not be broken.
  • Changes (features, bugfixes, etc.) are done on "change branches" created from the master branch.
  • Rebase change branches early and often.
  • When a change branch is stable and ready, it is merged back in to master.
  • A release is just a git tag who's name is the exact release version string (e.g. "2.11.4").
  • Release branches can be used to avoid change freezes on master. They are not required, instead they are available if you need them.

"메인 브랜치"는 최신 변경 사항이 있는 메인라인 브랜치이며 중단되면 안됨.

개발작업은 마스터 브랜치에서 생성된 change branch에서 진행.

 

 

 

 

Terminology

  • Master Branch - Must be named "master", must always have passing tests, and is not guaranteed to always work in production environments.
  • Change Branches - Any branch that introduces changes like a new feature, a bug fix, etc.
  • Source Branch - The branch that a change branch was created from. New changes in the source branch should be incorporated into the change branch via rebasing.
  • Merge Target - A branch that is the intended merge target for a change branch. Typically the merge target branch will be the same as the source branch.
  • Pull Request - A means of requesting that a change branch is merged in to its merge target, allowing others to review, discuss and approve the changes.
  • Release - May be considered safe to use in production environments. Is effectively just a git tag named after the version of the release.
  • Release Branches - Used both for short-term preparations of a release, and also for long-term maintenance of older version.

 

 

Git Common-Flow Specification (Common-Flow)

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

  1. TL;DR
    1. Do not break the master branch.
    2. A release is a git tag.

 

  1. The Master Branch
    1. A branch named "master" MUST exist and it MUST be referred to as the "master branch".
    2. The master branch MUST always be in a non-broken state with its test suite passing.
    3. The master branch IS NOT guaranteed to always work in production environments. Despite test suites passing it may at times contain unfinished work. Only releases may be considered safe for production use.
    4. The master branch SHOULD always be in a "as near as possibly ready for release/production" state to reduce any friction with creating a new release.

 

  1. Change Branches
    1. Each change (feature, bugfix, etc.) MUST be performed on separate branches that SHOULD be referred to as "change branches".
    2. All change branches MUST have descriptive names.
    3. It is RECOMMENDED that you commit often locally, and that you try and keep the commits reasonably structured to avoid a messy and confusing git history.
    4. You SHOULD regularly push your work to the same named branch on the remote server.
    5. You SHOULD create separate change branches for each distinctly different change. You SHOULD NOT include multiple unrelated changes into a single change branch.
    6. When a change branch is created, the branch that it is created from SHOULD be referred to as the "source branch". Each change branch also needs a designated "merge target" branch, typically this will be the same as the source branch.
    7. Change branches MUST be regularly updated with any changes from their source branch. This MUST be done by rebasing the change branch on top of the source branch.
    8. After updating a change branch from its source branch you MUST push the change branch to the remote server. Due to the nature of rebasing, you will be required to do a force push, and you MUST use the "--force-with-lease" git push option when doing so instead of the regular "--force".
    9. If there is a truly valid technical reason to not use rebase when updating change branches, then you can update change branches via merge instead of rebase. The decision to use merge MUST only be taken after all possible options to use rebase have been tried and failed. People not understanding how to use rebase is NOT a valid reason to use merge. If you do decide to use merge instead of rebase, you MUST NOT use a mixture of both methods, pick one and stick to it.

 

  1. Pull Requests
    1. To merge a change branch into its merge target, you MUST open a "pull request" (or equivalent).
    2. The purpose of a pull request is to allow others to review your changes and give feedback. You can then fix any issues, complaints, and more that might arise, and then let people review again.
    3. Before creating a pull request, it is RECOMMENDED that you consider the state of your change branch's commit history. If it is messy and confusing, it might be a good idea to rebase your branch with "git rebase -i" to present a cleaner and easier to follow commit history for your reviewers.
    4. A pull request MUST only be merged when the change branch is up-to-date with its source branch, the test suite is passing, and you and others are happy with the change. This is especially important if the merge target is the master branch.
    5. To get feedback, help, or generally just discuss a change branch with others, it is RECOMMENDED you create a pull request and discuss the changes with others there. This leaves a clear and visible history of how, when, and why the code looks and behaves the way it does.

 

  1. Versioning
    1. A "version string" is a typically mostly numeric string that identifies a specific version of a project. The version string itself MUST NOT have a "v" prefix, but the version string can be displayed with a "v" prefix to indicate it is a version that is being referred to.
    2. The source of truth for a project's version MUST be a git tag with a name based on the version string. This kind of tag MUST be referred to as a "release tag".
    3. It is OPTIONAL, but RECOMMENDED to also keep the version string hard-coded somewhere in the project code-base.
    4. If you hard-code the version string into the code-base, it is RECOMMENDED that you do so in a file called "VERSION" located in the root of the project. But be mindful of the conventions of your programming language and community when choosing if, where and how to hard-code the version string.
    5. If you are using a "VERSION" file in the root of the project, this file MUST only contain the exact version string, meaning it MUST NOT have a "v" prefix. For example "v2.11.4" is bad, and "2.11.4" is good.
    6. It is OPTIONAL, but RECOMMENDED that that the version string follows Semantic Versioning (http://semver.org/).

 

  1. Releases
    1. To create a new release, you MUST create a git tag named as the exact version string of the release. This kind of tag MUST be referred to as a "release tag".
    2. The release tag name can OPTIONALLY be prefixed with "v". For example the tag name can be either "2.11.4" or "v2.11.4". It is however RECOMMENDED that you do not use a "v" prefix. You MUST NOT use a mixture of "v" prefixed and non-prefixed tags. Pick one form and stick to it.
    3. If the version string is hard-coded into the code-base, you MUST create a "version bump" commit which changes the hard-coded version string of the project.
    4. When using version bump commits, the release tag MUST be placed on the version bump commit.
    5. If you are not using a release branch, then the release tag, and if relevant the version bump commit, MUST be created directly on the master branch.
    6. The version bump commit SHOULD have a commit message title of "Bump version to VERSION". For example, if the new version string is "2.11.4", the first line of the commit message SHOULD read: "Bump version to 2.11.4"
    7. It is RECOMMENDED that release tags are lightweight tags, but you can OPTIONALLY use annotated tags if you want to include changelog information in the release tag itself.
    8. If you use annotated release tags, the first line of the annotation SHOULD read "Release VERSION". For example for version "2.11.4" the first line of the tag annotation SHOULD read "Release 2.11.4". The second line MUST be blank, and the changelog MUST start on the third line.

 

  1. Short-Term Release Branches
    1. Any branch that has a name starting with "release-" SHOULD be referred to as a "release branch".
    2. Any release branch which has a name ending with a specific version string, MUST be referred to as a "short-term release branch".
    3. Use of short-term release branches are OPTIONAL, and intended to be used to create a specific versioned release.
    4. A short-term release branch is RECOMMENDED if there is a lengthy pre-release verification process to avoid a code freeze on the master branch.
    5. Short-term release branches MUST have a name of "release-VERSION". For example for version "2.11.4" the release branch name MUST be "release-2.11.4".
    6. When using a short-term release branch to create a release, the release tag and if used, version bump commit, MUST be placed directly on the short-term release branch itself.
    7. Only very minor changes should be performed on a short-term release branch directly. Any larger changes SHOULD be done in the master branch, and SHOULD be pulled into the release branch by rebasing it on top of the master branch the same way a change branch pulls in updates from its source branch.
    8. After a release tag has been created, the release branch MUST be merged back into its source branch and then deleted. Typically the source branch will be the master branch.

 

  1. Long-term Release Branches
    1. Any release branch which has a name ending with a non-specific version string, MUST be referred to as a "long-term release branch". For example "release-2.11" is a long-term release branch, while "release-2.11.4" is a short-term release branch.
    2. Use of long-term release branches are OPTIONAL, and intended for work on versions which are not currently part of the master branch. Typically this is useful when you need to create a new maintenance release for a older version.
    3. A long-term release branch MUST have a name with a non-specific version number. For example a long-term release branch for creating new 2.9.x releases MUST be named "release-2.9".
    4. Long-term release branches for maintenance releases of older versions MUST be created from the relevant release tag. For example if the master branch is on version 2.11.4 and there is a security fix for all 2.9.x releases, the latest of which is "2.9.7". Create a new branch called "release-2.9" from the "2.9.7" release tag. The security fix release will then end up being version "2.9.8".
    5. To create a new release from a long-term release branch, you MUST follow the same process as a release from the master branch, except the long-term release branch takes the place of the master branch.
    6. A long-term release branch should be treated with the same respect as the master branch. It is effectively the master branch for the release series in question. Meaning it MUST always be in a non-broken state, MUST NOT be force pushed to, etc.

 

  1. Bug Fixes & Rollback
    1. You MUST NOT under any circumstances force push to the master branch or to long-term release branches.
    2. If a change branch which has been merged into the master branch is found to have a bug in it, the bug fix work MUST be done as a new separate change branch and MUST follow the same workflow as any other change branch.
    3. If a change branch is wrongfully merged into master, or for any other reason the merge must be undone, you MUST undo the merge by reverting the merge commit itself. Effectively creating a new commit that reverses all the relevant changes.

 

  1. Git Best Practices
    1. All commit messages SHOULD follow the Commit Guidelines and format from the official git documentation: https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines
    2. You SHOULD never blindly commit all changes with "git commit -a". It is RECOMMENDED you use "git add -i" or "git add -p" to add individual changes to the staging area so you are fully aware of what you are committing.
    3. You SHOULD always use "--force-with-lease" when doing a force push. The regular "--force" option is dangerous and destructive. More information: https://developer.atlassian.com/blog/2015/04/force-with-lease/
    4. You SHOULD understand and be comfortable with rebasing: https://git-scm.com/book/en/v2/Git-Branching-Rebasing
    5. It is RECOMMENDED that you always do "git pull --rebase" instead of "git pull" to avoid unnecessary merge commits. You can make this the default behavior of "git pull" with "git config --global pull.rebase true".
    6. It is RECOMMENDED that all branches be merged using "git merge --no-ff". This makes sure the reference to the original branch is kept in the commits, allows one to revert a merge by reverting a single merge commit, and creates a merge commit to mark the integration of the branch with master.

 

FAQ

Why use Common-Flow instead of Git Flow, and how does it differ?

Common-Flow tries to be a lot less complicated than Git Flow by having fewer types of branches, and simpler rules. Normal day to day development doesn't really change much:

  • You create change branches instead of feature branches, without the need of a "feature/" or "change/" prefix in the branch name.
  • Change branches are typically created from and merged back into "master" instead of "develop".
  • Creating a release is done by simply creating a git tag, typically on the master branch.

 

 

In detail, the main differences between Git Flow and Common-Flow are:

  • There is no "develop" branch, there is only a "master" branch which contains the latest work. In Git Flow the master branch effectively ends up just being a pointer to the latest release, despite the fact that Git Flow includes release tags too. In Common-Flow you just look at the tags to find the latest release.
  • There are no "feature" or "hotfix" branches, there's only "change" branches. Any branch that is not master and introduces changes is a change branch. Change branches also don't have a enforced naming convention, they just have to have a "descriptive name". This makes things simpler and allows more flexibility.
  • Release branches are available, but optional. Instead of enforcing the use of release branches like Git Flow, Common-Flow only recommends the use of release branches when it makes things easier. If creating a new release by tagging "master" works for you, great, do that.

 

 

Why use Common-Flow instead of GitHub Flow, and how does it differ?

Common-Flow is essentially GitHub Flow with the addition of a "Release" concept that uses tags. It also attempts to define how certain common tasks are done, like updating change/feature branches from their source branches for example. This is to help end arguments about how such things are done.

If a deployment/release for you is just getting the latest code in the master branch out, without caring about bumping version numbers or anything, then GitHub Flow is a good fit for you, and you probably don't need the extras of Common-Flow.

However if your deployments/releases have specific version numbers, then Common-Flow gives you a simple set of rules of how to create and manage releases, on top of what GitHub Flow already does.

 

 

What does "descriptive name" mean for change branches?

It means what it sounds like. The name should be descriptive, as in by just reading the name of the branch you should understand what the branch's purpose is and what it does. Here's a few examples:

  • add-2fa-support
  • fix-login-issue
  • remove-sort-by-middle-name-functionality
  • update-font-awesome
  • change-search-behavior
  • improve-pagination-performance
  • tweak-footer-style

Notice how none of these have any prefixes like "feature/" or "hotfix/", they're not needed when branch names are properly descriptive. However there's nothing to say you can't use such prefixes if you want.

You can also add ticket numbers to the branch name if your team/org has that as part of it's process. But it is recommended that ticket numbers are added to the end of the branch name. The ticket number is essentially metadata, so put it at the end and out of the way of humans trying to read the descriptive name from left to right.

 

 

 

How do we release an emergency hotfix when the master branch is broken?

This should ideally never happen, however if it does you can do one of the following:

  • Review why the master branch is broken and revert the changes that caused the issues. Then apply the hotfix and release.
  • Or use a short-term release branch created from the latest release tag instead of the master branch. Apply the hotfix to the release branch, create a release tag on the release branch, and then merge it back into master.

In this situation, it is recommended you try to revert the offending changes that's preventing a new release from master. But if that proves to be a complicated task and you're short on time, a short-term release branch gives you a instant fix to the situation at hand, and let's you resolve the issues with the master branch when you have more time on your hands.

 

 

'job > devops' 카테고리의 다른 글

taskfile  (0) 2024.03.10
kubewarden  (0) 2024.01.20
openfunction  (0) 2023.12.01

+ Recent posts