diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..20b13708 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,142 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + tag: + description: 'Tag to release (e.g., v0.11.0). Leave empty to use latest tag.' + required: false + type: string + +permissions: + contents: write + +jobs: + build: + name: Build ${{ matrix.os }}-${{ matrix.arch }} + runs-on: ubuntu-latest + strategy: + matrix: + include: + - os: linux + arch: amd64 + extension: '' + - os: linux + arch: arm64 + extension: '' + - os: darwin + arch: amd64 + extension: '' + - os: darwin + arch: arm64 + extension: '' + - os: windows + arch: amd64 + extension: '.exe' + + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Determine version + id: version + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.tag }}" ]; then + TAG="${{ inputs.tag }}" + elif [ "${{ github.event_name }}" = "push" ]; then + TAG="${GITHUB_REF#refs/tags/}" + else + TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + fi + VERSION="${TAG#v}" + echo "tag=${TAG}" >> $GITHUB_OUTPUT + echo "version=${VERSION}" >> $GITHUB_OUTPUT + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: '1.25' + + - name: Build binary + env: + GOOS: ${{ matrix.os }} + GOARCH: ${{ matrix.arch }} + CGO_ENABLED: 0 + run: | + VERSION="${{ steps.version.outputs.version }}" + OUTPUT_NAME="gmailctl${{ matrix.extension }}" + go build -ldflags="-s -w -X github.com/mbrt/gmailctl/cmd/gmailctl/cmd.version=${VERSION}" \ + -o "${OUTPUT_NAME}" ./cmd/gmailctl + + - name: Create archive (Unix) + if: matrix.os != 'windows' + run: | + VERSION="${{ steps.version.outputs.version }}" + ARCHIVE_NAME="gmailctl_${VERSION}_${{ matrix.os }}_${{ matrix.arch }}.tar.gz" + tar -czvf "${ARCHIVE_NAME}" gmailctl + echo "ARCHIVE_NAME=${ARCHIVE_NAME}" >> $GITHUB_ENV + + - name: Create archive (Windows) + if: matrix.os == 'windows' + run: | + VERSION="${{ steps.version.outputs.version }}" + ARCHIVE_NAME="gmailctl_${VERSION}_${{ matrix.os }}_${{ matrix.arch }}.zip" + zip "${ARCHIVE_NAME}" gmailctl.exe + echo "ARCHIVE_NAME=${ARCHIVE_NAME}" >> $GITHUB_ENV + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: gmailctl-${{ matrix.os }}-${{ matrix.arch }} + path: ${{ env.ARCHIVE_NAME }} + retention-days: 1 + + release: + name: Create Release + needs: build + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Determine version + id: version + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.tag }}" ]; then + TAG="${{ inputs.tag }}" + elif [ "${{ github.event_name }}" = "push" ]; then + TAG="${GITHUB_REF#refs/tags/}" + else + TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + fi + echo "tag=${TAG}" >> $GITHUB_OUTPUT + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: dist + merge-multiple: true + + - name: Generate checksums + run: | + cd dist + sha256sum gmailctl_* > checksums.txt + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.version.outputs.tag }} + name: Release ${{ steps.version.outputs.tag }} + draft: false + prerelease: ${{ contains(steps.version.outputs.tag, '-') }} + generate_release_notes: true + files: | + dist/gmailctl_* + dist/checksums.txt