Bản phát hành werf 1.1: những cải tiến cho trình xây dựng ngày hôm nay và kế hoạch cho tương lai

Bản phát hành werf 1.1: những cải tiến cho trình xây dựng ngày hôm nay và kế hoạch cho tương lai

người sói là tiện ích GitOps CLI mã nguồn mở của chúng tôi để xây dựng và phân phối ứng dụng cho Kubernetes. Như đã hứa, phát hành phiên bản v1.0 đánh dấu sự bắt đầu bổ sung thêm các tính năng mới cho werf và sửa đổi các phương pháp tiếp cận truyền thống. Bây giờ chúng tôi vui mừng giới thiệu phiên bản v1.1, đây là một bước tiến lớn trong quá trình phát triển và là nền tảng cho tương lai người sưu tầm werf. Phiên bản hiện có sẵn tại kênh 1.1 ea.

Cơ sở của bản phát hành là kiến ​​trúc mới của giai đoạn lưu trữ và tối ưu hóa công việc của cả hai bộ sưu tập (đối với Stapel và Dockerfile). Kiến trúc lưu trữ mới mở ra khả năng triển khai các tập hợp phân tán từ nhiều máy chủ và các tập hợp song song trên cùng một máy chủ.

Tối ưu hóa công việc bao gồm loại bỏ các tính toán không cần thiết ở giai đoạn tính toán chữ ký giai đoạn và thay đổi cơ chế tính tổng kiểm tra tệp thành cơ chế hiệu quả hơn. Việc tối ưu hóa này giúp giảm thời gian trung bình của việc xây dựng dự án bằng cách sử dụng werf. Và các bản dựng không hoạt động, khi tất cả các giai đoạn tồn tại trong bộ đệm giai đoạn lưu trữ, bây giờ thực sự rất nhanh. Trong hầu hết các trường hợp, việc khởi động lại bản dựng sẽ mất chưa đến 1 giây! Điều này cũng áp dụng cho các thủ tục xác minh các giai đoạn trong quá trình làm việc của các nhóm. werf deploy и werf run.

Cũng trong bản phát hành này, một chiến lược gắn thẻ hình ảnh theo nội dung đã xuất hiện - gắn thẻ dựa trên nội dung, hiện được bật theo mặc định và là tùy chọn duy nhất được đề xuất.

Chúng ta hãy xem xét kỹ hơn những cải tiến quan trọng trong werf v1.1, đồng thời cho bạn biết về kế hoạch cho tương lai.

Điều gì đã thay đổi trong werf v1.1?

Định dạng và thuật toán đặt tên giai đoạn mới để chọn các giai đoạn từ bộ đệm

Quy tắc tạo tên sân khấu mới. Giờ đây, mỗi bản dựng giai đoạn sẽ tạo ra một tên giai đoạn duy nhất, bao gồm 2 phần: chữ ký (như trong phiên bản 1.0) cộng với mã định danh tạm thời duy nhất.

Ví dụ: tên hình ảnh sân khấu đầy đủ có thể trông như thế này:

werf-stages-storage/myproject:d2c5ad3d2c9fcd9e57b50edd9cb26c32d156165eb355318cebc3412b-1582656767835

...hoặc nói chung:

werf-stages-storage/PROJECT:SIGNATURE-TIMESTAMP_MILLISEC

Đây:

  • SIGNATURE là chữ ký giai đoạn, đại diện cho mã nhận dạng của nội dung giai đoạn và phụ thuộc vào lịch sử chỉnh sửa trong Git dẫn đến nội dung này;
  • TIMESTAMP_MILLISEC là mã nhận dạng hình ảnh duy nhất được đảm bảo được tạo tại thời điểm hình ảnh mới được tạo.

Thuật toán chọn các giai đoạn từ bộ đệm dựa trên việc kiểm tra mối quan hệ của các cam kết Git:

  1. Werf tính toán chữ ký của một giai đoạn nhất định.
  2. В giai đoạn lưu trữ Có thể có nhiều giai đoạn cho một chữ ký nhất định. Werf chọn tất cả các giai đoạn phù hợp với chữ ký.
  3. Nếu giai đoạn hiện tại được liên kết với Git (git-archive, giai đoạn tùy chỉnh với các bản vá Git: install, beforeSetup, setup; hoặc git-latest-patch), thì werf chỉ chọn những giai đoạn được liên kết với một cam kết là tổ tiên của cam kết hiện tại (mà bản dựng được gọi).
  4. Từ các giai đoạn phù hợp còn lại, một giai đoạn được chọn - giai đoạn cũ nhất tính theo ngày tạo.

