name: Release (Node) on: push: tags: - 'v*' jobs: release: runs-on: ubuntu-latest env: GITEA_API: https://git.kuns.dev/api/v1 REPO: releases/ClaudeMailbox NPM_REGISTRY_HOST: git.kuns.dev/api/packages/releases/npm/ defaults: run: working-directory: node steps: - name: Checkout tag uses: https://github.com/actions/checkout@v4 with: fetch-depth: 0 - name: Node version run: node --version && npm --version - name: Resolve version id: ver run: | set -euo pipefail TAG="${{ github.ref_name }}" VERSION="${TAG#v}" echo "tag=$TAG" >> "$GITHUB_OUTPUT" echo "version=$VERSION" >> "$GITHUB_OUTPUT" - name: Set package version env: VERSION: ${{ steps.ver.outputs.version }} run: npm version --no-git-tag-version --allow-same-version "$VERSION" - name: Sync plugin.json version working-directory: ${{ github.workspace }} env: VERSION: ${{ steps.ver.outputs.version }} run: | set -euo pipefail jq --arg v "$VERSION" '.version = $v' plugin/.claude-plugin/plugin.json > plugin/.claude-plugin/plugin.json.tmp mv plugin/.claude-plugin/plugin.json.tmp plugin/.claude-plugin/plugin.json cat plugin/.claude-plugin/plugin.json - name: Install run: npm ci - name: Test run: npm test - name: Pack env: VERSION: ${{ steps.ver.outputs.version }} run: | set -euo pipefail npm pack mv "kuns-claude-mailbox-${VERSION}.tgz" "claude-mailbox-${VERSION}.tgz" ( sha256sum "claude-mailbox-${VERSION}.tgz" > checksums.txt ) - name: Configure npm auth for Gitea env: NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} run: | set -euo pipefail if [ -z "${NPM_TOKEN:-}" ]; then echo "::error::NPM_PUBLISH_TOKEN secret is not set (needs Gitea token with write:package scope)" >&2 exit 1 fi echo "@kuns:registry=https://${NPM_REGISTRY_HOST}" > .npmrc echo "//${NPM_REGISTRY_HOST}:_authToken=${NPM_TOKEN}" >> .npmrc - name: Publish to Gitea npm registry run: npm publish --access public - name: Find or create Gitea release id: release env: TAG: ${{ steps.ver.outputs.tag }} TOKEN: ${{ secrets.GITEA_TOKEN }} run: | set -euo pipefail # Try to find an existing release for this tag (idempotent re-runs). EXISTING=$(curl -sS \ -H "Authorization: token ${TOKEN}" \ "${GITEA_API}/repos/${REPO}/releases/tags/${TAG}" || echo "") RELEASE_ID=$(echo "$EXISTING" | jq -r '.id // empty') if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then BODY=$(jq -n \ --arg tag "$TAG" \ --arg name "$TAG" \ '{tag_name:$tag, name:$name, body:"", draft:false, prerelease:false, target_commitish:"main"}') RESP=$(curl -sS -X POST \ -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/json" \ -d "$BODY" \ "${GITEA_API}/repos/${REPO}/releases") RELEASE_ID=$(echo "$RESP" | jq -r '.id // empty') fi if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then echo "::error::Could not resolve release id" >&2 exit 1 fi echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT" - name: Upload tarball + checksums env: VERSION: ${{ steps.ver.outputs.version }} RELEASE_ID: ${{ steps.release.outputs.release_id }} TOKEN: ${{ secrets.GITEA_TOKEN }} run: | set -euo pipefail for f in \ "claude-mailbox-${VERSION}.tgz" \ "checksums.txt" do curl -sS --fail-with-body -X POST \ -H "Authorization: token ${TOKEN}" \ -F "attachment=@${f}" \ "${GITEA_API}/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${f}" \ > /dev/null done