태그 보관물: continuous-integration

continuous-integration

마감일이있는 TODO 의견? 수행하면서 실현하고있는 것 중 하나는 데이터베이스를 변경하기가

배경

다운 타임 제로 배포를 구현하려는 팀에서 일하고 있습니다. 이를 달성하기 위해 블루 / 그린 배포 전략을 사용할 계획입니다. 제가 연구를 수행하면서 실현하고있는 것 중 하나는 데이터베이스를 변경하기가 얼마나 복잡하다는 것입니다. 열 이름을 바꾸는 것과 같은 간단한 작업은 완료 될 때까지 3 번의 전체 릴리스주기를 수행 할 수 있습니다 !

변경 사항을 여러 번 배포하면 전체 릴리스를 수행하면 인적 오류가 발생할 가능성이 높습니다. 링크 된 기사에서 2 개의 릴리스에는 코드 변경이 필요하고 3 개의 릴리스에는 데이터베이스 마이그레이션이 필요합니다.

내가 찾고있는 것

현재 무언가를 기억하고 싶다면 이슈 관리 시스템에서 티켓을 생성 할 수 있습니다.이 티켓은 혼란을 유발할뿐만 아니라 경영진에 의해 나중에 스프린트 또는 백 로그로 이동할 수 있습니다. 또는 TODO 주석을 작성할 수 있습니다.이 주석은 완전히 잊혀 질 것입니다.

내가 찾고있는 것은 TODO 주석에 마감 기한이있을 수있는 방법이며,이 마감 기한이 만료되면 Continuous Integration 시스템 (현재 결정되지 않은)이 빌드를 거부합니다.

예를 들어 열의 이름을 바꾸면 초기 마이그레이션을 만든 다음 TODO 주석 두 개를 사용하여 나머지 두 마이그레이션을 만들 수 있습니다.

// TODO by v55: Create migration to move constraints to new column, remove references to old column in app
// TODO by v56: Create migration to drop old column

이것은 구현하기가 상당히 간단 해 보이지만 바퀴를 다시 발명하고 싶지 않기 때문에 이와 같은 것이 이미 존재하는지 궁금합니다.

추가 생각

롤링 배포 및 블루 / 그린 배포가 최선의 방법으로 간주되므로 XY 문제로 어려움을 겪고있는 것 같습니다. 데이터베이스 업데이트를 덜 고통스럽게 만드는 솔루션을 찾을 수없는 것은 이상한 것 같습니다. 내가 틀린 것을 완전히보고 있다고 생각되면 의견을 남겨주세요! 즉, 내가 준 데이터베이스 예제는 단지 하나의 예이며 마감 날짜가있는 TODO 주석은 다른 상황에서도 유용 할 것이라고 생각합니다. 따라서이 특정 상황에 접근하더라도 잘못되고 있습니다. 실제 질문도. 감사!

편집 : 나는 이것이 도움이 될 수있는 또 다른 상황을 생각했습니다. 기능 토글을 사용하여 준비가되었을 때 앱의 일부를 켜면 정리해야합니다. 그렇지 않으면 토글 부채 가 생길 수 있습니다 . 마감일이있는 주석은이를 기억하는 좋은 방법이 될 수 있습니다.



답변

이 질문은 실제로 두 가지 질문입니다.

할일 코멘트

작업 항목을 추적하는 모든 방법 중에서 가장 나쁜 방법입니다. TODO 의견은 활발한 작업 중에 또는 관리자에게 제안하는 방법으로 유용합니다. “향후 개선 될 수있는 부분이 있습니다.” 그러나 작업을 완료하기 위해 TODO 의견에 의존하면 실패 할 것입니다.

그것에 대해해야 할 일

TODO 의견은 기본적으로 기술 부채이므로 다른 기술 부채처럼 처리해야합니다. 시간이 있으면 즉시 해결하거나 추적 및 우선 순위를 정할 수 있도록 백 로그에 넣습니다.

일반적으로 말하면 이것은 완전히 의견이 있고 논쟁의 여지가 있지만 TODO 의견은 코드 냄새로 간주 될 수 있습니다. TODO 주석이 버전 제어로 확인되는 한, 실제로 질문을해야합니까? 그렇지 않다면 괜찮습니다. 자신에게 정직하고 백 로그에 넣으십시오.

이 백 로그를 관리하는 방법은 비즈니스 프로세스, 회사 정치 및 개인 자율성에 달려 있습니다. 그러나 여전히 추적되고 우선 순위가 지정된 백 로그가 필요합니다.

