const version = process.argv[2]; if (!version) { console.error("Version not passed to create-gitea-release.js"); process.exit(1); } import fs from "fs-extra"; import path from "path"; import { spawnSync } from "child_process"; import { fileURLToPath } from "url"; import fetch from "node-fetch"; import dotenv from "dotenv"; dotenv.config({ path: "./.env" }); // Load package.json version // const pkg = await fs.readJson('package.json'); // const version = pkg.version; if (!version) { console.error("Version not found in package.json"); process.exit(1); } // Resolve the directory of the current script const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Absolute path to BUILD_NUMBER const buildNumberPath = path.resolve(__dirname, "../BUILD_NUMBER"); // Load build number from BUILD_NUMBER file let buildNumber = "0"; try { rawBuild = (await fs.readFile(buildNumberPath, "utf8")).trim(); console.log("Raw build", rawBuild); if (rawBuild) { const [numPart, namePart] = rawBuild.split("-"); const num = parseInt(numPart, 10); if (!isNaN(num) && namePart) { buildNumber = `${num - 1}-${namePart}`; } } } catch { console.warn("BUILD_NUMBER file not found, defaulting to 0"); } // Compose full version string with build number const fullVersion = `${version}.${buildNumber}`; const { GITEA_URL, GITEA_USERNAME, GITEA_REPO, GITEA_TOKEN } = process.env; if (!GITEA_URL || !GITEA_USERNAME || !GITEA_REPO || !GITEA_TOKEN) { console.error( "Missing required environment variables (GITEA_URL, GITEA_USERNAME, GITEA_REPO, GITEA_TOKEN)" ); process.exit(1); } // 1) Generate or update CHANGELOG.md using conventional-changelog CLI console.log("Generating CHANGELOG.md..."); const result = spawnSync( "npx", [ "conventional-changelog", "-p", "conventionalcommits", "-i", "CHANGELOG.md", "-s", "-r", "0", ], { stdio: "inherit", shell: true } ); if (result.status !== 0) { console.error("Failed to generate changelog"); process.exit(1); } // 2) Read changelog content for the current version const changelog = await fs.readFile("CHANGELOG.md", "utf8"); const regex = new RegExp(`## \\[${version}\\][\\s\\S]*?(?=## \\[|$)`, "m"); const releaseNotes = changelog.match(regex)?.[0] || changelog; console.log(`Release notes for v${version} saved`); // 3) Create Gitea release const createRelease = async () => { const apiUrl = `https://${GITEA_URL}/api/v1/repos/${GITEA_USERNAME}/${GITEA_REPO}/releases`; const releaseData = { tag_name: `v${version}`, name: `v${version}`, body: releaseNotes, draft: false, prerelease: true, }; const response = await fetch(apiUrl, { method: "POST", headers: { Authorization: `token ${GITEA_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(releaseData), }); if (!response.ok) { const errorText = await response.text(); throw new Error( `Failed to create release: ${response.status} - ${errorText}` ); } const release = await response.json(); console.log("Release created:", release.html_url || release.url); return release; }; // 4) Upload release zip asset const uploadAsset = async (release) => { const apiUrl = `https://${GITEA_URL}/api/v1/repos/${GITEA_USERNAME}/${GITEA_REPO}/releases/assets?tag=${release.tag_name}`; const filePath = `releases/release-${fullVersion}.zip`; if (!(await fs.pathExists(filePath))) { console.warn(`Zip file not found: ${filePath}. Skipping asset upload.`); return; } const FormData = (await import("form-data")).default; const form = new FormData(); form.append("name", `release-${fullVersion}.zip`); form.append("attachment", fs.createReadStream(filePath)); const response = await fetch(apiUrl, { method: "POST", headers: { Authorization: `token ${GITEA_TOKEN}`, ...form.getHeaders(), }, body: form, }); if (!response.ok) { const errorText = await response.text(); throw new Error( `Failed to upload asset: ${response.status} - ${errorText}` ); } const asset = await response.json(); console.log("Asset uploaded:", asset.browser_download_url || asset.url); }; (async () => { try { const release = await createRelease(); await uploadAsset(release); } catch (err) { console.error(err); process.exit(1); } })();