diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 97b603e..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Build - -on: - push: - branches: [main] - tags: ['v*'] - pull_request: - branches: [main] - -jobs: - build: - name: ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: '1.25' - - - name: Build - run: go build -trimpath -ldflags="-s -w" -o ${{ matrix.os == 'windows-latest' && 'bin/tele-tui.exe' || 'bin/tele-tui' }} ./cmd/teletui - env: - CGO_ENABLED: 0 - - - uses: actions/upload-artifact@v4 - with: - name: tele-tui-${{ matrix.os == 'ubuntu-latest' && 'linux' || matrix.os == 'windows-latest' && 'windows' || 'macos' }}-amd64 - path: bin/ - - release: - name: Release - needs: [build] - if: startsWith(github.ref, 'refs/tags/v') - runs-on: ubuntu-latest - permissions: - contents: write - - steps: - - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: Package - run: | - mkdir release - cp artifacts/tele-tui-linux-amd64/tele-tui release/tele-tui-linux-amd64 - cp artifacts/tele-tui-macos-amd64/tele-tui release/tele-tui-macos-amd64 - chmod +x release/tele-tui-linux-amd64 release/tele-tui-macos-amd64 - cp artifacts/tele-tui-windows-amd64/tele-tui.exe release/tele-tui-windows-amd64.exe - - - uses: softprops/action-gh-release@v2 - with: - files: release/* - generate_release_notes: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..46d23be --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +name: CI + +on: + push: + branches: [main, dev] + pull_request: + branches: [main, dev] + +jobs: + test: + name: Test & Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.25' + cache: true + + - name: Vet + run: go vet ./... + + - name: Format check + run: test -z "$(gofmt -l .)" + + - name: Test + run: go test ./... + + build: + name: Build ${{ matrix.target.goos }}/${{ matrix.target.goarch }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: + - { goos: linux, goarch: amd64 } + - { goos: linux, goarch: arm64 } + - { goos: darwin, goarch: amd64 } + - { goos: darwin, goarch: arm64 } + - { goos: windows, goarch: amd64 } + - { goos: android, goarch: arm64 } + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.25' + cache: true + + - name: Build all binaries + env: + GOOS: ${{ matrix.target.goos }} + GOARCH: ${{ matrix.target.goarch }} + CGO_ENABLED: 0 + run: | + set -e + EXT=""; [ "$GOOS" = "windows" ] && EXT=".exe" + mkdir -p dist + go build -trimpath -ldflags="-s -w" -o "dist/tele-tui${EXT}" ./cmd/teletui + go build -trimpath -ldflags="-s -w" -o "dist/telegram-mcp${EXT}" ./cmd/telegram-mcp + go build -trimpath -ldflags="-s -w" -o "dist/telegram-api${EXT}" ./cmd/telegram-api + + - uses: actions/upload-artifact@v4 + with: + name: telegram-cli-${{ matrix.target.goos }}-${{ matrix.target.goarch }} + path: dist/ + retention-days: 7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ac20270 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,142 @@ +name: Release + +# Fully automatic: every push to main bumps the patch version, creates a +# tag, builds all platforms, and publishes a GitHub release. +# Put "#minor" or "#major" in the commit message to bump those instead. +# Pushing a v* tag manually also works (uses that tag as-is). +on: + push: + branches: [main] + tags: ['v*'] + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: release + cancel-in-progress: false + +jobs: + version: + name: Determine version + runs-on: ubuntu-latest + outputs: + tag: ${{ steps.ver.outputs.tag }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - id: ver + env: + COMMIT_MSG: ${{ github.event.head_commit.message }} + run: | + set -e + if [[ "$GITHUB_REF" == refs/tags/v* ]]; then + TAG="$GITHUB_REF_NAME" + else + LATEST=$(git tag -l 'v*' --sort=-v:refname | head -n1) + LATEST=${LATEST:-v0.0.0} + IFS=. read -r MAJOR MINOR PATCH <<< "${LATEST#v}" + if grep -qi '#major' <<< "$COMMIT_MSG"; then + MAJOR=$((MAJOR+1)); MINOR=0; PATCH=0 + elif grep -qi '#minor' <<< "$COMMIT_MSG"; then + MINOR=$((MINOR+1)); PATCH=0 + else + PATCH=$((PATCH+1)) + fi + TAG="v${MAJOR}.${MINOR}.${PATCH}" + if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then + PATCH=$((PATCH+1)) + TAG="v${MAJOR}.${MINOR}.${PATCH}" + fi + fi + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" + echo "Releasing ${TAG}" + + build: + name: Build ${{ matrix.target.goos }}/${{ matrix.target.goarch }} + needs: [version] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: + - { goos: linux, goarch: amd64 } + - { goos: linux, goarch: arm64 } + - { goos: darwin, goarch: amd64 } + - { goos: darwin, goarch: arm64 } + - { goos: windows, goarch: amd64 } + - { goos: android, goarch: arm64 } + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.25' + cache: true + + - name: Build all binaries + env: + GOOS: ${{ matrix.target.goos }} + GOARCH: ${{ matrix.target.goarch }} + CGO_ENABLED: 0 + run: | + set -e + EXT=""; [ "$GOOS" = "windows" ] && EXT=".exe" + mkdir -p dist + go build -trimpath -ldflags="-s -w" -o "dist/tele-tui${EXT}" ./cmd/teletui + go build -trimpath -ldflags="-s -w" -o "dist/telegram-mcp${EXT}" ./cmd/telegram-mcp + go build -trimpath -ldflags="-s -w" -o "dist/telegram-api${EXT}" ./cmd/telegram-api + + - name: Package + env: + GOOS: ${{ matrix.target.goos }} + GOARCH: ${{ matrix.target.goarch }} + VERSION: ${{ needs.version.outputs.tag }} + run: | + set -e + PKG="telegram-cli_${VERSION}_${GOOS}_${GOARCH}" + mkdir -p "stage/${PKG}" + cp dist/* "stage/${PKG}/" + cp README.md LICENSE "stage/${PKG}/" + mkdir -p release + cd stage + if [ "$GOOS" = "windows" ]; then + zip -r "../release/${PKG}.zip" "${PKG}" + else + tar -czf "../release/${PKG}.tar.gz" "${PKG}" + fi + + - uses: actions/upload-artifact@v4 + with: + name: package-${{ matrix.target.goos }}-${{ matrix.target.goarch }} + path: release/ + retention-days: 7 + + publish: + name: Publish GitHub release + needs: [version, build] + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v4 + with: + pattern: package-* + path: packages + merge-multiple: true + + - name: Generate checksums + run: | + cd packages + sha256sum *.tar.gz *.zip > checksums.txt + + # softprops/action-gh-release creates the tag (pointing at this + # commit) when it does not exist yet — this is what makes the + # whole flow tagless on the pusher's side. + - uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ needs.version.outputs.tag }} + name: ${{ needs.version.outputs.tag }} + files: packages/* + generate_release_notes: true diff --git a/README.md b/README.md index fb4d9bc..41beada 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@

- Build + Build Release License Go @@ -60,6 +60,12 @@ ## Quick Start +### Prebuilt binaries + +Download the latest release for your platform from [Releases](https://github.com/imtaqin/telegram-cli/releases) — Linux, macOS, Windows, and Android/Termux (arm64). Each archive contains all three binaries: `tele-tui`, `telegram-mcp`, `telegram-api`. Releases are fully automatic: every push to `main` bumps the patch version, tags, builds, and publishes (use `#minor` / `#major` in a commit message to bump those instead). + +### Build from source + ```bash # Clone git clone https://github.com/imtaqin/telegram-cli.git