This is an automated email from the ASF dual-hosted git repository. jmckenzie-dev pushed a commit to branch sidecar/ghci in repository https://gitbox.apache.org/repos/asf/cassandra-ecosystem.git
commit aab36e100aa9587911c4084e48a12b223bc86862 Author: Jon Haddad <[email protected]> AuthorDate: Tue Nov 11 10:22:27 2025 -0800 Add GitHub Actions CI/CD with comprehensive test matrix Implements complete GitHub Actions pipeline replacing CircleCI: Main CI (.github/workflows/ci.yml): - Test matrix: Java 11/17/21 × Cassandra 4.0/4.1/5.0/5.1 - Cached dtest jar builds (saves ~25 min on subsequent runs) - Unit tests with static analysis (SpotBugs, Apache RAT, JaCoCo) - Lightweight + heavyweight integration tests (48 combinations total) - Checkstyle/Javadoc disabled pending fixes Artifact Publishing (.github/workflows/publish-test-artifacts.yml): - Auto-publishes after successful trunk CI runs - Docker: ghcr.io/apache/cassandra-sidecar:latest - Tarball: GitHub release at 'test-artifacts' tag Dependabot (.github/dependabot.yml): - Weekly Gradle dependency updates - Weekly GitHub Actions version updates --- .github/dependabot.yml | 53 +++++ .github/workflows/ci.yml | 320 +++++++++++++++++++++++++++ .github/workflows/publish-test-artifacts.yml | 164 ++++++++++++++ 3 files changed, 537 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..44f07e04 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,53 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +version: 2 +updates: + # Gradle dependencies + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + open-pull-requests-limit: 10 + groups: + gradle-dependencies: + patterns: + - "*" + labels: + - "dependencies" + - "gradle" + commit-message: + prefix: "chore" + include: "scope" + + # GitHub Actions versions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "github-actions" + commit-message: + prefix: "chore" + include: "scope" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..38309c6c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,320 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: CI + +on: + pull_request: + branches: [trunk] + push: + branches: [trunk] + +# Cancel in-progress runs for PRs when new commits are pushed +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +permissions: + contents: read + +jobs: + # Build Cassandra dtest jars once for all test jobs to reuse + build-dtest-jars: + name: Build dtest jars + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Java 11 + uses: actions/setup-java@v5 + with: + java-version: "11" + distribution: "temurin" + cache: "gradle" + + - name: Install prerequisites + run: | + sudo apt-get update + sudo apt-get install -y ant + + - name: Setup network aliases for multi-node tests + run: | + for i in {2..20}; do + sudo ip addr add 127.0.0.$i/8 dev lo + done + + - name: Cache dtest jars + id: cache-dtest-jars + uses: actions/cache@v4 + with: + path: dtest-jars/ + key: dtest-jars-${{ hashFiles('scripts/build-dtest-jars.sh', 'gradle/wrapper/gradle-wrapper.properties') }} + + - name: Dtest jars cache status + run: | + if [ "${{ steps.cache-dtest-jars.outputs.cache-hit }}" == "true" ]; then + echo "✅ Dtest jars restored from cache (saves ~25 minutes)" + else + echo "⚠️ Cache miss - will build dtest jars (~25 minutes)" + fi + + - name: Build dtest jars + if: steps.cache-dtest-jars.outputs.cache-hit != 'true' + run: | + ./scripts/build-dtest-jars.sh + + - name: Upload dtest jars artifact + uses: actions/upload-artifact@v5 + with: + name: dtest-jars + path: dtest-jars/ + retention-days: 90 + + # Run unit tests with static analysis on all Java versions + unit-tests: + name: Unit tests (Java ${{ matrix.java }}) + runs-on: ubuntu-latest + needs: build-dtest-jars + permissions: + contents: read + checks: write + strategy: + fail-fast: false + matrix: + java: ["11", "17", "21"] + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Java ${{ matrix.java }} + uses: actions/setup-java@v5 + with: + java-version: ${{ matrix.java }} + distribution: "temurin" + cache: "gradle" + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + with: + cache-read-only: ${{ github.ref != 'refs/heads/trunk' }} + + - name: Download dtest jars + uses: actions/download-artifact@v5 + with: + name: dtest-jars + path: dtest-jars/ + + - name: Run build with static analysis + run: | + ./gradlew build -x integrationTest -x checkstyleMain -x checkstyleTest -x checkstyleTestFixtures -x javadoc --stacktrace + env: + CASSANDRA_DEP_DIR: ${{ github.workspace }}/dtest-jars + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v5 + with: + name: unit-test-results-java-${{ matrix.java }} + path: | + **/build/test-results/test/*.xml + **/build/reports/tests/ + retention-days: 30 + + - name: Upload static analysis reports + if: always() + uses: actions/upload-artifact@v5 + with: + name: static-analysis-reports-java-${{ matrix.java }} + path: | + **/build/reports/spotbugs/ + **/build/reports/rat/ + **/build/reports/jacoco/ + retention-days: 30 + + # Run lightweight integration tests on full matrix + integration-tests-lightweight: + name: Integration tests lightweight (Java ${{ matrix.java }}, C* ${{ matrix.cassandra }}) + runs-on: ubuntu-latest + needs: [build-dtest-jars, unit-tests] + permissions: + contents: read + checks: write + strategy: + fail-fast: false + matrix: + java: ["11", "17", "21"] + cassandra: ["4.0", "4.1", "5.0", "5.1"] + include: + - cassandra: "4.0" + dtestVersion: "4.0.16" + - cassandra: "4.1" + dtestVersion: "4.1.6" + - cassandra: "5.0" + dtestVersion: "5.0.3" + - cassandra: "5.1" + dtestVersion: "5.1" + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Java ${{ matrix.java }} + uses: actions/setup-java@v5 + with: + java-version: ${{ matrix.java }} + distribution: "temurin" + cache: "gradle" + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + with: + cache-read-only: ${{ github.ref != 'refs/heads/trunk' }} + + - name: Install prerequisites + run: | + sudo apt-get update + sudo apt-get install -y ant + + - name: Setup network aliases for multi-node tests + run: | + for i in {2..20}; do + sudo ip addr add 127.0.0.$i/8 dev lo + done + + - name: Download dtest jars + uses: actions/download-artifact@v5 + with: + name: dtest-jars + path: dtest-jars/ + + - name: Install dtest jars to local Maven + run: | + ./scripts/install-shaded-dtest-jar-local.sh + env: + CASSANDRA_DEP_DIR: ${{ github.workspace }}/dtest-jars + + - name: Run lightweight integration tests + run: | + ./gradlew --no-daemon \ + -PdtestVersion=${{ matrix.dtestVersion }} \ + -Dcassandra.sidecar.versions_to_test="${{ matrix.cassandra }}" \ + integrationTestLightWeight \ + --stacktrace + env: + CASSANDRA_DEP_DIR: ${{ github.workspace }}/dtest-jars + INTEGRATION_MAX_PARALLEL_FORKS: 3 + INTEGRATION_MAX_HEAP_SIZE: 2500M + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v5 + with: + name: integration-lightweight-results-java-${{ matrix.java }}-cassandra-${{ matrix.cassandra }} + path: | + **/build/test-results/integrationTest*/*.xml + **/build/reports/tests/integrationTest*/ + retention-days: 30 + + # Run heavyweight integration tests on full matrix + integration-tests-heavyweight: + name: Integration tests heavyweight (Java ${{ matrix.java }}, C* ${{ matrix.cassandra }}) + runs-on: ubuntu-latest + needs: [build-dtest-jars, unit-tests] + permissions: + contents: read + checks: write + strategy: + fail-fast: false + matrix: + java: ["11", "17", "21"] + cassandra: ["4.0", "4.1", "5.0", "5.1"] + include: + - cassandra: "4.0" + dtestVersion: "4.0.16" + - cassandra: "4.1" + dtestVersion: "4.1.6" + - cassandra: "5.0" + dtestVersion: "5.0.3" + - cassandra: "5.1" + dtestVersion: "5.1" + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Java ${{ matrix.java }} + uses: actions/setup-java@v5 + with: + java-version: ${{ matrix.java }} + distribution: "temurin" + cache: "gradle" + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + with: + cache-read-only: ${{ github.ref != 'refs/heads/trunk' }} + + - name: Install prerequisites + run: | + sudo apt-get update + sudo apt-get install -y ant + + - name: Setup network aliases for multi-node tests + run: | + for i in {2..20}; do + sudo ip addr add 127.0.0.$i/8 dev lo + done + + - name: Download dtest jars + uses: actions/download-artifact@v5 + with: + name: dtest-jars + path: dtest-jars/ + + - name: Install dtest jars to local Maven + run: | + ./scripts/install-shaded-dtest-jar-local.sh + env: + CASSANDRA_DEP_DIR: ${{ github.workspace }}/dtest-jars + + - name: Run heavyweight integration tests + run: | + ./gradlew --no-daemon \ + -PdtestVersion=${{ matrix.dtestVersion }} \ + -Dcassandra.sidecar.versions_to_test="${{ matrix.cassandra }}" \ + integrationTestHeavyWeight \ + --stacktrace + env: + CASSANDRA_DEP_DIR: ${{ github.workspace }}/dtest-jars + INTEGRATION_MAX_PARALLEL_FORKS: 3 + INTEGRATION_MAX_HEAP_SIZE: 3600M + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v5 + with: + name: integration-heavyweight-results-java-${{ matrix.java }}-cassandra-${{ matrix.cassandra }} + path: | + **/build/test-results/integrationTest*/*.xml + **/build/reports/tests/integrationTest*/ + retention-days: 30 diff --git a/.github/workflows/publish-test-artifacts.yml b/.github/workflows/publish-test-artifacts.yml new file mode 100644 index 00000000..f350b6b2 --- /dev/null +++ b/.github/workflows/publish-test-artifacts.yml @@ -0,0 +1,164 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: Publish Test Artifacts + +on: + workflow_run: + workflows: ["CI"] + types: + - completed + branches: + - trunk + workflow_dispatch: + # Allow manual triggering for testing + +permissions: + contents: write # Required for creating releases + packages: write # Required for pushing to GHCR + +jobs: + # Build and publish test artifacts after successful CI + publish: + name: Publish test artifacts + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: write + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Java 11 + uses: actions/setup-java@v5 + with: + java-version: '11' + distribution: 'temurin' + cache: 'gradle' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + + - name: Get version + id: version + run: | + VERSION=$(grep "^version=" gradle.properties | cut -d'=' -f2) + COMMIT_SHORT=$(git rev-parse --short HEAD) + BUILD_DATE=$(date -u +"%Y%m%d") + TEST_VERSION="${VERSION}-test-${BUILD_DATE}-${COMMIT_SHORT}" + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "test_version=$TEST_VERSION" >> $GITHUB_OUTPUT + echo "commit_short=$COMMIT_SHORT" >> $GITHUB_OUTPUT + echo "build_date=$BUILD_DATE" >> $GITHUB_OUTPUT + echo "Building test artifact version: $TEST_VERSION" + + - name: Build distribution tarball + run: | + ./gradlew distTar --stacktrace + env: + SKIP_SIGNING: true + + - name: Rename tarball + run: | + ORIGINAL=$(find build/distributions -name "*.tar.gz" -type f | head -n 1) + TEST_NAME="apache-cassandra-sidecar-${{ steps.version.outputs.test_version }}.tar.gz" + cp "$ORIGINAL" "$TEST_NAME" + echo "Created test artifact tarball: $TEST_NAME" + ls -lh "$TEST_NAME" + + - name: Build and push Docker image (latest tag) + run: | + ./gradlew :server:jib \ + -Djib.to.image=ghcr.io/apache/cassandra-sidecar:latest \ + -Djib.to.auth.username=${{ github.actor }} \ + -Djib.to.auth.password=${{ secrets.GITHUB_TOKEN }} \ + --stacktrace + env: + SKIP_SIGNING: true + + - name: Delete existing test-artifacts release + continue-on-error: true + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release delete test-artifacts --yes --repo ${{ github.repository }} || true + git push --delete origin test-artifacts || true + + - name: Create test artifacts release + uses: softprops/action-gh-release@v2 + with: + tag_name: test-artifacts + name: "Test Artifacts - ${{ steps.version.outputs.build_date }}" + prerelease: true + draft: false + body: | + ## Test Artifacts (Not an Official Release) + + **⚠️ These are automated test artifacts built after successful CI runs. They are NOT official releases.** + + This contains test builds of Apache Cassandra Sidecar from the `trunk` branch after all CI tests pass. + + ### Build Information + + - **Version**: ${{ steps.version.outputs.test_version }} + - **Base Version**: ${{ steps.version.outputs.version }} + - **Commit**: ${{ steps.version.outputs.commit_short }} (${{ github.sha }}) + - **Build Date**: ${{ steps.version.outputs.build_date }} + - **Workflow Run**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + - **CI Run**: ${{ github.event.workflow_run.html_url }} + + ### Test Coverage + + All tests passed before creating these artifacts: + - ✅ Unit tests (Java 11, 17, 21) + - ✅ Lightweight integration tests (Java 11, 17, 21 × Cassandra 4.0, 4.1, 5.0, 5.1) + - ✅ Heavyweight integration tests (Java 11, 17, 21 × Cassandra 4.0, 4.1, 5.0, 5.1) + - ✅ Static analysis (SpotBugs, Apache RAT, JaCoCo) + + ### Artifacts + + - **Distribution Tarball**: `apache-cassandra-sidecar-${{ steps.version.outputs.test_version }}.tar.gz` + - **Docker Image**: `ghcr.io/apache/cassandra-sidecar:latest` + + ### Download URLs + + These URLs always point to the latest test artifacts: + + ``` + https://github.com/${{ github.repository }}/releases/download/test-artifacts/apache-cassandra-sidecar-${{ steps.version.outputs.test_version }}.tar.gz + ``` + + Docker pull: + ```bash + docker pull ghcr.io/apache/cassandra-sidecar:latest + ``` + + ### Usage + + These artifacts are suitable for: + - Testing and development + - Integration testing + - Preview of upcoming changes + + --- + + **Note**: These are test artifacts, not official releases. Do not use in production. + files: | + apache-cassandra-sidecar-${{ steps.version.outputs.test_version }}.tar.gz --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
