Thứ ba, 12/08/2014 | 00:00 GMT+7

Cách sử dụng Git Hooks để tự động hóa các nhiệm vụ triển khai và phát triển

Kiểm soát version đã trở thành một yêu cầu trung tâm để phát triển phần mềm hiện đại. Nó cho phép các dự án theo dõi các thay đổi một cách an toàn và cho phép đảo ngược, kiểm tra tính toàn vẹn và hợp tác giữa các lợi ích khác. Đặc biệt, hệ thống kiểm soát version git đã được áp dụng rộng rãi trong những năm gần đây do kiến trúc phi tập trung và tốc độ mà nó có thể thực hiện và chuyển các thay đổi giữa các bên.

Mặc dù bộ công cụ git cung cấp nhiều tính năng được triển khai tốt, nhưng một trong những đặc điểm hữu ích nhất là tính linh hoạt của nó. Thông qua việc sử dụng hệ thống “hooks”, git cho phép các nhà phát triển và administrator mở rộng chức năng bằng cách chỉ định các tập lệnh mà git sẽ gọi dựa trên các sự kiện và hành động khác nhau.

Trong hướng dẫn này, ta sẽ khám phá ý tưởng về git hook và trình bày cách triển khai mã có thể hỗ trợ bạn tự động hóa các việc trong môi trường độc đáo của bạn . Ta sẽ sử dụng server Ubuntu 14.04 trong hướng dẫn này, nhưng bất kỳ hệ thống nào có thể chạy git sẽ hoạt động theo cách tương tự.

Yêu cầu

Trước khi bắt đầu, bạn phải cài đặt git trên server của bạn . Nếu bạn đang theo dõi trên Ubuntu 14.04, bạn có thể xem hướng dẫn của ta về cách cài đặt git trên Ubuntu 14.04 tại đây.

Bạn nên làm quen với cách sử dụng git theo nghĩa chung. Nếu bạn cần phần giới thiệu, loạt bài cài đặt là một phần của nó, được gọi là Giới thiệu về Git: Cài đặt, Cách sử dụng và Các nhánh , là một nơi tốt để tham khảo .

Khi bạn hoàn thành các yêu cầu trên, hãy tiếp tục.

Ý tưởng cơ bản với Git Hooks

Git hook là một khái niệm khá đơn giản được thực hiện để giải quyết nhu cầu. Khi phát triển phần mềm trên một dự án được chia sẻ, duy trì các tiêu chuẩn hướng dẫn phong cách hoặc khi triển khai phần mềm (tất cả đều là những tình huống mà git thường liên quan), thường có những tác vụ lặp đi lặp lại mà bạn cần thực hiện mỗi khi thực hiện một hành động.

Các móc git dựa trên sự kiện. Khi bạn chạy các lệnh git nhất định, phần mềm sẽ kiểm tra folder hooks trong repository lưu trữ git để xem có tập lệnh liên quan nào để chạy hay không.

Một số tập lệnh chạy trước khi hành động diễn ra, được dùng đảm bảo mã tuân theo các tiêu chuẩn, để kiểm tra sự tỉnh táo hoặc để cài đặt môi trường. Các tập lệnh khác chạy sau một sự kiện để triển khai mã, cài đặt lại các quyền chính xác (thứ mà git không thể theo dõi tốt), v.v.

Sử dụng những khả năng này, bạn có thể thực thi các policy , đảm bảo tính nhất quán và kiểm soát môi trường của bạn và thậm chí xử lý các nhiệm vụ triển khai.

Cuốn sách Pro Git của Scott Chacon cố gắng phân chia các loại móc câu khác nhau thành các loại. Ông phân loại chúng như vậy:

  • Client-Side Hooks: Các móc được gọi và thực thi trên máy tính của người commit . Đến lượt mình, chúng được chia thành một số loại riêng biệt:
    • Móc commit -Quy trình làm việc: Móc commit được sử dụng để ra lệnh cho các hành động cần được thực hiện khi một commit được thực hiện. Chúng được sử dụng để chạy kiểm tra độ tỉnh táo, điền trước thông báo commit và xác minh chi tiết thông báo.Bạn cũng có thể sử dụng nó để cung cấp thông báo khi commit .
    • Các móc quy trình làm việc qua email: Loại móc này bao gồm các hành động được thực hiện khi làm việc với các bản vá được gửi qua email. Các dự án như nhân Linux gửi và xem xét các bản vá bằng phương pháp email. Chúng tương tự như các móc commit , nhưng được dùng bởi những người bảo trì chịu trách nhiệm áp dụng mã đã gửi.
    • Khác: Các móc phía client khác bao gồm các móc thực thi khi hợp nhất, kiểm tra mã, khôi phục, viết lại và làm sạch repo.
  • Móc phía server : Các móc này được thực thi trên các server được sử dụng để nhận các lần đẩy. Nói chung, đó sẽ là git repo chính cho một dự án. , Chacon chia chúng thành các loại:
    • Trước khi nhận và sau khi nhận: Chúng được thực thi trên server nhận được thúc đẩy để thực hiện những việc như kiểm tra sự phù hợp của dự án và triển khai sau một lần đẩy.
    • Cập nhật: Đây giống như nhận trước, nhưng hoạt động trên cơ sở từng nhánh để thực thi mã trước khi mỗi nhánh được chấp nhận.

