import fs from 'fs-extra'; import { spawnSync } from 'child_process'; import fetch from 'node-fetch'; import dotenv from 'dotenv'; dotenv.config({ path: './.env' }); // or specify your env file path here // Load environment variables for convenience (or use dotenv if you like) const { GITEA_URL, GITEA_USERNAME, GITEA_REPO, GITEA_TOKEN, VERSION, } = process.env; if (!GITEA_URL || !GITEA_USERNAME || !GITEA_REPO || !GITEA_TOKEN || !VERSION) { console.error('Missing required environment variables!'); process.exit(1); } // 1) Generate or update CHANGELOG.md for the version 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.log(result) console.error('Failed to generate changelog'); process.exit(1); } // 2) Read changelog content for the current version const changelog = fs.readFileSync('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: false, }; 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-${VERSION}.zip`; if (!fs.existsSync(filePath)) { console.warn(`Zip file not found: ${filePath}. Skipping asset upload.`); return; } // Use form-data and fetch for uploading binary const FormData = (await import('form-data')).default; const form = new FormData(); form.append('name', `release-${VERSION}.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); } })();