Một giai đoạn dành cho các nhánh Git khác nhau có thể có cùng chữ ký. Nhưng werf sẽ ngăn việc sử dụng bộ nhớ đệm liên kết với các nhánh khác nhau giữa các nhánh này, ngay cả khi chữ ký khớp nhau.

→ Tài liệu.

Thuật toán mới để tạo và lưu các giai đoạn trong bộ lưu trữ giai đoạn

Nếu khi chọn các giai đoạn từ bộ đệm, werf không tìm thấy giai đoạn phù hợp thì quá trình lắp ráp một giai đoạn mới sẽ được bắt đầu.

Lưu ý rằng nhiều quy trình (trên một hoặc nhiều máy chủ) có thể bắt đầu xây dựng cùng một giai đoạn vào khoảng cùng một thời điểm. Werf sử dụng thuật toán chặn lạc quan giai đoạn lưu trữ tại thời điểm lưu hình ảnh mới được thu thập vào giai đoạn lưu trữ. Bằng cách này, khi quá trình xây dựng giai đoạn mới đã sẵn sàng, các khối werf sẽ giai đoạn lưu trữ và chỉ lưu hình ảnh mới được thu thập ở đó nếu hình ảnh phù hợp không còn tồn tại ở đó (bằng chữ ký và các tham số khác - xem thuật toán mới để chọn các giai đoạn từ bộ đệm).

Một hình ảnh mới được lắp ráp được đảm bảo có mã định danh duy nhất bởi TIMESTAMP_MILLISEC (xem định dạng đặt tên giai đoạn mới). Trường hợp ở giai đoạn lưu trữ một hình ảnh phù hợp sẽ được tìm thấy, werf sẽ loại bỏ hình ảnh mới được biên dịch và sẽ sử dụng hình ảnh từ bộ đệm.

Nói cách khác: quy trình đầu tiên hoàn tất việc xây dựng hình ảnh (quy trình nhanh nhất) sẽ có quyền lưu trữ hình ảnh đó trong bộ lưu trữ giai đoạn (và sau đó chính hình ảnh này sẽ được sử dụng cho tất cả các bản dựng). Quá trình xây dựng chậm sẽ không bao giờ cản trở quá trình nhanh hơn lưu kết quả xây dựng của giai đoạn hiện tại và chuyển sang bản dựng tiếp theo.

→ Tài liệu.

Cải thiện hiệu suất của trình tạo Dockerfile

Hiện tại, quy trình các giai đoạn cho hình ảnh được xây dựng từ Dockerfile bao gồm một giai đoạn - dockerfile. Khi tính chữ ký, tổng kiểm tra của các tập tin được tính context, sẽ được sử dụng trong quá trình lắp ráp. Trước cải tiến này, werf đã duyệt qua tất cả các tệp một cách đệ quy và lấy tổng kiểm tra bằng cách tính tổng ngữ cảnh và chế độ của từng tệp. Bắt đầu với v1.1, werf có thể sử dụng tổng kiểm tra được tính toán được lưu trữ trong kho Git.

Thuật toán dựa trên git ls-cây. Thuật toán tính đến các bản ghi trong .dockerignore và chỉ duyệt cây tập tin một cách đệ quy khi cần thiết. Vì vậy, chúng tôi đã tách khỏi việc đọc hệ thống tệp và sự phụ thuộc của thuật toán vào kích thước context không đáng kể.

Thuật toán cũng kiểm tra các tệp không bị theo dõi và nếu cần, sẽ tính đến chúng trong tổng kiểm tra.

Cải thiện hiệu suất khi nhập tập tin

Các phiên bản của werf v1.1 sử dụng máy chủ rsync khi nhập tập tin từ đồ tạo tác và hình ảnh. Trước đây, việc nhập được thực hiện theo hai bước bằng cách sử dụng thư mục gắn kết từ hệ thống máy chủ.

Hiệu suất nhập trên macOS không còn bị giới hạn bởi khối lượng Docker và quá trình nhập hoàn tất trong cùng khoảng thời gian như Linux và Windows.

Gắn thẻ dựa trên nội dung

