Release Plugin

name: Release Plugin

on:
  workflow_dispatch:

jobs:
  release:
    runs-on: ubuntu-latest
    if: github.repository_owner == 'ballerina-platform'
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'temurin'

      - name: Run Gradle Build
        run: |
          ./gradlew build

      - name: Get Release Version
        run: echo "VERSION=$((grep -w 'pluginVersion' | cut -d= -f2) < gradle.properties | rev | cut -d- -f2 | rev)" >> $GITHUB_ENV

      - name: Checkout to Release Branch
        run: |
          echo "Version: ${VERSION}"
          git checkout -b release-${VERSION}

      - name: Perform Release
        run: |
          ./gradlew clean release -Prelease.useAutomaticVersion=true

      - name: Sign Plugin
        run: ./gradlew signPlugin
        env:
          CERTIFICATE_CHAIN: ${{ secrets.CERTIFICATE_CHAIN }}
          PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
          PRIVATE_KEY_PASSWORD: ${{ secrets.PRIVATE_KEY_PASSWORD }}

      - name: Publish Plugin
        run: ./gradlew publishPlugin
        env:
          PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}

      - name: GitHub Release and Release Sync PR
        env:
          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}
        run: |
          gh release create $VERSION --title "$VERSION"
          gh pr create --base ${GITHUB_REF##*/} --title "[Automated] Sync ${GITHUB_REF##*/} after $VERSION release" --body "Sync ${GITHUB_REF##*/} after $VERSION release"


Plugin Verification Build

name: Plugin Verification Build
description: |
  This workflow is used to verify the plugin against different versions of IntelliJ IDEA.
  It reads the minimum and maximum supported versions from the `gradle.properties` file
  and runs the plugin against each version in the range.

on:
  push:
    branches:
      - master
      - 2.[0-9]+.x
  workflow_dispatch:

jobs:
  read-versions:
    runs-on: ubuntu-latest
    outputs:
      min-idea-version: ${{ steps.set-env.outputs.min-idea-version }}
      max-idea-version: ${{ steps.set-env.outputs.max-idea-version }}
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3

      - name: Read IntelliJ IDEA versions
        id: set-env
        run: |
          sinceBuild=$(grep "^sinceBuild" gradle.properties | cut -d'=' -f2)
          untilBuild=$(grep "^untilBuild" gradle.properties | cut -d'=' -f2)
          echo "min-idea-version=${sinceBuild}" >> $GITHUB_ENV
          echo "max-idea-version=${untilBuild}" >> $GITHUB_ENV
          echo "::set-output name=min-idea-version::${sinceBuild}"
          echo "::set-output name=max-idea-version::${untilBuild}"

  verify-plugin:
    needs: read-versions
    runs-on: ubuntu-latest
    strategy:
      matrix:
        idea-version: [${{ needs.read-versions.outputs.min-idea-version }}, ${{ needs.read-versions.outputs.max-idea-version }}]

    concurrency:
      group: ${{ github.head_ref }}-ubuntu-verify
      cancel-in-progress: true

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3

      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'temurin'

      - name: Verify against IDEA ${{ matrix.idea-version }}
        run: ./gradlew runIde -PideaVersion=${{ matrix.idea-version }}


Build Android

name: Build Android

on:
  push:
    branches:
      - master
    paths:
      - '.github/workflows/build-android.yml'
      - 'android/**'
      - 'examples/basic/android/**'
      - 'yarn.lock'
      - 'examples/basic/yarn.lock'
  pull_request:
    paths:
      - '.github/workflows/build-android.yml'
      - 'android/**'
      - 'examples/basic/android/**'
      - 'yarn.lock'
      - 'examples/basic/yarn.lock'

jobs:
  build:
    name: Build Android Example App
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup JDK 17
        uses: actions/setup-java@v2
        with:
          distribution: 'zulu'
          java-version: 17
          java-package: jdk

      - name: Install node_modules
        uses: ./.github/actions/setup-node
        with:
          working-directory: examples/basic

      - name: Restore Gradle cache
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-
      - name: Run Gradle Build for basic example
        run: cd examples/basic/android && ./gradlew assembleDebug --build-cache && cd ../../..

  build-without-ads:
    name: Build Android Example App Without Ads
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup JDK 17
        uses: actions/setup-java@v2
        with:
          distribution: 'zulu'
          java-version: 17
          java-package: jdk

      - name: Install node_modules
        uses: ./.github/actions/setup-node
        with:
          working-directory: examples/basic

      - name: Restore Gradle cache
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-
      - name: Run Gradle Build for basic example
        run: cd examples/basic/android && export RNV_SAMPLE_ENABLE_ADS=false && ./gradlew assembleDebug --build-cache && cd ../../..


Build iOS

name: Build iOS

on:
  workflow_dispatch:
  push:
    branches:
      - master
    paths:
      - '.github/workflows/build-ios.yml'
      - 'ios/**'
      - '*.podspec'
      - 'examples/basic/ios/**'
  pull_request:
    paths:
      - '.github/workflows/build-ios.yml'
      - 'ios/**'
      - '*.podspec'
      - 'examples/basic/ios/**'

jobs:
  build:
    name: Build iOS Example App
    runs-on: macos-14 # This allow us to use Xcode 15.0.1 which is a lot faster - TODO change to "macos-latest" once it's out of beta
    defaults:
      run:
        working-directory: examples/basic/ios
    steps:
      - uses: actions/checkout@v4

      - name: Install node_modules
        uses: ./.github/actions/setup-node
        with:
          working-directory: examples/basic

      - name: Restore buildcache
        uses: mikehardy/buildcache-action@v2
        continue-on-error: true

      - name: Setup Ruby (bundle)
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.10
          bundler-cache: true

      - name: Restore Pods cache
        uses: actions/cache@v3
        with:
          path: |
            examples/basic/ios/Pods
            ~/Library/Caches/CocoaPods
            ~/.cocoapods
          key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-pods-
      - name: Install Pods
        run: pod install
      - name: Install xcpretty
        run: gem install xcpretty
      - name: Build App
        run: "set -o pipefail && xcodebuild \
          -derivedDataPath build -UseModernBuildSystem=YES \
          -workspace videoplayer.xcworkspace \
          -scheme videoplayer \
          -sdk iphonesimulator \
          -configuration Debug \
          -destination 'platform=iOS Simulator,name=iPhone 14' \
          build \
          CODE_SIGNING_ALLOWED=NO | xcpretty"

  build-with-ads:
    name: Build iOS Example App With Ads
    runs-on: macos-14 # This allow us to use Xcode 15.0.1 which is a lot faster - TODO change to "macos-latest" once it's out of beta
    defaults:
      run:
        working-directory: examples/basic/ios
    steps:
      - uses: actions/checkout@v4

      - name: Install node_modules
        uses: ./.github/actions/setup-node
        with:
          working-directory: examples/basic

      - name: Restore buildcache
        uses: mikehardy/buildcache-action@v2
        continue-on-error: true

      - name: Setup Ruby (bundle)
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.10
          bundler-cache: true

      - name: Restore Pods cache
        uses: actions/cache@v3
        with:
          path: |
            examples/basic/ios/Pods
            ~/Library/Caches/CocoaPods
            ~/.cocoapods
          key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-pods-
      - name: Install Pods
        run:  export RNV_SAMPLE_ENABLE_ADS=true && pod install
      - name: Install xcpretty
        run: gem install xcpretty
      - name: Build App
        run: "set -o pipefail && export RNV_SAMPLE_ENABLE_ADS=true && xcodebuild \
          -derivedDataPath build -UseModernBuildSystem=YES \
          -workspace videoplayer.xcworkspace \
          -scheme videoplayer \
          -sdk iphonesimulator \
          -configuration Debug \
          -destination 'platform=iOS Simulator,name=iPhone 14' \
          build \
          CODE_SIGNING_ALLOWED=NO | xcpretty"

  build-with-caching:
    name: Build iOS Example App With Caching
    runs-on: macos-14 # This allow us to use Xcode 15.0.1 which is a lot faster - TODO change to "macos-latest" once it's out of beta
    defaults:
      run:
        working-directory: examples/basic/ios
    steps:
      - uses: actions/checkout@v4

      - name: Install node_modules
        uses: ./.github/actions/setup-node
        with:
          working-directory: examples/basic

      - name: Restore buildcache
        uses: mikehardy/buildcache-action@v2
        continue-on-error: true

      - name: Setup Ruby (bundle)
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.10
          bundler-cache: true

      - name: Restore Pods cache
        uses: actions/cache@v3
        with:
          path: |
            examples/basic/ios/Pods
            ~/Library/Caches/CocoaPods
            ~/.cocoapods
          key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-pods-
      - name: Install Pods
        run: export RNV_SAMPLE_VIDEO_CACHING=true && pod install
      - name: Install xcpretty
        run: gem install xcpretty
      - name: Build App
        run: "set -o pipefail && export RNV_SAMPLE_VIDEO_CACHING=true && xcodebuild \
          -derivedDataPath build -UseModernBuildSystem=YES \
          -workspace videoplayer.xcworkspace \
          -scheme videoplayer \
          -sdk iphonesimulator \
          -configuration Debug \
          -destination 'platform=iOS Simulator,name=iPhone 14' \
          build \
          CODE_SIGNING_ALLOWED=NO | xcpretty"


Check Android

name: Check Android

on:
  push:
    branches:
      - master
    paths:
      - '.github/workflows/check-android.yml'
      - 'android/**'
  pull_request:
    paths:
      - '.github/workflows/check-android.yml'
      - 'android/**'

jobs:
  Kotlin-Lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: |
          curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.0.1/ktlint && chmod a+x ktlint && sudo mv ktlint /usr/local/bin/
      - name: run ktlint
        working-directory: ./android/
        run: |
          ktlint --reporter=checkstyle,output=build/ktlint-report.xml --relative --editorconfig=./.editorconfig
        continue-on-error: true
      - uses: yutailang0119/action-ktlint@v3
        with:
          report-path: ./android/build/*.xml
        continue-on-error: false
      - uses: actions/upload-artifact@v3
        with:
          name: ktlint-report
          path: ./android/build/*.xml


Check CLang

name: Check CLang

on:
  push:
    branches:
      - master
    paths:
      - '.github/workflows/check-clang.yml'
      - 'ios/**'
  pull_request:
    branches:
      - master
    paths:
      - '.github/workflows/check-clang.yml'
      - 'ios/**'

jobs:
  CLang-Format:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install clang-format
        run: sudo apt-get install clang-format
      - name: Check ios clang formatting
        run: |
          find ios -type f \( -name "*.h" -o -name "*.cpp" -o -name "*.m" -o -name "*.mm" \) -print0 | while read -d $'\0' file; do
            clang-format -style=file:./ios/.clang-format -i "$file"
          done
        shell: bash
      - name: Check for changes
        run: git diff --exit-code HEAD


Check iOS

name: Check iOS

on:
  push:
    branches:
      - master
    paths:
      - '.github/workflows/check-ios.yml'
      - 'ios/**'
  pull_request:
    paths:
      - '.github/workflows/check-ios.yml'
      - 'ios/**'

jobs:
  Swift-Lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Lint with SwiftLint
        uses: norio-nomura/action-swiftlint@master
        with:
          args: --strict
        env:
          WORKING_DIRECTORY: ios
  Swift-Format:
    runs-on: macos-14 # This allow us to use Xcode 15.0.1 which is a lot faster - TODO change to "macos-latest" once it's out of beta
    defaults:
      run:
        working-directory: ./ios
    steps:
      - uses: actions/checkout@v4

      - name: Install SwiftFormat
        run: brew install swiftformat

      - name: Format Swift code
        run: swiftformat --verbose .

      - name: Verify formatted code is unchanged
        run: git diff --exit-code HEAD


Check JS

name: Check JS

on:
  push:
    branches:
      - master
    paths:
      - '.github/workflows/check-js.yml'
      - 'src/**'
      - '*.json'
      - '*.js'
      - '*.jsx'
      - '*.ts'
      - '*.tsx'
      - '*.lock'
  pull_request:
    paths:
      - '.github/workflows/check-js.yml'
      - 'src/**'
      - '*.json'
      - '*.js'
      - '*.jsx'
      - '*.ts'
      - '*.tsx'
      - '*.lock'

jobs:
  TypeScript-Check:
    name: Check TS (tsc)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install node_modules
        uses: ./.github/actions/setup-node

      - name: Install reviewdog
        uses: reviewdog/action-setup@v1

      - name: Check TypeScript
        run: |
          yarn tsc | reviewdog -name="tsc" -efm="%f(%l,%c): error TS%n: %m" -reporter="github-pr-review" -filter-mode="nofilter" -fail-on-error -tee
        env:
          REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  JS-Lint:
    name: Lint JS (eslint, prettier)
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - name: Install node_modules
      uses: ./.github/actions/setup-node

    - name: Run ESLint
      run: yarn lint -f @jamesacarr/github-actions

    - name: Run ESLint with auto-fix
      run: yarn lint --fix

    - name: Verify no files have changed after auto-fix
      run: git diff --exit-code HEAD


deploy docs

name: deploy docs
on:
  workflow_dispatch:
  push:
    branches:
      - master
    paths:
      - '.github/workflows/deploy-docs.yml'
      - 'docs/**'

jobs:
  deploy-docs:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup
        uses: ./.github/actions/setup-bun
        with:
          working-directory: ./docs

      - name: Cache build
        uses: actions/cache@v3
        with:
          path: |
            docs/.next/cache
          key: ${{ runner.os }}-nextjs-${{ hashFiles('**/bun.lockb') }}-${{ hashFiles('**/package.json') }}
          restore-keys: |
            ${{ runner.os }}-nextjs-${{ hashFiles('**/bun.lockb') }}
            ${{ runner.os }}-nextjs-

      - name: Build docs
        run: |
          bun --cwd docs build
          touch docs/out/.nojekyll

      - name: Deploy docs to GitHub Pages
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          branch: gh-pages
          folder: docs/out

permissions:
  contents: write


Test Docs build

name: Test Docs build
on:
  workflow_dispatch:
  pull_request:
    paths:
      - '.github/workflows/test-build-docs.yml'
      - 'docs/**'

jobs:
  build-docs:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup
        uses: ./.github/actions/setup-bun
        with:
          working-directory: ./docs

      - name: Cache build
        uses: actions/cache@v3
        with:
          path: |
            docs/.next/cache
          key: ${{ runner.os }}-nextjs-${{ hashFiles('**/bun.lockb') }}-${{ hashFiles('**/package.json') }}
          restore-keys: |
            ${{ runner.os }}-nextjs-${{ hashFiles('**/bun.lockb') }}
            ${{ runner.os }}-nextjs-

      - name: Build docs
        run: |
          bun --cwd docs build
          touch docs/out/.nojekyll


Release minor version

name: Release minor version

on: workflow_dispatch

jobs:

  # bump up patch if dev release finished
  increment_minor_version:
    name: Increment minor version after release
    needs: release_dev
    if: startsWith(github.ref, 'refs/tags/')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.MZMINE_BOT_ACTIONS_TOKEN }}
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
      - name: Execute Gradle to increment version
        run: ./gradlew incrementMinor
      - name: Commit updated version
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: Increment minor version
          branch: master

  # release stable version after version increment
  release_stable:
    name: Release new mzmine version
    needs: increment_minor_version
    if: startsWith(github.ref, 'refs/tags/')
    runs-on: ubuntu-latest
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v2 # download all artifacts
        with:
          path: build/
      - name: Create stable release
        uses: marvinpinto/action-automatic-releases@latest
        with:
          repo_token: "${{ secrets.GITHUB_TOKEN}}"
          prerelease: true
          title: "Release build"
          files: build/*/*


repo analysis

name: repo analysis

on: workflow_dispatch

jobs:
  hercules-charts:
    runs-on: ubuntu-latest
    name: Charts generated by src-d/hercules
    steps:
      - uses: actions/checkout@master
        with:
          fetch-depth: 0
      - name: Hercules-patched
        uses: mzmine/mzmine3@master
      - uses: actions/upload-artifact@master
        with:
          name: hercules_charts
          path: hercules_charts.tar


CodeQL

# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  push:
    branches: [ "master", "jdk20" ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ "master", "jdk20" ]
  schedule:
    - cron: '26 2 * * 4'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'java' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    - uses: actions/setup-java@v3
      with:
        distribution: 'temurin'
        java-version: '20.0.1'
        cache: gradle

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.

        # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
        # queries: security-extended,security-and-quality

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    # - name: Autobuild
    #  uses: github/codeql-action/autobuild@v2
    - name: Setup Gradle
      uses: gradle/gradle-build-action@v2

    - name: Execute Gradle build
      run: ./gradlew --stacktrace --info

    # ℹ Command-line programs to run using the OS shell.
    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

    #   If the Autobuild fails above, remove it and uncomment the following three lines.
    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

    # - run: |
    #   echo "Run, Build Application using script"
    #   ./location_of_script_within_repo/buildscript.sh

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2


Development Build Release

name: Development Build Release

on:
  push:
    branches: [ master ]
    paths-ignore:
      - 'mzmine-community/src/main/resources/mzmineversion.properties'

jobs:
  gradle_dev_build:
    name: test and build
    strategy:
      matrix:
        os: [ ubuntu-latest, macos-latest, windows-latest ]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '21.0.2'
#          cache: 'gradle'  # now done with gradle

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

#      in push to master use signed version for macOS defined below
      - name: Execute Gradle build (unsigned)
        if: runner.os != 'macOS'
        run: ./gradlew -p mzmine-community --stacktrace --info --warning-mode all
        env:
          TESTRUNNER_USER: ${{ secrets.TESTRUNNER_USER }}

      # ZIP PORTABLE VERSIONS
      - name: Zip portable windows
        if: runner.os == 'Windows'
        uses: papeloto/action-zip@v1
        with:
          files: mzmine-community/build/jpackage/mzmine/
          dest: mzmine-community/build/jpackage/mzmine_Windows_portable.zip
      - name: Zip portable linux
        if: runner.os == 'Linux'
        uses: papeloto/action-zip@v1
        with:
          files: mzmine-community/build/jpackage/mzmine/
          dest: mzmine-community/build/jpackage/mzmine_Linux_portable.zip

      # UPLOAD ALL FILES
      - name: Upload windows builds
        if: runner.os == 'Windows'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_windows_msi_installer
          path: mzmine-community/build/jpackage/*.msi
          retention-days: 7  # store for 7 days
      - name: Upload windows portable builds
        if: runner.os == 'Windows'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_windows_portable
          path: mzmine-community/build/jpackage/mzmine_Windows_portable.zip
          retention-days: 7  # store for 7 days

      - name: Upload builds ubuntu deb
        if: runner.os == 'Linux'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_linux_deb_package
          path: mzmine-community/build/jpackage/*.deb
          retention-days: 7  # store for 7 days
      - name: Upload builds ubuntu rpm
        if: runner.os == 'Linux'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_linux_rpm_package
          path: mzmine-community/build/jpackage/*.rpm
          retention-days: 7  # store for 7 days
      - name: Upload linux portable builds
        if: runner.os == 'Linux'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_linux_portable
          path: mzmine-community/build/jpackage/mzmine_Linux_portable.zip
          retention-days: 7  # store for 7 days

      # for macOS:
      # 1. upload the dmg installer
      # 2. remove the dmg isntaller from path
      # 3. zip and upload the jpackage directory
      # This is needed because zipping of the /jpackage/mzmine.app portable version zips the content
      # of the folder not the folder itself
      - name: Setup node for macOS packaging
        if: runner.os == 'macOS'
        uses: actions/setup-node@v3  # To install appdmg

      - name: Execute Gradle build on macOS (signed)
        if: runner.os == 'macOS'
        run: |
          echo "$MACOS_DEVELOPER_CERTIFICATE" | base64 --decode > certificate.p12
          security create-keychain -p abc123 build.keychain
          security default-keychain -s build.keychain
          security unlock-keychain -p abc123 build.keychain
          security import certificate.p12 -k build.keychain -P "$MACOS_DEVELOPER_CERTIFICATE_PWD" -T /usr/bin/codesign
          security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k abc123 build.keychain
          ./gradlew -p mzmine-community --info --warning-mode all --stacktrace
        env:
          MACOS_DEVELOPER_CERTIFICATE: ${{ secrets.MACOS_DEVELOPER_CERTIFICATE }}
          MACOS_DEVELOPER_CERTIFICATE_PWD: ${{ secrets.MACOS_DEVELOPER_CERTIFICATE_PWD }}
          MACOS_APPLE_ID_PWD: ${{ secrets.MACOS_APPLE_ID_PWD }}
          MACOS_APP_IDENTITY_ID: ${{ secrets.MACOS_APP_IDENTITY_ID }}
          MACOS_APP_IDENTITY_TEAM_ID: ${{ secrets.MACOS_APP_IDENTITY_TEAM_ID }}
          TESTRUNNER_USER: ${{ secrets.TESTRUNNER_USER }}

      - name: Pack macOS .app to .dmg
        if: runner.os == 'macOS'
        run: |
          npm install --python=python3.11 -g appdmg
          appdmg mzmine-community/gradle/appdmg.json mzmine-community/build/jpackage/mzmine_macOS_installer.dmg

      - name: Upload macOS installer
        if: runner.os == 'macOS'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_macOS_installer
          path: mzmine-community/build/jpackage/mzmine_macOS_installer.dmg
          retention-days: 7  # store for 7 days

#      - name: Remove dmg File and Make .app executable
#        if: runner.os == 'macOS'
#        run: |
#          find ./build/jpackage/ -name '*.dmg' -delete
#          chmod a+x build/jpackage/mzmine.app/Contents/MacOS/mzmine
#      - name: Zip portable macos
#        if: runner.os == 'macOS'
#        uses: papeloto/action-zip@v1
#        with:
#          files: build/jpackage/
#          dest: build/jpackage/mzmine_macOS_portable.zip
      - name: Upload macOS portable builds
        if: runner.os == 'macOS'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_macos_portable
          path: mzmine-community/build/jpackage/mzmine_macOS_portable.zip
          retention-days: 7  # store for 7 days

  # release dev version
  release_dev:
    name: Release dev version
    needs: gradle_dev_build
    runs-on: ubuntu-latest
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v2 # download all artifacts
        with:
          path: build/
      - name: Create development release
        uses: marvinpinto/action-automatic-releases@latest
        with:
          repo_token: "${{ secrets.GITHUB_TOKEN}}"
          prerelease: true
          title: "Latest Development Build"
          automatic_release_tag: "Development-release"
          files: build/*/*

  # bump up patch if dev release finished
  increment_patch:
    name: Increment patch version
    needs: release_dev
    if: ${{ !startsWith(github.ref, 'refs/tags/') }} # only increment if not a tag push
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.MZMINE_BOT_ACTIONS_TOKEN }}
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
      - name: Execute Gradle to increment version
        run: ./gradlew incrementPatch
      - name: Commit updated patch version
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: Increment patch version
          branch: master


