name: Release — Package & Publish on: push: tags: - 'v*.*.*' jobs: release: name: Build & Package Release runs-on: ubuntu-latest container: image: node:22-bookworm steps: - name: Install zip run: apt-get update -qq && apt-get install -y zip curl - name: Checkout run: | git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git . git checkout ${{ gitea.sha }} - name: Install dependencies run: npm ci working-directory: packages/chrome - name: Run tests run: npm test -- --run working-directory: packages/chrome - name: Build extension run: npm run build working-directory: packages/chrome - name: Package as ZIP run: | VERSION=${{ gitea.ref_name }} ZIPFILE="$(cd ../.. && pwd)/lexai-chrome-mv3-${VERSION}.zip" # Zip from inside the chrome-mv3 dir so manifest.json is at root of the archive cd .output/chrome-mv3 && zip -r "$ZIPFILE" . && cd - echo "ZIP_FILE=${ZIPFILE}" >> $GITHUB_ENV working-directory: packages/chrome - name: Create Release run: | VERSION=${{ gitea.ref_name }} cat > build-release-payload.js <<'EOF' const fs = require('fs'); const tag = process.env.VERSION; const version = tag.replace(/^v/, ''); const installSteps = '### Installation\n1. Download ZIP below\n2. Extract it\n3. Open Chrome → chrome://extensions\n4. Enable Developer Mode\n5. Click Load unpacked → select the extracted folder'; let body = '## LexAI ' + tag + '\n\n' + installSteps; try { const changelog = fs.readFileSync('CHANGELOG.md', 'utf8'); const headingRe = new RegExp('^## \\[' + version.replace(/\./g, '\\.') + '\\].*$', 'm'); const match = headingRe.exec(changelog); if (match) { const rest = changelog.slice(match.index + match[0].length); const nextStop = rest.search(/^(## \[|\[[^\]]+\]:\s)/m); const section = (nextStop === -1 ? rest : rest.slice(0, nextStop)).trim(); body = match[0] + '\n\n' + section + '\n\n' + installSteps; } else { console.error('No CHANGELOG.md section found for ' + version + ', falling back to generic body'); } } catch (e) { console.error('Could not read CHANGELOG.md, falling back to generic body:', e.message); } const payload = { tag_name: tag, name: 'LexAI ' + tag, body, draft: false, prerelease: false, }; fs.writeFileSync('payload.json', JSON.stringify(payload)); EOF VERSION="$VERSION" node build-release-payload.js curl -s -X POST "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases" \ -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ -H "Content-Type: application/json" \ -d @payload.json > release.json cat release.json RELEASE_ID=$(node -e "const r=require('./release.json'); if(!r.id) { console.error('No release id in response:', JSON.stringify(r)); process.exit(1); } console.log(r.id)") echo "RELEASE_ID=${RELEASE_ID}" >> $GITHUB_ENV - name: Upload ZIP to Release run: | RELEASE_ID=${{ env.RELEASE_ID }} curl -s -X POST "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases/${RELEASE_ID}/assets" \ -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ -F "attachment=@${{ env.ZIP_FILE }}" echo "✅ Release ${{ gitea.ref_name }} published!" - name: Publish to Gitea Package Registry run: | VERSION=${{ gitea.ref_name }} curl -s -X PUT "https://git.juankibin.space/api/packages/kibin/generic/lexai-extension/${VERSION}/lexai-chrome-mv3-${VERSION}.zip" \ -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ -T "${{ env.ZIP_FILE }}" echo "✅ Published lexai-chrome-mv3-${VERSION}.zip to package registry" echo "📦 Download: https://git.juankibin.space/kibin/LexAI/packages"