Các phân loại này rất hữu ích để có được ý tưởng chung về các sự kiện mà bạn có thể tùy chọn cài đặt một hook. Nhưng để thực sự hiểu được cách thức hoạt động của những mục này, tốt nhất là bạn nên thử nghiệm và tìm ra giải pháp mà bạn đang cố gắng thực hiện.

Một số móc cũng có tham số. Điều này nghĩa là khi git gọi script cho hook, nó sẽ truyền vào một số dữ liệu liên quan mà sau đó script có thể sử dụng để hoàn thành nhiệm vụ. Nói chung, các móc có sẵn là:

Tên móc Được mời bởi Sự miêu tả Các thông số (Số và Mô tả)
applypatch-msg git am Có thể chỉnh sửa file thông báo commit và thường được sử dụng để xác minh hoặc chủ động định dạng thông báo của bản vá theo tiêu chuẩn của dự án. Trạng thái thoát khác 0 hủy bỏ commit . (1) tên của file chứa thông báo commit được đề xuất
đăng ký trước git am Điều này thực sự được gọi sau khi bản vá được áp dụng, nhưng trước khi các thay đổi được commit . Thoát với trạng thái khác 0 sẽ để lại các thay đổi ở trạng thái không commit . được dùng để kiểm tra trạng thái của cây trước khi thực sự áp dụng các thay đổi . (không ai)
post-applypatch git am Móc này được chạy sau khi bản vá được áp dụng và commit . Do đó, nó không thể hủy bỏ quá trình và chủ yếu được sử dụng để tạo thông báo. (không ai)
Commit trước git commit Hook này được gọi trước khi nhận được thông báo commit được đề xuất. Thoát với bất kỳ thứ gì khác 0 sẽ hủy bỏ commit . Nó được sử dụng để kiểm tra bản thân commit (thay vì thông báo). (không ai)
chuẩn bị- commit -msg git commit Được gọi sau khi nhận được thông báo commit mặc định, ngay trước khi kích hoạt editor thông báo commit . Một lối ra khác 0 hủy bỏ commit . Điều này được sử dụng để chỉnh sửa tin nhắn theo cách không thể bị chặn. (1 đến 3) Tên của file có thông báo commit , nguồn của thông báo commit ( message , template , merge , squash hoặc commit ) và commit SHA-1 (khi hoạt động trên một commit hiện có).
commit -tin nhắn git commit được dùng để điều chỉnh thông báo sau khi nó đã được chỉnh sửa đảm bảo sự phù hợp với tiêu chuẩn hoặc để loại bỏ dựa trên bất kỳ tiêu chí nào.Nó có thể hủy bỏ commit nếu nó thoát với giá trị khác 0. (1) Tệp chứa thông báo được đề xuất.
hậu commit git commit Được gọi sau khi commit thực sự được thực hiện. Vì điều này, nó không thể phá vỡ commit . Nó chủ yếu được sử dụng để cho phép thông báo. (không ai)
pre-rebase git rebase Được gọi khi giảm giá một nhánh. Chủ yếu được sử dụng để tạm dừng rebase nếu nó không được mong muốn. (1 hoặc 2) Ngược dòng từ nơi nó đã được phân nhánh, nhánh đang được khôi phục (không được cài đặt khi khôi phục dòng điện)
thanh toán sau git checkoutgit clone Chạy khi thanh toán được gọi sau khi cập nhật worktree hoặc sau khi git clone . Nó chủ yếu được sử dụng để xác minh các điều kiện, hiển thị sự khác biệt và cấu hình môi trường nếu cần thiết. (3) Tham chiếu của HEAD trước đó, tham chiếu của HEAD mới, cờ cho biết đó là kiểm tra chi nhánh (1) hay kiểm tra file (0)
hậu hợp nhất git merge hoặc git pull Được gọi sau khi hợp nhất. Vì điều này, nó không thể hủy bỏ hợp nhất. được dùng để lưu hoặc áp dụng quyền hoặc các loại dữ liệu khác mà git không xử lý. (1) Cờ cho biết liệu hợp nhất có phải là bí hay không.
đẩy trước git push Được gọi trước khi có một điều khiển từ xa. Ngoài các tham số, thông tin bổ sung, được phân tách bằng dấu cách được chuyển vào qua stdin dưới dạng “<local ref> <local sha1> <remote ref> <remote sha1>”. Phân tích cú pháp đầu vào có thể giúp bạn có thêm thông tin mà bạn có thể sử dụng để kiểm tra. Ví dụ, nếu sha1 local dài 40 số không, lần đẩy là xóa và nếu sha1 từ xa là 40 số không, nó là một nhánh mới. Điều này được dùng để thực hiện nhiều so sánh của ref được đẩy với những gì hiện có. Trạng thái thoát khác 0 sẽ hủy bỏ việc đẩy. (2) Tên của điều khiển từ xa đích, vị trí của điều khiển từ xa đích
nhận trước git-receive-pack trên đại diện từ xa Điều này được gọi trên repo từ xa ngay trước khi cập nhật các ref được đẩy. Trạng thái khác 0 sẽ hủy bỏ quá trình. Mặc dù nó không nhận được tham số nào, nhưng nó được truyền một chuỗi qua stdin dưới dạng “<old-value> <new-value> <ref-name>” cho mỗi lần tham chiếu. (không ai)
cập nhật git-receive-pack trên đại diện từ xa Điều này được chạy trên repo từ xa một lần cho mỗi lần giới thiệu được đẩy thay vì một lần cho mỗi lần đẩy. Trạng thái khác 0 sẽ hủy bỏ quá trình. Điều này được dùng đảm bảo rằng tất cả các commit chỉ được tua đi nhanh. (3) Tên tham chiếu đang được cập nhật, tên đối tượng cũ, tên đối tượng mới
sau khi nhận git-receive-pack trên đại diện từ xa Điều này được chạy trên điều khiển từ xa khi đẩy sau khi tất cả các tham chiếu đã được cập nhật. Nó không nhận tham số, nhưng nhận thông tin thông qua stdin dưới dạng “<old-value> <new-value> <ref-name>”. Bởi vì nó được gọi sau khi cập nhật, nó không thể hủy bỏ quá trình. (không ai)
sau cập nhật git-receive-pack trên repo từ xa Điều này chỉ được chạy một lần sau khi tất cả các tham chiếu đã được đẩy. Nó tương tự như hook post-nhận về mặt đó, nhưng không nhận các giá trị cũ hoặc mới. Nó được sử dụng chủ yếu để triển khai thông báo cho các giới thiệu được đẩy.(?) Một tham số cho mỗi refs được đẩy có chứa tên của nó
pre-auto-gc git gc --auto Được sử dụng để thực hiện một số kiểm tra trước khi tự động dọn dẹp repo. (không ai)
viết lại sau git commit --amend , git-rebase Điều này được gọi khi các lệnh git đang viết lại dữ liệu đã được commit . Ngoài các tham số, nó nhận các chuỗi trong stdin ở dạng “<old-sha1> <new-sha1>”. (1) Tên của lệnh đó gọi nó ( amend hoặc rebase )

