GitHub Packages
GitHub Packages 是 GitHub 提供的包托管服务,支持 npm、Docker、Maven、Gradle、NuGet、RubyGems 等多种包格式。
概述
GitHub Packages 的优势:
- 统一管理:代码和包在同一个平台
- 权限集成:使用 GitHub 权限系统
- 免费额度:公开包免费,私有包有一定免费额度
- Actions 集成:与 GitHub Actions 无缝集成
支持的包格式
| 格式 | 用途 | 注册表地址 |
|---|---|---|
| npm | JavaScript/TypeScript | npm.pkg.github.com |
| Docker | 容器镜像 | ghcr.io |
| Maven | Java | maven.pkg.github.com |
| Gradle | Java | maven.pkg.github.com |
| NuGet | .NET | nuget.pkg.github.com |
| RubyGems | Ruby | rubygems.pkg.github.com |
npm 包发布
配置 package.json
{
"name": "@username/package-name",
"version": "1.0.0",
"publishConfig": {
"registry": "https://npm.pkg.github.com"
},
"repository": {
"type": "git",
"url": "git+https://github.com/username/repo.git"
}
}
包名必须以 @用户名/ 开头,用户名必须小写。
本地认证
创建或编辑 ~/.npmrc 文件:
//npm.pkg.github.com/:_authToken=YOUR_TOKEN
@username:registry=https://npm.pkg.github.com
或使用 npm login 命令:
npm login --scope=@username --registry=https://npm.pkg.github.com
用户名使用 GitHub 用户名,密码使用 Personal Access Token(需要 read:packages 和 write:packages 权限)。
发布包
npm publish
安装包
创建项目根目录的 .npmrc 文件:
@username:registry=https://npm.pkg.github.com
然后安装:
npm install @username/package-name
使用 GitHub Actions 发布
name: Publish Package
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://npm.pkg.github.com'
scope: '@username'
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Docker 镜像
GitHub Container Registry
GitHub Container Registry(GHCR)是 GitHub 的容器镜像仓库,地址为 ghcr.io。
本地登录
echo $TOKEN | docker login ghcr.io -u USERNAME --password-stdin
构建并推送镜像
docker build -t ghcr.io/username/image-name:tag .
docker push ghcr.io/username/image-name:tag
镜像可见性
默认情况下,推送的镜像是私有的。可以在 GitHub 网页上修改为公开:
- 进入仓库的 Packages 页面
- 点击包名称
- 点击 "Package settings"
- 修改可见性
使用 GitHub Actions
name: Docker Publish
on:
push:
branches: [main]
tags: ['v*']
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Maven 包发布
配置 pom.xml
<project>
<distributionManagement>
<repository>
<id>github</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/username/repository</url>
</repository>
</distributionManagement>
</project>
配置 settings.xml
在 ~/.m2/settings.xml 中添加:
<settings>
<servers>
<server>
<id>github</id>
<username>USERNAME</username>
<password>TOKEN</password>
</server>
</servers>
</settings>
发布
mvn deploy
使用 GitHub Actions
name: Publish Maven Package
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- run: mvn -B deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Gradle 包发布
配置 build.gradle
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/username/repository")
credentials {
username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
password = project.findProperty("gpr.token") ?: System.getenv("TOKEN")
}
}
}
}
发布
./gradlew publish
使用 GitHub Actions
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- uses: gradle/actions/setup-gradle@v3
- run: ./gradlew publish
env:
USERNAME: ${{ github.actor }}
TOKEN: ${{ secrets.GITHUB_TOKEN }}
NuGet 包发布
配置 nuget.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="github" value="https://nuget.pkg.github.com/username/index.json" />
</packageSources>
<packageSourceCredentials>
<github>
<add key="Username" value="USERNAME" />
<add key="ClearTextPassword" value="TOKEN" />
</github>
</packageSourceCredentials>
</configuration>
发布
dotnet nuget push --source "github" package.nupkg
使用 GitHub Actions
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.x'
- run: dotnet build --configuration Release
- run: dotnet pack --configuration Release
- run: dotnet nuget push **/*.nupkg --source "github"
env:
NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
包管理
查看包
在 GitHub 网页上:
- 进入仓库页面
- 点击右侧 "Packages" 部分
- 查看该仓库发布的所有包
包版本管理
可以在包页面:
- 查看所有版本
- 下载特定版本
- 删除版本(需要权限)
包权限
包权限继承自仓库权限:
- 仓库管理员可以管理包
- 仓库写入者可以发布新版本
- 仓库读取者可以下载包
也可以单独配置包权限。
最佳实践
版本管理
使用语义化版本:
MAJOR.MINOR.PATCH
- MAJOR:不兼容的 API 变更
- MINOR:向后兼容的功能新增
- PATCH:向后兼容的问题修复
自动化发布
结合 GitHub Actions 实现自动化:
name: Publish
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: 发布包
run: |
echo "发布版本 ${{ github.event.release.tag_name }}"
安全考虑
- 使用
GITHUB_TOKEN而非 Personal Access Token - 配置最小权限
- 不要在日志中暴露敏感信息
- 定期检查和清理旧版本