Hướng Dẫn Triển Khai Maven Artifacts Với GitHub Actions
GitHub Packages là dịch vụ lưu trữ package cho phép bạn public hoặc private package của mình. Bài viết này hướng dẫn cách cấu hình dự án Maven và thiết lập GitHub Actions để tự động publish Java package lên GitHub Packages với xác thực và quản lý version phù hợp.

Giới thiệu
Trong bài viết này, tôi sẽ hướng dẫn bạn cách publish Java package lên GitHub Packages bằng Maven và GitHub Actions. Việc tự động hóa bằng CI/CD giúp artifacts của bạn luôn được cập nhật, có version rõ ràng và dễ dàng cho người khác hoặc chính các dự án nội bộ của bạn sử dụng lại. Hướng dẫn này dành cho các Java developer đã quen với Maven và muốn tự động hóa quá trình deploy bằng hệ sinh thái của GitHub.
Điều kiện chuẩn bị
- Java 8+
- Maven đã được cài đặt (để test)
- Một GitHub Repository
Vậy là bạn đã có đủ công cụ để bắt đầu. Cùng vào việc thôi!
Bắt đầu
1. Chuẩn bị GitHub repo với dự án Maven
- Với vai trò là developer muốn publish package lên GitHub package registry, bạn nên chuẩn bị một GitHub repo có cấu trúc Maven. Tôi đang dùng một repo có sẵn tên là vnd-to-text, dùng để chuyển đổi số tiền Việt Nam Đồng sang chữ. Bạn có thể tham khảo ý tưởng tại vnd-to-text.
- Trong bài viết này, tôi sẽ hướng dẫn bạn phần cấu hình và workflow file để publish repo này lên GitHub package registry.
Được rồi, chuyển sang bước tiếp theo nhé!
2. Thiết lập GitHub Action
2.1. Cấu hình pom.xml
Để publish Maven package lên GitHub package registry, bạn cần cấu hình pom.xml để chỉ repo của
bạn tới đúng package registry.
Đây là mẫu cấu hình bạn cần thêm vào POM.xml:
<distributionManagement>
<repository>
<id>github</id>
<name>GitHub OWNER Apache Maven Packages</name>
<url>https://maven.pkg.github.com/OWNER/REPOSITORY</url>
</repository>
</distributionManagement>Ví dụ:
<distributionManagement>
<repository>
<id>github</id>
<name>Github package</name>
<url>https://maven.pkg.github.com/trungntm/vnd-to-text</url>
</repository>
</distributionManagement>Đến đây bạn có thể đặt câu hỏi: Làm sao để quản lý Snapshot và Release version cho Maven package?
Đây là một câu hỏi rất hay, và tôi cũng từng thắc mắc như vậy.
Để giải quyết vấn đề này, chúng ta cần điều chỉnh cấu hình trong POM.xml để repo có thể dùng cả
Snapshot lẫn Release version.
Đây là format mới:
<distributionManagement>
<repository>
<id>github-release</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/OWNER/REPOSITORY</url>
</repository>
<snapshotRepository>
<id>github-snapshot</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/OWNER/REPOSITORY</url>
</snapshotRepository>
</distributionManagement>Với repo của tôi thì sẽ là:
<distributionManagement>
<repository>
<id>github-release</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/trungntm/vnd-to-text</url>
</repository>
<snapshotRepository>
<id>github-snapshot</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/trungntm/vnd-to-text</url>
</snapshotRepository>
</distributionManagement>2.2. Thiết lập GitHub workflow
Giờ hãy nói thêm một chút về cấu hình trong POM.xml.
Như bạn thấy, tôi đang dùng custom ID cho Snapshot và Release version:
- Snapshot: github-snapshot
- Release: github-release
Mặc định, GitHub chỉ cung cấp cho bạn một ID là github.
Nếu bạn muốn dùng ID riêng cho Snapshot và Release, bạn cần thêm một bước để định nghĩa các custom ID đó.
2.2.1. Thêm settings.xml vào thư mục .github
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>github-snapshot</id>
<username>${env.GITHUB_ACTOR}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
<server>
<id>github-release</id>
<username>${env.GITHUB_ACTOR}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
</servers>
</settings>GitHub tự động cung cấp một số Environment variable và Secret bắt đầu bằng tiền tố GITHUB_.
Trong file settings.xml này, tôi sử dụng GITHUB_ACTOR và GITHUB_TOKEN mà GitHub cung cấp sẵn.
GITHUB_ACTOR: chính là OWNER. Đây có thể là tên tài khoản GitHub hoặc tên organization của bạn.GITHUB_TOKEN: token này sẽ được tự động tạo khi GitHub Actions được trigger.
2.2.2. Workflow cho Snapshot version
Với snapshot version, workflow sẽ được trigger khi có thay đổi mới được push lên branch develop
hoặc khi bạn trigger thủ công.
Bạn cũng cần cấp quyền phù hợp cho workflow.
Hãy tạo snapshot.yml trong .github/workflows và tham khảo workflow bên dưới:
name: Publish to GitHub Snapshot Maven
on:
push:
branches: [ "develop" ]
workflow_dispatch:
permissions:
contents: read
packages: write
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'maven'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Publish to GitHub Packages
run: mvn deploy --settings .github/settings.xml -B --file pom.xml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_ACTOR: ${{ github.actor }}2.2.3. Workflow cho Release version
Ý tưởng của Release workflow sẽ tương tự Snapshot version. Tuy nhiên nó có thêm một bước: sau khi
publish Release version, workflow sẽ tự động tăng version trong POM.xml cho vòng phát triển tiếp
theo.
Ví dụ, nếu bạn đang phát triển ở version 0.0.1-SNAPSHOT rồi trigger release mới, workflow sẽ tạo
release version 0.0.1 và tự động bump version trong pom.xml lên 0.1.0-SNAPSHOT, sau đó commit
lại vào repo.
Để làm được điều này, bạn sẽ cần quyền write:
permissions:
contents: write
packages: writeHãy tạo release.yml trong .github/workflows và tham khảo workflow bên dưới:
name: Release to GitHub Maven
on:
workflow_dispatch:
permissions:
contents: write
packages: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'maven'
- name: Remove -SNAPSHOT from version
run: |
sed -i '0,/-SNAPSHOT</s/-SNAPSHOT</</' pom.xml
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git add pom.xml
git commit -m "Release: remove -SNAPSHOT from version"
- name: Deploy release to GitHub Packages
run: mvn deploy --settings .github/settings.xml -B --file pom.xml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_ACTOR: ${{ github.actor }}
- name: Bump version
run: |
VERSION=$(grep -m1 '<version>' pom.xml | sed -nE 's/.*<version>([0-9]+)\.([0-9]+)\.([0-9]+).*/\1 \2 \3/p')
MAJOR=$(echo $VERSION | cut -d' ' -f1)
MINOR=$(echo $VERSION | cut -d' ' -f2)
NEW_MINOR=$((MINOR+1))
sed -i "0,/<version>[0-9]\+\.[0-9]\+\.[0-9]\+<\/version>/s//<version>${MAJOR}.${NEW_MINOR}.0-SNAPSHOT<\/version>/" pom.xml
git add pom.xml
git commit -m "Bump version to ${MAJOR}.${NEW_MINOR}.0-SNAPSHOT"
git push
3. Các lỗi thường gặp và cách xử lý
Một số vấn đề bạn có thể gặp:
- 401 Unauthorized: bạn đang dùng sai OWNER hoặc gõ nhầm
GITHUB_TOKEN. Hãy kiểm tra lại OWNER có đúng là tên GitHub hoặc organization của bạn không, và token phải làGITHUB_TOKEN. - 403 Permission denied hoặc Incorrect repo URL: hãy kiểm tra lại OWNER/REPOSITORY. REPOSITORY phải là repo bạn đang làm việc và cũng là nơi GitHub Action đang được chạy.
- Version conflicts: hãy tăng Maven version. Lỗi này thường xảy ra khi bạn đã release một version nhưng chưa bump sang version mới. Hãy đảm bảo bạn đang làm việc trên code mới nhất trước khi Release.
Kết luận
Việc publish Maven package lên GitHub Packages thông qua Actions giúp quá trình release trở nên lặp lại được và dễ tự động hóa. Với cách thiết lập này, bạn đảm bảo người dùng package của mình luôn có thể truy cập phiên bản mới nhất với rất ít thao tác thủ công.