Đến đây bạn đã có tất cả thông tin chung này, ta có thể trình bày cách triển khai chúng trong một vài trường hợp.

Cài đặt repository

Để bắt đầu, ta sẽ tạo một repository mới, trống trong folder chính của ta . Ta sẽ gọi đây là proj .

mkdir ~/proj cd ~/proj git init 
Initialized empty Git repository in /home/demo/proj/.git/ 

Bây giờ, ta đang ở trong folder làm việc trống của folder do git kiểm soát. Trước khi ta làm bất cứ điều gì khác, hãy chuyển đến repository được lưu trữ trong file ẩn có tên .git trong .git này:

cd .git ls -F 
branches/  config  description  HEAD  hooks/  info/  objects/  refs/ 

Ta có thể thấy một số file và folder . Cái mà ta quan tâm là folder hooks :

cd hooks ls -l 
total 40 -rwxrwxr-x 1 demo demo  452 Aug  8 16:50 applypatch-msg.sample -rwxrwxr-x 1 demo demo  896 Aug  8 16:50 commit-msg.sample -rwxrwxr-x 1 demo demo  189 Aug  8 16:50 post-update.sample -rwxrwxr-x 1 demo demo  398 Aug  8 16:50 pre-applypatch.sample -rwxrwxr-x 1 demo demo 1642 Aug  8 16:50 pre-commit.sample -rwxrwxr-x 1 demo demo 1239 Aug  8 16:50 prepare-commit-msg.sample -rwxrwxr-x 1 demo demo 1352 Aug  8 16:50 pre-push.sample -rwxrwxr-x 1 demo demo 4898 Aug  8 16:50 pre-rebase.sample -rwxrwxr-x 1 demo demo 3611 Aug  8 16:50 update.sample 

