mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-08 11:31:57 +08:00
✨ feat(driver): 拆分驱动资产到独立发布仓库
- 驱动下载和版本查询统一切换到 Syngnat/GoNavi-DriverAgents - release/dev-build 将单驱动资产、总包、索引和校验文件发布到独立仓库 - GoNavi 主仓库 Release 仅保留主程序资产和主程序校验文件 - dev 构建驱动资产使用 dev-latest 预发布供测试版下载 - 补充驱动仓库 URL、dev tag 和总包兜底相关测试
This commit is contained in:
88
.github/workflows/dev-build.yml
vendored
88
.github/workflows/dev-build.yml
vendored
@@ -579,8 +579,12 @@ jobs:
|
||||
out_name = "GoNavi-DriverAgents.zip"
|
||||
index_name = "GoNavi-DriverAgents-Index.json"
|
||||
base = Path("drivers")
|
||||
out_path = Path(out_name)
|
||||
index_path = Path(index_name)
|
||||
driver_release_dir = Path("../driver-release-assets")
|
||||
if driver_release_dir.exists():
|
||||
shutil.rmtree(driver_release_dir)
|
||||
driver_release_dir.mkdir(parents=True, exist_ok=True)
|
||||
out_path = driver_release_dir / out_name
|
||||
index_path = driver_release_dir / index_name
|
||||
if out_path.exists():
|
||||
out_path.unlink()
|
||||
if index_path.exists():
|
||||
@@ -597,7 +601,7 @@ jobs:
|
||||
raise RuntimeError(f"driver asset name conflict: {p.name}")
|
||||
zf.write(p, arcname)
|
||||
size_index[p.name] = p.stat().st_size
|
||||
standalone_path = Path(p.name)
|
||||
standalone_path = driver_release_dir / p.name
|
||||
if standalone_path.exists():
|
||||
raise RuntimeError(f"release asset already exists: {standalone_path}")
|
||||
shutil.copy2(p, standalone_path)
|
||||
@@ -632,6 +636,22 @@ jobs:
|
||||
sha256sum "${FILES[@]}" > SHA256SUMS
|
||||
fi
|
||||
|
||||
- name: Generate Driver SHA256SUMS
|
||||
shell: bash
|
||||
run: |
|
||||
cd driver-release-assets
|
||||
FILES=()
|
||||
while IFS= read -r file; do
|
||||
if [ -n "$file" ]; then
|
||||
FILES+=("$file")
|
||||
fi
|
||||
done < <(find . -maxdepth 1 -type f ! -name SHA256SUMS -exec basename {} \; | sort)
|
||||
if [ ${#FILES[@]} -eq 0 ]; then
|
||||
echo "❌ 未找到驱动发布资产"
|
||||
exit 1
|
||||
fi
|
||||
sha256sum "${FILES[@]}" > SHA256SUMS
|
||||
|
||||
- name: Generate Dev Version
|
||||
id: version
|
||||
run: |
|
||||
@@ -697,6 +717,68 @@ jobs:
|
||||
}
|
||||
}
|
||||
|
||||
- name: Reset Previous Driver Dev Release
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.DRIVER_RELEASE_TOKEN }}
|
||||
script: |
|
||||
const tag = 'dev-latest';
|
||||
const ref = `tags/${tag}`;
|
||||
const [owner, repo] = 'Syngnat/GoNavi-DriverAgents'.split('/');
|
||||
const releases = await github.paginate(github.rest.repos.listReleases, {
|
||||
owner,
|
||||
repo,
|
||||
per_page: 100,
|
||||
});
|
||||
|
||||
const matchedReleases = releases.filter((release) => release.tag_name === tag);
|
||||
if (matchedReleases.length === 0) {
|
||||
core.info(`No existing driver releases found for tag ${tag}`);
|
||||
} else {
|
||||
for (const release of matchedReleases) {
|
||||
core.info(`Deleting driver release ${release.id} (${release.name || 'unnamed'}) for tag ${tag}`);
|
||||
await github.rest.repos.deleteRelease({
|
||||
owner,
|
||||
repo,
|
||||
release_id: release.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await github.rest.git.deleteRef({
|
||||
owner,
|
||||
repo,
|
||||
ref,
|
||||
});
|
||||
core.info(`Deleted driver ref ${ref}`);
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
core.info(`No existing driver ref found for ${ref}`);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
- name: Create Dev Driver Agents Pre-release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
repository: Syngnat/GoNavi-DriverAgents
|
||||
tag_name: dev-latest
|
||||
name: "GoNavi Driver Agents (${{ steps.version.outputs.version }})"
|
||||
files: driver-release-assets/*
|
||||
fail_on_unmatched_files: true
|
||||
prerelease: true
|
||||
draft: false
|
||||
make_latest: false
|
||||
body: |
|
||||
GoNavi dev driver-agent assets.
|
||||
|
||||
**版本**: `${{ steps.version.outputs.version }}`
|
||||
**来源仓库**: `${{ github.repository }}`
|
||||
**提交**: [`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})
|
||||
token: ${{ secrets.DRIVER_RELEASE_TOKEN }}
|
||||
|
||||
- name: Create Dev Pre-release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
|
||||
42
.github/workflows/release.yml
vendored
42
.github/workflows/release.yml
vendored
@@ -620,8 +620,12 @@ jobs:
|
||||
out_name = "GoNavi-DriverAgents.zip"
|
||||
index_name = "GoNavi-DriverAgents-Index.json"
|
||||
base = Path("drivers")
|
||||
out_path = Path(out_name)
|
||||
index_path = Path(index_name)
|
||||
driver_release_dir = Path("../driver-release-assets")
|
||||
if driver_release_dir.exists():
|
||||
shutil.rmtree(driver_release_dir)
|
||||
driver_release_dir.mkdir(parents=True, exist_ok=True)
|
||||
out_path = driver_release_dir / out_name
|
||||
index_path = driver_release_dir / index_name
|
||||
if out_path.exists():
|
||||
out_path.unlink()
|
||||
if index_path.exists():
|
||||
@@ -638,7 +642,7 @@ jobs:
|
||||
raise RuntimeError(f"driver asset name conflict: {p.name}")
|
||||
zf.write(p, arcname)
|
||||
size_index[p.name] = p.stat().st_size
|
||||
standalone_path = Path(p.name)
|
||||
standalone_path = driver_release_dir / p.name
|
||||
if standalone_path.exists():
|
||||
raise RuntimeError(f"release asset already exists: {standalone_path}")
|
||||
shutil.copy2(p, standalone_path)
|
||||
@@ -654,7 +658,7 @@ jobs:
|
||||
print(f"published standalone driver assets={len(standalone_assets)}")
|
||||
PY
|
||||
|
||||
# Release 同时发布单驱动资产与总包:应用优先下载单驱动,失败后仍可用总包兜底。
|
||||
# GoNavi 主仓库只保留主程序包;驱动资产发布到独立仓库。
|
||||
rm -rf drivers
|
||||
|
||||
- name: Generate SHA256SUMS
|
||||
@@ -674,6 +678,36 @@ jobs:
|
||||
sha256sum "${FILES[@]}" > SHA256SUMS
|
||||
fi
|
||||
|
||||
- name: Generate Driver SHA256SUMS
|
||||
shell: bash
|
||||
run: |
|
||||
cd driver-release-assets
|
||||
FILES=()
|
||||
while IFS= read -r file; do
|
||||
if [ -n "$file" ]; then
|
||||
FILES+=("$file")
|
||||
fi
|
||||
done < <(find . -maxdepth 1 -type f ! -name SHA256SUMS -exec basename {} \; | sort)
|
||||
if [ ${#FILES[@]} -eq 0 ]; then
|
||||
echo "❌ 未找到驱动发布资产"
|
||||
exit 1
|
||||
fi
|
||||
sha256sum "${FILES[@]}" > SHA256SUMS
|
||||
|
||||
- name: Create Driver Agents Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
repository: Syngnat/GoNavi-DriverAgents
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: "GoNavi Driver Agents ${{ github.ref_name }}"
|
||||
files: driver-release-assets/*
|
||||
fail_on_unmatched_files: true
|
||||
make_latest: true
|
||||
body: |
|
||||
GoNavi driver-agent assets for `${{ github.ref_name }}`.
|
||||
token: ${{ secrets.DRIVER_RELEASE_TOKEN }}
|
||||
|
||||
- name: Checkout code for changelog
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
@@ -293,6 +293,9 @@ type driverBundleAssetIndex struct {
|
||||
const (
|
||||
// 默认使用内置 manifest,避免依赖网络与外部仓库 404。
|
||||
defaultDriverManifestURLValue = "builtin://manifest"
|
||||
driverReleaseRepo = "Syngnat/GoNavi-DriverAgents"
|
||||
driverReleaseLatestAPIURL = "https://api.github.com/repos/" + driverReleaseRepo + "/releases/latest"
|
||||
driverReleaseDevTag = "dev-latest"
|
||||
optionalDriverBundleAssetName = "GoNavi-DriverAgents.zip"
|
||||
optionalDriverBundleIndexAssetName = "GoNavi-DriverAgents-Index.json"
|
||||
optionalDriverBundleDownloadTimeout = 45 * time.Minute
|
||||
@@ -883,7 +886,7 @@ func (a *App) CheckDriverNetworkStatus() connection.QueryResult {
|
||||
},
|
||||
{
|
||||
Name: "GitHub 驱动发布",
|
||||
URL: fmt.Sprintf("https://github.com/%s/releases/latest/download/%s", updateRepo, optionalDriverBundleAssetName),
|
||||
URL: driverReleaseLatestDownloadURL(optionalDriverBundleAssetName),
|
||||
},
|
||||
{
|
||||
Name: "GitHub Release 资产域名",
|
||||
@@ -1873,18 +1876,26 @@ func optionalDriverSourceBuildAvailable(definition driverDefinition, selectedVer
|
||||
}
|
||||
|
||||
func resolvePublishedDriverDownloadURL(definition driverDefinition, version string) (string, bool) {
|
||||
driverType := normalizeDriverType(definition.Type)
|
||||
versionText := normalizeVersion(strings.TrimSpace(version))
|
||||
if driverType == "" || versionText == "" {
|
||||
if versionText == "" {
|
||||
return "", false
|
||||
}
|
||||
|
||||
tag := "v" + versionText
|
||||
assetName, ok := resolvePublishedDriverReleaseAssetName(driverType, versionText, tag)
|
||||
return resolvePublishedDriverDownloadURLForTag(definition, versionText, "v"+versionText)
|
||||
}
|
||||
|
||||
func resolvePublishedDriverDownloadURLForTag(definition driverDefinition, selectedVersion string, tag string) (string, bool) {
|
||||
driverType := normalizeDriverType(definition.Type)
|
||||
tagName := strings.TrimSpace(tag)
|
||||
if driverType == "" || tagName == "" {
|
||||
return "", false
|
||||
}
|
||||
|
||||
assetName, ok := resolvePublishedDriverReleaseAssetName(driverType, selectedVersion, tagName)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
return fmt.Sprintf("https://github.com/%s/releases/download/%s/%s", updateRepo, tag, assetName), true
|
||||
return driverReleaseDownloadURL(tagName, assetName), true
|
||||
}
|
||||
|
||||
func resolvePublishedDriverReleaseAssetName(driverType string, version string, tag string) (string, bool) {
|
||||
@@ -2265,7 +2276,7 @@ func resolveDriverVersionOptionsFromReleases(definition driverDefinition) []driv
|
||||
}
|
||||
result = append(result, driverVersionOptionItem{
|
||||
Version: version,
|
||||
DownloadURL: fmt.Sprintf("https://github.com/%s/releases/download/%s/%s", updateRepo, tag, assetName),
|
||||
DownloadURL: driverReleaseDownloadURL(tag, assetName),
|
||||
Source: "release",
|
||||
})
|
||||
}
|
||||
@@ -2311,7 +2322,7 @@ func loadDriverReleaseListCached() ([]githubRelease, error) {
|
||||
}
|
||||
|
||||
func fetchDriverReleaseList() ([]githubRelease, error) {
|
||||
apiURL := fmt.Sprintf("https://api.github.com/repos/%s/releases?per_page=30", updateRepo)
|
||||
apiURL := fmt.Sprintf("https://api.github.com/repos/%s/releases?per_page=30", driverReleaseRepo)
|
||||
client := newHTTPClientWithGlobalProxy(driverReleaseListProbeTimeout)
|
||||
req, err := http.NewRequest(http.MethodGet, apiURL, nil)
|
||||
if err != nil {
|
||||
@@ -4175,6 +4186,34 @@ func optionalDriverReleaseAssetNameForVersion(driverType string, selectedVersion
|
||||
return names[0]
|
||||
}
|
||||
|
||||
func currentDriverReleaseTag() string {
|
||||
currentVersion := normalizeVersion(getCurrentVersion())
|
||||
if currentVersion == "" || currentVersion == "0.0.0" {
|
||||
return ""
|
||||
}
|
||||
if strings.HasPrefix(strings.ToLower(currentVersion), "dev-") {
|
||||
return driverReleaseDevTag
|
||||
}
|
||||
return "v" + currentVersion
|
||||
}
|
||||
|
||||
func driverReleaseDownloadURL(tag string, assetName string) string {
|
||||
tagName := strings.TrimSpace(tag)
|
||||
asset := strings.TrimSpace(assetName)
|
||||
if tagName == "" || asset == "" {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("https://github.com/%s/releases/download/%s/%s", driverReleaseRepo, url.PathEscape(tagName), url.PathEscape(asset))
|
||||
}
|
||||
|
||||
func driverReleaseLatestDownloadURL(assetName string) string {
|
||||
asset := strings.TrimSpace(assetName)
|
||||
if asset == "" {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("https://github.com/%s/releases/latest/download/%s", driverReleaseRepo, url.PathEscape(asset))
|
||||
}
|
||||
|
||||
func optionalDriverBundlePlatformDir(goos string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(goos)) {
|
||||
case "windows":
|
||||
@@ -4261,11 +4300,10 @@ func resolveOptionalDriverBundleDownloadURLs() []string {
|
||||
candidates = append(candidates, trimmed)
|
||||
}
|
||||
|
||||
currentVersion := normalizeVersion(getCurrentVersion())
|
||||
if currentVersion != "" && currentVersion != "0.0.0" {
|
||||
appendURL(fmt.Sprintf("https://github.com/Syngnat/GoNavi/releases/download/v%s/%s", currentVersion, optionalDriverBundleAssetName))
|
||||
if tag := currentDriverReleaseTag(); tag != "" {
|
||||
appendURL(driverReleaseDownloadURL(tag, optionalDriverBundleAssetName))
|
||||
}
|
||||
appendURL(fmt.Sprintf("https://github.com/Syngnat/GoNavi/releases/latest/download/%s", optionalDriverBundleAssetName))
|
||||
appendURL(driverReleaseLatestDownloadURL(optionalDriverBundleAssetName))
|
||||
return candidates
|
||||
}
|
||||
|
||||
@@ -4483,9 +4521,8 @@ func resolveOptionalDriverAgentDownloadURLs(definition driverDefinition, rawURL
|
||||
return candidates
|
||||
}
|
||||
|
||||
currentVersion := normalizeVersion(getCurrentVersion())
|
||||
if currentVersion != "" && currentVersion != "0.0.0" {
|
||||
if publishedURL, ok := resolvePublishedDriverDownloadURL(definition, currentVersion); ok {
|
||||
if tag := currentDriverReleaseTag(); tag != "" {
|
||||
if publishedURL, ok := resolvePublishedDriverDownloadURLForTag(definition, selectedVersion, tag); ok {
|
||||
appendURL(publishedURL)
|
||||
}
|
||||
}
|
||||
@@ -4907,11 +4944,7 @@ func preloadOptionalDriverPackageSizes(definitions []driverDefinition) map[strin
|
||||
return result
|
||||
}
|
||||
|
||||
currentVersion := normalizeVersion(getCurrentVersion())
|
||||
tag := ""
|
||||
if currentVersion != "" && currentVersion != "0.0.0" {
|
||||
tag = "v" + currentVersion
|
||||
}
|
||||
tag := currentDriverReleaseTag()
|
||||
|
||||
fillFromSizes := func(sizeByAsset map[string]int64, driverTypes []string) []string {
|
||||
missing := make([]string, 0, len(driverTypes))
|
||||
@@ -5098,7 +5131,7 @@ func fetchDriverBundleAssetSizeIndex(release *githubRelease) (map[string]int64,
|
||||
}
|
||||
|
||||
func fetchLatestReleaseForDriverAssets() (*githubRelease, error) {
|
||||
return fetchDriverReleaseByURL(updateAPIURL)
|
||||
return fetchDriverReleaseByURL(driverReleaseLatestAPIURL)
|
||||
}
|
||||
|
||||
func resolveLatestPublishedDriverDownloadURL(definition driverDefinition) (string, bool) {
|
||||
@@ -5114,7 +5147,7 @@ func resolveLatestPublishedDriverDownloadURL(definition driverDefinition) (strin
|
||||
if sizeByAsset, publishedAssets, ok := readReleaseAssetSizesFromCache("latest"); ok {
|
||||
for _, assetName := range assetNames {
|
||||
if publishedAssets[assetName] && sizeByAsset[assetName] > 0 {
|
||||
return fmt.Sprintf("https://github.com/%s/releases/latest/download/%s", updateRepo, assetName), true
|
||||
return driverReleaseLatestDownloadURL(assetName), true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
@@ -5126,7 +5159,7 @@ func resolveLatestPublishedDriverDownloadURL(definition driverDefinition) (strin
|
||||
}
|
||||
for _, assetName := range assetNames {
|
||||
if publishedAssets[assetName] && sizeByAsset[assetName] > 0 {
|
||||
return fmt.Sprintf("https://github.com/%s/releases/latest/download/%s", updateRepo, assetName), true
|
||||
return driverReleaseLatestDownloadURL(assetName), true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
@@ -5137,7 +5170,7 @@ func fetchReleaseByTag(tag string) (*githubRelease, error) {
|
||||
if tagName == "" {
|
||||
return nil, fmt.Errorf("Tag 为空")
|
||||
}
|
||||
apiURL := fmt.Sprintf("https://api.github.com/repos/%s/releases/tags/%s", updateRepo, url.PathEscape(tagName))
|
||||
apiURL := fmt.Sprintf("https://api.github.com/repos/%s/releases/tags/%s", driverReleaseRepo, url.PathEscape(tagName))
|
||||
return fetchDriverReleaseByURL(apiURL)
|
||||
}
|
||||
|
||||
|
||||
@@ -36,12 +36,42 @@ func TestResolveVersionedDriverOptionUsesPublishedMongoV1Release(t *testing.T) {
|
||||
t.Fatalf("expected version %q, got %q", version, gotVersion)
|
||||
}
|
||||
|
||||
wantURL := fmt.Sprintf("https://github.com/%s/releases/download/v%s/%s", updateRepo, version, assetName)
|
||||
wantURL := fmt.Sprintf("https://github.com/%s/releases/download/v%s/%s", driverReleaseRepo, version, assetName)
|
||||
if gotURL != wantURL {
|
||||
t.Fatalf("expected published release URL %q, got %q", wantURL, gotURL)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrentDriverReleaseTagUsesDevLatestForDevBuild(t *testing.T) {
|
||||
originalVersion := AppVersion
|
||||
AppVersion = "dev-abc1234"
|
||||
t.Cleanup(func() {
|
||||
AppVersion = originalVersion
|
||||
})
|
||||
|
||||
if got := currentDriverReleaseTag(); got != driverReleaseDevTag {
|
||||
t.Fatalf("expected dev driver release tag %q, got %q", driverReleaseDevTag, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveOptionalDriverBundleDownloadURLsUsesDriverReleaseRepo(t *testing.T) {
|
||||
originalVersion := AppVersion
|
||||
AppVersion = "0.7.4"
|
||||
t.Cleanup(func() {
|
||||
AppVersion = originalVersion
|
||||
})
|
||||
|
||||
urls := resolveOptionalDriverBundleDownloadURLs()
|
||||
wantTagged := driverReleaseDownloadURL("v0.7.4", optionalDriverBundleAssetName)
|
||||
wantLatest := driverReleaseLatestDownloadURL(optionalDriverBundleAssetName)
|
||||
if len(urls) != 2 {
|
||||
t.Fatalf("expected tagged and latest bundle URLs, got %v", urls)
|
||||
}
|
||||
if urls[0] != wantTagged || urls[1] != wantLatest {
|
||||
t.Fatalf("unexpected driver bundle URLs: got %v want [%q %q]", urls, wantTagged, wantLatest)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDriverVersionSupportRangeForMongoDB(t *testing.T) {
|
||||
definition, ok := resolveDriverDefinition("mongodb")
|
||||
if !ok {
|
||||
@@ -119,7 +149,7 @@ func TestResolveOptionalDriverAgentDownloadURLsDoesNotFallbackForHistoricalVersi
|
||||
t.Fatal("expected mongodb driver definition")
|
||||
}
|
||||
|
||||
explicitURL := fmt.Sprintf("https://github.com/Syngnat/GoNavi/releases/download/v1.17.4/%s", mongoVersionedReleaseAssetName(1))
|
||||
explicitURL := driverReleaseDownloadURL("v1.17.4", mongoVersionedReleaseAssetName(1))
|
||||
urls := resolveOptionalDriverAgentDownloadURLs(
|
||||
definition,
|
||||
explicitURL,
|
||||
@@ -364,7 +394,7 @@ func TestShouldForceSourceBuildForResolvedDownload(t *testing.T) {
|
||||
t.Fatal("expected mongodb v1 builtin install to keep source build mode")
|
||||
}
|
||||
|
||||
explicitURL := fmt.Sprintf("https://github.com/%s/releases/download/v1.17.4/%s", updateRepo, mongoVersionedReleaseAssetName(1))
|
||||
explicitURL := driverReleaseDownloadURL("v1.17.4", mongoVersionedReleaseAssetName(1))
|
||||
if shouldForceSourceBuildForResolvedDownload("mongodb", "1.17.4", explicitURL) {
|
||||
t.Fatal("expected mongodb v1 published asset install to skip forced source build")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user