Werf v1.1 hỗ trợ tính năng gắn thẻ theo nội dung hình ảnh - gắn thẻ dựa trên nội dung. Thẻ của hình ảnh Docker thu được phụ thuộc vào nội dung của những hình ảnh đó.

Khi chạy lệnh werf publish --tags-by-stages-signature hoặc werf ci-env --tagging-strategy=stages-signature hình ảnh được công bố của cái gọi là chữ ký sân khấu hình ảnh. Mỗi hình ảnh được gắn thẻ chữ ký riêng của các giai đoạn của hình ảnh này, được tính theo quy tắc tương tự như chữ ký thông thường của từng giai đoạn riêng biệt, nhưng là mã nhận dạng chung của hình ảnh.

Chữ ký của các giai đoạn hình ảnh phụ thuộc vào:

  1. nội dung của hình ảnh này;
  2. lịch sử của những thay đổi Git dẫn đến nội dung này.

Kho lưu trữ Git luôn có các cam kết giả không thay đổi nội dung của tệp hình ảnh. Ví dụ: cam kết chỉ có nhận xét hoặc cam kết hợp nhất hoặc cam kết thay đổi các tệp đó trong Git sẽ không được nhập vào hình ảnh.

Khi sử dụng gắn thẻ dựa trên nội dung, các vấn đề khởi động lại nhóm ứng dụng không cần thiết trong Kubernetes do thay đổi tên hình ảnh sẽ được giải quyết, ngay cả khi nội dung của hình ảnh không thay đổi. Nhân tiện, đây là một trong những lý do ngăn cản việc lưu trữ nhiều dịch vụ vi mô của một ứng dụng trong một kho lưu trữ Git.

Ngoài ra, gắn thẻ dựa trên nội dung là phương pháp gắn thẻ đáng tin cậy hơn so với gắn thẻ trên các nhánh Git, vì nội dung của hình ảnh thu được không phụ thuộc vào thứ tự các quy trình được thực thi trong hệ thống CI để tập hợp nhiều cam kết của cùng một nhánh.

Điều quan trọng là: bắt đầu từ bây giờ chữ ký giai đoạn - chiến lược gắn thẻ duy nhất được đề xuất. Nó sẽ được sử dụng theo mặc định trong lệnh werf ci-env (trừ khi bạn chỉ định rõ ràng một sơ đồ gắn thẻ khác).

→ Tài liệu. Một ấn phẩm riêng biệt cũng sẽ được dành cho tính năng này. ĐÃ CẬP NHẬT (3/XNUMX): Bài viết chi tiết xuất bản.

Mức độ ghi nhật ký

Giờ đây, người dùng có cơ hội kiểm soát đầu ra, đặt mức ghi nhật ký và làm việc với thông tin gỡ lỗi. Đã thêm tùy chọn --log-quiet, --log-verbose, --log-debug.

Theo mặc định, đầu ra chứa thông tin tối thiểu:

Bản phát hành werf 1.1: những cải tiến cho trình xây dựng ngày hôm nay và kế hoạch cho tương lai

Khi sử dụng đầu ra dài dòng (--log-verbose) bạn có thể thấy cách hoạt động của werf:

Bản phát hành werf 1.1: những cải tiến cho trình xây dựng ngày hôm nay và kế hoạch cho tương lai

Đầu ra chi tiết (--log-debug), ngoài thông tin gỡ lỗi werf, còn chứa nhật ký của các thư viện đã sử dụng. Ví dụ: bạn có thể xem cách tương tác với Docker Đăng ký xảy ra và cũng ghi lại những nơi sử dụng một lượng thời gian đáng kể:

Bản phát hành werf 1.1: những cải tiến cho trình xây dựng ngày hôm nay và kế hoạch cho tương lai

Kế hoạch xa hơn

Cảnh báo! Các tùy chọn được mô tả dưới đây được đánh dấu v1.1 sẽ có sẵn trong phiên bản này, nhiều trong số đó sẽ có trong tương lai gần. Cập nhật sẽ đến thông qua cập nhật tự động khi sử dụng multiwerf. Các tính năng này không ảnh hưởng đến phần ổn định của các chức năng v1.1, sự xuất hiện của chúng sẽ không yêu cầu người dùng can thiệp thủ công vào các cấu hình hiện có.

Hỗ trợ đầy đủ cho các triển khai Docker Đăng ký khác nhau (MỚI)