Ta có thể thấy một vài điều ở đây. Đầu tiên, ta có thể thấy rằng mỗi file này được đánh dấu là có thể thực thi được. Vì các tập lệnh này chỉ được gọi bằng tên nên chúng phải thực thi được và dòng đầu tiên của chúng phải là tham chiếu số ma thuật toàn phần để gọi trình thông dịch tập lệnh chính xác. Thông thường nhất, đây là các ngôn ngữ kịch bản như bash, perl, python, v.v.

Điều thứ hai bạn có thể nhận thấy là tất cả các file đều kết thúc bằng .sample . Đó là bởi vì git chỉ đơn giản là nhìn vào tên file khi cố gắng tìm các file hook để thực thi. Chệch khỏi tên của script git đang tìm kiếm về cơ bản vô hiệu hóa script. Để bật bất kỳ tập lệnh nào trong folder này, ta sẽ phải xóa hậu tố .sample .

Hãy quay lại folder làm việc của ta :

cd ../.. 

Ví dụ đầu tiên: Triển khai tới web server local có móc sau commit

Ví dụ đầu tiên của ta sẽ sử dụng hook post-commit để chỉ cho bạn cách triển khai tới một web server local khi nào một commit được thực hiện. Đây không phải là hook bạn sẽ sử dụng cho môi trường production , nhưng nó cho phép ta trình bày một số mục quan trọng, ít được ghi chép lại mà bạn nên biết khi sử dụng hook.

Đầu tiên, ta sẽ cài đặt web server Apache để chứng minh:

sudo apt-get update sudo apt-get install apache2 

Để tập lệnh của ta sửa đổi root web tại /var/www/html (đây là root tài liệu trên Ubuntu 14.04. Sửa đổi nếu cần), ta cần có quyền ghi. Hãy cho user bình thường của ta quyền sở hữu folder này. Bạn có thể thực hiện việc này bằng lệnh :

sudo chown -R `whoami`:`id -gn` /var/www/html 

Bây giờ, trong folder dự án của ta , hãy tạo index.html :

cd ~/proj nano index.html 

Bên trong, ta có thể thêm một chút HTML chỉ để thể hiện ý tưởng. Nó không cần phải phức tạp:

<h1>Here is a title!</h1>  <p>Please deploy me!</p> 

Thêm file mới để yêu cầu git theo dõi file :

git add . 

Bây giờ, trước khi bạn commit , ta sẽ cài đặt hook post-commit cho repository . Tạo file này trong .git/hooks cho dự án:

vim .git/hooks/post-commit 

Trước khi xem xét những gì cần đưa vào file này, ta cần tìm hiểu một chút về cách git cài đặt môi trường khi chạy hook.

Một chút về các biến môi trường với Git Hooks

Trước khi có thể bắt đầu tập lệnh của bạn , ta cần tìm hiểu một chút về những biến môi trường git đặt khi gọi hook. Để tập lệnh của ta hoạt động, cuối cùng ta cần hủy đặt một biến môi trường mà git đặt khi gọi hook post-commit .

Đây là một điểm rất quan trọng cần bổ sung nếu bạn hy vọng viết các git hook hoạt động một cách tin cậy . Git cài đặt các biến môi trường khác nhau tùy thuộc vào hook nào đang được gọi. Điều này nghĩa là môi trường mà git đang lấy thông tin sẽ khác nhau tùy thuộc vào hook.

Vấn đề đầu tiên với điều này là nó có thể làm cho môi trường kịch bản của bạn rất khó đoán nếu bạn không biết những biến nào đang được đặt tự động. Vấn đề thứ hai là các biến được cài đặt gần như hoàn toàn không có trong tài liệu của git.

May mắn là Mark Longair đã phát triển một phương pháp để kiểm tra từng biến mà git đặt khi chạy các hook này. Nó liên quan đến việc đưa các nội dung sau vào các đoạn mã git hook khác nhau:

#!/bin/bash echo Running $BASH_SOURCE set | egrep GIT echo PWD is $PWD 

Thông tin trên trang của anh là từ năm 2011 hoạt động với version git 1.7.1 nên có một vài thay đổi. Tại thời điểm viết bài này vào tháng 8 năm 2014, version git hiện tại trong Ubuntu 14.04 là 1.9.1.

Dưới đây là kết quả của các bài kiểm tra trên version git này (bao gồm cả folder làm việc mà git nhìn thấy khi chạy mỗi hook). Thư mục làm việc local cho thử nghiệm là /home/demo/test_hooks và điều khiển từ xa (nếu cần) là /home/demo/origin/test_hooks.git :

  • Hooks : applypatch-msg , pre-applypatch , post-applypatch
    • Các biến môi trường :
    • GIT_AUTHOR_DATE='Mon, 11 Aug 2014 11:25:16 -0400'
    • GIT_AUTHOR_EMAIL=demo@example.com
    • GIT_AUTHOR_NAME='Demo User'
    • GIT_INTERNAL_GETTEXT_SH_SCHEME=gnu
    • GIT_REFLOG_ACTION=am
    • Thư mục làm việc : /home/demo/test_hooks
  • Hooks : pre-commit , prepare-commit-msg , commit-msg , post-commit
    • Các biến môi trường :
    • GIT_AUTHOR_DATE='@1407774159 -0400'
    • GIT_AUTHOR_EMAIL=demo@example.com
    • GIT_AUTHOR_NAME='Demo User'
    • GIT_DIR=.git
    • GIT_EDITOR=:
    • GIT_INDEX_FILE=.git/index
    • GIT_PREFIX=
    • Thư mục làm việc : /home/demo/test_hooks
  • Hooks : pre-rebase
    • Các biến môi trường :
    • GIT_INTERNAL_GETTEXT_SH_SCHEME=gnu
    • GIT_REFLOG_ACTION=rebase
    • Thư mục làm việc : /home/demo/test_hooks
  • Hooks : post-checkout
    • Các biến môi trường :
    • GIT_DIR=.git
    • GIT_PREFIX=
    • Thư mục làm việc : /home/demo/test_hooks
  • Hooks : post-merge
    • Các biến môi trường :
    • GITHEAD_4b407c...
    • GIT_DIR=.git
    • GIT_INTERNAL_GETTEXT_SH_SCHEME=gnu
    • GIT_PREFIX=
    • GIT_REFLOG_ACTION='pull other master'
    • Thư mục làm việc : /home/demo/test_hooks
  • Hooks : pre-push
    • Các biến môi trường :
    • GIT_PREFIX=
    • Thư mục làm việc : /home/demo/test_hooks
  • Hooks : pre-receive , update , post-receive , post-update
    • Các biến môi trường :
    • GIT_DIR=.
    • Thư mục làm việc : /home/demo/origin/test_hooks.git
  • Hooks : pre-auto-gc
    • (không xác định vì điều này khó kích hoạt một cách tin cậy )
  • Hooks : post-rewrite
    • Các biến môi trường :
    • GIT_AUTHOR_DATE='@1407773551 -0400'
    • GIT_AUTHOR_EMAIL=demo@example.com
    • GIT_AUTHOR_NAME='Demo User'
    • GIT_DIR=.git
    • GIT_PREFIX=
    • Thư mục làm việc : /home/demo/test_hooks

Các biến này có hàm ý về cách git nhìn thấy môi trường của nó. Ta sẽ sử dụng thông tin trên về các biến đảm bảo rằng tập lệnh của ta có tính đến môi trường của nó một cách chính xác.

Quay lại Script

Đến đây bạn đã có ý tưởng về kiểu môi trường sẽ có (xem các biến được đặt cho hook post-commit ), ta có thể bắt đầu tập lệnh của bạn .

Vì git hook là script tiêu chuẩn, ta cần cho git biết trình thông dịch sẽ sử dụng:

#!/bin/bash 

Sau đó, ta sẽ sử dụng chính git để extract version mới nhất của repository sau khi commit , vào folder web của ta . Để làm điều này, ta nên đặt folder làm việc của bạn thành folder root của Apache. Ta cũng nên đặt folder git của bạn thành repo.

Ta sẽ muốn bắt buộc giao dịch này đảm bảo rằng điều này thành công mỗi lần, ngay cả khi có xung đột giữa những gì hiện có trong folder làm việc. Nó sẽ giống như thế này:

