Khi làm việc với các dự án .NET, việc quản lý và chia sẻ các gói thư viện nội bộ thường yêu cầu một kho lưu trữ NuGet riêng biệt. Các công cụ như Nexus Repository Manager cung cấp một nền tảng mạnh mẽ cho mục đích này. Bài viết này sẽ hướng dẫn cách đẩy các gói NuGet (tệp .nupkg) lên một kho lưu trữ riêng, đồng thời giải quyết các vấn đề xác thực và tự động hóa quy trình.
Lấy Khóa API từ Nexus
Để có thể đẩy gói lên Nexus, bạn cần một khóa API (API Key) để xác thực. Sau khi đăng nhập vào giao diện quản trị Nexus bằng tài khoản của bạn (ví dụ: admin), bạn có thể tìm thấy khóa API này trong phần cài đặt người dùng hoặc hồ sơ của mình.
Thực Hiện Đẩy Gói NuGet qua Dòng Lệnh
Lệnh cơ bản để đẩy một gói NuGet lên kho lưu trữ là nuget.exe push. Dưới đây là ví dụ về cách sử dụng lệnh này:
nuget.exe push MyProject.Package.1.0.0.nupkg -Source http://your.nexus.host:port/repository/nuget-hosted/ -ApiKey "your-api-key-from-nexus"
Trong đó:
MyProject.Package.1.0.0.nupkg: Đường dẫn đến tệp gói NuGet bạn muốn đẩy lên.-Source: Địa chỉ URL của kho lưu trữ NuGet trên Nexus.-ApiKey: Khóa API bạn đã lấy từ Nexus.
Khi chạy lệnh push lần đầu tiên hoặc nếu Nexus yêu cầu xác thực cho các yêu cầu GET trước khi PUT, bạn có thể được nhắc nhập tên người dùng và mật khẩu. Để tránh phải nhập thông tin này nhiều lần, đặc biệt trong các kịch bản tự động hóa, bạn có thể cấu hình thông tin xác thực cho nguồn NuGet của mình.
Cấu Hình Thông Tin Xác Thực Nguồn
Sử dụng lệnh nuget.exe Sources Update để lưu trữ thông tin đăng nhập của bạn một cách an toàn. Điều này sẽ giúp lệnh push sau này không còn hỏi lại thông tin xác thực:
nuget.exe Sources Update -Name "MyNexusNugetFeed" -Source "http://your.nexus.host:port/repository/nuget-group/" -UserName "admin" -Password "admin_password"
Sau khi thực hiện lệnh này, mọi hoạt động đẩy gói đến nguồn có tên "MyNexusNugetFeed" sẽ tự động sử dụng thông tin xác thực đã được lưu.
Tự Động Hóa Việc Đẩy Gói bằng C# với CliWrap
Trong các ứng dụng .NET hoặc kịch bản CI/CD, bạn có thể lập trình để gọi các lệnh dòng lệnh. Thư viện CliWrap là một lựa chọn tuyệt vời để thực hiện việc này trong C#. Dưới đây là một ví dụ về cách đóng gói lệnh nuget.exe push vào một hàm C# sử dụng CliWrap:
using CliWrap;
using CliWrap.EventStream; // Dùng cho ListenAsync
using System.Text;
using System.Threading.Tasks;
using System;
using System.IO; // Dùng cho File.Exists
public static class NugetPackagePublisher
{
/// <summary>
/// Thực hiện việc đẩy gói NuGet (.nupkg) lên một kho lưu trữ từ xa.
/// </summary>
/// <param name="packageFilePath">Đường dẫn đầy đủ đến tệp .nupkg.</param>
/// <param name="apiKey">Khóa API để xác thực với kho lưu trữ NuGet.</param>
/// <param name="repositoryUri">URI của kho lưu trữ NuGet đích (ví dụ: http://myrepo/nuget-hosted/).</param>
public static async Task PublishNugetPackage(string packageFilePath, string apiKey, string repositoryUri)
{
// Kiểm tra sự tồn tại của nuget.exe
if (!File.Exists("nuget.exe") && Environment.GetEnvironmentVariable("PATH")?.Split(';').All(p => !File.Exists(Path.Combine(p, "nuget.exe"))) == true)
{
Console.WriteLine("Lỗi: Không tìm thấy 'nuget.exe'. Đảm bảo nó có trong biến môi trường PATH hoặc trong cùng thư mục.");
return;
}
// Kiểm tra sự tồn tại của tệp gói NuGet
if (!File.Exists(packageFilePath))
{
Console.WriteLine($"Lỗi: Không tìm thấy gói NuGet tại đường dẫn: {packageFilePath}");
return;
}
// Xây dựng chuỗi đối số cho lệnh nuget.exe push
var argumentsBuilder = new StringBuilder();
argumentsBuilder.Append("push ");
argumentsBuilder.Append($"\"{packageFilePath}\" "); // Đảm bảo đường dẫn có khoảng trắng được bao quanh bởi dấu ngoặc kép
argumentsBuilder.Append($"-Source \"{repositoryUri}\" ");
argumentsBuilder.Append($"-ApiKey \"{apiKey}\"");
Console.WriteLine($"Đang thực hiện lệnh: nuget.exe {argumentsBuilder}");
// Tạo và thực thi lệnh bằng CliWrap
var commandExecution = Cli.Wrap("nuget.exe")
.WithArguments(argumentsBuilder.ToString());
// Lắng nghe các sự kiện từ tiến trình (output, error, exited)
await foreach (var commandEvent in commandExecution.ListenAsync())
{
switch (commandEvent)
{
case StartedCommandEvent started:
Console.WriteLine($"Tiến trình nuget.exe bắt đầu; ID: {started.ProcessId}");
break;
case StandardOutputCommandEvent stdOut:
Console.WriteLine($"[OUTPUT] {stdOut.Text}");
break;
case StandardErrorCommandEvent stdErr:
Console.Error.WriteLine($"[ERROR] {stdErr.Text}");
break;
case ExitedCommandEvent exited:
Console.WriteLine($"Tiến trình nuget.exe đã kết thúc; Mã thoát: {exited.ExitCode}");
if (exited.ExitCode != 0)
{
Console.Error.WriteLine("Có lỗi xảy ra trong quá trình đẩy gói NuGet.");
}
break;
}
}
}
}