귀중한 구축 시간 절약!Git 트리 해시를 사용하여 출력 재사용🌳

요약: master 지점의 내용이 합병 요청 단추를 누르기 전의 제출과 같아도 이 지점의 구축을 기다리는 데 많은 시간이 걸립니까?캐시 구축을 통해 시간을 절약하고 Git 트리 해시를 캐시 키로 사용할 수 있습니다.
이것은 성능 최적화를 구축하는 시리즈의 두 번째 부분이다.
이것에 대해 나는 최적화Taskworld의 전단에 파이프를 구축할 때 이 기술을 발견했다.

컨텍스트: Netlify 구축 워크플로우


Taskworld에서 우리는 줄곧 하나의 구축 작업 흐름을 사용하고 있으며, 이 작업 흐름은 현재 "Netlify Build"로 확대되었다이것은 Git 워크플로우로서 운영 사이트의 개발, 테스트 및 납품 JAMStack 에 사용됩니다.
  • 기능 지점을 처리할 때 자동화 시스템은 코드를 구축하고 배치 미리 보기 환경에 배치합니다. 그러면 사람들이 응용 프로그램을 보고 테스트할 수 있습니다.
  • 변경 사항이 git checkout && yarn && yarn dev에 통합되면 자동화 시스템이 코드를 구축하여 생산 환경에 배치합니다.
  • 나는 이것이 the GitHub flow와 매우 비슷하다고 생각한다. 그러나 GitHub 흐름에서 그들은 마스터에 합병되기 전에 물건을 생산 환경에 배치한다.반면 Netlify의 기본 구축 작업 흐름은 마스터에 통합된 후 생산 환경에 배치됩니다. (사용자가 정의할 수 있지만)

    😩 왜 두 번 지어야 합니까?


    마스터 브랜치가 보호되고 기능 브랜치가 병합되기 전에 마스터 브랜치와 최신 상태를 유지하도록 요구하는 경우 마스터 브랜치에 병합될 때 생성된 커밋이 병합 전의 커밋과 완전히 동일하다는 것을 알 수 있습니다.

    그러나 기본적으로 대부분의 CI 파이핑은 이 경우 코드를 처음부터 구성합니다.
    지금 이것은 작은 프로젝트에 있어서 매우 좋다.그러나 우리 응용 프로그램이 발전함에 따라 과거에는 몇 초가 걸렸지만 지금은 몇 분이 걸린다.우리는 완전히 같은 코드를 한 번 또 한 번 구축할 때 약간의 군더더기를 보기 시작했다.

    🌳 Git 트리 해시 소개

    master를 실행하면 헤더에서 제출한 해시 값이 표시됩니다.
    $ git rev-parse HEAD
    10684e38090ed90d2d58d3ff3c81ace99ce658fe
    
    git rev-parse HEAD (마지막 사칭 주의) 를 실행하면 헤더가 대표하는 내용을 제출하는 해시를 받을 수 있습니다.이것은 나무 해시입니다.
    $ git rev-parse HEAD:
    29aa6872b8bfa8a911995c6a6b206fdd158339e3
    
    🤔 지금, 무슨 차이가 있습니까?

  • 해시를 제출한 것은 그 내용과 메타데이터에 근거하여 계산한 것이다.메타데이터는 제출 메시지, 제출자 및 작성자 정보(예를 들어 이름, 이메일, 날짜), 그리고 아버지가 제출한 해시를 포함한다.이것이 바로 제출을 만들 때마다 완전히 다른 해시 값을 얻는 이유입니다.

  • 다른 한편, 트리해시는 그 파일의 상태만 포착했다.이것은 커밋할 때 저장소의 스냅샷을 촬영하고 내용을 산열하는 것과 같다.내용이 같으면 기록을 제출하든 안 제출하든 트리해시는 같다.
  • 하위 디렉터리의 트리하시도 얻을 수 있습니다.이미 짐작한 바와 같이, 하위 디렉터리의 내용을 수정하지 않으면, 하위 디렉터리의 트리 해시는 변하지 않습니다.
    $ git rev-parse HEAD:docs
    1c771ff483992f38b268f08e9c015b613aa51e0a
    
    만약에 이 개념에 대한 더 많은 정보를 알고 싶다면 이 글“The anatomy of a Git commit” by Christoph Burgdorf을 추천합니다. 그 중에서 이해하기 쉬운 그림을 사용해서 Gitblob, 트리, 제출을 가시화할 수 있습니다.

    💡 Git 트리 해시를 사용하여 출력 재사용


    지금 우리는 그것을 어떻게 사용합니까?
    Git 트리 해시를 출력을 위한 캐시 키로 사용할 수 있습니다.
    구축 스크립트를 무조건 실행할 필요가 없습니다. 구축 과정은 먼저 캐시에서 구축 출력을 복구한 다음에 캐시가 존재하지 않을 때만 구축 스크립트를 실행할 수 있습니다.
    다음은 CircleCI 구성의 예입니다.다른 CI 시스템에도 동일한 개념을 적용할 수 있습니다.
    +      - run:
    +          name: obtain tree hash
    +          command: |
    +            git rev-parse HEAD: | tee /tmp/tree.hash
    +      - restore_cache:
    +          keys:
    +            - v1-tree-{{ checksum "/tmp/tree.hash" }}
           - run:
               name: build
               command: |
    -            yarn build
    +            test -f build/index.html || yarn build
    +      - save_cache:
    +          key: v1-tree-{{ checksum "/tmp/tree.hash" }}
    +          paths:
    +            - build
    
    캐시 스토리지를 제공하지 않는 CI 시스템에서는 Amazon S3 또는 Google 클라우드 스토리지 같은 클라우드 스토리지 서비스를 사용할 수 있습니다.
    ⚠️ 보안 고려 사항:

  • 캐시에서 출력을 복원하기 전에 git rev-parse HEAD: 디렉터리가 존재하지 않는지 확인하십시오.GitHub Actions 및 CircleCI와 같은 원본 구축 환경을 제공하는 구축 시스템에는 문제가 없습니다.그러나 작업공간 디렉터리를 재사용할 수 있는 구축 시스템(예를 들어 Jenkins)을 사용하는 경우 이 경고를 주의하십시오.

  • 캐시 복원의 유효성을 확인합니다.손상된 캐시는 손상된 생성을 초래할 수 있습니다.CircleCI는 복구 캐시의 무결성을 검증했기 때문에 CircleCI가 있으면 무료로 받을 수 있습니다.

  • 생성에 실패하면 생성된 출력을 캐시에 저장하지 마십시오.이로 인해 캐시가 손상될 수 있습니다.
  • 🤩 더 섬세한 입도의 나무 해시를 사용하다


    이것은 출력 생성에 영향을 미칠 수 있는 모든 내용을 열거해야 하지만, 이렇게 하면 캐시 적중 가능성을 증가시킬 수 있다.
           - run:
               name: obtain tree hash
               command: |
    -            git rev-parse HEAD: | tee /tmp/tree.hash
    +            git rev-parse HEAD:src | tee -a /tmp/tree.hash
    +            git rev-parse HEAD:public | tee -a /tmp/tree.hash
    +            git rev-parse HEAD:.babelrc | tee -a /tmp/tree.hash
    +            git rev-parse HEAD:postcss.config.js | tee -a /tmp/tree.hash
    +            git rev-parse HEAD:tsconfig.json | tee -a /tmp/tree.hash
    +            git rev-parse HEAD:yarn.lock | tee -a /tmp/tree.hash
    
    ⚠️ 보안 고려 사항:
  • 여기에 의존항을 포함하는 것을 잊어버리면 개발자가 설정을 변경할 수 있습니다. 단지 구축 출력이 변하지 않는 것을 발견하기 위해서입니다.이 점을 추적하는 것은 아마도 고통스러운 경험일 것이다.따라서 이러한 캐시 정책과 관련될 때 개발자에게 출력 생성 절차를 다시 사용할지 여부를 명확하게 결정하고 캐시를 무효화시키는 방법에 대한 설명을 제공해 주십시오.
  • 🏘 하위 항목과 함께 사용


    하나의 항목이 같은 저장소에 주 응용 프로그램과 문서 사이트를 동시에 포함할 수도 있습니다.이것은 구축하는 데 시간이 필요할 수도 있다.
    하위 디렉터리의 트리 해시를 얻을 수 있기 때문에 문서 사이트를 캐시하고 문서 내용이 변경될 때만 재구성할 수 있습니다.
    ⚠️ 보안 고려 사항:
  • 이 기술을monorepo 프로젝트에 사용할 수도 있지만, 같은 저장소 의존 항목의 내용도 하위 항목에 의존하는 캐시 키에 넣어야 합니다.나는 이러한 임시 해결 방안이 아니라monorepos를 위한 도구를 사용할 것을 건의합니다.
  • Nx 회사 ✅ 테스트와 함께 사용


    만약 테스트가 실행되기까지 시간이 오래 걸린다면, 테스트가 통과되었을 때, build 파일이나 유사한 파일을 캐시할 수도 있습니다. 그러면 테스트가 통과되고 있다는 것을 알았을 때, 테스트를 다시 실행할 필요가 없습니다.

    바젤 ℹ️ 생성 출력에 제출 해시 포함


    구축된 응용 프로그램에 제출 해시를 포함하면 버그를 쉽게 추적할 수 있습니다. 예를 들어 일반적으로 이것은 구축 시 환경 변수를 제공함으로써 이루어진다. :
    env REACT_APP_GIT_SHA=`git rev-parse --short HEAD` yarn build
    
    이것은 출력 캐시를 생성하는 데 적합하지 않을 수 있습니다.이전에 제출한 생성 출력을 다시 사용할 때, 삽입된 제출 ID는 배치 중인 제출과 일치하지 않을 수 있습니다.
    우리는 구축할 때 제출 해시를 사용하지 않고 구축할 때 해시 주입 패키지 (예를 들어 주입 junit.xml 나 목록 JSON 파일) 를 제출하고 구축된 프로그램이 실행될 때 읽을 수 있습니다.

    보초병 결론


    Git가 백그라운드에서 어떻게 작동하는지 배우고 데이터가 Git 저장소에 어떻게 저장되는지 탐색함으로써 우리는 구축 성능을 향상시키는 방법을 찾을 수 있다.
    Taskworld에서 이전에 제출한 생성 출력을 다시 사용할 수 있을 때 3분 동안의 구축 시간 절약을 보았습니다.
    따라서 병합 상황에서 파이프를 구축하는 것이 더욱 빨라진다.또한 CI 시스템에서 더욱 신속하게 피드백을 얻을 수 있습니다. 특히 우리가 저장소에서 주 응용 프로그램을 제외한 부분을 변경할 때 (예를 들어 끝에서 끝까지 테스트하고 스크립트를 구축하는 것) 입니다.
    당신이 이것이 매우 유용하다는 것을 발견할 수 있기를 바랍니다. 읽어 주셔서 감사합니다!

    좋은 웹페이지 즐겨찾기