#!/bin/bash git --work-tree=/var/www/html --git-dir=/home/demo/proj/.git checkout -f 

Đến đây, ta gần như đã hoàn thành. Tuy nhiên, ta cần xem xét kỹ các biến môi trường được đặt mỗi khi hook post-commit được gọi. Đặc biệt, GIT_INDEX_FILE được đặt thành .git/index .

Đường dẫn này liên quan đến folder làm việc, trong trường hợp này là /var/www/html . Vì index git không tồn tại tại vị trí này, tập lệnh sẽ bị lỗi nếu ta để nguyên. Để tránh trường hợp này, ta có thể hủy đặt biến theo cách thủ công, điều này sẽ khiến git tìm kiếm liên quan đến folder repo, như nó thường làm. Ta cần thêm điều này vào phía trên dòng thanh toán:

#!/bin/bash unset GIT_INDEX_FILE git --work-tree=/var/www/html --git-dir=/home/demo/proj/.git checkout -f 

Những loại xung đột này là lý do tại sao các vấn đề git hook đôi khi rất khó chẩn đoán. Bạn phải biết git đã xây dựng môi trường mà nó đang làm việc như thế nào.

Khi bạn hoàn tất những thay đổi này, hãy lưu file .

Vì đây là một file script thông thường, ta cần làm cho nó có thể thực thi được:

chmod +x .git/hooks/post-commit 

Bây giờ, ta cuối cùng đã sẵn sàng commit những thay đổi mà ta đã thực hiện trong git repo của bạn . Đảm bảo rằng bạn đã trở lại đúng folder và sau đó áp dụng các thay đổi :

cd ~/proj git commit -m "here we go..." 

Bây giờ, nếu bạn truy cập domain hoặc địa chỉ IP của server trong trình duyệt của bạn , bạn sẽ thấy index.html bạn đã tạo:

http://server_domain_or_IP 

Kiểm tra index.html

Như bạn thấy , các thay đổi mới nhất của ta đã được tự động đẩy vào folder root của web server của ta khi commit . Ta có thể thực hiện một số thay đổi bổ sung để cho thấy rằng nó hoạt động trên mỗi commit :

echo "<p>Here is a change.</p>" >> index.html git add . git commit -m "First change" 

Khi làm mới trình duyệt của bạn , bạn sẽ thấy ngay những thay đổi mới mà bạn đã áp dụng:

 áp dụng các thay đổi

Như bạn thấy , kiểu cài đặt này có thể giúp mọi thứ dễ dàng hơn cho việc thử nghiệm các thay đổi local . Tuy nhiên, bạn hầu như không bao giờ muốn xuất bản commit trong môi trường production . Sẽ an toàn hơn nhiều nếu bạn đẩy sau khi bạn đã kiểm tra mã của bạn và chắc chắn rằng nó đã sẵn sàng.

Sử dụng Git Hooks để triển khai tới một server production riêng biệt

Trong ví dụ tiếp theo này, ta sẽ trình bày một cách tốt hơn để cập nhật server production . Ta có thể làm điều này bằng cách sử dụng mô hình push-to-deploy để cập nhật web server của ta khi nào ta đẩy lên repository git trần.

Ta có thể sử dụng cùng một server mà ta đã cài đặt làm máy phát triển của bạn . Đây là nơi ta sẽ thực hiện công việc của bạn . Ta sẽ có thể thấy những thay đổi của bạn sau mỗi lần commit .

Trên máy production của ta , ta sẽ cài đặt một web server khác, một repository git trần mà ta sẽ đẩy các thay đổi vào và một móc git sẽ thực thi khi nào nhận được một lần đẩy. Hoàn thành các bước dưới đây với quyền là user bình thường với các quyền sudo.

Cài đặt Hook sau khi nhận của server production

Trên server production , hãy bắt đầu bằng cách cài đặt web server :

sudo apt-get update sudo apt-get install apache2 

, ta nên cấp quyền sở hữu root tài liệu cho user mà ta đang điều hành với quyền :

sudo chown -R `whoami`:`id -gn` /var/www/html 

Ta cũng cần nhớ cài đặt git trên máy này:

sudo apt-get install git 

Bây giờ, ta có thể tạo một folder trong folder chính của user để chứa kho. Sau đó, ta có thể di chuyển vào folder đó và khởi tạo một repository trống. Một repository trống không có folder làm việc và tốt hơn cho các server mà bạn sẽ không làm việc trực tiếp nhiều:

mkdir ~/proj cd ~/proj git init --bare 

Vì đây là một repository trống, không có folder làm việc và tất cả các file nằm trong .git trong một cài đặt thông thường đều nằm trong chính folder chính.

Ta cần tạo một git hook khác. Lần này, ta quan tâm đến hook post-receive , được chạy trên server nhận git push . Mở file này trong editor :

nano hooks/post-receive 

, ta cần bắt đầu bằng cách xác định loại script ta đang viết. Sau đó, ta có thể gõ lệnh kiểm tra tương tự mà ta đã sử dụng trong file post-commit , được sửa đổi để sử dụng các đường dẫn trên máy này:

#!/bin/bash git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f 

Vì đây là một repository trống, --git-dir phải trỏ đến --git-dir cấp cao nhất của kho đó. Phần còn lại là khá giống nhau.

Tuy nhiên, ta cần thêm một số logic bổ sung vào tập lệnh này. Nếu ta vô tình đẩy một nhánh test-feature đến server này, ta không muốn điều đó được triển khai. Ta muốn chắc chắn rằng ta chỉ sẽ được triển khai master chi nhánh.

Đối với hook post-receive , bạn có thể đã nhận thấy trong bảng trước đó rằng git chuyển hàm băm commit của bản sửa đổi cũ, hàm băm commit của bản sửa đổi mới và tham chiếu đang được đẩy làm đầu vào chuẩn cho tập lệnh. Ta có thể sử dụng điều này để kiểm tra xem ref có phải là nhánh chính hay không.

Đầu tiên, ta cần đọc đầu vào chuẩn. Đối với mỗi lần giới thiệu được đẩy, ba phần thông tin (phiên bản cũ, version mới, số liệu giới thiệu) sẽ được đưa vào tập lệnh, được phân tách bằng khoảng trắng, làm đầu vào tiêu chuẩn. Ta có thể đọc với một while vòng lặp để bao quanh git lệnh:

#!/bin/bash while read oldrev newrev ref do     git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f done 

Vì vậy, bây giờ, ta sẽ có ba biến được cài đặt dựa trên những gì đang được đẩy. Đối với một lần đẩy nhánh chính, đối tượng ref sẽ chứa một cái gì đó giống như refs/heads/master . Ta có thể kiểm tra xem ref mà server đang nhận có định dạng này hay không bằng cách sử dụng cấu trúc if :

#!/bin/bash while read oldrev newrev ref do     if [[ $ref =~ .*/master$ ]];     then         git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f     fi done 

Đối với các hook phía server , git có thể chuyển các thông báo trở lại client . Mọi thứ được gửi đến tiêu chuẩn sẽ được chuyển hướng đến client . Điều này cho ta cơ hội thông báo rõ ràng cho user về quyết định đã được thực hiện.

Ta nên thêm một số văn bản mô tả tình huống nào đã được phát hiện và hành động đã được thực hiện. Ta nên thêm một khối else để thông báo cho user khi một nhánh không phải chính được nhận thành công, mặc dù hành động sẽ không kích hoạt triển khai:

#!/bin/bash while read oldrev newrev ref do     if [[ $ref =~ .*/master$ ]];     then         echo "Master ref received.  Deploying master branch to production..."         git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f     else         echo "Ref $ref successfully received.  Doing nothing: only the master branch may be deployed on this server."     fi done 

Khi bạn hoàn tất, hãy lưu file .

Lưu ý , ta phải thực thi tập lệnh để hook hoạt động:

chmod +x hooks/post-receive 

Bây giờ, ta có thể cài đặt quyền truy cập vào server từ xa này trên client của ta .

Cấu hình Server Từ xa trên Máy khách của bạn

Quay lại client (phát triển) của bạn, quay lại folder làm việc của dự án của bạn:

cd ~/proj 

Bên trong, thêm server từ xa làm điều khiển từ xa được gọi là production . Bạn cần biết tên user mà bạn đã sử dụng trên server production của bạn , cũng như địa chỉ IP hoặc domain của nó. Bạn cũng cần biết vị trí của repository trống mà bạn cài đặt liên quan đến folder chính của user .

Lệnh bạn nhập sẽ trông giống như sau:

git remote add production demo@server_domain_or_IP:proj 

Hãy đẩy chi nhánh chính hiện tại của ta lên server production của ta :

git push production master 

Nếu bạn chưa cấu hình SSH key , bạn có thể phải nhập password của user server production của bạn . Bạn sẽ thấy một cái gì đó giống như sau:

