Files
logistics_support_tool/scripts/create-gitea-release.js
2025-07-12 15:50:40 -05:00

150 lines
4.0 KiB
JavaScript

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 { spawnSync } from 'child_process';
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);
}
// Load build number from BUILD_NUMBER file
let buildNumber = '0';
try {
rawBuild = (await fs.readFile('../BUILD_NUMBER', '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}:\n`, releaseNotes);
// 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);
}
})();