PR Test Build

name: PR Test Build

on:
  pull_request_target:
    branches: [ "master" ]

jobs:
  gradle_build:
    name: test and build
    strategy:
      matrix:
        os: [ ubuntu-latest, macos-latest, windows-latest ]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '21.0.2'
#          cache: 'gradle'  # now done with gradle

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

# requires two secrets just in case: the user license string and
# USER_BASE64 a Base64 encoded version of this
      - name: Create testrunner user file
        env:
          TESTRUNNER_USER: ${{ secrets.TESTRUNNER_USER }}
          USER_BASE64: ${{ secrets.USER_BASE64 }}
        run: |
          mkdir -p $HOME/.mzmine/users/
          echo $HOME/.mzmine/users/
          echo $USER_BASE64 | base64 --decode > $HOME/.mzmine/users/testrunner.mzuserstr
# another option to set env var globally
#          echo "TESTRUNNER_USER_GIT_ENV=$TESTRUNNER_USER" >> "$GITHUB_ENV"

#      in PR, without signing
#      in push to master use signed version for macOS
      - name: Execute Gradle build (unsigned)
        env:
          TESTRUNNER_USER: ${{ secrets.TESTRUNNER_USER }}
        run: ./gradlew -p mzmine-community --stacktrace --info --warning-mode all

      # ZIP PORTABLE VERSIONS
      - name: Zip portable windows
        if: runner.os == 'Windows'
        uses: papeloto/action-zip@v1
        with:
          files: mzmine-community/build/jpackage/mzmine/
          dest: mzmine-community/build/jpackage/mzmine_Windows_portable.zip
      - name: Zip portable linux
        if: runner.os == 'Linux'
        uses: papeloto/action-zip@v1
        with:
          files: mzmine-community/build/jpackage/mzmine/
          dest: mzmine-community/build/jpackage/mzmine_Linux_portable.zip

      # UPLOAD ALL FILES
      - name: Upload windows builds
        if: runner.os == 'Windows'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_windows_msi_installer
          path: mzmine-community/build/jpackage/*.msi
          retention-days: 7  # store for 7 days
      - name: Upload windows portable builds
        if: runner.os == 'Windows'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_windows_portable
          path: mzmine-community/build/jpackage/mzmine_Windows_portable.zip
          retention-days: 7  # store for 7 days

      - name: Upload builds ubuntu deb
        if: runner.os == 'Linux'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_linux_deb_package
          path: mzmine-community/build/jpackage/*.deb
          retention-days: 7  # store for 7 days
      - name: Upload builds ubuntu rpm
        if: runner.os == 'Linux'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_linux_rpm_package
          path: mzmine-community/build/jpackage/*.rpm
          retention-days: 7  # store for 7 days
      - name: Upload linux portable builds
        if: runner.os == 'Linux'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_linux_portable
          path: mzmine-community/build/jpackage/mzmine_Linux_portable.zip
          retention-days: 7  # store for 7 days

      # for macOS:
      # 1. upload the dmg installer
      # 2. remove the dmg isntaller from path
      # 3. zip and upload the jpackage directory
      # This is needed because zipping of the /jpackage/mzmine.app portable version zips the content
      # of the folder not the folder itself
      - name: Setup node for macOS packaging
        if: runner.os == 'macOS'
        uses: actions/setup-node@v3  # To install appdmg

      - name: Pack macOS .app to .dmg
        if: runner.os == 'macOS'
        run: |
          npm install --python=python3.11 -g appdmg
          appdmg mzmine-community/gradle/appdmg.json mzmine-community/build/jpackage/mzmine_macOS_installer.dmg

      - name: Upload macOS installer
        if: runner.os == 'macOS'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_macOS_installer
          path: mzmine-community/build/jpackage/mzmine_macOS_installer.dmg
          retention-days: 7  # store for 7 days

#      - name: Remove dmg File and Make .app executable
#        if: runner.os == 'macOS'
#        run: |
#          find ./build/jpackage/ -name '*.dmg' -delete
#          chmod a+x build/jpackage/mzmine.app/Contents/MacOS/mzmine
#      - name: Zip portable macos
#        if: runner.os == 'macOS'
#        uses: papeloto/action-zip@v1
#        with:
#          files: build/jpackage/
#          dest: build/jpackage/mzmine_macOS_portable.zip
      - name: Upload macOS portable builds
        if: runner.os == 'macOS'
        uses: actions/upload-artifact@v2
        with:
          name: mzmine_macos_portable
          path: mzmine-community/build/jpackage/mzmine_macOS_portable.zip
          retention-days: 7  # store for 7 days


Check dependency licenses

name: Check dependency licenses

on:
  pull_request:
    branches: [ "master" ]

jobs:
  gradle_build:
    name: test and build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '21.0.2'
      #          cache: 'gradle'  # now done with gradle

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Execute dependency license check
        run: ./gradlew mzmine-community:checkLicense --stacktrace

      - name: Upload license report
        if: runner.os == 'Linux'
        uses: actions/upload-artifact@v2
        with:
          name: license_report
          path: mzmine-community/licensereport/*.json
          retention-days: 7  # store for 7 days


build

name: build

on:
  pull_request:
    branches:
      - '**'
  push:
    branches:
      - main

jobs:
  unit-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          submodules: true

      - name: Copy CI gradle.properties
        run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

      - name: Run unit tests
        run: ./gradlew clean build optimizedJar

  integration-test:
    needs: unit-test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          submodules: true

      - name: Copy CI gradle.properties
        run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

      - name: Start local Blockchain
        run: docker logout public.ecr.aws && docker-compose up -d

      # - name: Check if all contracts are deployable
      #   run: ./gradlew deployContractsToLocal --max-workers=2

      - name: Run integration tests
        run: ./gradlew integrationTest --max-workers=2


Dependabot auto-approve

name: Dependabot auto-approve
on: pull_request_target
permissions:
  pull-requests: write
jobs:
  dependabot:
    runs-on: ubuntu-latest
    # Checking the author will prevent your Action run failing on non-Dependabot PRs
    if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
    steps:
      - name: Dependabot metadata
        id: dependabot-metadata
        uses: dependabot/fetch-metadata@v1
      - uses: actions/checkout@v4
      - name: Approve a PR if not already approved
        run: |
          gh pr checkout "$PR_URL" # sets the upstream metadata for `gh pr status`
          if [ "$(gh pr status --json reviewDecision -q .currentBranch.reviewDecision)" != "APPROVED" ];
          then gh pr review --approve "$PR_URL"
          else echo "PR already approved, skipping additional approvals to minimize emails/notification noise.";
          fi
        env:
          PR_URL: ${{github.event.pull_request.html_url}}
          GITHUB_TOKEN: ${{secrets.ACTIONS_PAT}}


Dependabot auto-merge

name: Dependabot auto-merge
on: pull_request_target
permissions:
  pull-requests: write
  contents: write
jobs:
  dependabot:
    runs-on: ubuntu-latest
    if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
    steps:
      - name: Dependabot metadata
        id: dependabot-metadata
        uses: dependabot/fetch-metadata@v1
      - name: Enable auto-merge for Dependabot PRs
        run: gh pr merge --auto --squash "$PR_URL"
        env:
          PR_URL: ${{github.event.pull_request.html_url}}
          GH_TOKEN: ${{secrets.ACTIONS_PAT}}


Dev Build

name: Dev Build

on:
  push:
    branches: [ dev ]
    paths: [ src/** ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        name: Checkout repo
        with:
          path: app
          token: ${{ secrets.ACTIONS_PAT }}
      - name: Configure git
        run: |
          git config --global user.name "Build Monkey"
          git config --global user.email "<>"
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: 17
          server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml
          settings-path: ${{ github.workspace }} # location for the settings.xml file
          gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
          gpg-passphrase: MAVEN_GPG_PASSPHRASE
      - name: 'Create settings.xml'
        uses: s4u/maven-settings-action@v2.8.0
        with:
          githubServer: false
          servers: '[{"id": "ossrh", "username": "${{ secrets.SONATYPE_USERNAME }}", "password": "${{ secrets.SONATYPE_DEPLOY_KEY }}"}]'
      - name: Publish to Maven Central
        env:
          MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
        run: |
          cd app
          mvn clean deploy -P gpg,publish -DcreateChecksum=true 2>&1 | tee log.txt
          result_code=${PIPESTATUS[0]}
          exit $result_code
      - name: Tag release version
        run: |
          cd app
          git add .
          git commit -m "[ci skip] Deploy dev version $version"
          version=$(mvn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.version -q -DforceStdout)
          git tag -a $version -m "Dev $version"
      - uses: actions/checkout@v3
        name: Checkout editor branch
        with:
          ref: editor
          path: editor
      - name: Update Javadocs
        run: |
          rm -rf editor/static/javadocs
          cp -r app/gh-pages/javadocs editor/static
          cd editor
          git add .
          git commit -m "Update javadocs"
          git push
      - name: Update version
        run: cd app && python ./.github/update_version.py true
      - name: Push to git
        run: |
          cd app
          git add .
          git commit -m "[ci skip] Update dev version"
          git push
          git push --tags
      - name: Notify Discord
        run: cd app && pip install simplejson && python ./.github/notify_published.py ${{ secrets.WEBHOOK_URL }} true


Test Editor PR

name: Test Editor PR
on:
  pull_request:
    branches:
      - editor

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout 🛎
        uses: actions/checkout@v3 # If you're using actions/checkout@v3 you must set persist-credentials to false in most cases for the deployment to work correctly.
        with:
          persist-credentials: false

      - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
        run: |
          npm install
          npm run build


Build Artifacts

name: Build Artifacts

on:
  pull_request:
    branches: [ main, dev ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v2
        with:
          distribution: 'zulu'
          java-version: 17
          server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml
          settings-path: ${{ github.workspace }} # location for the settings.xml file
          gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
          gpg-passphrase: MAVEN_GPG_PASSPHRASE
      - name: 'Create settings.xml'
        uses: s4u/maven-settings-action@v2.8.0
        with:
          githubServer: false
      - name: Build with Maven
        run: mvn clean package -e
        env:
          GITHUB_TOKEN_REF: ${{ secrets.GH_PAT_FOR_ACTIONS_TOKEN }}


Build and Deploy Editor

name: Build and Deploy Editor
on:
  push:
    branches:
      - editor

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout 🛎
        uses: actions/checkout@v3
        with:
          persist-credentials: false

      - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
        run: |
          npm install
          npm run build

      - name: Deploy 🚀
        uses: JamesIves/github-pages-deploy-action@releases/v3
        with:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          BRANCH: gh-pages # The branch the action should deploy to.
          FOLDER: gh-pages # The folder the action should deploy.


Release Build

name: Release Build

on:
  push:
    branches: [ main ]
    paths: [ src/** ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          token: ${{ secrets.ACTIONS_PAT }}
      - name: Configure git
        run: |
          git config user.name "Build Monkey"
          git config user.email "<>"
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: 17
          server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml
          settings-path: ${{ github.workspace }} # location for the settings.xml file
          gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
          gpg-passphrase: MAVEN_GPG_PASSPHRASE
      - name: 'Create settings.xml'
        uses: s4u/maven-settings-action@v2.8.0
        with:
          githubServer: false
          servers: '[{"id": "ossrh", "username": "Travja", "password": "${{ secrets.SONATYPE_DEPLOY_KEY }}"}, {"id": "central", "username": "${{ secrets.SONATYPE_USERNAME }}", "password": "${{ secrets.SONATYPE_DEPLOY_KEY }}"}]'
      - name: Update version
        run: python ./.github/update_version.py false true
      - name: Publish to Maven Central
        env:
          MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
        run: |
          mvn clean deploy -P gpg,publish -DcreateChecksum=true 2>&1 | tee log.txt
          result_code=${PIPESTATUS[0]}
          exit $result_code
      - name: Update README
        run: python ./.github/update_readme.py
      - name: Tag release version
        run: |
          git add .
          git commit -m "[ci skip] Update release version"
          version=$(mvn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.version -q -DforceStdout)
          git tag -a $version -m "Release $version"
          git push
          git push --tags
          git fetch --unshallow --all
          git checkout dev
          git merge -X theirs --no-edit main
      - name: Update version
        run: python ./.github/update_version.py
      - name: Update version
        run: python ./.github/update_version.py true
      - name: Push to git
        run: |
          git add .
          git commit -m "[ci skip] Update version for development"
          git push
      - name: Notify Discord
        run: pip install simplejson && python ./.github/notify_published.py ${{ secrets.WEBHOOK_URL }}


Grace CI

name: Grace CI
on:
  push:
    branches:
      - 2023.0.x
  pull_request:
    branches:
      - 2023.0.x
  workflow_dispatch:
jobs:
  build:
    if: ${{ github.repository == 'graceframework/grace-framework' }}
    permissions:
      contents: read  #  to fetch code (actions/checkout)
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        java: ['17']
    env:
      WORKSPACE: ${{ github.workspace }}
    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: ${{ matrix.java }}
      - name: Run Build
        id: build
        uses: gradle/gradle-build-action@v3
        with:
          arguments: build -x codenarcMain -x codenarcTest -x checkstyleMain -x checkstyleTest
  publish:
    if: github.event_name == 'push'
    needs: ["build"]
    permissions:
      contents: read  #  to fetch code (actions/checkout)
      checks: write
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout repository
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: 17
      - name: Generate secring file
        env:
          SECRING_FILE: ${{ secrets.SECRING_FILE }}
        run: echo $SECRING_FILE | base64 -d > ${{ github.workspace }}/secring.gpg
      - name: Publish to Sonatype OSSRH
        id: publish
        uses: gradle/gradle-build-action@v3
        env:
          SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
          SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
          SONATYPE_NEXUS_URL: ${{ secrets.SONATYPE_NEXUS_URL }}
          SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }}
          SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
          SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }}
          SECRING_FILE: ${{ secrets.SECRING_FILE }}
        with:
          arguments: -Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg publishToSonatype closeAndReleaseSonatypeStagingRepository


Grace Joint Validation Build

# 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: "Grace Joint Validation Build"
#  GROOVY_3_0_X == Grace 2022.0.x
#  GROOVY_4_0_X == Grace 2023.0.x
#  Groovy master branch does not map to any due to changed package names.
on:
  push:
    branches:
      - master
      - '[2020-2024]+.[0-9]+.x'
  pull_request:
    branches:
      - master
      - '[2020-2024]+.[0-9]+.x'
jobs:
  build:
    if: ${{ github.repository == 'graceframework/grace-framework' }}
    strategy:
      fail-fast: true
      matrix:
        os: [ubuntu-22.04]
        java: ['17']
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          distribution: 'adopt'
          java-version: ${{ matrix.java }}
      - name: env
        run: env

      # Select correct Groovy branch for this build:
      - name: Checkout Groovy 3_0_X (Grace 2022.1.x)
        run: cd .. && git clone --depth 1 https://github.com/apache/groovy.git -b GROOVY_3_0_X --single-branch
        if: github.ref == 'refs/heads/2022.2.x' || github.base_ref == '2022.2.x' || github.ref == 'refs/heads/2022.1.x' || github.base_ref == '2022.1.x' || github.ref == 'refs/heads/2022.0.x' || github.base_ref == '2022.0.x' || github.ref == 'refs/heads/master' || github.base_ref == 'master'
      - name: Checkout Groovy 4_0_X (Grace 2023.0.x)
        run: cd .. && git clone --depth 1 https://github.com/graceframework/grace-framework.git -b GROOVY_4_0_X --single-branch
        if: github.ref == 'refs/heads/2023.0.x' || github.base_ref == '2023.0.x'
      - name: Set CI_GROOVY_VERSION for Grace
        run: |
          cd ../groovy
          echo 'CI_GROOVY_VERSION<<EOF' >> $GITHUB_ENV
          echo "$(cat gradle.properties | grep groovyVersion | cut -d\= -f2 |  tr -d '[:space:]' >> $GITHUB_ENV)" >> $GITHUB_ENV
          echo 'EOF' >> $GITHUB_ENV
      - name: echo CI_GROOVY_VERSION
        run: echo $CI_GROOVY_VERSION

      - name: Build and install groovy (no docs)
        run: cd ../groovy && ./gradlew clean install -x groovydoc -x javadoc -x javadocAll -x groovydocAll -x asciidoc -x docGDK -x codenarcMain -x codenarcTest -x checkstyleMain -x checkstyleTest --no-build-cache --no-scan --no-daemon
        timeout-minutes: 60

      - name: Build Grace
        run: ./gradlew clean build test -x groovydoc -x codenarcMain -x codenarcTest -x checkstyleMain -x checkstyleTest --no-build-cache --no-scan --no-daemon
        timeout-minutes: 60


Grace Changelog

name: Grace Changelog
on:
  issues:
    types: [closed,reopened]
  push:
    branches:
      - master
      - '[2020-2024]+.[0-9]+.x'
  workflow_dispatch:
jobs:
  release_notes:
    if: ${{ github.repository == 'graceframework/grace-framework' }}
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - name: Check if it has release drafter config file
        id: check_release_drafter
        run: |
          has_release_drafter=$([ -f .github/release-drafter.yml ] && echo "true" || echo "false")
          echo ::set-output name=has_release_drafter::${has_release_drafter}
      - name: Extract branch name
        id: extract_branch
        run: echo ::set-output name=value::${GITHUB_REF:11}
      # If it has release drafter:
      - uses: release-drafter/release-drafter@v6
        if: steps.check_release_drafter.outputs.has_release_drafter == 'true'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          commitish: ${{ steps.extract_branch.outputs.value }}


Grace Release

name: Grace Release

on:
  push:
    tags:
      - v*

permissions:
  contents: write

jobs:
  create_draft_release:
    if: ${{ github.repository == 'graceframework/grace-framework' }}
    runs-on: ubuntu-22.04
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - name: Create draft release
        run: |
          gh release create \
            --repo ${{ github.repository }} \
            --title ${{ github.ref_name }} \
            --notes '' \
            --draft \
            ${{ github.ref_name }}
  release_and_publish:
    needs: create_draft_release
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        java: ['17']
    env:
      GIT_USER_NAME: rainboyan
      GIT_USER_EMAIL: rain@rainboyan.com
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - uses: gradle/wrapper-validation-action@v2
      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: ${{ matrix.java }}
      - name: Extract Target Branch
        id: extract_branch
        run: |
          echo "Determining Target Branch"
          TARGET_BRANCH=`cat $GITHUB_EVENT_PATH | jq '.release.target_commitish' | sed -e 's/^"\(.*\)"$/\1/g'`
          echo $TARGET_BRANCH
          echo ::set-output name=value::${TARGET_BRANCH}
      - name: Set the current release version
        id: release_version
        run: echo "release_version=${GITHUB_REF:11}" >> $GITHUB_OUTPUT
      - name: Run Assemble
        id: assemble
        uses: gradle/gradle-build-action@v3
        with:
          arguments: assemble
      - name: Upload artifacts to the Github release
        id: upload_artifact
        if: steps.assemble.outcome == 'success'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release upload --clobber "${{ github.ref_name }}" \
            build/distributions/grace-${{ steps.release_version.outputs.release_version }}.zip
      - name: Generate secring file
        env:
          SECRING_FILE: ${{ secrets.SECRING_FILE }}
        run: echo $SECRING_FILE | base64 -d > ${{ github.workspace }}/secring.gpg
      - name: Publish to Sonatype OSSRH
        id: publish
        if: steps.assemble.outcome == 'success'
        uses: gradle/gradle-build-action@v3
        env:
          SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
          SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
          SONATYPE_NEXUS_URL: ${{ secrets.SONATYPE_NEXUS_URL }}
          SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }}
          SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
          SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }}
          SECRING_FILE: ${{ secrets.SECRING_FILE }}
        with:
          arguments: -Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg publishToSonatype closeAndReleaseSonatypeStagingRepository


SDKMAN Release

name: SDKMAN Release

on:
  release:
    types: [published]

permissions: {}
jobs:
  sdkman_release:
    if: ${{ github.repository == 'graceframework/grace-framework' }}
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        java: ['17']
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          ref: ${{ github.ref_name }}
      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: ${{ matrix.java }}
      - name: SDKMan release
        uses: gradle/gradle-build-action@v3
        with:
          arguments: sdkManRelease
        env:
          SDKMAN_KEY: ${{ secrets.SDKMAN_KEY }}
          SDKMAN_TOKEN: ${{ secrets.SDKMAN_TOKEN }}


Android CI

name: Android CI

# Avoid running this on the gh-pages branch
on:
  push:
    branches-ignore:
      - "gh-pages"
  pull_request:
    branches-ignore:
      - "gh-pages"
  workflow_dispatch: # Allow running manually from web UI

jobs:
  build:
    name: Build and Test
    runs-on: ubuntu-latest
    # Only run on pushes or if pull request from fork
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    permissions:
      checks: write # to publish unit test results

    steps:
      - name: Check out
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
      - name: Set up JDK 17
        uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: gradle

      - name: Gradle info
        run: ./gradlew -version

      # Note: Currently no difference between flavors or debug and release
      # Note: running tests will also compile
      - name: Build and run unit tests
        run: ./gradlew :app:testPureDebugUnitTest

      - name: Test Report
        uses: dorny/test-reporter@eaa763f6ffc21c7a37837f56cd5f9737f27fc6c8 # v1.8.0
        if: always() # also run if tests failed
        with:
          name: JUnit Report
          path: app/build/test-results/**/*.xml
          reporter: java-junit

  lint:
    name: Lint
    runs-on: ubuntu-latest
    # Only run on pushes or if pull request from fork
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name

    steps:
      - name: Check out
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
      - name: Set up JDK 17
        uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: gradle

      # To speed up lint check only run for release variant and only on app module
      # Note: the app module has lintOptions.checkDependencies true, so submodules will be checked
      # Source: https://groups.google.com/forum/#!topic/lint-dev/RGTvK_uHQGQ
      # Note: running lint will also compile
      - name: Lint goog release
        run: ./gradlew :app:lintPureRelease

      - name: Lint amzn release
        if: ${{ contains(github.ref, 'release') }}
        run: ./gradlew :app:lintAmazonRelease

      - name: Upload lint reports
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
        if: ${{ always() }} # also upload of lint errors
        with:
          name: Lint reports
          path: |
            app/build/reports/lint-results-pureRelease.html
            app/build/reports/lint-results-amazonRelease.html


