diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml new file mode 100644 index 0000000..4756468 --- /dev/null +++ b/.github/workflows/release-beta.yml @@ -0,0 +1,227 @@ +name: Release Beta + +on: + push: + branches: + - dev + workflow_dispatch: + inputs: + force: + description: 'Force publish even if version unchanged' + required: false + default: false + type: boolean + +permissions: + contents: write + id-token: write + +jobs: + publish-beta: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: https://registry.npmjs.org + always-auth: true + + - name: Determine release state + id: determine + run: | + set -euo pipefail + CURRENT_VERSION=$(node -p "require('./package.json').version") + echo "current_version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT" + + # Check if this is already a beta version + if [[ "$CURRENT_VERSION" == *"-beta"* ]] || [[ "$CURRENT_VERSION" == *"-alpha"* ]] || [[ "$CURRENT_VERSION" == *"-rc"* ]]; then + echo "is_prerelease=true" >> "$GITHUB_OUTPUT" + else + echo "is_prerelease=false" >> "$GITHUB_OUTPUT" + fi + + # Check if tag already exists + git fetch --tags --force + if git tag -l "v$CURRENT_VERSION" | grep -q "v$CURRENT_VERSION"; then + echo "tag_exists=true" >> "$GITHUB_OUTPUT" + else + echo "tag_exists=false" >> "$GITHUB_OUTPUT" + fi + + # Check npm for existing version + NPM_VERSION=$(npm view opencode-antigravity-auth@"$CURRENT_VERSION" version 2>/dev/null || echo "") + if [ -n "$NPM_VERSION" ]; then + echo "npm_exists=true" >> "$GITHUB_OUTPUT" + else + echo "npm_exists=false" >> "$GITHUB_OUTPUT" + fi + + - name: Check if should publish + id: should_publish + run: | + FORCE="${{ github.event.inputs.force }}" + TAG_EXISTS="${{ steps.determine.outputs.tag_exists }}" + NPM_EXISTS="${{ steps.determine.outputs.npm_exists }}" + + if [ "$FORCE" = "true" ]; then + echo "should_publish=true" >> "$GITHUB_OUTPUT" + echo "Forcing publish due to manual trigger" + elif [ "$TAG_EXISTS" = "true" ] || [ "$NPM_EXISTS" = "true" ]; then + echo "should_publish=false" >> "$GITHUB_OUTPUT" + echo "Version already exists (tag=$TAG_EXISTS, npm=$NPM_EXISTS)" + else + echo "should_publish=true" >> "$GITHUB_OUTPUT" + echo "New version detected, will publish" + fi + + - name: Verify NPM token + if: steps.should_publish.outputs.should_publish == 'true' + run: | + if [ -z "${NPM_TOKEN}" ]; then + echo "NPM_TOKEN secret is required" >&2 + exit 1 + fi + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Install dependencies + if: steps.should_publish.outputs.should_publish == 'true' + run: npm install + + - name: Run type check + if: steps.should_publish.outputs.should_publish == 'true' + run: npm run typecheck + + - name: Run tests + if: steps.should_publish.outputs.should_publish == 'true' + run: npm test + + - name: Build + if: steps.should_publish.outputs.should_publish == 'true' + run: npm run build + + - name: Verify build artifacts + if: steps.should_publish.outputs.should_publish == 'true' + run: | + set -euo pipefail + [ -f dist/index.js ] || { echo "dist/index.js missing" >&2; exit 1; } + [ -f dist/index.d.ts ] || { echo "dist/index.d.ts missing" >&2; exit 1; } + [ -d dist/src ] || { echo "dist/src/ missing" >&2; exit 1; } + + - name: Create git tag + if: steps.should_publish.outputs.should_publish == 'true' && steps.determine.outputs.tag_exists == 'false' + run: | + CURRENT_VERSION="${{ steps.determine.outputs.current_version }}" + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag "v$CURRENT_VERSION" + git push origin "v$CURRENT_VERSION" + + - name: Generate release notes + if: steps.should_publish.outputs.should_publish == 'true' + id: release_notes + run: | + set -euo pipefail + CURRENT_VERSION="${{ steps.determine.outputs.current_version }}" + + # Get commits since last tag + LAST_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + if [ -n "$LAST_TAG" ]; then + CHANGELOG=$(git log --no-merges --pretty=format:'- %s (%h)' "${LAST_TAG}..HEAD") + COMPARE_URL="https://github.com/${GITHUB_REPOSITORY}/compare/${LAST_TAG}...v${CURRENT_VERSION}" + else + CHANGELOG=$(git log --no-merges --pretty=format:'- %s (%h)' -20) + COMPARE_URL="" + fi + + if [ -z "$CHANGELOG" ]; then + CHANGELOG="- Beta release" + fi + + BODY_FILE=$(mktemp) + { + echo "## Beta Release v${CURRENT_VERSION}" + echo "" + echo "⚠️ **This is a beta release for testing. Use at your own risk.**" + echo "" + if [ -n "$COMPARE_URL" ]; then + echo "Compare changes: $COMPARE_URL" + echo "" + fi + printf "%s\n" "$CHANGELOG" + echo "" + echo "### Install Beta" + echo "" + echo "Update your \`opencode.json\`:" + echo "" + printf '%s\n' '```json' + printf '%s\n' '{' + printf '%s\n' " \"plugin\": [\"opencode-antigravity-auth@${CURRENT_VERSION}\"]" + printf '%s\n' '}' + printf '%s\n' '```' + echo "" + echo "Or use the beta tag:" + echo "" + printf '%s\n' '```json' + printf '%s\n' '{' + printf '%s\n' ' "plugin": ["opencode-antigravity-auth@beta"]' + printf '%s\n' '}' + printf '%s\n' '```' + echo "" + echo "Clear cache if stuck on old version:" + echo "" + printf '%s\n' '```bash' + printf '%s\n' 'rm -rf ~/.cache/opencode/node_modules ~/.cache/opencode/bun.lock' + printf '%s\n' '```' + } >"$BODY_FILE" + + { + echo "body<>"$GITHUB_OUTPUT" + + - name: Create GitHub pre-release + if: steps.should_publish.outputs.should_publish == 'true' + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: v${{ steps.determine.outputs.current_version }} + release_name: v${{ steps.determine.outputs.current_version }} (Beta) + body: ${{ steps.release_notes.outputs.body }} + prerelease: true + draft: false + + - name: Publish to npm with beta tag + if: steps.should_publish.outputs.should_publish == 'true' + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npm publish --access public --tag beta --provenance + + - name: Summary + if: steps.should_publish.outputs.should_publish == 'true' + run: | + echo "## Beta Release Published! 🚀" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Version:** ${{ steps.determine.outputs.current_version }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Install:**" >> $GITHUB_STEP_SUMMARY + echo '```json' >> $GITHUB_STEP_SUMMARY + echo '{ "plugin": ["opencode-antigravity-auth@beta"] }' >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + + - name: Skip summary + if: steps.should_publish.outputs.should_publish == 'false' + run: | + echo "## Skipped Beta Release" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Version ${{ steps.determine.outputs.current_version }} already exists." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "To publish, bump the version in package.json or use manual trigger with force option." >> $GITHUB_STEP_SUMMARY