데이터베이스 변경

예, 다운 타임없는 정책으로 데이터베이스 변경이 까다 롭습니다. 덜 고통스럽게 만드는 몇 가지 트릭 :

배포 후 프로세스

동일한 릴리스의 일부로 실행되는 배치 후 프로세스를 작성하십시오. 그러나 당신은 그것이 작동하기를 원합니다. 마지막으로 작업 한 시스템에서 4 단계 배포를 설계했습니다.

  1. preapp 데이터베이스 스크립트
  2. 웹앱
  3. postapp 데이터베이스 스크립트
  4. 유지 관리 기간 데이터베이스 스크립트

아이디어는 가능한 한 많은 데이터베이스 변경 사항을 가능한 한 사전 응용 프로그램에 적용한다는 것이 었습니다.

Postapp는 호환되지 않는 스키마 변경이 필요한 특별한 경우를 위해 예약되었습니다. 이러한 경우, preapp는 새로운 응용 프로그램 코드를 호환 가능하게 만들기 위해 충분히 변경하고 (호환성을 위해 임시 뷰를 생성 할 수 있음) postapp는 그러한 임시 아티팩트를 정리합니다.

유지 관리 기간은 실제로 가동 중지 시간이 필요하거나 실제 배포의 위험이나 비용이 합당하지 않은 변경을 위해 예약되었습니다. 예를 들어, 대량의 데이터를 변경하는 스크립트는 전체 테이블을 잠 가야 할 수도 있습니다.

자주 배포

새 릴리스를 충분히 자주 배포하면 2 개 또는 3 개의 릴리스를 변경하는 것이 쉽지 않은 시점에 도달 할 수 있습니다. 긴 릴리스주기는 데이터베이스 변경 비용을 증폭시킵니다.


답변

TODO를 사용하지 마십시오. 프로젝트에 이미 TODO 목록이 있습니다. 이를 이슈 트래커라고합니다.

나는이 문제에 실제 문제가 있다고 생각합니다.

우리는 이슈 관리 시스템에서 티켓을 생성 할 수 있습니다.이 티켓은 혼란을 야기하며 관리에 의해 나중에 스프린트 또는 백 로그로 이동 될 수 있습니다.

이슈 트래커가 복잡해지면이를 해결하는 방법을 찾으십시오. 의식이 적은 특별 이슈 유형 / 태그 일 수 있습니다. 하위 문제 일 수도 있습니다. 어쩌면 더 적은 식일지도 모른다. 우리는 실제로 말할 수 없습니다. 그러나 이슈 트래커가 너무 많은 작업을 생성하면 사람들이 공개 포럼에서 해당 이슈를 추가하는 것보다 정교한 질문을 작성하는 것이 문제가됩니다.

경영진이 작업의 마지막 부분을 과도하게 지연시키는 경우 두 가지 옵션이 있습니다.

  1. 이것이 나쁜 생각 인 이유를 경영진과상의하십시오.

  2. 단일 작업으로 처리하십시오. 이것이 골드 표준 솔루션 일 수 있습니다. 완벽한 세상에서는 각 단계에서 필요한 세 가지 사항을 변경할 수 있어야합니다. 마스터 브랜치에 하나를 적용하여 빌드 및 배포하십시오. 그 동안 두 번째를 마스터 브랜치에 적용하고 모든 스프린트에서 발생하고 완료되지 않은 경우 빌드 및 배포 등을 수행하십시오. 논리적으로 하나의 배포를 수행하는 경우 자동으로도 의미가 있지만 실제로는 3으로 나뉩니다.


답변

내가 찾고있는 것은 TODO 주석에 마감 기한이있을 수있는 방법이며,이 마감 기한이 만료되면 Continuous Integration 시스템 (현재 결정되지 않은)이 빌드를 거부합니다.

당신이 요구하는 것은 당신이 일을하고 따르기를 원한다면 할 수 있습니다.

// v55에 의한 TODO : 제약 조건을 새 열로 이동하기 위해 마이그레이션 생성, 앱에서 이전 열에 대한 참조 제거 // v56에 의한 TODO : 이전 열 삭제를위한 마이그레이션 생성

//TODO by v55v55를 배포 할시기가되면 grep하십시오 . 배포 빌드는이를 통합 테스트로 수행하는 스크립트를 실행합니다.

55를 버전 추적에 연결하거나 프롬프트를 표시 할 수 있습니다.