Mục tiêu là để người dùng sử dụng triển khai tùy chỉnh mà không bị hạn chế khi sử dụng werf.

Hiện tại, chúng tôi đã xác định được bộ giải pháp sau đây mà chúng tôi sẽ đảm bảo hỗ trợ đầy đủ:

  • Mặc định (thư viện/đăng ký)*,
  • AWS ECR
  • Màu xanh*,
  • Trung tâm Docker
  • GCR*,
  • Gói GitHub
  • Sổ đăng ký GitLab*,
  • Hải cảng*,
  • Quay lại.

Các giải pháp hiện được werf hỗ trợ đầy đủ sẽ được đánh dấu bằng dấu hoa thị. Đối với những người khác có hỗ trợ, nhưng có những hạn chế.

Hai vấn đề chính có thể được xác định:

  • Một số giải pháp không hỗ trợ loại bỏ thẻ bằng API đăng ký Docker, ngăn người dùng sử dụng tính năng dọn dẹp tự động của werf. Điều này đúng với các gói AWS ECR, Docker Hub và GitHub.
  • Một số giải pháp không hỗ trợ cái gọi là kho lưu trữ lồng nhau (Docker Hub, GitHub Packages và Quay), nhưng người dùng phải tạo chúng theo cách thủ công bằng UI hoặc API (AWS ECR).

Chúng tôi sẽ giải quyết những vấn đề này và các vấn đề khác bằng cách sử dụng API gốc của giải pháp. Nhiệm vụ này cũng bao gồm việc thực hiện toàn bộ chu trình vận hành werf bằng các thử nghiệm cho từng chu trình đó.

Xây dựng hình ảnh phân tán (↑)

  • Phiên bản: v1.2 v1.1 (mức độ ưu tiên triển khai tính năng này đã được tăng lên)
  • Ngày: Tháng 3-Tháng 4
  • Vấn đề

Hiện tại, werf v1.0 và v1.1 chỉ có thể được sử dụng trên một máy chủ chuyên dụng cho các hoạt động xây dựng và xuất bản hình ảnh cũng như triển khai ứng dụng lên Kubernetes.

Để mở ra khả năng làm việc phân tán của werf, khi quá trình xây dựng và triển khai ứng dụng trong Kubernetes được khởi chạy trên một số máy chủ tùy ý và các máy chủ này không lưu trạng thái giữa các bản dựng (chạy tạm thời), werf cần phải triển khai khả năng sử dụng Docker Đăng ký làm cửa hàng giai đoạn.

Trước đây, khi dự án werf còn được gọi là dapp thì nó đã có cơ hội như vậy. Tuy nhiên, chúng tôi đã gặp phải một số vấn đề cần được tính đến khi triển khai chức năng này trong werf.

Ghi. Tính năng này không yêu cầu bộ sưu tập hoạt động bên trong nhóm Kubernetes, bởi vì Để thực hiện việc này, bạn cần loại bỏ sự phụ thuộc vào máy chủ Docker cục bộ (trong nhóm Kubernetes không có quyền truy cập vào máy chủ Docker cục bộ, vì bản thân tiến trình này đang chạy trong một thùng chứa và werf không và sẽ không hỗ trợ làm việc với máy chủ Docker qua mạng). Hỗ trợ chạy Kubernetes sẽ được triển khai riêng.

Hỗ trợ chính thức cho GitHub Actions (MỚI)

Bao gồm tài liệu werf (phần tài liệu tham khảo и hướng dẫn), cũng như GitHub Action chính thức để làm việc với werf.

Ngoài ra, nó sẽ cho phép werf hoạt động trên các vận động viên phù du.

Cơ chế tương tác của người dùng với hệ thống CI sẽ dựa trên việc đặt nhãn trên các yêu cầu kéo để bắt đầu một số hành động nhất định nhằm xây dựng/triển khai ứng dụng.

Phát triển và triển khai ứng dụng cục bộ với werf (↓)

  • Phiên bản: v1.1
  • Ngày: Tháng Một-Tháng Hai Tháng Tư
  • Vấn đề

Mục tiêu chính là đạt được một cấu hình thống nhất duy nhất để triển khai các ứng dụng cả cục bộ và trong sản xuất mà không cần thực hiện các hành động phức tạp.

werf cũng được yêu cầu phải có chế độ hoạt động để thuận tiện cho việc chỉnh sửa mã ứng dụng và nhận ngay phản hồi từ ứng dụng đang chạy để gỡ lỗi.