Counting objects: 8, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (4/4), 473 bytes | 0 bytes/s, done. Total 4 (delta 0), reused 0 (delta 0) remote: Master ref received.  Deploying master branch... To demo@107.170.14.32:proj    009183f..f1b9027  master -> master 

Như bạn thấy , văn bản từ hook post-receive của ta nằm trong kết quả của lệnh. Nếu ta truy cập domain hoặc địa chỉ IP của server production trong trình duyệt web, ta sẽ thấy version hiện tại của dự án của bạn :

thúc đẩy production

Có vẻ như hook đã đẩy thành công mã của ta sang trạng thái production sau khi nhận được thông tin.

Bây giờ, ta hãy thử nghiệm một số mã mới. Quay lại máy phát triển, ta sẽ tạo một nhánh mới để chứa các thay đổi của ta . Bằng cách này, ta có thể đảm bảo mọi thứ đã sẵn sàng trước khi triển khai vào production .

Tạo một nhánh mới có tên là test_feature và kiểm tra nhánh mới bằng lệnh :

git checkout -b test_feature 

Ta hiện đang làm việc trong nhánh test_feature . Hãy thực hiện một thay đổi mà ta có thể muốn chuyển sang production . Ta sẽ commit nó với chi nhánh này:

echo "<h2>New Feature Here</h2>" >> index.html git add . git commit -m "Trying out new feature" 

Đến đây, nếu bạn truy cập địa chỉ IP hoặc domain của máy phát triển của bạn , bạn sẽ thấy các thay đổi của bạn được hiển thị:

 commit  thay đổi

Điều này là do máy phát triển của ta vẫn đang được triển khai lại ở mỗi lần commit . Luồng công việc này rất phù hợp để kiểm tra các thay đổi trước khi chuyển chúng sang production .

Ta có thể đẩy chi nhánh test_feature của test_feature lên server production từ xa:

git push production test_feature 

Bạn sẽ thấy thông báo khác từ móc post-receive của ta trong kết quả :

Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 301 bytes | 0 bytes/s, done. Total 3 (delta 1), reused 0 (delta 0) remote: Ref refs/heads/test_feature successfully received.  Doing nothing: only the master branch may be deployed on this server To demo@107.170.14.32:proj    83e9dc4..5617b50  test_feature -> test_feature 

Nếu bạn kiểm tra lại server production trong trình duyệt của bạn , bạn sẽ thấy không có gì thay đổi. Đây là những gì ta mong đợi, vì thay đổi mà ta đã đẩy không nằm trong nhánh chính.

Bây giờ ta đã thử nghiệm các thay đổi của bạn trên máy phát triển của bạn , ta chắc chắn rằng ta muốn kết hợp tính năng này vào nhánh chính của ta . Ta có thể kiểm của ta master chi nhánh và hợp nhất trong ta test_feature chi nhánh trên máy tính phát triển của ta :

git checkout master git merge test_feature 

Bây giờ, bạn đã hợp nhất tính năng mới vào nhánh chính. Việc đẩy đến server production sẽ áp dụng các thay đổi của ta :

git push production master 

Nếu ta kiểm tra domain hoặc địa chỉ IP của server production , ta sẽ thấy các thay đổi của bạn :

Được đẩy sang production

Sử dụng quy trình làm việc này, ta có thể có một cỗ máy phát triển sẽ hiển thị ngay lập tức mọi thay đổi đã commit . Máy production sẽ được cập nhật khi nào ta đẩy nhánh chính.

Kết luận

Nếu bạn đã theo dõi đến đây, bạn có thể thấy các cách khác nhau mà git hooks có thể giúp tự động hóa một số tác vụ của bạn. Họ có thể giúp bạn triển khai mã của bạn hoặc giúp bạn duy trì các tiêu chuẩn chất lượng bằng cách từ chối các thay đổi không tuân theo hoặc thông báo commit .

Mặc dù tiện ích của git hook là khó có thể tranh cãi, nhưng việc triển khai thực tế có thể hơi khó nắm bắt và khó khắc phục sự cố. Thực hành triển khai các cấu hình khác nhau, thử nghiệm với các đối số phân tích cú pháp và đầu vào tiêu chuẩn, đồng thời theo dõi cách git xây dựng môi trường hooks sẽ giúp bạn học cách viết hook hiệu quả. Về lâu dài, khoản đầu tư thời gian thường đáng giá, vì nó có thể dễ dàng giúp bạn và group của bạn tiết kiệm vô số công việc thủ công trong suốt vòng đời dự án của bạn.


Tags:

Các tin liên quan