55를 할 때 v54로 // TODO를 확인하고 싶다면 흥미로워진다. 오히려 코드베이스를 55 번 검색하면 // TODO by 만 검색하면된다. 그런 다음 그 결과를 1-55로 필터링하십시오. 이제 56은 실패를 트리거하지 않습니다.

당신은 “아, 우리는 그것을 필요로하지 않을 것입니다. 우리는 점검 할 때마다 이것을 고칠 것입니다”라고 생각할 것입니다. 아뇨.


답변

우리 팀에서도 비슷한 문제가있었습니다. 이를 해결하기 위해 우리는 그들이 참조하는 JIRA 문제 또는 Git 문제를 확인하여 이러한 TODO를 처리하는 정적 분석 검사를 작성했습니다. 지정된 이슈가 “개발 중”열을 지나면 빌드가 실패합니다.

따라서 TODO를 잊어 버릴 염려없이 편안하게 TODO를 가질 수 있습니다.

Java로 오픈 소스 구현을 만들었습니다. 그렇습니다. 면책 조항은이 글을 썼다는 것입니다. 그러나 말했듯이 완전히 공개 소스이며 라이센스가 있습니다.

이 도구는 Westie 라고 하며 Jira 문제 검사기의 예는 README.md에 있습니다. GitIssueAnalyser도 참조하십시오.

더 궁금한 점이 있으면 스스로 홍보하지 않으려면 메시지를 보내주세요. 그것을 사용하기로 결정하고 제안 사항이 있으면 github에 대한 문제를 제기하십시오.


답변

하지 마십시오. 지금 그것을 할.

TLDR : 지금은 아니지만 나중에 DB 스크립트를 작성하고 테스트하십시오. 코드를 작성하여 DB 버전에서 실행되도록하십시오.

예를 들어, 국제적으로 갈 때 일반적인 요구 사항 인 에서 열 이름을에서 (으) SSN로 변경하려고한다고 가정 해 봅시다 TaxID.

이를 위해 일시적으로 a TaxIDSSN열 이있을 수 있습니다 . 두 버전을 모두 지원하는 동안 서로 업데이트 할 트리거가 있습니다. 그러나 트리거를 무기한으로 유지하고 싶지 않으므로 나중에 이전 버전과의 호환성이 더 이상 필요하지 않으면 트리거를 제거하고 SSN열을 삭제 하려고합니다 . 우리는 ToDo 아이템 없이도 모든 것을 미리 코딩 할 것입니다.

이 예에서는 빌드 102와의 호환성을 유지하면서 빌드 102 (새 열이 있음)를 배포합니다.

단계는 다음과 같습니다.

1. 버저 닝 테이블 설정

  1. 라는 하나의 테이블 추가 Configuration두 개의 열이를 Name하고 Value.

  2. Name“TargetVersion” 으로 행을 추가하고 Value배포 할 새 빌드 버전으로 설정하십시오 .

  3. Name“CompatibleWith” 로 행을 추가 Value하고 배치가 호환되어야하는 최소 버전 번호로 설정하십시오 .

모든 배치 전에 이러한 행을 검사하고 업데이트하십시오.

2. 배포 스크립트 수정

  1. TaxID와 나란히 새 열을 작성하고 열에서 SSN채우는 스크립트를 추가하십시오 SSN. IfTargetVersion을 확인 하는 명령문 으로이 코드를 묶으십시오 . 대상 버전이 너무 낮은 경우 (즉, TaxID아직 필요하지 않은 경우) 건너 뜁니다.

    SELECT @TargetVersion = TargetVersion FROM Configuration
    IF @TargetVersion < '102' THEN RETURN
    ALTER TABLE Customer ADD COLUMN taxID VarChar(12) NOT NULL
    UPDATE Customer SET TaxID = SSN
    
  2. TaxID삽입하거나 업데이트 할 때 채워지는 트리거를 작성하는 스크립트를 추가하십시오 SSN. If대상 코드 및 호환 가능한 버전을 확인 하는 명령문 으로이 코드를 묶으십시오 . TargetVersion이 너무 낮거나 ( TaxID필요하지 않은 경우) 또는 CompatibleWith 버전이 너무 높으면 ( SSN필드가 필요하지 않은 경우) 건너 뜁니다 .

    SELECT @TargetVersion  = TargetVersion,
           @CompatibleWith = CompatibleWith
    FROM Configuration
    IF @TargetVersion  < '102' THEN RETURN
    IF @CompatibleWith > '101' THEN RETURN
    CREATE TRIGGER SSNAndTaxIDTrigger ON Customer etc.
    
  3. SSN열 을 제거하는 스크립트를 추가하십시오 . IfCompatibleWith 버전이 충분히 높은 경우 ( SSN더 이상 필요하지 않은 경우) 에만 열을 제거 하는 명령문으로 묶으십시오 .

    SELECT @CompatibleWith = CompatibleWith FROM Configuration
    IF @CompatibleWith <= '101' THEN RETURN
    IF OBJECT_ID('SSNAndTaxIDTrigger') IS NOT NULL DROP TRIGGER SSNAndTaxIDTrigger
    IF EXISTS (SELECT * FROM syscolumns c JOIN sysobject o ON o.id = c.is WHERE o.Name = 'Custeomr' AND c.Name = 'SSN') BEGIN
        ALTER TABLE Customer DROP COLUMN SSN
    END
    