Add Platform Label

name: Add Platform Label
on:
  issues:
    types: [opened]
  pull_request:
    types: [opened]

jobs:
  add_label:
    runs-on: ubuntu-latest
    permissions:
      issues: write
    steps:
      - uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 # pin@1.0.4
        with:
          add-labels: 'Platform: Java'
          repo-token: ${{ secrets.GITHUB_TOKEN }}


AGP Matrix Compatibility

name: AGP Matrix Compatibility

on:
  push:
    branches:
      - main
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  agp-matrix-compatibility:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        agp: [ '8.0.0','8.1.4','8.2.0','8.3.0-beta01' ]
        integrations: [ true, false ]

    name: AGP Matrix Release - AGP ${{ matrix.agp }} - Integrations ${{ matrix.integrations }}
    env:
      VERSION_AGP: ${{ matrix.agp }}
      APPLY_SENTRY_INTEGRATIONS: ${{ matrix.integrations }}

    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - name: Setup Java Version
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      - name: Setup KVM
        shell: bash
        run: |
          # check if virtualization is supported...
          sudo apt install -y --no-install-recommends cpu-checker coreutils && echo "CPUs=$(nproc --all)" && kvm-ok
          # allow access to KVM to run the emulator
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \
            | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm

      # Clean, build and release a test apk
      - name: Make assembleUiTests
        run: make assembleUiTests

      # We tried to use the cache action to cache gradle stuff, but it made tests slower and timeout
      - name: Run instrumentation tests
        uses: reactivecircus/android-emulator-runner@6b0df4b0efb23bb0ec63d881db79aefbc976e4b2 # pin@v2
        with:
          api-level: 30
          force-avd-creation: false
          emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: true
          disable-spellchecker: true
          target: 'aosp_atd'
          arch: x86
          channel: canary # Necessary for ATDs
          script: ./gradlew sentry-android-integration-tests:sentry-uitest-android:connectedReleaseAndroidTest -DtestBuildType=release --daemon

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results-AGP${{ matrix.agp }}-Integrations${{ matrix.integrations }}
          path: |
            **/build/reports/*
            **/build/outputs/*/connected/*
            **/build/outputs/mapping/release/*

      - name: Test Report
        uses: phoenix-actions/test-reporting@41efe7ebebe7ef156ef46f6b0acf50ec0f10315b # pin@v12
        if: always()
        with:
          name: JUnit AGP ${{ matrix.agp }} - Integrations ${{ matrix.integrations }}
          path: |
            **/build/outputs/androidTest-results/**/*.xml
          reporter: java-junit
          output-to: step-summary
          fail-on-error: false


