name: Release on: push: branches: [main] env: IMAGE: ${{ vars.REGISTRY_HOST }}/${{ gitea.repository_owner }}/catalyst jobs: release: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: 'lts/*' - run: npm ci - run: npm test - name: Read version run: | VERSION=$(node -p "require('./package.json').version") echo "VERSION=${VERSION}" >> $GITEA_ENV - name: Assert tag does not exist run: | if git ls-remote --tags origin "refs/tags/v${{ env.VERSION }}" | grep -q .; then echo "ERROR: tag v${{ env.VERSION }} already exists — bump version in package.json before merging to main." exit 1 fi - name: Create and push tag run: | git config user.name "gitea-actions" git config user.email "actions@gitea" git tag "v${{ env.VERSION }}" git push origin "v${{ env.VERSION }}" - name: Generate release notes run: | LAST_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") if [ -n "$LAST_TAG" ]; then git log "${LAST_TAG}..HEAD" --pretty=format:"- %s" --no-merges > /tmp/release_notes.txt else git log --pretty=format:"- %s" --no-merges > /tmp/release_notes.txt fi - name: Docker metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.IMAGE }} tags: | type=semver,pattern={{version}},value=v${{ env.VERSION }} type=semver,pattern={{major}}.{{minor}},value=v${{ env.VERSION }} type=sha,prefix=,format=short type=raw,value=latest - name: Log in to registry uses: docker/login-action@v3 with: registry: ${{ vars.REGISTRY_HOST }} username: ${{ gitea.actor }} password: ${{ secrets.TOKEN }} - name: Build and push uses: docker/build-push-action@v5 with: context: . push: true tags: ${{ steps.meta.outputs.tags }} - name: Create Gitea release run: | cat > /tmp/make_release.py << 'PYEOF' import json, os v = os.environ['VERSION'] img = os.environ['IMAGE'] raw = open('/tmp/release_notes.txt').read().strip() feats, fixes = [], [] for line in raw.splitlines(): msg = line.lstrip('- ').strip() if msg.startswith('feat:'): feats.append('- ' + msg[5:].strip()) elif msg.startswith('fix:'): fixes.append('- ' + msg[4:].strip()) sections = [] if feats: sections.append('### New Features\n\n' + '\n'.join(feats)) if fixes: sections.append('### Bug Fixes\n\n' + '\n'.join(fixes)) notes = '\n\n'.join(sections) or '_No changes_' body = notes + '\n\n### Image\n\n' + img + ':' + v payload = {'tag_name': 'v'+v, 'name': 'Catalyst v'+v, 'body': body, 'draft': False, 'prerelease': False} open('/tmp/release_body.json', 'w').write(json.dumps(payload)) PYEOF python3 /tmp/make_release.py curl -sf -X POST \ -H "Authorization: token ${{ secrets.TOKEN }}" \ -H "Content-Type: application/json" \ "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases" \ --data @/tmp/release_body.json