Merge pull request #15 from logdash-io/feat/snapshot #48
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/CD Pipeline | |
| on: | |
| push: | |
| branches: [ main, dev ] | |
| tags: [ 'v*' ] | |
| pull_request: | |
| branches: [ main, dev ] | |
| permissions: | |
| contents: write | |
| actions: read | |
| checks: write | |
| security-events: write | |
| pull-requests: write | |
| env: | |
| JAVA_VERSION: '17' | |
| MAVEN_OPTS: > | |
| -Dmaven.repo.local=.m2/repository | |
| -Xmx2048m | |
| -XX:+UseG1GC | |
| -Daether.connector.http.connectionMaxTtl=25 | |
| -Dmaven.artifact.threads=8 | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| validate: | |
| name: Code Quality & Security | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: ${{ env.JAVA_VERSION }} | |
| distribution: 'temurin' | |
| - name: Validate Project | |
| uses: nick-fields/retry@v3 | |
| with: | |
| timeout_minutes: 10 | |
| max_attempts: 2 | |
| retry_wait_seconds: 30 | |
| command: mvn clean validate compile -B --no-transfer-progress -DskipTests | |
| - name: Verify Dependencies | |
| run: | | |
| mvn dependency:analyze -B --no-transfer-progress -Pquality | |
| mvn dependency:tree -B --no-transfer-progress | tee dependency-tree.txt | |
| - name: Code Style Check (Spotless) | |
| run: mvn spotless:check -B --no-transfer-progress | |
| - name: Security Analysis (SpotBugs) | |
| run: mvn spotbugs:check -B --no-transfer-progress | |
| - name: Upload Dependency Tree | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dependency-analysis | |
| path: dependency-tree.txt | |
| retention-days: 7 | |
| test: | |
| name: Test Suite (Java ${{ matrix.java }}) | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| timeout-minutes: 25 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| java: [ 17, 21, 22 ] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup JDK ${{ matrix.java }} | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: ${{ matrix.java }} | |
| distribution: 'temurin' | |
| - name: Run Tests & Coverage Check | |
| uses: nick-fields/retry@v3 | |
| with: | |
| timeout_minutes: 20 | |
| max_attempts: 3 | |
| retry_wait_seconds: 30 | |
| command: mvn clean verify -B --no-transfer-progress -Djava.version=${{ matrix.java }} | |
| - name: List test report files | |
| if: always() && matrix.java == 17 | |
| run: | | |
| echo "Surefire reports:" | |
| ls -l target/surefire-reports || true | |
| echo "Failsafe reports:" | |
| ls -l target/failsafe-reports || true | |
| echo "JaCoCo reports:" | |
| ls -l target/site/jacoco* || true | |
| - name: Upload coverage reports to Codecov | |
| if: matrix.java == 17 | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: target/site/jacoco-merged/jacoco.xml,target/site/jacoco/jacoco.xml | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| fail_ci_if_error: false | |
| - name: Upload Test Results | |
| uses: dorny/test-reporter@v1 | |
| if: always() && matrix.java == 17 | |
| with: | |
| name: Test Results (Java ${{ matrix.java }}) | |
| path: target/surefire-reports/TEST-*.xml,target/failsafe-reports/TEST-*.xml | |
| reporter: java-junit | |
| fail-on-error: false | |
| build: | |
| name: Build & Package | |
| runs-on: ubuntu-latest | |
| needs: [ validate, test ] | |
| timeout-minutes: 15 | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| is-snapshot: ${{ steps.version.outputs.is-snapshot }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: ${{ env.JAVA_VERSION }} | |
| distribution: 'temurin' | |
| - name: Extract Version | |
| id: version | |
| run: | | |
| VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "is-snapshot=$(echo $VERSION | grep -q SNAPSHOT && echo true || echo false)" >> $GITHUB_OUTPUT | |
| - name: Build Package | |
| uses: nick-fields/retry@v3 | |
| with: | |
| timeout_minutes: 10 | |
| max_attempts: 2 | |
| retry_wait_seconds: 30 | |
| command: mvn clean package -B --no-transfer-progress -DskipTests | |
| - name: Generate Documentation | |
| run: mvn javadoc:javadoc -B --no-transfer-progress | |
| - name: Verify JAR Structure | |
| run: | | |
| jar -tf target/logdash-*.jar | head -20 | |
| echo "JAR size: $(du -h target/logdash-*.jar | cut -f1)" | |
| - name: Upload Build Artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-artifacts-${{ steps.version.outputs.version }} | |
| path: | | |
| target/*-${{ steps.version.outputs.version }}.jar | |
| !target/*-tests.jar | |
| !target/original-*.jar | |
| target/site/apidocs/** | |
| retention-days: ${{ steps.version.outputs.is-snapshot == 'true' && 7 || 90 }} | |
| security-scan: | |
| name: Security Scanning | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| timeout-minutes: 15 | |
| if: > | |
| (github.event_name == 'push' && github.ref == 'refs/heads/main') || | |
| (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'security-scan')) || | |
| startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: ${{ env.JAVA_VERSION }} | |
| distribution: 'temurin' | |
| - name: Build for Security Scan | |
| run: mvn clean compile -B --no-transfer-progress -DskipTests | |
| - name: Run Trivy Scan | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: '.' | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| - name: Upload SARIF | |
| uses: github/codeql-action/upload-sarif@v3 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| continue-on-error: true | |
| github-release: | |
| name: Release to GitHub Packages | |
| runs-on: ubuntu-latest | |
| needs: [ build, security-scan ] | |
| timeout-minutes: 15 | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| contents: write | |
| packages: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: ${{ env.JAVA_VERSION }} | |
| distribution: 'temurin' | |
| - name: Configure Maven Settings | |
| uses: whelk-io/maven-settings-xml-action@v22 | |
| with: | |
| servers: | | |
| [ | |
| { | |
| "id": "github", | |
| "username": "${env.GITHUB_ACTOR}", | |
| "password": "${env.GITHUB_TOKEN}" | |
| } | |
| ] | |
| - name: Extract Version Info | |
| id: version | |
| run: | | |
| VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT | |
| # Validate version matches tag | |
| if [[ "v$VERSION" != "${GITHUB_REF#refs/tags/}" ]]; then | |
| echo "::error::Version mismatch: POM version ($VERSION) doesn't match tag (${GITHUB_REF#refs/tags/})" | |
| exit 1 | |
| fi | |
| - name: Check if version exists in GitHub Packages | |
| run: | | |
| VERSION=${{ steps.version.outputs.version }} | |
| # Check if version already exists in GitHub Packages | |
| if gh api /orgs/logdash-io/packages/maven/io.logdash.logdash/versions --jq '.[] | .name' | grep -q "^$VERSION$"; then | |
| echo "::warning::Version $VERSION already exists in GitHub Packages" | |
| echo "Either delete the existing version or bump the version in pom.xml" | |
| else | |
| echo "✅ Version $VERSION is available for release" | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and Deploy to GitHub Packages | |
| run: | | |
| mvn clean deploy -B --no-transfer-progress \ | |
| -Pgithub-release \ | |
| -DperformRelease=true \ | |
| -DskipTests=true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Notify GitHub Release Success | |
| run: | | |
| echo "✅ Successfully deployed logdash:${{ steps.version.outputs.version }} to GitHub Packages" | |
| echo "📦 Available at: https://github.com/logdash-io/java-sdk/packages" | |
| maven-central-release: | |
| name: Release to Maven Central | |
| runs-on: ubuntu-latest | |
| needs: [ build, security-scan ] | |
| timeout-minutes: 30 | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: ${{ env.JAVA_VERSION }} | |
| distribution: 'temurin' | |
| - name: Import GPG key | |
| uses: crazy-max/ghaction-import-gpg@v6 | |
| with: | |
| gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} | |
| passphrase: ${{ secrets.GPG_PASSPHRASE }} | |
| - name: Verify GPG import | |
| run: | | |
| gpg --list-secret-keys --keyid-format LONG | |
| echo "✅ GPG key imported successfully" | |
| - name: Configure Maven Settings for Central | |
| uses: whelk-io/maven-settings-xml-action@v22 | |
| with: | |
| servers: | | |
| [ | |
| { | |
| "id": "central", | |
| "username": "${env.CENTRAL_TOKEN_USERNAME}", | |
| "password": "${env.CENTRAL_TOKEN_PASSWORD}" | |
| } | |
| ] | |
| - name: Extract Version Info | |
| id: version | |
| run: | | |
| VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT | |
| # Validate version matches tag | |
| if [[ "v$VERSION" != "${GITHUB_REF#refs/tags/}" ]]; then | |
| echo "::error::Version mismatch: POM version ($VERSION) doesn't match tag (${GITHUB_REF#refs/tags/})" | |
| exit 1 | |
| fi | |
| - name: Check if version exists on Maven Central | |
| run: | | |
| VERSION=${{ steps.version.outputs.version }} | |
| # Check if version exists on Maven Central using search API | |
| SEARCH_RESULT=$(curl -s "https://search.maven.org/solrsearch/select?q=g:io.logdash+AND+a:logdash+AND+v:$VERSION&rows=1&wt=json") | |
| COUNT=$(echo "$SEARCH_RESULT" | jq -r '.response.numFound') | |
| if [[ "$COUNT" != "0" ]]; then | |
| echo "::error::Version $VERSION already exists on Maven Central" | |
| echo "Cannot redeploy existing version to Maven Central" | |
| exit 1 | |
| else | |
| echo "✅ Version $VERSION is available for Maven Central release" | |
| fi | |
| - name: Build and Deploy to Maven Central | |
| run: | | |
| mvn clean deploy -B --no-transfer-progress \ | |
| -Pmaven-central-release \ | |
| -DskipTests=true \ | |
| -Dgpg.keyname="$GPG_KEY_ID" | |
| env: | |
| CENTRAL_TOKEN_USERNAME: ${{ secrets.CENTRAL_TOKEN_USERNAME }} | |
| CENTRAL_TOKEN_PASSWORD: ${{ secrets.CENTRAL_TOKEN_PASSWORD }} | |
| GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} | |
| GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} | |
| - name: Verify Maven Central Deployment | |
| run: | | |
| VERSION=${{ steps.version.outputs.version }} | |
| # Check if artifact appears in Central Portal (deployment confirmation) | |
| if curl -s -f "https://central.sonatype.com/api/internal/browse/component?namespace=io.logdash&name=logdash&version=$VERSION" > /dev/null; then | |
| echo "✅ Deployment confirmed via Central Portal API" | |
| else | |
| echo "⚠️ Not yet visible via Central Portal API (may take time to propagate)" | |
| fi | |
| - name: Notify Maven Central Success | |
| run: | | |
| echo "✅ Successfully deployed logdash:${{ steps.version.outputs.version }} to Maven Central" | |
| echo "📦 Will be available at: https://central.sonatype.com/artifact/io.logdash/logdash/${{ steps.version.outputs.version }}" | |
| echo "🌐 Maven Central: https://search.maven.org/artifact/io.logdash/logdash/${{ steps.version.outputs.version }}" | |
| echo "⏱️ Note: It may take up to 2 hours for the artifact to be searchable via Maven Central" | |
| create-github-release: | |
| name: Create GitHub Release | |
| runs-on: ubuntu-latest | |
| needs: [ github-release, maven-central-release ] | |
| timeout-minutes: 10 | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: ${{ env.JAVA_VERSION }} | |
| distribution: 'temurin' | |
| - name: Extract Version Info | |
| id: version | |
| run: | | |
| VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Build Release Artifacts | |
| run: | | |
| mvn clean package -B --no-transfer-progress -DskipTests=true | |
| mkdir -p release-assets | |
| cp target/logdash-${{ steps.version.outputs.version }}.jar release-assets/ | |
| cp target/logdash-${{ steps.version.outputs.version }}-sources.jar release-assets/ | |
| cp target/logdash-${{ steps.version.outputs.version }}-javadoc.jar release-assets/ | |
| # Create checksums | |
| cd release-assets | |
| sha256sum *.jar > checksums.sha256 | |
| cd .. | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| release-assets/*.jar | |
| release-assets/checksums.sha256 | |
| generate_release_notes: true | |
| draft: false | |
| body: | | |
| # 🚀 Logdash Java SDK ${{ steps.version.outputs.version }} | |
| Official Java SDK for [Logdash.io](https://logdash.io) – Zero-configuration observability for developers. | |
| ## ✨ Features | |
| - **Zero Configuration**: Start logging and tracking metrics in seconds | |
| - **Real-time Dashboard**: Cloud-hosted interface with live data updates | |
| - **Structured Logging**: Multiple log levels with rich context support | |
| - **Custom Metrics**: Track counters, gauges, and business metrics | |
| - **Async & Fast**: Non-blocking, production-ready, framework-agnostic | |
| - **Java 17+ Compatible**: Works with Java 17, 21, 22+ | |
| ## 📦 Installation | |
| **Maven Central** | |
| ```xml | |
| <dependency> | |
| <groupId>io.logdash</groupId> | |
| <artifactId>logdash</artifactId> | |
| <version>${{ steps.version.outputs.version }}</version> | |
| </dependency> | |
| ``` | |
| **Gradle** | |
| ```gradle | |
| implementation 'io.logdash:logdash:${{ steps.version.outputs.version }}' | |
| ``` | |
| ## 🏁 Quick Start | |
| ```java | |
| var logdash = Logdash.builder() | |
| .apiKey("your-api-key") | |
| .build(); | |
| logdash.logger().info("Application started"); | |
| logdash.metrics().mutate("app_starts", 1); | |
| ``` | |
| ## ⚙️ Requirements | |
| - Java 17 or higher | |
| - Internet connection | |
| - Logdash API key ([get yours](https://logdash.io)) | |
| ## 📖 Documentation & Support | |
| - [Full Documentation](https://logdash.io/docs) | |
| - [Live Demo](https://logdash.io/demo-dashboard) | |
| - [GitHub Issues](https://github.com/logdash-io/java-sdk/issues) | |
| - [Discord Community](https://discord.gg/naftPW4Hxe) | |
| - [Email Support](mailto:[email protected]) | |
| --- | |
| _See below for full release notes and change log._ | |
| - name: Deployment Summary | |
| run: | | |
| echo "📋 Deployment Status Summary:" | |
| echo "✅ GitHub Packages: ${{ needs.github-release.result }}" | |
| echo "✅ Maven Central: ${{ needs.maven-central-release.result }}" | |
| echo "📦 Version: ${{ steps.version.outputs.version }}" | |
| echo "🔗 Maven Central: https://central.sonatype.com/artifact/io.logdash/logdash/${{ steps.version.outputs.version }}" | |
| notification: | |
| name: Notification | |
| runs-on: ubuntu-latest | |
| needs: [ validate, test, build, security-scan, github-release, maven-central-release ] | |
| if: always() && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) | |
| steps: | |
| - name: Check Workflow Status | |
| run: | | |
| if [[ "${{ needs.validate.result }}" == "failure" || "${{ needs.test.result }}" == "failure" || "${{ needs.build.result }}" == "failure" ]]; then | |
| echo "❌ Workflow failed" | |
| echo "::error::Critical job failed" | |
| elif [[ "${{ startsWith(github.ref, 'refs/tags/v') }}" == "true" ]]; then | |
| if [[ "${{ needs.github-release.result }}" == "success" && "${{ needs.maven-central-release.result }}" == "success" ]]; then | |
| echo "🎉 Release completed successfully!" | |
| echo "📦 Available on GitHub Packages and Maven Central" | |
| else | |
| echo "⚠️ Release partially failed" | |
| echo "GitHub Release: ${{ needs.github-release.result }}" | |
| echo "Maven Central: ${{ needs.maven-central-release.result }}" | |
| fi | |
| else | |
| echo "✅ Workflow completed successfully on main branch" | |
| fi |