Build

name: 'Build'
on:
  push:
    branches:
      - main
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  build:
    name: Build Job ubuntu-latest - Java 17
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - name: Setup Java Version
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      - name: Run Tests with coverage and Lint
        run: make preMerge

      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # pin@v4
        with:
          name: sentry-java
          fail_ci_if_error: false
          token: ${{ secrets.CODECOV_TOKEN }}

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results-build
          path: |
            **/build/reports/*

      - name: Test Report
        uses: phoenix-actions/test-reporting@41efe7ebebe7ef156ef46f6b0acf50ec0f10315b # pin@v12
        if: always()
        with:
          name: JUnit Build
          list-suites: 'failed'
          list-tests: 'failed'
          path: |
            **/build/test-results/**/*.xml
          reporter: java-junit
          output-to: step-summary
          fail-on-error: false


CodeQL

name: 'CodeQL'

on:
  push:
    branches: [main]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [main]
  schedule:
    - cron: '17 23 * * 3'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        language: ['cpp', 'java']

    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - name: Setup Java Version
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      - name: Initialize CodeQL
        uses: github/codeql-action/init@cdcdbb579706841c47f7063dda365e292e5cad7a # pin@v2
        with:
          languages: ${{ matrix.language }}

      - if: matrix.language == 'cpp'
        name: Build Cpp
        run: |
          ./gradlew sentry-android-ndk:buildCMakeRelWithDebInfo
      - if: matrix.language == 'java'
        name: Build Java
        run: |
          ./gradlew buildForCodeQL

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@cdcdbb579706841c47f7063dda365e292e5cad7a # pin@v2


