ci: setup GPG signing #9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [master, develop] | |
| tags: ["v*"] | |
| pull_request: | |
| branches: [master, develop] | |
| jobs: | |
| # Linting and code quality | |
| lint: | |
| name: Lint and Format Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Cache Go modules | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/go-build | |
| ~/go/pkg/mod | |
| key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go- | |
| - name: Install dependencies | |
| run: make deps | |
| - name: Run linting | |
| run: make lint-dev | |
| - name: Check formatting and go mod tidy | |
| run: make verify | |
| # Security scanning | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Install dependencies | |
| run: make deps | |
| - name: Run vulnerability check | |
| run: make vuln-check | |
| # Build and test on multiple platforms | |
| test: | |
| name: Test | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| go-version: ["1.23", "1.24", "1.25"] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ matrix.go-version }} | |
| - name: Cache Go modules | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/go-build | |
| ~/go/pkg/mod | |
| key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go-${{ matrix.go-version }}- | |
| - name: Install dependencies | |
| run: make deps | |
| - name: Run tests with coverage | |
| run: make test-coverage | |
| - name: Run benchmarks | |
| run: make benchmark | |
| - name: Upload coverage to Codecov | |
| if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.25' | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| file: ./coverage.out | |
| flags: unittests | |
| name: codecov-umbrella | |
| fail_ci_if_error: false | |
| # Integration tests | |
| integration: | |
| name: Integration Tests | |
| runs-on: ubuntu-latest | |
| needs: [test] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Build binary | |
| run: make build | |
| - name: Run integration tests | |
| run: make test-integration | |
| # Build cross-platform binaries | |
| build: | |
| name: Build Cross-Platform | |
| runs-on: ubuntu-latest | |
| needs: [lint, test, security] | |
| if: github.event_name == 'push' || github.event_name == 'pull_request' | |
| strategy: | |
| matrix: | |
| goos: [linux, windows, darwin] | |
| goarch: [amd64, arm64] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Build optimized cross-platform binary | |
| env: | |
| GOOS: ${{ matrix.goos }} | |
| GOARCH: ${{ matrix.goarch }} | |
| run: | | |
| EXT="" | |
| if [ "$GOOS" = "windows" ]; then | |
| EXT=".exe" | |
| fi | |
| make release | |
| mv build/emojify "emojify-$GOOS-$GOARCH$EXT" | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: emojify-${{ matrix.goos }}-${{ matrix.goarch }} | |
| path: emojify-* | |
| retention-days: 30 | |
| # Docker build and push | |
| # docker: | |
| # name: Build Docker Images | |
| # runs-on: ubuntu-latest | |
| # needs: [test, lint] | |
| # if: github.event_name == 'push' | |
| # permissions: | |
| # contents: read | |
| # packages: write | |
| # id-token: write | |
| # steps: | |
| # - name: Checkout code | |
| # uses: actions/checkout@v5 | |
| # - name: Set up Docker Buildx | |
| # uses: docker/setup-buildx-action@v3 | |
| # - name: Log in to GitHub Container Registry | |
| # uses: docker/login-action@v3 | |
| # with: | |
| # registry: ghcr.io | |
| # username: ${{ github.repository_owner }} | |
| # password: ${{ secrets.GITHUB_TOKEN }} | |
| # - name: Extract metadata | |
| # id: meta | |
| # uses: docker/metadata-action@v5 | |
| # with: | |
| # images: ghcr.io/${{ github.repository }} | |
| # tags: | | |
| # type=ref,event=branch | |
| # type=ref,event=pr | |
| # type=semver,pattern={{version}} | |
| # type=semver,pattern={{major}}.{{minor}} | |
| # type=raw,value=latest,enable={{is_default_branch}} | |
| # - name: Build and push Docker image | |
| # uses: docker/build-push-action@v6 | |
| # with: | |
| # context: . | |
| # platforms: linux/amd64,linux/arm64 | |
| # push: true | |
| # tags: ${{ steps.meta.outputs.tags }} | |
| # labels: ${{ steps.meta.outputs.labels }} | |
| # cache-from: type=gha | |
| # cache-to: type=gha,mode=max | |
| # Validate release prerequisites | |
| validate-release: | |
| name: Validate Release Prerequisites | |
| runs-on: ubuntu-latest | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Validate prerequisites | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
| AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} | |
| GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} | |
| GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }} | |
| run: ./scripts/validate-release-prerequisites.sh | |
| # GoReleaser configuration and build test | |
| goreleaser-test: | |
| name: GoReleaser Test | |
| runs-on: ubuntu-latest | |
| needs: [test, lint, security, integration, build, validate-release] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Cache Go modules | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/go-build | |
| ~/go/pkg/mod | |
| key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go- | |
| - name: Install dependencies | |
| run: make deps | |
| - name: Install GoReleaser | |
| uses: goreleaser/goreleaser-action@v6 | |
| with: | |
| distribution: goreleaser | |
| version: "~> v2" | |
| install-only: true | |
| - name: Run comprehensive GoReleaser test | |
| env: | |
| # Provide dummy values for test environment | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| CHOCOLATEY_API_KEY: "dummy" | |
| WINGET_GITHUB_TOKEN: "dummy" | |
| AUR_KEY: "dummy" | |
| GPG_KEY_FILE: "dummy" | |
| run: | | |
| echo "🧪 Running GoReleaser configuration validation and build test..." | |
| # 1. Configuration check | |
| echo "📋 Validating GoReleaser configuration..." | |
| goreleaser check || { | |
| if [[ $? -eq 2 ]]; then | |
| echo "⚠️ Configuration valid but has deprecation warnings" | |
| else | |
| echo "❌ Configuration has errors" | |
| exit 1 | |
| fi | |
| } | |
| # 2. Build test (without publishing) | |
| echo "🔨 Testing build process..." | |
| goreleaser release --snapshot --clean --skip=publish --skip=sign --skip=snapcraft --skip=chocolatey --skip=docker | |
| # 3. Verify artifacts were created | |
| echo "📦 Verifying artifacts..." | |
| if [[ -d "dist" ]]; then | |
| BINARIES=$(find dist -name "emojify*" -type f | wc -l) | |
| ARCHIVES=$(find dist -name "*.tar.gz" -o -name "*.zip" | wc -l) | |
| echo "✅ Generated $BINARIES binaries and $ARCHIVES archives" | |
| # Show key artifacts | |
| echo "📁 Key artifacts created:" | |
| find dist -maxdepth 1 \( -name "*.tar.gz" -o -name "*.zip" -o -name "checksums.txt" \) | head -5 | sed 's/^/ - /' | |
| else | |
| echo "❌ No dist directory found" | |
| exit 1 | |
| fi | |
| echo "✅ GoReleaser test completed successfully - ready for release!" | |
| # Release with GoReleaser | |
| release: | |
| name: Release | |
| runs-on: ubuntu-latest | |
| needs: | |
| [ | |
| test, | |
| lint, | |
| security, | |
| integration, | |
| build, | |
| validate-release, | |
| goreleaser-test, | |
| ] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| contents: write | |
| packages: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Install dependencies | |
| run: make deps | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Import GPG key | |
| uses: crazy-max/ghaction-import-gpg@v6 | |
| with: | |
| gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} | |
| - name: Run GoReleaser | |
| uses: goreleaser/goreleaser-action@v6 | |
| with: | |
| distribution: goreleaser | |
| version: "~> v2" | |
| args: release --clean | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
| AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} | |
| GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }} |