diff --git a/.github/workflows/release-lsp-binary.yml b/.github/workflows/release-lsp-binary.yml new file mode 100644 index 0000000..0f79b5d --- /dev/null +++ b/.github/workflows/release-lsp-binary.yml @@ -0,0 +1,113 @@ +name: Release LSP Binary + +on: + push: + tags: + - 'iii-lsp/v*' + workflow_dispatch: + inputs: + tag: + description: 'Tag to release (e.g., iii-lsp/v1.0.0)' + required: true + type: string + +permissions: + contents: write + +concurrency: + group: release-iii-lsp-${{ github.ref }} + cancel-in-progress: false + +jobs: + # ────────────────────────────────────────────────────────────── + # Setup: Parse tag metadata + # ────────────────────────────────────────────────────────────── + + setup: + name: Setup + runs-on: ubuntu-latest + outputs: + tag: ${{ steps.resolve.outputs.tag }} + version: ${{ steps.meta.outputs.version }} + is_prerelease: ${{ steps.meta.outputs.is_prerelease }} + dry_run: ${{ steps.meta.outputs.dry_run }} + steps: + - name: Resolve tag + id: resolve + run: | + TAG="${{ inputs.tag || github.ref_name }}" + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + + - name: Extract metadata from tag + id: meta + env: + TAG: ${{ steps.resolve.outputs.tag }} + run: | + VERSION="${TAG#iii-lsp/v}" + + if [[ "$VERSION" =~ -dry-run\.[0-9]+$ ]]; then + echo "dry_run=true" >> "$GITHUB_OUTPUT" + echo "is_prerelease=true" >> "$GITHUB_OUTPUT" + elif [[ "$VERSION" =~ -([a-z]+)\.[0-9]+$ ]]; then + echo "dry_run=false" >> "$GITHUB_OUTPUT" + echo "is_prerelease=true" >> "$GITHUB_OUTPUT" + else + echo "dry_run=false" >> "$GITHUB_OUTPUT" + echo "is_prerelease=false" >> "$GITHUB_OUTPUT" + fi + + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "::notice::iii-lsp release -- tag=$TAG version=$VERSION" + + # ────────────────────────────────────────────────────────────── + # GitHub Release + # ────────────────────────────────────────────────────────────── + + create-release: + name: Create GitHub Release + needs: [setup] + if: needs.setup.outputs.dry_run != 'true' + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Generate token + id: generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.GH_APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + + - uses: actions/checkout@v4 + with: + token: ${{ steps.generate_token.outputs.token }} + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + token: ${{ steps.generate_token.outputs.token }} + tag_name: ${{ needs.setup.outputs.tag }} + name: iii-lsp ${{ needs.setup.outputs.version }} + draft: false + prerelease: ${{ needs.setup.outputs.is_prerelease == 'true' }} + generate_release_notes: true + + # ────────────────────────────────────────────────────────────── + # Binary Build + # ────────────────────────────────────────────────────────────── + + binary-build: + name: Binary Release + needs: [setup, create-release] + if: ${{ !failure() && !cancelled() }} + uses: ./.github/workflows/_rust-binary.yml + with: + bin_name: iii-lsp + manifest_path: iii-lsp/Cargo.toml + tag_name: ${{ needs.setup.outputs.tag }} + is_prerelease: ${{ needs.setup.outputs.is_prerelease == 'true' }} + skip_create_release: true + dry_run: ${{ needs.setup.outputs.dry_run == 'true' }} + secrets: + GH_APP_ID: ${{ secrets.GH_APP_ID }} + GH_APP_PRIVATE_KEY: ${{ secrets.GH_APP_PRIVATE_KEY }}