Danger

name: Danger

on:
  pull_request:
    types: [opened, synchronize, reopened, edited, ready_for_review]

jobs:
  danger:
    uses: getsentry/github-workflows/.github/workflows/danger.yml@v2


Enforce License Compliance

name: Enforce License Compliance

on:
  push:
    branches: [master, main, release/*]
  pull_request:
    branches: [master, main]

jobs:
  enforce-license-compliance:
    runs-on: ubuntu-latest
    steps:
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      - name: Set up Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: 'Enforce License Compliance'
        uses: getsentry/action-enforce-license-compliance@main
        with:
          fossa_api_key: ${{ secrets.FOSSA_API_KEY }}


format code

name: format code
on:
  pull_request:

jobs:
  format-code:
    name: Format Code
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - name: set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Cache Gradle packages
        uses: actions/cache@v4
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Make format
        run: make format

      # actions/checkout fetches only a single commit in a detached HEAD state. Therefore
      # we need to pass the current branch, otherwise we can't commit the changes.
      # GITHUB_HEAD_REF is the name of the head branch. GitHub Actions only sets this for PRs.
      - name: Commit Formatted Code
        run: ./scripts/commit-formatted-code.sh $GITHUB_HEAD_REF


Generate Javadocs

name: 'Generate Javadocs'
on:
  release:
    types: [released]

jobs:
  build-and-deploy-javadocs:
    name: Build and deploy Javadocs
    runs-on: ubuntu-latest
    steps:
      - name: Checkout 🛎
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - name: set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      - name: Generate Aggregate Javadocs
        run: |
          ./gradlew aggregateJavadocs
      - name: Deploy
        uses: JamesIves/github-pages-deploy-action@65b5dfd4f5bcd3a7403bbc2959c144256167464e # pin@4.5.0
        with:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          BRANCH: gh-pages
          FOLDER: build/docs/javadoc
          CLEAN: true


Validate Gradle Wrapper

name: 'Validate Gradle Wrapper'
on:
  push:
    branches:
      - main
      - release/**
  pull_request:

jobs:
  validation:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: 'recursive'
      - uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 # pin@v1


Integration Tests - Benchmarks

name: 'Integration Tests - Benchmarks'
on:
  schedule:
    - cron: '0 0 * * *' # every night at midnight UTC
  pull_request:
    paths:
      - '**/sentry/**'
      - '**/sentry-android/**'
      - '**/sentry-android-core/**'
      - '**/sentry-android-ndk/**'
      - '**/sentry-android-integration-tests/**'
      - '**/.github/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    name: Benchmarks
    runs-on: ubuntu-latest

    # we copy the secret to the env variable in order to access it in the workflow
    env:
      SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }}

    steps:
      - name: Git checkout
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - name: 'Set up Java: 17'
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      # Clean, build and release a test apk, but only if we will run the benchmark
      - name: Make assembleBenchmarks
        if: env.SAUCE_USERNAME != null
        run: make assembleBenchmarks

      - name: Run All Tests in SauceLab
        uses: saucelabs/saucectl-run-action@7fe025ef1fdc6f211add3751a6c7d8bba27ba9b1 # pin@v3
        if: github.event_name != 'pull_request' && env.SAUCE_USERNAME != null
        env:
          GITHUB_TOKEN: ${{ github.token }}
        with:
          sauce-username: ${{ secrets.SAUCE_USERNAME }}
          sauce-access-key: ${{ secrets.SAUCE_ACCESS_KEY }}
          config-file: .sauce/sentry-uitest-android-benchmark.yml

      - name: Run one test in SauceLab
        uses: saucelabs/saucectl-run-action@7fe025ef1fdc6f211add3751a6c7d8bba27ba9b1 # pin@v3
        if: github.event_name == 'pull_request' && env.SAUCE_USERNAME != null
        env:
          GITHUB_TOKEN: ${{ github.token }}
        with:
          sauce-username: ${{ secrets.SAUCE_USERNAME }}
          sauce-access-key: ${{ secrets.SAUCE_ACCESS_KEY }}
          config-file: .sauce/sentry-uitest-android-benchmark-lite.yml

  app-metrics:
    runs-on: ubuntu-latest

    # we copy the secret to the env variable in order to access it in the workflow
    env:
      SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }}

    steps:
      - name: Git checkout
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - name: 'Set up Java: 17'
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      - uses: actions/cache@v4
        id: app-plain-cache
        with:
          path: sentry-android-integration-tests/test-app-plain/build/outputs/apk/release/test-app-plain-release.apk
          key: ${{ github.workflow }}-${{ github.job }}-appplain-${{ hashFiles('sentry-android-integration-tests/test-app-plain/**') }}

      - name: Build Android app plain
        if: steps.app-plain-cache.outputs['cache-hit'] != 'true'
        run: ./gradlew :sentry-android-integration-tests:test-app-plain:assembleRelease

      - name: Build Android app with Sentry
        run: ./gradlew :sentry-android-integration-tests:test-app-sentry:assembleRelease

      - name: Collect app metrics
        uses: getsentry/action-app-sdk-overhead-metrics@v1
        with:
          config: sentry-android-integration-tests/metrics-test.yml
          sauce-user: ${{ secrets.SAUCE_USERNAME }}
          sauce-key: ${{ secrets.SAUCE_ACCESS_KEY }}
        if: env.SAUCE_USERNAME != null