Thuật toán làm sạch mới (MỚI)

Trong phiên bản hiện tại của werf v1.1 trong quy trình cleanup Không có quy định nào về việc làm sạch hình ảnh đối với sơ đồ gắn thẻ dựa trên nội dung - những hình ảnh này sẽ tích lũy.

Ngoài ra, phiên bản hiện tại của werf (v1.0 và v1.1) sử dụng các chính sách dọn dẹp khác nhau cho hình ảnh được xuất bản theo sơ đồ gắn thẻ: nhánh Git, thẻ Git hoặc cam kết Git.

Một thuật toán mới để làm sạch hình ảnh dựa trên lịch sử cam kết trong Git, được thống nhất cho tất cả các sơ đồ gắn thẻ, đã được phát minh:

  • Giữ không quá N1 hình ảnh được liên kết với N2 cam kết gần đây nhất cho mỗi git HEAD (nhánh và thẻ).
  • Lưu trữ không quá N1 hình ảnh giai đoạn được liên kết với N2 cam kết gần đây nhất cho mỗi git HEAD (nhánh và thẻ).
  • Lưu trữ tất cả hình ảnh được sử dụng trong bất kỳ tài nguyên cụm Kubernetes nào (tất cả bối cảnh kube của tệp cấu hình và không gian tên đều được quét; bạn có thể hạn chế hành vi này bằng các tùy chọn đặc biệt).
  • Lưu trữ tất cả hình ảnh được sử dụng trong bảng kê khai cấu hình tài nguyên được lưu trong bản phát hành Helm.
  • Một hình ảnh có thể bị xóa nếu nó không được liên kết với bất kỳ HEAD nào từ git (ví dụ: vì chính HEAD tương ứng đã bị xóa) và không được sử dụng trong bất kỳ bảng kê khai nào trong cụm Kubernetes và trong các bản phát hành Helm.

Xây dựng hình ảnh song song (↓)

  • Phiên bản: v1.1
  • Thời gian: Tháng 1-Tháng 2 Tháng 4*

Phiên bản hiện tại của werf thu thập các hình ảnh và hiện vật được mô tả trong werf.yaml, tuần tự. Cần phải song song hóa quá trình lắp ráp các giai đoạn độc lập của hình ảnh và hiện vật, cũng như cung cấp đầu ra thuận tiện và nhiều thông tin.

* Lưu ý: thời hạn đã được thay đổi do mức độ ưu tiên tăng lên đối với việc triển khai tổ hợp phân tán, điều này sẽ bổ sung thêm nhiều khả năng mở rộng quy mô theo chiều ngang cũng như việc sử dụng werf với GitHub Actions. Lắp ráp song song là bước tối ưu hóa tiếp theo, cung cấp khả năng mở rộng theo chiều dọc khi lắp ráp một dự án.

Chuyển sang Mũ 3 (↓)

  • Phiên bản: v1.2
  • Thời gian: Tháng 2-Tháng 3 Tháng 5*

Bao gồm việc di chuyển sang cơ sở mã mới Mũ bảo hiểm 3 và một cách thuận tiện đã được chứng minh để di chuyển các cài đặt hiện có.

* Lưu ý: chuyển sang Helm 3 sẽ không thêm các tính năng quan trọng cho werf, vì tất cả các tính năng chính của Helm 3 (hợp nhất 3 chiều và không có xới) đều đã được triển khai trong werf. Hơn nữa, werf có Tính năng bổ sung ngoài những điều đã chỉ ra. Tuy nhiên, quá trình chuyển đổi này vẫn nằm trong kế hoạch của chúng tôi và sẽ được thực hiện.

Jsonnet để mô tả cấu hình Kubernetes (↓)

  • Phiên bản: v1.2
  • Ngày: Tháng Một-Tháng Hai Tháng Tư-Tháng Năm

Werf sẽ hỗ trợ mô tả cấu hình cho Kubernetes ở định dạng Jsonnet. Đồng thời, werf sẽ vẫn tương thích với Helm và sẽ có lựa chọn định dạng mô tả.

Nguyên nhân là do các mẫu Go, theo nhiều người, có rào cản gia nhập cao và khả năng hiểu code của các mẫu này cũng bị ảnh hưởng.

Khả năng giới thiệu các hệ thống mô tả cấu hình Kubernetes khác (ví dụ: Kustomize) cũng đang được xem xét.

