diff --git a/.gitea/release.js b/.gitea/release.js new file mode 100644 index 0000000..201b508 --- /dev/null +++ b/.gitea/release.js @@ -0,0 +1,94 @@ +const fs = require('fs'); + +async function main() { + const token = process.env.GITEA_TOKEN; + const url = process.env.GITEA_URL || 'http://gitea:3000'; + const repo = process.env.REPO; + const tag = process.env.TAG; + const filePath = 'dist/gq-to-org-redirector.zip'; + const fileName = 'gq-to-org-redirector.zip'; + + if (!token || !repo || !tag) { + throw new Error(`Missing required env vars: GITEA_TOKEN, REPO, TAG`); + } + + if (!fs.existsSync(filePath)) { + throw new Error(`File not found: ${filePath}`); + } + + const apiBase = `${url}/api/v1/repos/${repo}`; + const headers = { + 'Authorization': `token ${token}`, + 'Content-Type': 'application/json' + }; + + console.log(`Checking release for tag ${tag} at ${apiBase}...`); + + // 1. Get or create release + let release; + const getRes = await fetch(`${apiBase}/releases/tags/${encodeURIComponent(tag)}`, { headers }); + if (getRes.ok) { + release = await getRes.json(); + console.log(`Found existing release: ID ${release.id}`); + } else { + console.log(`Release not found. Creating release for tag ${tag}...`); + const createRes = await fetch(`${apiBase}/releases`, { + method: 'POST', + headers, + body: JSON.stringify({ + tag_name: tag, + name: `Release ${tag}`, + body: `Automated release of ${fileName} for ${tag}`, + draft: false, + prerelease: false + }) + }); + if (!createRes.ok) { + throw new Error(`Failed to create release: ${createRes.status} ${await createRes.text()}`); + } + release = await createRes.json(); + console.log(`Created release: ID ${release.id}`); + } + + // 2. Remove existing asset with same name if already uploaded + const assetsRes = await fetch(`${apiBase}/releases/${release.id}/assets`, { headers }); + if (assetsRes.ok) { + const assets = await assetsRes.json(); + for (const asset of assets) { + if (asset.name === fileName) { + console.log(`Deleting existing asset: ${asset.name} (ID: ${asset.id})`); + await fetch(`${apiBase}/releases/${release.id}/assets/${asset.id}`, { + method: 'DELETE', + headers + }); + } + } + } + + // 3. Upload new asset + console.log(`Uploading ${fileName} (${fs.statSync(filePath).size} bytes)...`); + const fileBuffer = fs.readFileSync(filePath); + const blob = new Blob([fileBuffer], { type: 'application/zip' }); + const formData = new FormData(); + formData.append('attachment', blob, fileName); + + const uploadRes = await fetch(`${apiBase}/releases/${release.id}/assets?name=${encodeURIComponent(fileName)}`, { + method: 'POST', + headers: { + 'Authorization': `token ${token}` + }, + body: formData + }); + + if (!uploadRes.ok) { + throw new Error(`Failed to upload asset: ${uploadRes.status} ${await uploadRes.text()}`); + } + + const uploaded = await uploadRes.json(); + console.log(`Release published successfully! Asset: ${uploaded.name} (Download URL: ${uploaded.browser_download_url})`); +} + +main().catch(err => { + console.error('Error during release publication:', err); + process.exit(1); +}); diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 6c04ca4..431c4d3 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -25,3 +25,12 @@ jobs: with: name: gq-to-org-redirector path: dist/gq-to-org-redirector.zip + + - name: Publish to Gitea Releases + if: startsWith(github.ref, 'refs/tags/v') + env: + GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITEA_URL: http://gitea:3000 + REPO: ${{ github.repository }} + TAG: ${{ github.ref_name }} + run: node .gitea/release.js