Integration Tests

name: 'Integration Tests'
on:
  push:
    branches:
      - main
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    name: Ui tests
    runs-on: ubuntu-latest

    # we copy the secret to the env variable in order to access it in the workflow
    env:
      SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }}
      SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}

    steps:
      - name: Git checkout
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - name: 'Set up Java: 17'
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      # Clean, build and release a test apk, but only if we will run the benchmark
      - name: Make assembleUiTests
        if: env.SAUCE_USERNAME != null
        run: make assembleUiTests

      - name: Install SauceLabs CLI
        uses: saucelabs/saucectl-run-action@7fe025ef1fdc6f211add3751a6c7d8bba27ba9b1 # pin@v3
        env:
          GITHUB_TOKEN: ${{ github.token }}
        with:
          skip-run: true
        if: env.SAUCE_USERNAME != null

      - name: Run Tests
        id: saucelabs
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |
          exec &> >(tee -a "test_logs.txt")
          saucectl run -c .sauce/sentry-uitest-android-ui.yml
        if: env.SAUCE_USERNAME != null
        continue-on-error: true

      - name: Verify Test Results
        run: |
          processCrashed=$(cat test_logs.txt | grep "Instrumentation run failed due to 'Process crashed.'" | wc -l)
          if [[ ${{ steps.saucelabs.outcome }} == 'success' ]]; then
            exit 0
          elif [[ "$processCrashed" -ne 0 ]]; then
            exit 0
          else
            exit 1
          fi
        if: env.SAUCE_USERNAME != null