3. 테스트

프로덕션에서 지원할 수있는 Blue / Green 버전 번호 조합으로 배포를 테스트해야합니다. ConfigurationQA 환경에서 테이블 을 조작하여 코드가 준비되는 즉시 테스트 할 수 있습니다 .

4. 배포 플레이 북에서

엔지니어가 CompatibleWith 버전 및 TargetVersion 행을 업데이트하는 단계를 추가하십시오. Blue에 배치하는 경우 TargetVersion을 Blue의 버전 번호로 설정하고 CompatibleWith 버전을 Green의 버전 번호로 설정하십시오. Green을 배포하는 경우에는 뒤집으십시오.

함정

당신의 것은 괜찮다 배포 스크립트를 참조하고 DB 테이블에서 개최하는 버전 번호에 의존 할 수 있습니다. 런타임 코드가 아닙니다.

버전 번호를 검사하기 위해 런타임 코드 작성을 시작하면 잠재적으로 큰 유지 보수성 문제가 될 수있는 새로운 수준의 복잡성이 애플리케이션에 도입됩니다. 각 런타임 실행 경로를 테스트해야합니다. 이러한 조건을 계속 진행하는 경우 QA는 각각의 모든 릴리스에서이를 확인하기 위해 고통매트릭스를 구성 해야합니다. 내 충고는 이러한 조건을 배포 스크립트에만 유지하는 것입니다.

이 모든 것의 결과

결국, 너무 일찍 실행될 것이라는 두려움없이 모든 코드를 미리 작성하고 테스트 할 수 있어야합니다. 또한 코드는 더 이상 걱정할 필요없이 시간이 오면 이전 버전과의 호환성 트리거를 정리합니다.

이런 식으로 생각할 때 모든 코드를 미리 작성하고 테스트 할 수 있으며 지저분한 ToDo 주석을 처리 할 필요가 없습니다.


답변

TODO 아이디어에 대해 많은 답을 얻고 있지만 개인적으로는 아무런 문제가 없습니다. 결국, 마이그레이션이 프로덕션으로 진행되도록하는 가장 좋은 (가장 쉬운) 방법은 유닛 테스트가 실패하면 실패하는 것입니다. 버전이 55 이상 (또는 요구 사항이 무엇이든) 인 경우 예외를 발생시키는 빈 마이그레이션 함수를 제거하는 데 문자 그대로 1 분도 걸리지 않습니다.

그런 다음 릴리스하려고하면 테스트에 실패하게되며 누군가 예외를 실제 마이그레이션 코드로 바꿔야합니다.


답변

데이터베이스 변경에 너무 많은 릴리스주기가 소요될 수 있다는 사실에 불만을 제기 한 사람은 아무도 없습니다. 그는 블루 / 그린 배포 일정을 계속 진행하고 싶어하며 솔루션이 이미 있어야하지만 뭔가 빠진 경우가 아니라면 그의 설명은 두 시스템에서 공유하는 데이터베이스가 하나만 있음을 나타냅니다. 이 경우 진정한 블루 / 그린 시스템이 아닙니다. 데이터베이스가 텐트의 장대 인 것처럼 보이므로 오프라인 시스템에서 데이터베이스 변경을 구현하는 데 얼마나 오래 걸리거나 릴리스주기가 완료 되더라도 완료 될 때까지 실행되지 않고 복제주기가 길어 지더라도 복제되어야합니다. 완전히 테스트되었습니다. 중간 오프라인 시스템 스크립트에서 오프라인 데이터베이스를 매일 완전히 업데이트 된 상태로 유지할 수 있습니다.