Làm việc bên trong Kubernetes (↓)

  • Phiên bản: v1.2
  • Ngày: Tháng 4-tháng 5 tháng 5-tháng 6

Mục tiêu: Đảm bảo rằng hình ảnh được xây dựng và ứng dụng được phân phối bằng các trình chạy trong Kubernetes. Những thứ kia. Hình ảnh mới có thể được xây dựng, xuất bản, làm sạch và triển khai trực tiếp từ nhóm Kubernetes.

Để triển khai khả năng này, trước tiên bạn cần có khả năng xây dựng các hình ảnh được phân phối (xem điểm ở trên).

Nó cũng yêu cầu hỗ trợ cho chế độ hoạt động của trình xây dựng mà không cần máy chủ Docker (tức là bản dựng giống Kaniko hoặc bản dựng trong không gian người dùng).

Werf sẽ hỗ trợ xây dựng trên Kubernetes không chỉ với Dockerfile mà còn với trình tạo Stapel với các bản dựng lại gia tăng và Ansible.

Một bước tiến tới phát triển mở

Chúng tôi yêu cộng đồng của chúng tôi (GitHub, Telegram) và chúng tôi mong muốn ngày càng có nhiều người giúp cải thiện werf, hiểu được hướng đi mà chúng tôi đang hướng tới và tham gia vào quá trình phát triển.

Gần đây người ta đã quyết định chuyển sang Ban dự án GitHub để tiết lộ quá trình làm việc của nhóm chúng tôi. Bây giờ bạn có thể xem các kế hoạch trước mắt cũng như công việc hiện tại trong các lĩnh vực sau:

Rất nhiều công việc đã được thực hiện với các vấn đề:

  • Đã loại bỏ những cái không liên quan.
  • Những cái hiện có được đưa về một định dạng duy nhất, với đủ số lượng chi tiết và chi tiết.
  • Các vấn đề mới với ý tưởng và đề xuất đã được thêm vào.

Cách kích hoạt phiên bản v1.1

Phiên bản hiện có sẵn tại kênh 1.1 ea (trong các kênh ổn định и sỏi đá Tuy nhiên, các bản phát hành sẽ xuất hiện khi quá trình ổn định diễn ra ea bản thân nó đã đủ ổn định để sử dụng, bởi vì đã đi qua các kênh alpha и beta). Đã kích hoạt qua multiwerf theo cách sau:

source $(multiwerf use 1.1 ea)
werf COMMAND ...

Kết luận

Kiến trúc lưu trữ giai đoạn mới và tối ưu hóa trình xây dựng dành cho trình xây dựng Stapel và Dockerfile mở ra khả năng triển khai các bản dựng song song và phân tán trong werf. Các tính năng này sẽ sớm xuất hiện trong cùng bản phát hành v1.1 và sẽ tự động có sẵn thông qua cơ chế tự động cập nhật (đối với người dùng multiwerf).

Trong bản phát hành này, chiến lược gắn thẻ dựa trên nội dung hình ảnh đã được thêm vào - gắn thẻ dựa trên nội dung, đã trở thành chiến lược mặc định. Nhật ký lệnh chính cũng đã được làm lại: werf build, werf publish, werf deploy, werf dismiss, werf cleanup.

Bước quan trọng tiếp theo là thêm các cụm phân phối. Các bản dựng phân tán đã trở thành mức độ ưu tiên cao hơn so với các bản dựng song song kể từ phiên bản 1.0 vì chúng mang lại nhiều giá trị hơn cho werf: mở rộng quy mô theo chiều dọc của các trình tạo và hỗ trợ cho các trình tạo tạm thời trong các hệ thống CI/CD khác nhau, cũng như khả năng hỗ trợ chính thức cho GitHub Actions . Vì vậy, thời hạn thực hiện các hội đồng song song đã được thay đổi. Tuy nhiên, chúng tôi đang nỗ lực triển khai cả hai khả năng này càng sớm càng tốt.

Theo dõi tin tức! Và đừng quên ghé thăm chúng tôi tại GitHubđể tạo ra một vấn đề, tìm một vấn đề hiện có và thêm điểm cộng, tạo PR hoặc đơn giản là xem sự phát triển của dự án.

PS

Đọc thêm trên blog của chúng tôi:

Nguồn: www.habr.com

Thêm một lời nhận xét