Build Release Artifacts

name: 'Build Release Artifacts'
on:
  push:
    branches:
      - release/**

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  release:
    name: Build release artifacts
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - name: Setup Java Version
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      - name: Build artifacts
        run: make publish

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: ${{ github.sha }}
          if-no-files-found: error
          path: |
            ./*/build/distributions/*.zip
            ./sentry-opentelemetry/*/build/distributions/*.zip
            ./sentry-android-ndk/build/intermediates/merged_native_libs/release/out/lib/*


release

name: release
on:
  workflow_dispatch:
    inputs:
      version:
        description: Version to release
        required: true
      force:
        description: Force a release even when there are release-blockers (optional)
        required: false
      merge_target:
        description: Target branch to merge into. Uses the default branch as a fallback (optional)
        required: false

jobs:
  release:
    runs-on: ubuntu-latest
    name: "Release a new version"
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{ secrets.GH_RELEASE_PAT }}
          # Needs to be set, otherwise git describe --tags will fail with: No names found, cannot describe anything
          fetch-depth: 0
          submodules: 'recursive'
      - name: Prepare release
        uses: getsentry/action-prepare-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GH_RELEASE_PAT }}
        with:
          version: ${{ github.event.inputs.version }}
          force: ${{ github.event.inputs.force }}
          merge_target: ${{ github.event.inputs.merge_target }}


System Tests Backend

name: 'System Tests Backend'

on:
  push:
    branches:
      - main
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  system-test:
    runs-on: ubuntu-latest
    continue-on-error: true
    env:
      SENTRY_URL: http://127.0.0.1:8000
    strategy:
      fail-fast: false
      matrix:
        sample: [ "sentry-samples-spring-boot-jakarta" ]
        include:
          - sample: "sentry-samples-spring-boot"
          - sample: "sentry-samples-spring-boot-webflux-jakarta"
          - sample: "sentry-samples-spring-boot-webflux"
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: 'recursive'

      - uses: actions/setup-python@v5
        with:
          python-version: '3.10.5'

      - name: Set up Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@579fbbe7221704325eb4c4d4bf20c2b0859fba76 # pin@v3
        with:
          gradle-home-cache-cleanup: true

      - name: Exclude android modules from build
        run: |
          sed -i -e '/.*"sentry-android-ndk",/d' -e '/.*"sentry-android",/d' -e '/.*"sentry-compose",/d' -e '/.*"sentry-android-core",/d' -e '/.*"sentry-android-fragment",/d' -e '/.*"sentry-android-navigation",/d' -e '/.*"sentry-android-okhttp",/d' -e '/.*"sentry-android-sqlite",/d' -e '/.*"sentry-android-timber",/d' -e '/.*"sentry-android-integration-tests:sentry-uitest-android-benchmark",/d' -e '/.*"sentry-android-integration-tests:sentry-uitest-android",/d' -e '/.*"sentry-android-integration-tests:test-app-sentry",/d' -e '/.*"sentry-samples:sentry-samples-android",/d' settings.gradle.kts

      - name: Exclude android modules from ignore list
        run: |
          sed -i -e '/.*"sentry-uitest-android",/d' -e '/.*"sentry-uitest-android-benchmark",/d' -e '/.*"test-app-sentry",/d' -e '/.*"sentry-samples-android",/d' build.gradle.kts

      - name: Build server jar
        run: |
          ./gradlew :sentry-samples:${{ matrix.sample }}:bootJar

      - name: Start server and run integration test for sentry-cli commands
        run: |
          test/system-test-sentry-server-start.sh > sentry-mock-server.txt 2>&1 & test/system-test-spring-server-start.sh "${{ matrix.sample }}" > spring-server.txt 2>&1 & test/wait-for-spring.sh && ./gradlew :sentry-samples:${{ matrix.sample }}:systemTest

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results-${{ matrix.sample }}-system-test
          path: |
            **/build/reports/*
            sentry-mock-server.txt
            spring-server.txt

      - name: Test Report
        uses: phoenix-actions/test-reporting@41efe7ebebe7ef156ef46f6b0acf50ec0f10315b # pin@v12
        if: always()
        with:
          name: JUnit System Tests ${{ matrix.sample }}
          path: |
            **/build/test-results/**/*.xml
          reporter: java-junit
          output-to: step-summary
          fail-on-error: false


