diff --git a/lib/publish.js b/lib/publish.js index 0efe7132..39497268 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -55,12 +55,37 @@ export default async (pluginConfig, context) => { debug("milestones: %o", milestones); if (assets && assets.length > 0) { + const templatedAssets = assets.map((asset) => { + if (isPlainObject(asset)) { + const templatedAsset = { ...asset }; + if (asset.path) { + templatedAsset.path = Array.isArray(asset.path) + ? asset.path.map((pattern) => template(pattern)(context)) + : template(asset.path)(context); + } + templatedAsset.url = asset.url ? template(asset.url)(context) : asset.url; + templatedAsset.label = asset.label ? template(asset.label)(context) : asset.label; + templatedAsset.type = asset.type ? template(asset.type)(context) : asset.type; + templatedAsset.filepath = asset.filepath ? template(asset.filepath)(context) : asset.filepath; + templatedAsset.target = asset.target ? template(asset.target)(context) : asset.target; + templatedAsset.status = asset.status ? template(asset.status)(context) : asset.status; + templatedAsset.packageName = asset.packageName ? template(asset.packageName)(context) : asset.packageName; + return templatedAsset; + } else if (Array.isArray(asset)) { + // Handle array of glob patterns + return asset.map((pattern) => template(pattern)(context)); + } else { + // String asset path + return template(asset)(context); + } + }); + // Skip glob if url is provided - const urlAssets = assets.filter((asset) => asset.url); + const urlAssets = templatedAssets.filter((asset) => asset.url); debug("url assets: %o", urlAssets); const globbedAssets = await getAssets( context, - assets.filter((asset) => !asset.url) + templatedAssets.filter((asset) => !asset.url) ); debug("globbed assets: %o", globbedAssets); const allAssets = [...urlAssets, ...globbedAssets]; @@ -68,18 +93,11 @@ export default async (pluginConfig, context) => { await Promise.all( allAssets.map(async (asset) => { - const path = template((isPlainObject(asset) ? asset : { path: asset }).path)(context); - const _url = asset.url ? template(asset.url)(context) : undefined; - const label = asset.label ? template(asset.label)(context) : undefined; - const type = asset.type ? template(asset.type)(context) : undefined; - const filepath = asset.filepath ? template(asset.filepath)(context) : undefined; - const target = asset.target ? template(asset.target)(context) : undefined; - const status = asset.status ? template(asset.status)(context) : undefined; - const packageName = asset.packageName ? template(asset.packageName)(context) : "release"; - - if (_url) { - assetsList.push({ label, rawUrl: _url, type, filepath }); - debug("use link from release setting: %s", _url); + const path = isPlainObject(asset) ? asset.path : asset; + + if (asset.url) { + assetsList.push({ label: asset.label, rawUrl: asset.url, type: asset.type, filepath: asset.filepath }); + debug("use link from release setting: %s", asset.url); } else { const file = pathlib.resolve(cwd, path); @@ -98,18 +116,19 @@ export default async (pluginConfig, context) => { } debug("file path: %o", path); - debug("file label: %o", label); - debug("file type: %o", type); - debug("file filepath: %o", filepath); - debug("file target: %o", target); - debug("file status: %o", status); - debug("package name: %o", packageName); + debug("file label: %o", asset.label); + debug("file type: %o", asset.type); + debug("file filepath: %o", asset.filepath); + debug("file target: %o", asset.target); + debug("file status: %o", asset.status); + debug("package name: %o", asset.packageName); let uploadEndpoint; let response; - if (target === "generic_package") { - const finalLabel = label ?? pathlib.basename(file); + if (asset.target === "generic_package") { + const finalLabel = asset.label ?? pathlib.basename(file); + const packageName = asset.packageName ?? "release"; // Upload generic packages const encodedVersion = encodeURIComponent(version); const encodedPackageName = encodeURIComponent(packageName); @@ -118,7 +137,7 @@ export default async (pluginConfig, context) => { uploadEndpoint = urlJoin( projectApiUrl, `packages/generic/${encodedPackageName}/${encodedVersion}/${encodedLabel}?${ - status ? `status=${status}&` : "" + asset.status ? `status=${asset.status}&` : "" }select=package_file` ); @@ -137,7 +156,7 @@ export default async (pluginConfig, context) => { `packages/generic/${encodedPackageName}/${encodedVersion}/${encodedLabel}` ); - assetsList.push({ label: finalLabel, alt: packageName, url, type: "package", filepath }); + assetsList.push({ label: finalLabel, alt: packageName, url, type: "package", filepath: asset.filepath }); logger.log("Uploaded file: %s (%s)", url, response.file.url); } else { @@ -158,7 +177,7 @@ export default async (pluginConfig, context) => { const { alt, full_path } = response; const url = urlJoin(gitlabUrl, full_path); - assetsList.push({ label, alt, url, type, filepath }); + assetsList.push({ label: asset.label, alt, url, type: asset.type, filepath: asset.filepath }); logger.log("Uploaded file: %s", url); } diff --git a/test/fixtures/versioned/upload_v1.0.0.txt b/test/fixtures/versioned/upload_v1.0.0.txt new file mode 100644 index 00000000..ea123bef --- /dev/null +++ b/test/fixtures/versioned/upload_v1.0.0.txt @@ -0,0 +1 @@ +Test file content for release with version in filename. \ No newline at end of file diff --git a/test/publish.test.js b/test/publish.test.js index f423d745..d12443a9 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -823,3 +823,48 @@ test.serial("Publish a release with error response", async (t) => { t.is(error.message, `Response code 499 (Something went wrong)`); t.true(gitlab.isDone()); }); + +test.serial("Publish a release with templated wildcard path", async (t) => { + const cwd = "test/fixtures"; + const owner = "test_user"; + const repo = "test_repo"; + const env = { GITLAB_TOKEN: "gitlab_token" }; + const nextRelease = { gitHead: "123", gitTag: "v1.0.0", notes: "Test release note body", version: "1.0.0" }; + const options = { repositoryUrl: `https://gitlab.com/${owner}/${repo}.git` }; + const encodedProjectPath = encodeURIComponent(`${owner}/${repo}`); + const encodedGitTag = encodeURIComponent(nextRelease.gitTag); + + const assets = ["versioned/upload_v${nextRelease.version}.txt"]; + + const uploaded = { + url: "/uploads/upload_v1.0.0.txt", + alt: "upload_v1.0.0.txt", + full_path: "/-/project/4/66dbcd21ec5d24ed6ea225176098d52b/upload_v1.0.0.txt", + }; + + const gitlab = authenticate(env) + .post(`/projects/${encodedProjectPath}/releases`, { + tag_name: nextRelease.gitTag, + description: nextRelease.notes, + assets: { + links: [ + { + name: "upload_v1.0.0.txt", + url: `https://gitlab.com${uploaded.full_path}`, + }, + ], + }, + }) + .reply(200); + const gitlabUpload = authenticate(env) + .post(`/projects/${encodedProjectPath}/uploads`, /Content-Disposition.*upload_v1\.0\.0\.txt/g) + .reply(200, uploaded); + + const result = await publish({ assets }, { env, cwd, options, nextRelease, logger: t.context.logger }); + + t.is(result.url, `https://gitlab.com/${owner}/${repo}/-/releases/${encodedGitTag}`); + t.deepEqual(t.context.log.args[0], ["Uploaded file: %s", `https://gitlab.com${uploaded.full_path}`]); + t.deepEqual(t.context.log.args[1], ["Published GitLab release: %s", nextRelease.gitTag]); + t.true(gitlab.isDone()); + t.true(gitlabUpload.isDone()); +});