Publish distributions to Gitea PyPI registry alongside the release
This commit is contained in:
@@ -341,3 +341,51 @@ jobs:
|
|||||||
throw "release asset mismatch: $($publishedNames -join ', ')"
|
throw "release asset mismatch: $($publishedNames -join ', ')"
|
||||||
}
|
}
|
||||||
Write-Host "release verified: $tag ($($localNames.Count) files)"
|
Write-Host "release verified: $tag ($($localNames.Count) files)"
|
||||||
|
|
||||||
|
- name: Publish packages to Gitea PyPI
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
TWINE_USERNAME: antior
|
||||||
|
TWINE_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
TWINE_REPOSITORY_URL: ${{ gitea.server_url }}/api/packages/antior/pypi
|
||||||
|
run: |
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
if ([string]::IsNullOrWhiteSpace($env:TWINE_PASSWORD)) {
|
||||||
|
throw "GITHUB_TOKEN is required to publish packages"
|
||||||
|
}
|
||||||
|
$headers = @{ Authorization = "token $env:TWINE_PASSWORD" }
|
||||||
|
$simpleUrl = "$env:TWINE_REPOSITORY_URL/simple/dlp-io/"
|
||||||
|
|
||||||
|
function Get-RegistryFileNames {
|
||||||
|
try {
|
||||||
|
$response = Invoke-WebRequest -Headers $headers -Uri $simpleUrl
|
||||||
|
} catch {
|
||||||
|
if ([int]$_.Exception.Response.StatusCode -eq 404) { return @() }
|
||||||
|
throw
|
||||||
|
}
|
||||||
|
return @([regex]::Matches($response.Content, '<a\s+href="[^"]+"[^>]*>(?<name>[^<]+)</a>', "IgnoreCase") |
|
||||||
|
ForEach-Object { [Net.WebUtility]::HtmlDecode($_.Groups["name"].Value) })
|
||||||
|
}
|
||||||
|
|
||||||
|
$published = @(Get-RegistryFileNames)
|
||||||
|
$missing = @(Get-ChildItem -LiteralPath dist -File | Where-Object { $published -notcontains $_.Name })
|
||||||
|
if ($missing.Count -gt 0) {
|
||||||
|
$uploadArgs = @("-3.13", "-m", "twine", "upload", "--non-interactive", "--disable-progress-bar") +
|
||||||
|
@($missing | ForEach-Object FullName)
|
||||||
|
& py @uploadArgs
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "twine upload failed" }
|
||||||
|
} else {
|
||||||
|
Write-Host "all registry artifacts already published"
|
||||||
|
}
|
||||||
|
|
||||||
|
$expected = @(Get-ChildItem -LiteralPath dist -File | ForEach-Object Name)
|
||||||
|
for ($attempt = 1; $attempt -le 20; $attempt++) {
|
||||||
|
$published = @(Get-RegistryFileNames)
|
||||||
|
$unpublished = @($expected | Where-Object { $published -notcontains $_ })
|
||||||
|
if ($unpublished.Count -eq 0) { break }
|
||||||
|
if ($attempt -lt 20) { Start-Sleep -Seconds 3 }
|
||||||
|
}
|
||||||
|
if ($unpublished.Count -ne 0) {
|
||||||
|
throw "registry package files missing after upload: $($unpublished -join ', ')"
|
||||||
|
}
|
||||||
|
Write-Host "registry verified: dlp-io==$($env:DLP_IO_PACKAGE_VERSION) ($($expected.Count) files)"
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ pytest
|
|||||||
- `dlp_io-X.Y.Z.tar.gz`(sdist)
|
- `dlp_io-X.Y.Z.tar.gz`(sdist)
|
||||||
- `dlp_io.py` 和 5 个裸 `dlp_io.cp3XX-win_amd64.pyd`(免安装单文件,放进项目目录即可 import)
|
- `dlp_io.py` 和 5 个裸 `dlp_io.cp3XX-win_amd64.pyd`(免安装单文件,放进项目目录即可 import)
|
||||||
|
|
||||||
|
同一批 wheel/sdist 还会同步发布到 Gitea PyPI registry(`https://gitea.docker.antior.cn/api/packages/antior/pypi/simple`),可直接 `pip install --index-url ... dlp-io`。
|
||||||
|
|
||||||
安装方式见 [docs/DLP_IO_LIBRARY.md](docs/DLP_IO_LIBRARY.md)。
|
安装方式见 [docs/DLP_IO_LIBRARY.md](docs/DLP_IO_LIBRARY.md)。
|
||||||
|
|
||||||
本地只构建纯 Python 版:
|
本地只构建纯 Python 版:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from enum import Enum
|
|||||||
from multiprocessing.context import AuthenticationError
|
from multiprocessing.context import AuthenticationError
|
||||||
from multiprocessing.connection import Client
|
from multiprocessing.connection import Client
|
||||||
|
|
||||||
__version__ = "0.1.0"
|
__version__ = "0.1.1"
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"DlpConfig",
|
"DlpConfig",
|
||||||
|
|||||||
+17
-5
@@ -2,11 +2,23 @@
|
|||||||
|
|
||||||
`dlp-io` 为 Windows DLP 透明加密环境提供接近 `io.open` 的 Python 文件 API。非白名单进程负责业务逻辑和写入;文件读取由已获 DLP 白名单授权的 Python helper 完成,再通过经过认证的 Windows Named Pipe 返回明文字节。
|
`dlp-io` 为 Windows DLP 透明加密环境提供接近 `io.open` 的 Python 文件 API。非白名单进程负责业务逻辑和写入;文件读取由已获 DLP 白名单授权的 Python helper 完成,再通过经过认证的 Windows Named Pipe 返回明文字节。
|
||||||
|
|
||||||
当前版本为 `dlp-io==0.1.0`,distribution 名是 `dlp-io`,import 名是 `dlp_io`。
|
当前版本为 `dlp-io==0.1.1`,distribution 名是 `dlp-io`,import 名是 `dlp_io`。
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
发布物托管在 Gitea Release 页面,由 `.gitea/workflows/publish-dlp-io.yaml` 从 immutable tag `dlp-io-vX.Y.Z` 自动构建并上传,全部产物在 CI runner 上编译,不依赖本地环境。
|
### 方式一:Gitea PyPI registry(推荐)
|
||||||
|
|
||||||
|
registry 已开放匿名下载,一条命令即可安装;pip 会自动选择最匹配的 wheel:Windows 上 CPython 3.10–3.14 会得到对应的 pyd wheel(整个库编译为单个 `.pyd`),其余环境得到纯 Python wheel。
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
py -m pip install --index-url https://gitea.docker.antior.cn/api/packages/antior/pypi/simple dlp-io==0.1.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Package 页面:<https://gitea.docker.antior.cn/antior/-/packages/pypi/dlp-io>
|
||||||
|
|
||||||
|
### 方式二:Gitea Release 页面
|
||||||
|
|
||||||
|
发布物由 `.gitea/workflows/publish-dlp-io.yaml` 从 immutable tag `dlp-io-vX.Y.Z` 自动构建并上传,全部产物在 CI runner 上编译,不依赖本地环境。
|
||||||
|
|
||||||
Release 页面:<https://gitea.docker.antior.cn/antior/dlp-io/releases>
|
Release 页面:<https://gitea.docker.antior.cn/antior/dlp-io/releases>
|
||||||
|
|
||||||
@@ -21,13 +33,13 @@ Release 页面:<https://gitea.docker.antior.cn/antior/dlp-io/releases>
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# 纯 Python 版(任意平台)
|
# 纯 Python 版(任意平台)
|
||||||
py -m pip install https://gitea.docker.antior.cn/antior/dlp-io/releases/download/dlp-io-v0.1.0/dlp_io-0.1.0-py3-none-any.whl
|
py -m pip install https://gitea.docker.antior.cn/antior/dlp-io/releases/download/dlp-io-v0.1.1/dlp_io-0.1.1-py3-none-any.whl
|
||||||
|
|
||||||
# pyd 版(示例为 CPython 3.13,其它版本替换文件名中的 cp313)
|
# pyd 版(示例为 CPython 3.13,其它版本替换文件名中的 cp313)
|
||||||
py -3.13 -m pip install https://gitea.docker.antior.cn/antior/dlp-io/releases/download/dlp-io-v0.1.0/dlp_io-0.1.0-cp313-cp313-win_amd64.whl
|
py -3.13 -m pip install https://gitea.docker.antior.cn/antior/dlp-io/releases/download/dlp-io-v0.1.1/dlp_io-0.1.1-cp313-cp313-win_amd64.whl
|
||||||
```
|
```
|
||||||
|
|
||||||
也可以先从 Release 页面下载 wheel,再 `py -m pip install <文件路径>`。下载 Release 资产不需要 token;发布只能在 CI 中通过注入的 `GITHUB_TOKEN` 完成,发布凭据不得写入命令行、URL 或 tracked 文件。
|
也可以先从 Release 页面下载 wheel,再 `py -m pip install <文件路径>`。下载 Release 资产和 registry 包都不需要 token;发布只能在 CI 中通过注入的 `GITHUB_TOKEN` 完成,发布凭据不得写入命令行、URL 或 tracked 文件。
|
||||||
|
|
||||||
调用方需要安装 `dlp-io`。白名单 Python 无需安装该包:helper 源码由调用方以 UTF-8 通过 stdin 注入,且只依赖 Python 标准库,不会在磁盘创建临时 `.py` 文件。
|
调用方需要安装 `dlp-io`。白名单 Python 无需安装该包:helper 源码由调用方以 UTF-8 通过 stdin 注入,且只依赖 Python 标准库,不会在磁盘创建临时 `.py` 文件。
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ class WorkflowStep(Enum):
|
|||||||
BUILD = "Build and check distribution"
|
BUILD = "Build and check distribution"
|
||||||
SMOKE = "Smoke test release artifacts"
|
SMOKE = "Smoke test release artifacts"
|
||||||
RELEASE = "Create Gitea release with wheels"
|
RELEASE = "Create Gitea release with wheels"
|
||||||
|
PYPI = "Publish packages to Gitea PyPI"
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user