feat!: set asset label to real file name (#1189)

This commit is contained in:
Fabian-Lars
2025-11-16 17:05:49 +01:00
committed by GitHub
parent 1898cf45ee
commit 5d35c8e318
6 changed files with 72 additions and 45 deletions
+5
View File
@@ -0,0 +1,5 @@
---
action: major
---
The upload release assets will now have the original file as its `label` which will show as the filename on the GitHub Release page and will be used internally to update assets on reruns and to get the download urls for latest.json
+8 -8
View File
@@ -81,14 +81,14 @@ jobs:
These inputs allow you to change how your Tauri project will be build.
| Name | Required | Description | Type | Default |
| ----------------------- | :------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | ------------------------------------------------------------------------------ |
| `projectPath` | false | The path to the root of the tauri project relative to the current working directory | string | . |
| `includeUpdaterJson` | false | whether to upload a JSON file for the updater or not (only relevant if the updater is configured) | bool | true |
| `updaterJsonPreferNsis` | false | whether the action will use the NSIS (setup.exe) or WiX (.msi) bundles for the updater JSON if both types exist | bool | `false`. May be changed to `true` for projects using `tauri@v2` in the future. |
| `tauriScript` | false | the script to execute the Tauri CLI. It must not include any args or commands like `build` | string | `npm run\|pnpm\|yarn tauri` |
| `args` | false | Additional arguments to the current build command | string | |
| `retryAttempts` | false | The number of times to re-try building the app if the initial build fails. For now this only affects `tauri build` but may include the upload steps in the future. | number | 0 |
| Name | Required | Description | Type | Default |
| ----------------------- | :------: | ------------------------------------------------------------------------------------------------------------------ | ------ | ------------------------------------------------------------------------------ |
| `projectPath` | false | The path to the root of the tauri project relative to the current working directory | string | . |
| `includeUpdaterJson` | false | whether to upload a JSON file for the updater or not (only relevant if the updater is configured) | bool | true |
| `updaterJsonPreferNsis` | false | whether the action will use the NSIS (setup.exe) or WiX (.msi) bundles for the updater JSON if both types exist | bool | `false`. May be changed to `true` for projects using `tauri@v2` in the future. |
| `tauriScript` | false | the script to execute the Tauri CLI. It must not include any args or commands like `build` | string | `npm run\|pnpm\|yarn tauri` |
| `args` | false | Additional arguments to the current build command | string | |
| `retryAttempts` | false | The number of times to re-try building the app if the initial build fails or uploading assets if the upload fails. | number | 0 |
### Release Configuration
+3 -3
View File
File diff suppressed because one or more lines are too long
+12 -9
View File
@@ -2,7 +2,12 @@ import fs from 'node:fs';
import { getOctokit } from '@actions/github';
import { deleteGiteaReleaseAsset, getAssetName, retry } from './utils';
import {
deleteGiteaReleaseAsset,
getAssetName,
ghAssetName,
retry,
} from './utils';
import type { Artifact } from './types';
export async function uploadAssets(
@@ -47,16 +52,10 @@ export async function uploadAssets(
};
const assetName = getAssetName(asset, releaseAssetNamePattern);
const assetNameGH = ghAssetName(asset, releaseAssetNamePattern);
const existingAsset = existingAssets.find(
(a) =>
a.name ===
assetName
.trim()
.replace(/[ ()[\]{}]/g, '.')
.replace(/\.\./g, '.')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, ''),
(a) => a.label === assetName || a.name === assetNameGH,
);
if (existingAsset) {
@@ -85,6 +84,8 @@ export async function uploadAssets(
github.rest.repos.uploadReleaseAsset({
headers,
name: assetName,
// GitHub renames the filename so we'll also set the label which it leaves as-is.
label: assetName,
// https://github.com/tauri-apps/tauri-action/pull/45
// @ts-expect-error error TS2322: Type 'Buffer' is not assignable to type 'string'.
data: fs.createReadStream(asset.path),
@@ -94,5 +95,7 @@ export async function uploadAssets(
}),
retryAttempts + 1,
);
console.log(`${assetName} successfully uploaded.`);
}
}
+34 -25
View File
@@ -4,7 +4,7 @@ import { basename, extname, resolve } from 'node:path';
import { getOctokit } from '@actions/github';
import { uploadAssets } from './upload-release-assets';
import { deleteGiteaReleaseAsset, getAssetName } from './utils';
import { deleteGiteaReleaseAsset, getAssetName, ghAssetName } from './utils';
import type { Artifact, TargetInfo } from './types';
import { createArtifact } from './utils';
@@ -23,18 +23,6 @@ type VersionContent = {
};
};
function ghAssetName(
artifact: Artifact,
releaseAssetNamePattern?: string,
): string {
return getAssetName(artifact, releaseAssetNamePattern)
.trim()
.replace(/[ ()[\]{}]/g, '.')
.replace(/\.\./g, '.')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '');
}
export async function uploadVersionJSON(
owner: string,
repo: string,
@@ -122,9 +110,17 @@ export async function uploadVersionJSON(
}
}
const downloadUrls = new Map<string, string>();
const downloadUrls: {
name: string;
label: string | null;
url: string;
}[] = [];
for (const data of assets.data) {
downloadUrls.set(data.name, data.browser_download_url);
downloadUrls.push({
name: data.name,
label: data.label,
url: data.browser_download_url,
});
}
// Assets matching artifacts generated by this action
@@ -134,23 +130,31 @@ export async function uploadVersionJSON(
let hasNativeX64;
for (const artifact of artifacts) {
if (artifact.ext === '.app.tar.gz' && artifact.arch === 'universal') {
const arm = ghAssetName(
{ ...artifact, arch: 'aarch64' },
releaseAssetNamePattern,
const arm = { ...artifact, arch: 'aarch64' };
const x64 = { ...artifact, arch: 'x86_64' };
const armName = ghAssetName(arm, releaseAssetNamePattern);
const armLabel = getAssetName(arm, releaseAssetNamePattern);
const x64Name = ghAssetName(x64, releaseAssetNamePattern);
const x64Label = getAssetName(x64, releaseAssetNamePattern);
hasNativeArm = !!downloadUrls.find(
(a) => a.label === armLabel || a.name === armName,
);
const x86 = ghAssetName(
{ ...artifact, arch: 'x86_64' },
releaseAssetNamePattern,
hasNativeX64 = !!downloadUrls.find(
(a) => a.label === x64Label || a.name === x64Name,
);
hasNativeArm = downloadUrls.has(arm);
hasNativeX64 = downloadUrls.has(x86);
}
const assetLabel = getAssetName(artifact, releaseAssetNamePattern);
const assetName = ghAssetName(artifact, releaseAssetNamePattern);
const downloadUrl = downloadUrls.get(assetName);
const downloadUrl = downloadUrls.find(
(a) => a.label === assetLabel || a.name === assetName,
)?.url;
if (downloadUrl) {
filteredAssets.push({
downloadUrl,
assetLabel,
assetName,
path: artifact.path,
arch: artifact.arch,
@@ -195,12 +199,17 @@ export async function uploadVersionJSON(
}
for (const [idx, signatureFile] of signatureFiles.entries()) {
const updaterFileLabel = basename(
signatureFile.assetLabel,
extname(signatureFile.assetLabel),
);
const updaterFileName = basename(
signatureFile.assetName,
extname(signatureFile.assetName),
);
let updaterFileDownloadUrl = filteredAssets.find(
(asset) => asset.assetName === updaterFileName,
(a) =>
a.assetLabel === updaterFileLabel || a.assetName === updaterFileName,
)?.downloadUrl;
if (!updaterFileDownloadUrl) {
+10
View File
@@ -595,4 +595,14 @@ export function deleteGiteaReleaseAsset(
);
}
export function ghAssetName(
artifact: Artifact,
releaseAssetNamePattern?: string,
) {
return getAssetName(artifact, releaseAssetNamePattern)
.trim()
.replace(/[^a-zA-Z0-9_-]/g, '.')
.replace(/\.\./g, '.');
}
// TODO: Properly resolve the eslint issues in this file.