Update Dependencies

name: Update Dependencies

on:
  # Run every day.
  schedule:
    - cron: '0 3 * * *'
  # And on on every PR merge so we get the updated dependencies ASAP, and to make sure the changelog doesn't conflict.
  push:
    branches:
      - main

jobs:
  native:
    uses: getsentry/github-workflows/.github/workflows/updater.yml@v2
    with:
      path: sentry-android-ndk/sentry-native
      name: Native SDK
    secrets:
      # If a custom token is used instead, a CI would be triggered on a created PR.
      api-token: ${{ secrets.CI_DEPLOY_KEY }}

  gradle-wrapper:
    uses: getsentry/github-workflows/.github/workflows/updater.yml@v2
    with:
      path: scripts/update-gradle.sh
      name: Gradle
      pattern: '^v[0-9.]+$' # only match non-preview versions
    secrets:
      api-token: ${{ secrets.CI_DEPLOY_KEY }}


build

name: build

on:
  push:
    branches:
      - master
  pull_request:
    types: [opened, labeled, unlabeled, synchronize]

permissions:
  contents: read

env:
  GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false -Dkotlin.incremental=false"

jobs:
  publish:
    runs-on: ubuntu-latest
    if: github.repository == 'square/okhttp' && github.ref == 'refs/heads/master'

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Upload Artifacts
        run: ./gradlew clean publish --stacktrace
        env:
          ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }}
          ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }}
          ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ARTIFACT_SIGNING_PRIVATE_KEY }}

  validation:
    name: "Validation"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: gradle/actions/wrapper-validation@v3
      - name: Validate Renovate
        uses: rinchsan/renovate-config-validator@v0.2.0
        with:
          pattern: '.github/renovate.json'

  checkjdk11:
    permissions:
      checks: write # for mikepenz/action-junit-report
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew check -PandroidBuild=true -PgraalBuild=true -x test -x test

  testopenjdk11:
    permissions:
      checks: write # for mikepenz/action-junit-report
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=11

      - name: Publish Test Report
        if: github.repository == 'square/okhttp' && github.ref == 'refs/heads/master'
        uses: mikepenz/action-junit-report@v4
        with:
          report_paths: '**/build/test-results/*/TEST-*.xml'
          check_name: OpenJDK 11 Test Report

      - name: Publish Test Results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: github.repository == 'square/okhttp' && github.ref == 'refs/heads/master'
        with:
          files: |
            **/build/test-results/*/TEST-*.xml

  testzulu11:
    runs-on: ubuntu-latest
    if: contains(github.event.pull_request.labels.*.name, 'zulu')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=11

  testopenjdk8:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'jdkversions') || contains(github.event.pull_request.labels.*.name, 'renovate')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=8

  testopenjdk8alpn:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'jdkversions')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install Old JDK 8
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 8.0.242

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=8 -Dokhttp.platform=jdk8alpn -Dalpn.boot.version=8.1.13.v20181017 -Dorg.gradle.java.installations.paths=/opt/hostedtoolcache/Java_Adopt_jdk/8.0.242-8.1/x64

  testopenjsse:
    runs-on: ubuntu-latest
    if: contains(github.event.pull_request.labels.*.name, 'providers')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=8 -Dokhttp.platform=openjsse

  testconscrypt:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'conscrypt')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dokhttp.platform=conscrypt

  testbouncycastle:
    runs-on: ubuntu-latest
    if: contains(github.event.pull_request.labels.*.name, 'providers')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dokhttp.platform=bouncycastle

  testcorretto:
    runs-on: ubuntu-latest
    # TODO add master build after fixing all tests in CI
    if: contains(github.event.pull_request.labels.*.name, 'providers')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dokhttp.platform=corretto

  testopenjdk17:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'jdkversions') || contains(github.event.pull_request.labels.*.name, 'renovate')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=17

  testopenjdk21:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'jdkversions') || contains(github.event.pull_request.labels.*.name, 'renovate')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 21

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=21

  testwindows:
    runs-on: windows-latest
    # TODO add master build after fixing all tests in CI
    if: contains(github.event.pull_request.labels.*.name, 'windows')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Test
        run: ./gradlew test

  testgraal:
    runs-on: ubuntu-latest
    # TODO add master build after fixing all tests in CI
    if: contains(github.event.pull_request.labels.*.name, 'graal')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Build okcurl
        run: ./gradlew okcurl:nativeImage

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Build ConsoleLauncher
        run: ./gradlew -PgraalBuild=true native-image-tests:nativeImage

      - name: Run Checks
        run: ./native-image-tests/build/graal/ConsoleLauncher

  testandroid:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'android') || contains(github.event.pull_request.labels.*.name, 'renovate')

    strategy:
      fail-fast: false
      matrix:
        api-level:
          - 21
          - 29
          - 34

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Enable KVM group perms
        # https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
        run: |
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Gradle cache
        run: ./gradlew -PandroidBuild=true :okhttp-android:test

      - name: AVD cache
        uses: actions/cache@v4
        id: avd-cache
        with:
          path: |
            ~/.android/avd/*
            ~/.android/adb*
          key: avd-${{ matrix.api-level }}

      - name: Create AVD and generate snapshot for caching
        if: steps.avd-cache.outputs.cache-hit != 'true'
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          force-avd-creation: false
          emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: false
          script: echo "Generated AVD snapshot for caching."

      - name: Run Tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          script: ./gradlew -PandroidBuild=true :okhttp-android:connectedCheck :android-test:connectedCheck
        env:
          API_LEVEL: ${{ matrix.api-level }}

      - name: Run Release Tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          script: ./gradlew -PandroidBuild=true :android-test-app:connectedCheck
        env:
          API_LEVEL: ${{ matrix.api-level }}

  testloom:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'loom')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 21

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dokhttp.platform=loom -Dtest.java.version=21 -PcontainerTests=true

  testandroidregression:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    if: contains(github.event.pull_request.labels.*.name, 'android-regression')

    strategy:
      fail-fast: false
      matrix:
        api-level:
          - 29
          - 34

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Enable KVM group perms
        # https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
        run: |
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm

      - name: Gradle cache
        uses: gradle/actions/setup-gradle@v3

      - name: AVD cache
        uses: actions/cache@v4
        id: avd-cache
        with:
          path: |
            ~/.android/avd/*
            ~/.android/adb*
          key: avd-${{ matrix.api-level }}

      - name: Create AVD and generate snapshot for caching
        if: steps.avd-cache.outputs.cache-hit != 'true'
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          force-avd-creation: false
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: false
          script: echo "Generated AVD snapshot for caching."

      - name: Run Tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          script: ./gradlew -PandroidBuild=true :regression-test:connectedCheck
        env:
          API_LEVEL: ${{ matrix.api-level }}


containers

name: containers

on:
  push:
    branches:
      - master
  pull_request:
    types: [opened, labeled, unlabeled, synchronize]

permissions:
  contents: read

env:
  GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false -Dkotlin.incremental=false"

jobs:
  test_containers:
    permissions:
      checks: write # for actions/upload-artifact
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'containers')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Container Tests
        run: ./gradlew container-tests:test -PcontainerTests=true